More Info
Private Name Tags
ContractCreator
Latest 25 from a total of 110 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Join Global Game | 15431327 | 851 days ago | IN | 0 ETH | 0.00187791 | ||||
Commence Game | 15146609 | 896 days ago | IN | 0 ETH | 0.00051574 | ||||
Join Global Game | 15146461 | 896 days ago | IN | 0 ETH | 0.00225771 | ||||
Withdraw Rewards | 14982861 | 923 days ago | IN | 0 ETH | 0.00097707 | ||||
Commence Game | 14982856 | 923 days ago | IN | 0 ETH | 0.00324589 | ||||
Join Global Game | 14980837 | 923 days ago | IN | 0 ETH | 0.00659209 | ||||
Join Global Game | 14980830 | 923 days ago | IN | 0 ETH | 0.01076333 | ||||
Commence Game | 14631512 | 980 days ago | IN | 0 ETH | 0.00313842 | ||||
Join Global Game | 14630909 | 980 days ago | IN | 0 ETH | 0.01229737 | ||||
Withdraw Rewards | 14630775 | 980 days ago | IN | 0 ETH | 0.00352777 | ||||
Withdraw Rewards | 14604800 | 984 days ago | IN | 0 ETH | 0.00149345 | ||||
Withdraw Rewards | 14603968 | 984 days ago | IN | 0 ETH | 0.0026193 | ||||
Withdraw Rewards | 14600639 | 985 days ago | IN | 0 ETH | 0.00086152 | ||||
Commence Game | 14600637 | 985 days ago | IN | 0 ETH | 0.00086607 | ||||
Join Global Game | 14599969 | 985 days ago | IN | 0 ETH | 0.00371386 | ||||
Withdraw Rewards | 14599799 | 985 days ago | IN | 0 ETH | 0.00139363 | ||||
Withdraw Rewards | 14599790 | 985 days ago | IN | 0 ETH | 0.00125305 | ||||
Withdraw Rewards | 14599784 | 985 days ago | IN | 0 ETH | 0.00128495 | ||||
Withdraw Rewards | 14599779 | 985 days ago | IN | 0 ETH | 0.00097504 | ||||
Withdraw Rewards | 14599779 | 985 days ago | IN | 0 ETH | 0.00124895 | ||||
Withdraw Rewards | 14599779 | 985 days ago | IN | 0 ETH | 0.00099909 | ||||
Commence Game | 14599770 | 985 days ago | IN | 0 ETH | 0.00144005 | ||||
Commence Game | 14599770 | 985 days ago | IN | 0 ETH | 0.0043338 | ||||
Join Global Game | 14599744 | 985 days ago | IN | 0 ETH | 0.00329444 | ||||
Join Global Game | 14599643 | 985 days ago | IN | 0 ETH | 0.00557266 |
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
Contract Name:
ConfettiRoll
Compiler Version
v0.8.13+commit.abaa5c0e
Optimization Enabled:
Yes with 1000 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "@openzeppelin/contracts/interfaces/IERC20.sol"; import "@openzeppelin/contracts/access/Ownable.sol"; import "@openzeppelin/contracts/access/AccessControlEnumerable.sol"; import "@openzeppelin/contracts/utils/structs/EnumerableSet.sol"; import "@openzeppelin/contracts/security/Pausable.sol"; import "./RpSeeder.sol"; /// @title A Death Roll-inspired game for Raid Party /// @author xanewok.eth /// @notice The games uses $CFTI, the native Raid Party token contract ConfettiRoll is AccessControlEnumerable, Ownable, Pausable { using EnumerableSet for EnumerableSet.Bytes32Set; IERC20 public immutable confetti; RpSeeder public immutable seeder; address public immutable treasury; uint256 public tipAmount; uint256 public treasuryAmount; uint128 public minBet = 1e17; // 0.1 $CFTI uint128 public maxBet = 150e18; // 150 $CFTI uint128 public defaultBet = 30e18; // 30 $CFTI uint16 public treasuryFee = 500; // 5% uint16 public betTip = 50; // 0.5% uint16 constant FEE_PRECISION = 1e4; uint16 public minStartingRoll = 2; uint16 public maxStartingRoll = 1000; uint16 public defaultStartingRoll = 100; uint16 public defaultMaxParticipants = 10; bytes32 public constant TREASURY_ROLE = keccak256("TREASURY_ROLE"); struct Game { address[] participants; uint128 poolBet; uint32 roundNum; uint16 startingRoll; uint16 maxParticipants; } struct GameResult { // In theory this should always be equal to `getSeed(game.roundNum)`; // however, since we depend on an external seeder, let's always remember // the seed for a given finalized game to make the results verifiable // and deterministic uint256 finalizedSeed; // The amount that every participant (except for the loser) is due, // after the game finishes uint256 prizeShare; address loser; } event PlayerLost(bytes32 indexed gameId, address indexed player); event GameCreated(bytes32 indexed gameId); event PlayerJoined(bytes32 indexed gameId, address indexed player); mapping(bytes32 => GameResult) gameResults; mapping(bytes32 => Game) games; mapping(address => EnumerableSet.Bytes32Set) pendingGames; constructor( IERC20 confetti_, address seeder_, address treasury_ ) { _setupRole(TREASURY_ROLE, treasury_); seeder = RpSeeder(seeder_); treasury = treasury_; confetti = confetti_; tipAmount = 0; treasuryAmount = 0; } function setTreasuryFee(uint16 treasuryFee_) public onlyRole(TREASURY_ROLE) { require(treasuryFee_ <= 3000, "Let the gamblers gamble in peace"); treasuryFee = treasuryFee_; } function withdrawTax() public onlyRole(TREASURY_ROLE) { require(treasuryAmount > 0, "Nothing to withdraw"); confetti.transfer(treasury, treasuryAmount); treasuryAmount = 0; } function withdrawTip() public onlyOwner { require(tipAmount > 0, "Nothing to withdraw"); confetti.transfer(owner(), tipAmount); tipAmount = 0; } function setBetTip(uint16 betTip_) public onlyOwner { betTip = betTip_; } function setBets( uint128 min, uint128 max, uint128 default_ ) public onlyOwner { minBet = min; maxBet = max; defaultBet = default_; } function setStartingRolls( uint16 min, uint16 max, uint16 default_ ) public onlyOwner { minStartingRoll = min; maxStartingRoll = max; defaultStartingRoll = default_; } function setDefaultMaxParticipants(uint16 value) public onlyOwner { defaultMaxParticipants = value; } /// @dev We piggyback on the RaidParty batch seeder for our game round abstraction function currentRound() public view returns (uint32) { return uint32(seeder.getBatch()); } /// @notice Return generated random words for a given game round function getSeed(uint32 roundNum) public view returns (uint256) { bytes32 reqId = seeder.getReqByBatch(roundNum); return seeder.getRandomness(reqId); } function getGame(bytes32 gameId) public view returns (Game memory) { return games[gameId]; } function getGameResults(bytes32 gameId) public view returns (GameResult memory) { return gameResults[gameId]; } function isGameFinished(bytes32 gameId) public view returns (bool) { return gameResults[gameId].loser != address(0x0); } /// @notice Returns the order in which the players roll for a given game function getRollingPlayers(bytes32 gameId) public view returns (address[] memory) { Game memory game = games[gameId]; uint256 seed = getSeed(game.roundNum); require(seed > 0, "Game not seeded yet"); require(game.participants.length >= 2, "Need at least 2 players"); return shuffledPlayers(game.participants, seed); } /// @notice Returns player rolls for a given game. They correspond to player order returned by `getRollingPlayers` function getRolls(bytes32 gameId) public view returns (uint256[] memory) { Game memory game = games[gameId]; uint256 seed = getSeed(game.roundNum); require(seed > 0, "Game not seeded yet"); require(game.participants.length >= 2, "Need at least 2 players"); // NOTE: The part below is the same as `simulateGame` only with // remembering the roll values (which are originally not to save gas). // The upper bound for the number of rolls is the starting roll value uint256[] memory rolls = new uint256[](game.startingRoll); uint256 roll = game.startingRoll; uint256 rollCount = 0; while (roll > 0) { // NOTE: `roll` is always in the [1, game.startingRoll - 1] range // here, as we start if it's positive and we always use modulo, // starting from the `game.startingRoll` roll = uint256(keccak256(abi.encodePacked(rollCount, seed))) % roll; rolls[rollCount] = roll + 1; rollCount++; } // NOTE: This is meant to be executed in a read-only fashion - to get rid // of the extra zeroes, we just copy over the actual rolls to a new array uint256[] memory returnedRolls = new uint256[](rollCount); for (uint256 i = 0; i < returnedRolls.length; i++) { returnedRolls[i] = rolls[i]; } return returnedRolls; } /// @notice Returns a list of outstanding games for the player function getPendingGames(address player) public view returns (bytes32[] memory) { bytes32[] memory pendingGames_ = new bytes32[]( pendingGames[player].length() ); for (uint256 i = 0; i < pendingGames[player].length(); i++) { pendingGames_[i] = pendingGames[player].at(i); } return pendingGames_; } /// @notice Returns whether the player is eligible to collect a prize for a given game function canCollectReward(address player, bytes32 gameId) public view returns (bool) { return (isGameFinished(gameId) && gameResults[gameId].loser != player); } /// @notice Returns a total amount of claimable rewards by the player function getPendingRewards(address player) public view returns (uint256) { uint256 sum = 0; for (uint256 i = 0; i < pendingGames[player].length(); i++) { bytes32 gameId = pendingGames[player].at(i); if (canCollectReward(player, gameId)) { sum += gameResults[gameId].prizeShare; } } return sum; } /// @notice Process and clear every outstanding game, collecting the rewards function withdrawRewards() public whenNotPaused returns (uint256) { address player = msg.sender; uint256 rewards = 0; for (uint256 i = 0; i < pendingGames[player].length(); ) { bytes32 gameId = pendingGames[player].at(i); if (canCollectReward(player, gameId)) { rewards += gameResults[gameId].prizeShare; } // NOTE: This is the main function that is responsible for clearing // up pending games (e.g. for UI reasons), so make sure to clear up // pending *lost* games as well, even if we didn't collect a prize if (isGameFinished(gameId)) { pendingGames[player].remove(gameId); // Deleting an element might've shifted the order of the elements // and since we're deleting while iterating (a Bad Idea^TM), // simply start iterating from the start to be safe i = 0; } else { i++; } } confetti.transfer(msg.sender, rewards); return rewards; } /// @notice Calculates the game identifier for a given game initializer and roundNum /// The game initializer can be either the address of the contract if we're /// creating a "global" game or the address of the callee function calcGameId(address initializer, uint256 roundNum) public pure returns (bytes32) { return keccak256(abi.encodePacked(initializer, roundNum)); } /// @notice Returns a game identifier for the currently running, global game function currentGlobalGameId() public view returns (bytes32) { return calcGameId(address(this), currentRound()); } // Anyone can join the game for the current round where either they are the // initializer and they can set a custom bet or they can create a global // game per round with a default bet amount /// @notice Create a new game /// @param initializer needs to be an address of the contract or the sender /// @param poolBet The amount of money that the player enters with. Use 18 decimals, just like for $CFTI /// @param maxParticipants The maximum number of players that can join the game /// @param startingRoll The upper roll that the game begins with /// @param roundNum The round when the game will be played. Must be bigger than the current round function createGame( address initializer, uint128 poolBet, uint16 startingRoll, uint16 maxParticipants, uint32 roundNum ) public whenNotPaused returns (bytes32) { if (startingRoll == 0) { startingRoll = defaultStartingRoll; } if (poolBet == 0) { poolBet = defaultBet; } if (maxParticipants < 2) { maxParticipants = defaultMaxParticipants; } uint256 seed = getSeed(roundNum); require(seed == 0, "Game already seeded"); require( roundNum >= currentRound(), "Can't create games in the past" ); require( poolBet >= minBet && poolBet <= maxBet, "Bet outside legal range" ); require( startingRoll >= minStartingRoll && startingRoll <= maxStartingRoll, "Start roll outside legal range" ); // Allow for creating a custom game with the sender as initializer or // a "global" (per round) one that needs to have default values set require( initializer == msg.sender || (initializer == address(this) && poolBet == defaultBet && startingRoll == defaultStartingRoll && maxParticipants == defaultMaxParticipants) ); bytes32 gameId = calcGameId(initializer, roundNum); require(!isGameFinished(gameId), "Game already finished"); games[gameId].poolBet = poolBet; games[gameId].roundNum = roundNum; games[gameId].startingRoll = startingRoll; games[gameId].maxParticipants = maxParticipants; emit GameCreated(gameId); return gameId; } /// @notice Join the given game. Needs $CFTI approval as the player needs to deposit the pool bet in order to play. function joinGame(bytes32 gameId) public whenNotPaused { Game memory game = games[gameId]; require(game.startingRoll > 0, "Game doesn't exist yet"); require(!isGameFinished(gameId), "Game already finished"); // Mitigate possible front-running - close the game sign-ups about a minute // before the seeder can request randomness. The RP seeder is pre-configured // to require 3 block confirmations, so 60 seconds makes sense (< 3 * 14s) uint256 seed = getSeed(game.roundNum); require(seed == 0, "Game already seeded"); require( seeder.getNextAvailableBatch() > (block.timestamp + 60), "Seed imminent; sign-up is closed" ); require(!pendingGames[msg.sender].contains(gameId), "Already joined"); require( games[gameId].participants.length < game.maxParticipants && games[gameId].participants.length <= (FEE_PRECISION / betTip), "Too many players" ); uint256 tip = (game.poolBet * betTip) / FEE_PRECISION; tipAmount += tip; confetti.transferFrom(msg.sender, address(this), game.poolBet); games[gameId].participants.push(msg.sender); pendingGames[msg.sender].add(gameId); emit PlayerJoined(gameId, msg.sender); } /// @notice A convenient method to join the currently running global game function joinGlobalGame() public whenNotPaused returns (bytes32) { bytes32 globalGameId = currentGlobalGameId(); // Lazily create a global game if there isn't one already if (games[globalGameId].startingRoll == 0) { createGame( address(this), defaultBet, defaultStartingRoll, defaultMaxParticipants, currentRound() ); } joinGame(globalGameId); return globalGameId; } /// @return Shuffled randomly players from the given ones, using supplied seed function shuffledPlayers(address[] memory players, uint256 seed) public pure returns (address[] memory) { address[] memory shuffled = players; address temp; uint256 pick; for (uint256 i = 0; i < players.length; i++) { // Randomly pick a value from i (incl.) till the end of the array // To further increase randomness entropy, add the current player address pick = uint256(keccak256(abi.encodePacked(players[i], seed))) % (players.length - i); temp = shuffled[i]; // Save the randomly picked number as the i-th address in the sequence shuffled[i] = shuffled[i + pick]; // Return the original value to the pool that we pick from shuffled[i + pick] = temp; } return shuffled; } /// @dev Given an unitialized yet game, simulate the game and commit the results to the storage function simulateGame(bytes32 gameId) internal whenNotPaused returns (GameResult storage) { require(!isGameFinished(gameId), "Game already finished"); Game memory game = games[gameId]; uint256 seed = getSeed(game.roundNum); require(seed > 0, "Game not seeded yet"); require(game.participants.length >= 2, "Need at least 2 players"); // To remove any bias from the order that players registered with, make // sure to shuffle them before starting the actual game // NOTE: This is the same as `getRollingPlayers` address[] memory players = shuffledPlayers(game.participants, seed); // NOTE: This is the same as `getRolls`, however we don't use that as // we'd spend too much gas on remembering the rolls - we're interested // only in the outcome itself, which is the losing player uint256 roll = game.startingRoll; uint256 rollCount = 0; while (roll > 0) { // NOTE: `roll` is always in the [1, game.startingRoll - 1] range // here, as we start if it's positive and we always use modulo, // starting from the `game.startingRoll` unchecked { roll = uint256(keccak256(abi.encodePacked(rollCount, seed))) % roll; rollCount++; } } // The last to roll is the one who lost address loser = players[(rollCount - 1) % players.length]; gameResults[gameId].loser = loser; // Saved for bookkeeping gameResults[gameId].finalizedSeed = seed; return gameResults[gameId]; } /// @notice Simulates a given game, assuming it's been seeded since its creation function commenceGame(bytes32 gameId) public whenNotPaused { Game memory game = games[gameId]; require(game.participants.length > 0, "No players in the game"); if (game.participants.length == 1) { // Not much of a game if we have a single participant, return the bet confetti.transfer(game.participants[0], game.poolBet); pendingGames[game.participants[0]].remove(gameId); return; } GameResult storage results = simulateGame(gameId); require(isGameFinished(gameId), "Game not finished after simul."); require(results.loser != address(0), "Finished game has no loser"); emit PlayerLost(gameId, results.loser); // Tax the prize money for the treasury uint256 collectedBetTip = (game.poolBet * betTip) / FEE_PRECISION; uint256 payableBet = game.poolBet - collectedBetTip; uint256 treasuryShare = (payableBet * treasuryFee) / FEE_PRECISION; treasuryAmount += treasuryShare; // Split the remaining prize pool among the winners; they need to collect // them themselves to amortize gas cost of the game simulation results.prizeShare = // Original bet payableBet + // Taxed prize pool that's split among everyone (payableBet - treasuryShare) / (game.participants.length - 1); } function pause() public onlyOwner { _pause(); } function unpause() public onlyOwner { _unpause(); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import './ISeederV2.sol'; import './ISeedStorage.sol'; /// @title Access to the batch seeder used by the Raid Party game contract RpSeeder is ISeederV2, ISeedStorage { ISeederV2 private immutable seederV2; ISeedStorage private immutable seedStorage; constructor(address seederV2_, address seedStorage_) { seederV2 = ISeederV2(seederV2_); seedStorage = ISeedStorage(seedStorage_); } function getBatch() external override view returns (uint256) { return seederV2.getBatch(); } function getReqByBatch(uint256 batch) external override view returns (bytes32) { return seederV2.getReqByBatch(batch); } function getNextAvailableBatch() external override view returns (uint256) { return ISeederV2(seederV2).getNextAvailableBatch(); } function getRandomness(bytes32 key) external override view returns (uint256) { return seedStorage.getRandomness(key); } function executeRequestMulti() external { return seederV2.executeRequestMulti(); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; // Originally deployed at https://etherscan.io/address/0x2Ed251752DA7F24F33CFbd38438748BB8eeb44e1 interface ISeederV2 { function getBatch() external view returns (uint256); function getReqByBatch(uint256 batch) external view returns (bytes32); function getNextAvailableBatch() external view returns (uint256); function executeRequestMulti() external; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; // Originally deployed at https://etherscan.io/address/0xFc8f72Ac252d5409ba427629F0F1bab113a7492F interface ISeedStorage { function getRandomness(bytes32 key) external view returns (uint256); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; /** * @dev Library for managing * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive * types. * * Sets have the following properties: * * - Elements are added, removed, and checked for existence in constant time * (O(1)). * - Elements are enumerated in O(n). No guarantees are made on the ordering. * * ``` * contract Example { * // Add the library methods * using EnumerableSet for EnumerableSet.AddressSet; * * // Declare a set state variable * EnumerableSet.AddressSet private mySet; * } * ``` * * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`) * and `uint256` (`UintSet`) are supported. */ library EnumerableSet { // To implement this library for multiple types with as little code // repetition as possible, we write it in terms of a generic Set type with // bytes32 values. // The Set implementation uses private functions, and user-facing // implementations (such as AddressSet) are just wrappers around the // underlying Set. // This means that we can only create new EnumerableSets for types that fit // in bytes32. struct Set { // Storage of set values bytes32[] _values; // Position of the value in the `values` array, plus 1 because index 0 // means a value is not in the set. mapping(bytes32 => uint256) _indexes; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function _add(Set storage set, bytes32 value) private returns (bool) { if (!_contains(set, value)) { set._values.push(value); // The value is stored at length-1, but we add 1 to all indexes // and use 0 as a sentinel value set._indexes[value] = set._values.length; return true; } else { return false; } } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function _remove(Set storage set, bytes32 value) private returns (bool) { // We read and store the value's index to prevent multiple reads from the same storage slot uint256 valueIndex = set._indexes[value]; if (valueIndex != 0) { // Equivalent to contains(set, value) // To delete an element from the _values array in O(1), we swap the element to delete with the last one in // the array, and then remove the last element (sometimes called as 'swap and pop'). // This modifies the order of the array, as noted in {at}. uint256 toDeleteIndex = valueIndex - 1; uint256 lastIndex = set._values.length - 1; if (lastIndex != toDeleteIndex) { bytes32 lastvalue = set._values[lastIndex]; // Move the last value to the index where the value to delete is set._values[toDeleteIndex] = lastvalue; // Update the index for the moved value set._indexes[lastvalue] = valueIndex; // Replace lastvalue's index to valueIndex } // Delete the slot where the moved value was stored set._values.pop(); // Delete the index for the deleted slot delete set._indexes[value]; return true; } else { return false; } } /** * @dev Returns true if the value is in the set. O(1). */ function _contains(Set storage set, bytes32 value) private view returns (bool) { return set._indexes[value] != 0; } /** * @dev Returns the number of values on the set. O(1). */ function _length(Set storage set) private view returns (uint256) { return set._values.length; } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function _at(Set storage set, uint256 index) private view returns (bytes32) { return set._values[index]; } /** * @dev Return the entire set in an array * * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that * this function has an unbounded cost, and using it as part of a state-changing function may render the function * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block. */ function _values(Set storage set) private view returns (bytes32[] memory) { return set._values; } // Bytes32Set struct Bytes32Set { Set _inner; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function add(Bytes32Set storage set, bytes32 value) internal returns (bool) { return _add(set._inner, value); } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) { return _remove(set._inner, value); } /** * @dev Returns true if the value is in the set. O(1). */ function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) { return _contains(set._inner, value); } /** * @dev Returns the number of values in the set. O(1). */ function length(Bytes32Set storage set) internal view returns (uint256) { return _length(set._inner); } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) { return _at(set._inner, index); } /** * @dev Return the entire set in an array * * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that * this function has an unbounded cost, and using it as part of a state-changing function may render the function * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block. */ function values(Bytes32Set storage set) internal view returns (bytes32[] memory) { return _values(set._inner); } // AddressSet struct AddressSet { Set _inner; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function add(AddressSet storage set, address value) internal returns (bool) { return _add(set._inner, bytes32(uint256(uint160(value)))); } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function remove(AddressSet storage set, address value) internal returns (bool) { return _remove(set._inner, bytes32(uint256(uint160(value)))); } /** * @dev Returns true if the value is in the set. O(1). */ function contains(AddressSet storage set, address value) internal view returns (bool) { return _contains(set._inner, bytes32(uint256(uint160(value)))); } /** * @dev Returns the number of values in the set. O(1). */ function length(AddressSet storage set) internal view returns (uint256) { return _length(set._inner); } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function at(AddressSet storage set, uint256 index) internal view returns (address) { return address(uint160(uint256(_at(set._inner, index)))); } /** * @dev Return the entire set in an array * * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that * this function has an unbounded cost, and using it as part of a state-changing function may render the function * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block. */ function values(AddressSet storage set) internal view returns (address[] memory) { bytes32[] memory store = _values(set._inner); address[] memory result; assembly { result := store } return result; } // UintSet struct UintSet { Set _inner; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function add(UintSet storage set, uint256 value) internal returns (bool) { return _add(set._inner, bytes32(value)); } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function remove(UintSet storage set, uint256 value) internal returns (bool) { return _remove(set._inner, bytes32(value)); } /** * @dev Returns true if the value is in the set. O(1). */ function contains(UintSet storage set, uint256 value) internal view returns (bool) { return _contains(set._inner, bytes32(value)); } /** * @dev Returns the number of values on the set. O(1). */ function length(UintSet storage set) internal view returns (uint256) { return _length(set._inner); } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function at(UintSet storage set, uint256 index) internal view returns (uint256) { return uint256(_at(set._inner, index)); } /** * @dev Return the entire set in an array * * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that * this function has an unbounded cost, and using it as part of a state-changing function may render the function * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block. */ function values(UintSet storage set) internal view returns (uint256[] memory) { bytes32[] memory store = _values(set._inner); uint256[] memory result; assembly { result := store } return result; } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; /** * @dev Interface of the ERC165 standard, as defined in the * https://eips.ethereum.org/EIPS/eip-165[EIP]. * * Implementers can declare support of contract interfaces, which can then be * queried by others ({ERC165Checker}). * * For an implementation, see {ERC165}. */ interface IERC165 { /** * @dev Returns true if this contract implements the interface defined by * `interfaceId`. See the corresponding * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] * to learn more about how these ids are created. * * This function call must use less than 30 000 gas. */ function supportsInterface(bytes4 interfaceId) external view returns (bool); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "./IERC165.sol"; /** * @dev Implementation of the {IERC165} interface. * * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check * for the additional interface id that will be supported. For example: * * ```solidity * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId); * } * ``` * * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation. */ abstract contract ERC165 is IERC165 { /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { return interfaceId == type(IERC165).interfaceId; } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; /** * @dev String operations. */ library Strings { bytes16 private constant _HEX_SYMBOLS = "0123456789abcdef"; /** * @dev Converts a `uint256` to its ASCII `string` decimal representation. */ function toString(uint256 value) internal pure returns (string memory) { // Inspired by OraclizeAPI's implementation - MIT licence // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol if (value == 0) { return "0"; } uint256 temp = value; uint256 digits; while (temp != 0) { digits++; temp /= 10; } bytes memory buffer = new bytes(digits); while (value != 0) { digits -= 1; buffer[digits] = bytes1(uint8(48 + uint256(value % 10))); value /= 10; } return string(buffer); } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation. */ function toHexString(uint256 value) internal pure returns (string memory) { if (value == 0) { return "0x00"; } uint256 temp = value; uint256 length = 0; while (temp != 0) { length++; temp >>= 8; } return toHexString(value, length); } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length. */ function toHexString(uint256 value, uint256 length) internal pure returns (string memory) { bytes memory buffer = new bytes(2 * length + 2); buffer[0] = "0"; buffer[1] = "x"; for (uint256 i = 2 * length + 1; i > 1; --i) { buffer[i] = _HEX_SYMBOLS[value & 0xf]; value >>= 4; } require(value == 0, "Strings: hex length insufficient"); return string(buffer); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; /** * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ abstract contract Context { function _msgSender() internal view virtual returns (address) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { return msg.data; } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20 { /** * @dev Returns the amount of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the amount of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves `amount` tokens from the caller's account to `recipient`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address recipient, uint256 amount) external returns (bool); /** * @dev Returns the remaining number of tokens that `spender` will be * allowed to spend on behalf of `owner` through {transferFrom}. This is * zero by default. * * This value changes when {approve} or {transferFrom} are called. */ function allowance(address owner, address spender) external view returns (uint256); /** * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. * * Returns a boolean value indicating whether the operation succeeded. * * IMPORTANT: 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 * * Emits an {Approval} event. */ function approve(address spender, uint256 amount) external returns (bool); /** * @dev Moves `amount` tokens from `sender` to `recipient` using the * allowance mechanism. `amount` is then deducted from the caller's * allowance. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transferFrom( address sender, address recipient, uint256 amount ) external returns (bool); /** * @dev Emitted when `value` tokens are moved from one account (`from`) to * another (`to`). * * Note that `value` may be zero. */ event Transfer(address indexed from, address indexed to, uint256 value); /** * @dev Emitted when the allowance of a `spender` for an `owner` is set by * a call to {approve}. `value` is the new allowance. */ event Approval(address indexed owner, address indexed spender, uint256 value); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "../utils/Context.sol"; /** * @dev Contract module which allows children to implement an emergency stop * mechanism that can be triggered by an authorized account. * * This module is used through inheritance. It will make available the * modifiers `whenNotPaused` and `whenPaused`, which can be applied to * the functions of your contract. Note that they will not be pausable by * simply including this module, only once the modifiers are put in place. */ abstract contract Pausable is Context { /** * @dev Emitted when the pause is triggered by `account`. */ event Paused(address account); /** * @dev Emitted when the pause is lifted by `account`. */ event Unpaused(address account); bool private _paused; /** * @dev Initializes the contract in unpaused state. */ constructor() { _paused = false; } /** * @dev Returns true if the contract is paused, and false otherwise. */ function paused() public view virtual returns (bool) { return _paused; } /** * @dev Modifier to make a function callable only when the contract is not paused. * * Requirements: * * - The contract must not be paused. */ modifier whenNotPaused() { require(!paused(), "Pausable: paused"); _; } /** * @dev Modifier to make a function callable only when the contract is paused. * * Requirements: * * - The contract must be paused. */ modifier whenPaused() { require(paused(), "Pausable: not paused"); _; } /** * @dev Triggers stopped state. * * Requirements: * * - The contract must not be paused. */ function _pause() internal virtual whenNotPaused { _paused = true; emit Paused(_msgSender()); } /** * @dev Returns to normal state. * * Requirements: * * - The contract must be paused. */ function _unpause() internal virtual whenPaused { _paused = false; emit Unpaused(_msgSender()); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "../token/ERC20/IERC20.sol";
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "../utils/Context.sol"; /** * @dev Contract module which provides a basic access control mechanism, where * there is an account (an owner) that can be granted exclusive access to * specific functions. * * By default, the owner account will be the one that deploys the contract. This * can later be changed with {transferOwnership}. * * This module is used through inheritance. It will make available the modifier * `onlyOwner`, which can be applied to your functions to restrict their use to * the owner. */ abstract contract Ownable is Context { address private _owner; event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the deployer as the initial owner. */ constructor() { _setOwner(_msgSender()); } /** * @dev Returns the address of the current owner. */ function owner() public view virtual returns (address) { return _owner; } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { require(owner() == _msgSender(), "Ownable: caller is not the owner"); _; } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions anymore. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby removing any functionality that is only available to the owner. */ function renounceOwnership() public virtual onlyOwner { _setOwner(address(0)); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Can only be called by the current owner. */ function transferOwnership(address newOwner) public virtual onlyOwner { require(newOwner != address(0), "Ownable: new owner is the zero address"); _setOwner(newOwner); } function _setOwner(address newOwner) private { address oldOwner = _owner; _owner = newOwner; emit OwnershipTransferred(oldOwner, newOwner); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "./IAccessControl.sol"; /** * @dev External interface of AccessControlEnumerable declared to support ERC165 detection. */ interface IAccessControlEnumerable is IAccessControl { /** * @dev Returns one of the accounts that have `role`. `index` must be a * value between 0 and {getRoleMemberCount}, non-inclusive. * * Role bearers are not sorted in any particular way, and their ordering may * change at any point. * * WARNING: When using {getRoleMember} and {getRoleMemberCount}, make sure * you perform all queries on the same block. See the following * https://forum.openzeppelin.com/t/iterating-over-elements-on-enumerableset-in-openzeppelin-contracts/2296[forum post] * for more information. */ function getRoleMember(bytes32 role, uint256 index) external view returns (address); /** * @dev Returns the number of accounts that have `role`. Can be used * together with {getRoleMember} to enumerate all bearers of a role. */ function getRoleMemberCount(bytes32 role) external view returns (uint256); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; /** * @dev External interface of AccessControl declared to support ERC165 detection. */ interface IAccessControl { /** * @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole` * * `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite * {RoleAdminChanged} not being emitted signaling this. * * _Available since v3.1._ */ event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole); /** * @dev Emitted when `account` is granted `role`. * * `sender` is the account that originated the contract call, an admin role * bearer except when using {AccessControl-_setupRole}. */ event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender); /** * @dev Emitted when `account` is revoked `role`. * * `sender` is the account that originated the contract call: * - if using `revokeRole`, it is the admin role bearer * - if using `renounceRole`, it is the role bearer (i.e. `account`) */ event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender); /** * @dev Returns `true` if `account` has been granted `role`. */ function hasRole(bytes32 role, address account) external view returns (bool); /** * @dev Returns the admin role that controls `role`. See {grantRole} and * {revokeRole}. * * To change a role's admin, use {AccessControl-_setRoleAdmin}. */ function getRoleAdmin(bytes32 role) external view returns (bytes32); /** * @dev Grants `role` to `account`. * * If `account` had not been already granted `role`, emits a {RoleGranted} * event. * * Requirements: * * - the caller must have ``role``'s admin role. */ function grantRole(bytes32 role, address account) external; /** * @dev Revokes `role` from `account`. * * If `account` had been granted `role`, emits a {RoleRevoked} event. * * Requirements: * * - the caller must have ``role``'s admin role. */ function revokeRole(bytes32 role, address account) external; /** * @dev Revokes `role` from the calling account. * * Roles are often managed via {grantRole} and {revokeRole}: this function's * purpose is to provide a mechanism for accounts to lose their privileges * if they are compromised (such as when a trusted device is misplaced). * * If the calling account had been granted `role`, emits a {RoleRevoked} * event. * * Requirements: * * - the caller must be `account`. */ function renounceRole(bytes32 role, address account) external; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "./IAccessControlEnumerable.sol"; import "./AccessControl.sol"; import "../utils/structs/EnumerableSet.sol"; /** * @dev Extension of {AccessControl} that allows enumerating the members of each role. */ abstract contract AccessControlEnumerable is IAccessControlEnumerable, AccessControl { using EnumerableSet for EnumerableSet.AddressSet; mapping(bytes32 => EnumerableSet.AddressSet) private _roleMembers; /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { return interfaceId == type(IAccessControlEnumerable).interfaceId || super.supportsInterface(interfaceId); } /** * @dev Returns one of the accounts that have `role`. `index` must be a * value between 0 and {getRoleMemberCount}, non-inclusive. * * Role bearers are not sorted in any particular way, and their ordering may * change at any point. * * WARNING: When using {getRoleMember} and {getRoleMemberCount}, make sure * you perform all queries on the same block. See the following * https://forum.openzeppelin.com/t/iterating-over-elements-on-enumerableset-in-openzeppelin-contracts/2296[forum post] * for more information. */ function getRoleMember(bytes32 role, uint256 index) public view override returns (address) { return _roleMembers[role].at(index); } /** * @dev Returns the number of accounts that have `role`. Can be used * together with {getRoleMember} to enumerate all bearers of a role. */ function getRoleMemberCount(bytes32 role) public view override returns (uint256) { return _roleMembers[role].length(); } /** * @dev Overload {grantRole} to track enumerable memberships */ function grantRole(bytes32 role, address account) public virtual override(AccessControl, IAccessControl) { super.grantRole(role, account); _roleMembers[role].add(account); } /** * @dev Overload {revokeRole} to track enumerable memberships */ function revokeRole(bytes32 role, address account) public virtual override(AccessControl, IAccessControl) { super.revokeRole(role, account); _roleMembers[role].remove(account); } /** * @dev Overload {renounceRole} to track enumerable memberships */ function renounceRole(bytes32 role, address account) public virtual override(AccessControl, IAccessControl) { super.renounceRole(role, account); _roleMembers[role].remove(account); } /** * @dev Overload {_setupRole} to track enumerable memberships */ function _setupRole(bytes32 role, address account) internal virtual override { super._setupRole(role, account); _roleMembers[role].add(account); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "./IAccessControl.sol"; import "../utils/Context.sol"; import "../utils/Strings.sol"; import "../utils/introspection/ERC165.sol"; /** * @dev Contract module that allows children to implement role-based access * control mechanisms. This is a lightweight version that doesn't allow enumerating role * members except through off-chain means by accessing the contract event logs. Some * applications may benefit from on-chain enumerability, for those cases see * {AccessControlEnumerable}. * * Roles are referred to by their `bytes32` identifier. These should be exposed * in the external API and be unique. The best way to achieve this is by * using `public constant` hash digests: * * ``` * bytes32 public constant MY_ROLE = keccak256("MY_ROLE"); * ``` * * Roles can be used to represent a set of permissions. To restrict access to a * function call, use {hasRole}: * * ``` * function foo() public { * require(hasRole(MY_ROLE, msg.sender)); * ... * } * ``` * * Roles can be granted and revoked dynamically via the {grantRole} and * {revokeRole} functions. Each role has an associated admin role, and only * accounts that have a role's admin role can call {grantRole} and {revokeRole}. * * By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means * that only accounts with this role will be able to grant or revoke other * roles. More complex role relationships can be created by using * {_setRoleAdmin}. * * WARNING: The `DEFAULT_ADMIN_ROLE` is also its own admin: it has permission to * grant and revoke this role. Extra precautions should be taken to secure * accounts that have been granted it. */ abstract contract AccessControl is Context, IAccessControl, ERC165 { struct RoleData { mapping(address => bool) members; bytes32 adminRole; } mapping(bytes32 => RoleData) private _roles; bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00; /** * @dev Modifier that checks that an account has a specific role. Reverts * with a standardized message including the required role. * * The format of the revert reason is given by the following regular expression: * * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/ * * _Available since v4.1._ */ modifier onlyRole(bytes32 role) { _checkRole(role, _msgSender()); _; } /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { return interfaceId == type(IAccessControl).interfaceId || super.supportsInterface(interfaceId); } /** * @dev Returns `true` if `account` has been granted `role`. */ function hasRole(bytes32 role, address account) public view override returns (bool) { return _roles[role].members[account]; } /** * @dev Revert with a standard message if `account` is missing `role`. * * The format of the revert reason is given by the following regular expression: * * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/ */ function _checkRole(bytes32 role, address account) internal view { if (!hasRole(role, account)) { revert( string( abi.encodePacked( "AccessControl: account ", Strings.toHexString(uint160(account), 20), " is missing role ", Strings.toHexString(uint256(role), 32) ) ) ); } } /** * @dev Returns the admin role that controls `role`. See {grantRole} and * {revokeRole}. * * To change a role's admin, use {_setRoleAdmin}. */ function getRoleAdmin(bytes32 role) public view override returns (bytes32) { return _roles[role].adminRole; } /** * @dev Grants `role` to `account`. * * If `account` had not been already granted `role`, emits a {RoleGranted} * event. * * Requirements: * * - the caller must have ``role``'s admin role. */ function grantRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) { _grantRole(role, account); } /** * @dev Revokes `role` from `account`. * * If `account` had been granted `role`, emits a {RoleRevoked} event. * * Requirements: * * - the caller must have ``role``'s admin role. */ function revokeRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) { _revokeRole(role, account); } /** * @dev Revokes `role` from the calling account. * * Roles are often managed via {grantRole} and {revokeRole}: this function's * purpose is to provide a mechanism for accounts to lose their privileges * if they are compromised (such as when a trusted device is misplaced). * * If the calling account had been granted `role`, emits a {RoleRevoked} * event. * * Requirements: * * - the caller must be `account`. */ function renounceRole(bytes32 role, address account) public virtual override { require(account == _msgSender(), "AccessControl: can only renounce roles for self"); _revokeRole(role, account); } /** * @dev Grants `role` to `account`. * * If `account` had not been already granted `role`, emits a {RoleGranted} * event. Note that unlike {grantRole}, this function doesn't perform any * checks on the calling account. * * [WARNING] * ==== * This function should only be called from the constructor when setting * up the initial roles for the system. * * Using this function in any other way is effectively circumventing the admin * system imposed by {AccessControl}. * ==== */ function _setupRole(bytes32 role, address account) internal virtual { _grantRole(role, account); } /** * @dev Sets `adminRole` as ``role``'s admin role. * * Emits a {RoleAdminChanged} event. */ function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual { bytes32 previousAdminRole = getRoleAdmin(role); _roles[role].adminRole = adminRole; emit RoleAdminChanged(role, previousAdminRole, adminRole); } function _grantRole(bytes32 role, address account) private { if (!hasRole(role, account)) { _roles[role].members[account] = true; emit RoleGranted(role, account, _msgSender()); } } function _revokeRole(bytes32 role, address account) private { if (hasRole(role, account)) { _roles[role].members[account] = false; emit RoleRevoked(role, account, _msgSender()); } } }
{ "remappings": [], "optimizer": { "enabled": true, "runs": 1000 }, "evmVersion": "london", "libraries": {}, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"contract IERC20","name":"confetti_","type":"address"},{"internalType":"address","name":"seeder_","type":"address"},{"internalType":"address","name":"treasury_","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"gameId","type":"bytes32"}],"name":"GameCreated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Paused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"gameId","type":"bytes32"},{"indexed":true,"internalType":"address","name":"player","type":"address"}],"name":"PlayerJoined","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"gameId","type":"bytes32"},{"indexed":true,"internalType":"address","name":"player","type":"address"}],"name":"PlayerLost","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"previousAdminRole","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"newAdminRole","type":"bytes32"}],"name":"RoleAdminChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleGranted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleRevoked","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Unpaused","type":"event"},{"inputs":[],"name":"DEFAULT_ADMIN_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"TREASURY_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"betTip","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"initializer","type":"address"},{"internalType":"uint256","name":"roundNum","type":"uint256"}],"name":"calcGameId","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"player","type":"address"},{"internalType":"bytes32","name":"gameId","type":"bytes32"}],"name":"canCollectReward","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"gameId","type":"bytes32"}],"name":"commenceGame","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"confetti","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"initializer","type":"address"},{"internalType":"uint128","name":"poolBet","type":"uint128"},{"internalType":"uint16","name":"startingRoll","type":"uint16"},{"internalType":"uint16","name":"maxParticipants","type":"uint16"},{"internalType":"uint32","name":"roundNum","type":"uint32"}],"name":"createGame","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"currentGlobalGameId","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"currentRound","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"defaultBet","outputs":[{"internalType":"uint128","name":"","type":"uint128"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"defaultMaxParticipants","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"defaultStartingRoll","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"gameId","type":"bytes32"}],"name":"getGame","outputs":[{"components":[{"internalType":"address[]","name":"participants","type":"address[]"},{"internalType":"uint128","name":"poolBet","type":"uint128"},{"internalType":"uint32","name":"roundNum","type":"uint32"},{"internalType":"uint16","name":"startingRoll","type":"uint16"},{"internalType":"uint16","name":"maxParticipants","type":"uint16"}],"internalType":"struct ConfettiRoll.Game","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"gameId","type":"bytes32"}],"name":"getGameResults","outputs":[{"components":[{"internalType":"uint256","name":"finalizedSeed","type":"uint256"},{"internalType":"uint256","name":"prizeShare","type":"uint256"},{"internalType":"address","name":"loser","type":"address"}],"internalType":"struct ConfettiRoll.GameResult","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"player","type":"address"}],"name":"getPendingGames","outputs":[{"internalType":"bytes32[]","name":"","type":"bytes32[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"player","type":"address"}],"name":"getPendingRewards","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"getRoleAdmin","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"getRoleMember","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"getRoleMemberCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"gameId","type":"bytes32"}],"name":"getRollingPlayers","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"gameId","type":"bytes32"}],"name":"getRolls","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"roundNum","type":"uint32"}],"name":"getSeed","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"grantRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"hasRole","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"gameId","type":"bytes32"}],"name":"isGameFinished","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"gameId","type":"bytes32"}],"name":"joinGame","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"joinGlobalGame","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"maxBet","outputs":[{"internalType":"uint128","name":"","type":"uint128"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxStartingRoll","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"minBet","outputs":[{"internalType":"uint128","name":"","type":"uint128"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"minStartingRoll","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"renounceRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"revokeRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"seeder","outputs":[{"internalType":"contract RpSeeder","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"betTip_","type":"uint16"}],"name":"setBetTip","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint128","name":"min","type":"uint128"},{"internalType":"uint128","name":"max","type":"uint128"},{"internalType":"uint128","name":"default_","type":"uint128"}],"name":"setBets","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"value","type":"uint16"}],"name":"setDefaultMaxParticipants","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"min","type":"uint16"},{"internalType":"uint16","name":"max","type":"uint16"},{"internalType":"uint16","name":"default_","type":"uint16"}],"name":"setStartingRolls","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"treasuryFee_","type":"uint16"}],"name":"setTreasuryFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"players","type":"address[]"},{"internalType":"uint256","name":"seed","type":"uint256"}],"name":"shuffledPlayers","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"tipAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"treasury","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"treasuryAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"treasuryFee","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"unpause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdrawRewards","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdrawTax","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdrawTip","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
60e0604052780821ab0d44149800000000000000000000016345785d8a0000600555600680546001600160e01b0319167a0a006403e80002003201f40000000000000001a055690d9db800001790553480156200005b57600080fd5b5060405162004359380380620043598339810160408190526200007e91620002b9565b6200008933620000e9565b6002805460ff60a01b19169055620000c27fe1dcbdb91df27212a29bc27177c840cf2f819ecf2187432e1fac86c2dd5dfca9826200013b565b6001600160a01b0391821660a052811660c05216608052600060038190556004556200030d565b600280546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6200015282826200017e60201b62002d9f1760201c565b60008281526001602090815260409091206200017991839062002dad6200018e821b17901c565b505050565b6200018a8282620001ae565b5050565b6000620001a5836001600160a01b0384166200024e565b90505b92915050565b6000828152602081815260408083206001600160a01b038516845290915290205460ff166200018a576000828152602081815260408083206001600160a01b03851684529091529020805460ff191660011790556200020a3390565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b60008181526001830160205260408120546200029757508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155620001a8565b506000620001a8565b6001600160a01b0381168114620002b657600080fd5b50565b600080600060608486031215620002cf57600080fd5b8351620002dc81620002a0565b6020850151909350620002ef81620002a0565b60408501519092506200030281620002a0565b809150509250925092565b60805160a05160c051613fd662000383600039600081816105920152612ae70152600081816105d101528181611135015281816111d201528181611dd7015261236801526000818161079a01528181611830015281816125d50152818161281e015281816129690152612aba0152613fd66000f3fe608060405234801561001057600080fd5b506004361061036d5760003560e01c8063715018a6116101d35780639f20829d11610104578063d11a57ec116100a2578063dfa20f0a1161007c578063dfa20f0a14610884578063f18a065e1461088c578063f2fde38b1461089f578063f6ed2017146108b257600080fd5b8063d11a57ec14610842578063d547741f14610869578063d98011461461087c57600080fd5b8063bf474766116100de578063bf474766146107ff578063c7b8981c14610812578063ca15c8731461081a578063cc32d1761461082d57600080fd5b80639f20829d146107d1578063a217fddf146107e4578063a652db49146107ec57600080fd5b80638f468988116101715780639619367d1161014b5780639619367d1461076f57806397bebf9d146107825780639e609005146107955780639e9ed821146107bc57600080fd5b80638f4689881461071d5780639010d07c1461072557806391d148541461073857600080fd5b80637aa8977f116101ad5780637aa8977f146106d45780638456cb59146106e75780638a19c8bc146106ef5780638da5cb5b1461070c57600080fd5b8063715018a61461065757806373931bbf1461065f5780637559b8811461067f57600080fd5b80633ce4f515116102ad5780635c975abb1161024b578063684931ed11610225578063684931ed146105cc57806368f46b62146105f35780636d6b0eb3146106065780636e8539251461064457600080fd5b80635c975abb14610572578063608ac8d51461058457806361d027b31461058d57600080fd5b80634c223a82116102875780634c223a8214610519578063556bc85e1461052c57806359fe289e1461053f5780635a744c4d1461055257600080fd5b80633ce4f515146104e95780633f4ba83a146104fc57806342dc6b8b1461050457600080fd5b80632ad9bf951161031a5780632f2ff15d116102f45780632f2ff15d146104a3578063345d9a8d146104b857806336568abe146104cd578063368acb09146104e057600080fd5b80632ad9bf95146104495780632c0c4af9146104515780632e5b21681461047157600080fd5b8063230669e51161034b578063230669e5146103e3578063248a9ca3146103f857806328119fb81461041b57600080fd5b806301b654961461037257806301ffc9a71461039f57806312c61d3f146103c2575b600080fd5b60065461038790600160b01b900461ffff1681565b60405161ffff90911681526020015b60405180910390f35b6103b26103ad3660046138f2565b6108c5565b6040519015158152602001610396565b6103d56103d0366004613970565b610909565b604051908152602001610396565b60065461038790600160a01b900461ffff1681565b6103d56104063660046139d5565b60009081526020819052604090206001015490565b6103b26104293660046139d5565b6000908152600760205260409020600201546001600160a01b0316151590565b6103d5610d56565b61046461045f3660046139d5565b610db6565b60405161039691906139ee565b60055461048b90600160801b90046001600160801b031681565b6040516001600160801b039091168152602001610396565b6104b66104b1366004613a32565b6110ab565b005b60065461038790600160c01b900461ffff1681565b6104b66104db366004613a32565b6110d2565b6103d560045481565b6103d56104f7366004613a5e565b6110f4565b6104b661124c565b60065461038790600160901b900461ffff1681565b6104b6610527366004613a79565b6112b0565b6104b661053a366004613a79565b611346565b6104b661054d366004613a94565b6113dc565b6105656105603660046139d5565b611483565b6040516103969190613b1b565b600254600160a01b900460ff166103b2565b6103d560035481565b6105b47f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b039091168152602001610396565b6105b47f000000000000000000000000000000000000000000000000000000000000000081565b6103b2610601366004613b2e565b611613565b6106196106143660046139d5565b61165c565b604080518251815260208084015190820152918101516001600160a01b031690820152606001610396565b6104b66106523660046139d5565b6116cb565b6104b6611b36565b61067261066d3660046139d5565b611b9a565b6040516103969190613b58565b6103d561068d366004613b2e565b6040516bffffffffffffffffffffffff19606084901b1660208201526034810182905260009060540160405160208183030381529060405280519060200120905092915050565b6104646106e2366004613bc1565b611c85565b6104b6611d71565b6106f7611dd3565b60405163ffffffff9091168152602001610396565b6002546001600160a01b03166105b4565b6103d5611e57565b6105b4610733366004613bdc565b611f14565b6103b2610746366004613a32565b6000918252602082815260408084206001600160a01b0393909316845291905290205460ff1690565b60055461048b906001600160801b031681565b60065461048b906001600160801b031681565b6105b47f000000000000000000000000000000000000000000000000000000000000000081565b60065461038790600160d01b900461ffff1681565b6105656107df366004613c14565b611f2c565b6103d5600081565b6104b66107fa366004613a79565b612074565b6104b661080d3660046139d5565b612132565b6103d56126d2565b6103d56108283660046139d5565b61289a565b60065461038790600160801b900461ffff1681565b6103d57fe1dcbdb91df27212a29bc27177c840cf2f819ecf2187432e1fac86c2dd5dfca981565b6104b6610877366004613a32565b6128b1565b6104b66128bb565b6104b6612a22565b6104b661089a366004613cdf565b612b6d565b6104b66108ad366004613bc1565b612c2e565b6103d56108c0366004613bc1565b612d0d565b60006001600160e01b031982167f5a05180f000000000000000000000000000000000000000000000000000000001480610903575061090382612dc2565b92915050565b600254600090600160a01b900460ff161561095e5760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b60448201526064015b60405180910390fd5b8361ffff1660000361097b57600654600160c01b900461ffff1693505b846001600160801b031660000361099b576006546001600160801b031694505b60028361ffff1610156109b957600654600160d01b900461ffff1692505b60006109c4836110f4565b90508015610a145760405162461bcd60e51b815260206004820152601360248201527f47616d6520616c726561647920736565646564000000000000000000000000006044820152606401610955565b610a1c611dd3565b63ffffffff168363ffffffff161015610a775760405162461bcd60e51b815260206004820152601e60248201527f43616e2774206372656174652067616d657320696e20746865207061737400006044820152606401610955565b6005546001600160801b0390811690871610801590610aac57506005546001600160801b03600160801b909104811690871611155b610af85760405162461bcd60e51b815260206004820152601760248201527f426574206f757473696465206c6567616c2072616e67650000000000000000006044820152606401610955565b60065461ffff600160a01b909104811690861610801590610b2a575060065461ffff600160b01b909104811690861611155b610b765760405162461bcd60e51b815260206004820152601e60248201527f537461727420726f6c6c206f757473696465206c6567616c2072616e676500006044820152606401610955565b6001600160a01b038716331480610be357506001600160a01b03871630148015610bad57506006546001600160801b038781169116145b8015610bc8575060065461ffff868116600160c01b90920416145b8015610be3575060065461ffff858116600160d01b90920416145b610bec57600080fd5b6000610c40888563ffffffff166040516bffffffffffffffffffffffff19606084901b1660208201526034810182905260009060540160405160208183030381529060405280519060200120905092915050565b6000818152600760205260409020600201549091506001600160a01b031615610cab5760405162461bcd60e51b815260206004820152601560248201527f47616d6520616c72656164792066696e697368656400000000000000000000006044820152606401610955565b60008181526008602052604080822060010180546001600160801b038b1673ffffffffffffffffffffffffffffffffffffffff1990911617600160801b63ffffffff8916021763ffffffff60a01b1916600160a01b61ffff8b81169190910261ffff60b01b191691909117600160b01b918a16919091021790555182917f7195cf6f05afbbfa979e2346d841dcb24356d5956eec907794f47ff7acaf701291a2979650505050505050565b6000610db130610d64611dd3565b63ffffffff166040516bffffffffffffffffffffffff19606084901b1660208201526034810182905260009060540160405160208183030381529060405280519060200120905092915050565b905090565b60008181526008602090815260408083208151815460c09481028201850190935260a081018381526060959491938492849190840182828015610e2257602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311610e04575b5050509183525050600191909101546001600160801b038116602083015263ffffffff600160801b82041660408084019190915261ffff600160a01b830481166060850152600160b01b909204909116608090920191909152810151909150600090610e8d906110f4565b905060008111610edf5760405162461bcd60e51b815260206004820152601360248201527f47616d65206e6f742073656564656420796574000000000000000000000000006044820152606401610955565b81515160021115610f325760405162461bcd60e51b815260206004820152601760248201527f4e656564206174206c65617374203220706c61796572730000000000000000006044820152606401610955565b6000826060015161ffff1667ffffffffffffffff811115610f5557610f55613bfe565b604051908082528060200260200182016040528015610f7e578160200160208202803683370190505b50606084015190915061ffff1660005b81156110035760408051602080820184905281830187905282518083038401815260609092019092528051910120610fc7908390613d2f565b9150610fd4826001613d59565b838281518110610fe657610fe6613d71565b602090810291909101015280610ffb81613d87565b915050610f8e565b60008167ffffffffffffffff81111561101e5761101e613bfe565b604051908082528060200260200182016040528015611047578160200160208202803683370190505b50905060005b815181101561109f5784818151811061106857611068613d71565b602002602001015182828151811061108257611082613d71565b60209081029190910101528061109781613d87565b91505061104d565b50979650505050505050565b6110b58282612e29565b60008281526001602052604090206110cd9082612dad565b505050565b6110dc8282612e4f565b60008281526001602052604090206110cd9082612ed7565b6040517f591c0e1c00000000000000000000000000000000000000000000000000000000815263ffffffff8216600482015260009081906001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063591c0e1c90602401602060405180830381865afa15801561117c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111a09190613da0565b6040517f05b19402000000000000000000000000000000000000000000000000000000008152600481018290529091507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906305b1940290602401602060405180830381865afa158015611221573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112459190613da0565b9392505050565b6002546001600160a01b031633146112a65760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610955565b6112ae612eec565b565b6002546001600160a01b0316331461130a5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610955565b6006805461ffff909216600160d01b027fffffffff0000ffffffffffffffffffffffffffffffffffffffffffffffffffff909216919091179055565b6002546001600160a01b031633146113a05760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610955565b6006805461ffff909216600160901b027fffffffffffffffffffffffff0000ffffffffffffffffffffffffffffffffffff909216919091179055565b6002546001600160a01b031633146114365760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610955565b6001600160801b03928316600160801b9284169290920291909117600555600680547fffffffffffffffffffffffffffffffff000000000000000000000000000000001691909216179055565b60008181526008602090815260408083208151815460c09481028201850190935260a0810183815260609594919384928491908401828280156114ef57602002820191906000526020600020905b81546001600160a01b031681526001909101906020018083116114d1575b5050509183525050600191909101546001600160801b038116602083015263ffffffff600160801b82041660408084019190915261ffff600160a01b830481166060850152600160b01b90920490911660809092019190915281015190915060009061155a906110f4565b9050600081116115ac5760405162461bcd60e51b815260206004820152601360248201527f47616d65206e6f742073656564656420796574000000000000000000000000006044820152606401610955565b815151600211156115ff5760405162461bcd60e51b815260206004820152601760248201527f4e656564206174206c65617374203220706c61796572730000000000000000006044820152606401610955565b815161160b9082611f2c565b949350505050565b6000818152600760205260408120600201546001600160a01b0316151580156112455750506000908152600760205260409020600201546001600160a01b039081169116141590565b6116896040518060600160405280600081526020016000815260200160006001600160a01b031681525090565b50600090815260076020908152604091829020825160608101845281548152600182015492810192909252600201546001600160a01b03169181019190915290565b600254600160a01b900460ff16156117185760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b6044820152606401610955565b60008181526008602090815260408083208151815460c09481028201850190935260a0810183815290939192849284919084018282801561178257602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311611764575b5050509183525050600191909101546001600160801b038116602083015263ffffffff600160801b820416604083015261ffff600160a01b820481166060840152600160b01b909104166080909101528051519091506118245760405162461bcd60e51b815260206004820152601660248201527f4e6f20706c617965727320696e207468652067616d65000000000000000000006044820152606401610955565b805151600103611954577f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663a9059cbb826000015160008151811061187457611874613d71565b602002602001015183602001516040518363ffffffff1660e01b81526004016118bb9291906001600160a01b039290921682526001600160801b0316602082015260400190565b6020604051808303816000875af11580156118da573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118fe9190613db9565b506110cd8260096000846000015160008151811061191e5761191e613d71565b60200260200101516001600160a01b03166001600160a01b03168152602001908152602001600020612f9290919063ffffffff16565b600061195f83612f9e565b6000848152600760205260409020600201549091506001600160a01b03166119c95760405162461bcd60e51b815260206004820152601e60248201527f47616d65206e6f742066696e69736865642061667465722073696d756c2e00006044820152606401610955565b60028101546001600160a01b0316611a235760405162461bcd60e51b815260206004820152601a60248201527f46696e69736865642067616d6520686173206e6f206c6f7365720000000000006044820152606401610955565b60028101546040516001600160a01b039091169084907fd5a82ebfa8edb5cbec605a5fe6ef6469bb00d282b0d42748e6434ced9617b5b090600090a3600654602083015160009161271091611a8391600160901b900461ffff1690613ddb565b611a8d9190613e0a565b6001600160801b0316905060008184602001516001600160801b0316611ab39190613e30565b60065490915060009061271090611ad590600160801b900461ffff1684613e47565b611adf9190613e66565b90508060046000828254611af39190613d59565b9091555050845151611b0790600190613e30565b611b118284613e30565b611b1b9190613e66565b611b259083613d59565b846001018190555050505050505b50565b6002546001600160a01b03163314611b905760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610955565b6112ae60006132c3565b6040805160a0810182526060808252600060208301819052928201839052810182905260808101919091526000828152600860209081526040918290208251815460c09381028201840190945260a081018481529093919284928491840182828015611c2f57602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311611c11575b5050509183525050600191909101546001600160801b038116602083015263ffffffff600160801b820416604083015261ffff600160a01b820481166060840152600160b01b9091041660809091015292915050565b6001600160a01b038116600090815260096020526040812060609190611caa90613322565b67ffffffffffffffff811115611cc257611cc2613bfe565b604051908082528060200260200182016040528015611ceb578160200160208202803683370190505b50905060005b6001600160a01b0384166000908152600960205260409020611d1290613322565b811015611d6a576001600160a01b0384166000908152600960205260409020611d3b908261332c565b828281518110611d4d57611d4d613d71565b602090810291909101015280611d6281613d87565b915050611cf1565b5092915050565b6002546001600160a01b03163314611dcb5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610955565b6112ae613338565b60007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316633b1fee6c6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611e33573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610db19190613da0565b600254600090600160a01b900460ff1615611ea75760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b6044820152606401610955565b6000611eb1610d56565b600081815260086020526040812060010154919250600160a01b90910461ffff169003611f0b57600654611f099030906001600160801b0381169061ffff600160c01b8204811691600160d01b9004166103d0611dd3565b505b610db181612132565b6000828152600160205260408120611245908361332c565b606082600080805b865181101561206957808751611f4a9190613e30565b878281518110611f5c57611f5c613d71565b602002602001015187604051602001611f9392919060609290921b6bffffffffffffffffffffffff19168252601482015260340190565b6040516020818303038152906040528051906020012060001c611fb69190613d2f565b9150838181518110611fca57611fca613d71565b60200260200101519250838282611fe19190613d59565b81518110611ff157611ff1613d71565b602002602001015184828151811061200b5761200b613d71565b6001600160a01b0390921660209283029190910190910152828461202f8484613d59565b8151811061203f5761203f613d71565b6001600160a01b03909216602092830291909101909101528061206181613d87565b915050611f34565b509195945050505050565b7fe1dcbdb91df27212a29bc27177c840cf2f819ecf2187432e1fac86c2dd5dfca961209f81336133c0565b610bb88261ffff1611156120f55760405162461bcd60e51b815260206004820181905260248201527f4c6574207468652067616d626c6572732067616d626c6520696e2070656163656044820152606401610955565b506006805461ffff909216600160801b027fffffffffffffffffffffffffffff0000ffffffffffffffffffffffffffffffff909216919091179055565b600254600160a01b900460ff161561217f5760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b6044820152606401610955565b60008181526008602090815260408083208151815460c09481028201850190935260a081018381529093919284928491908401828280156121e957602002820191906000526020600020905b81546001600160a01b031681526001909101906020018083116121cb575b5050509183525050600191909101546001600160801b038116602083015263ffffffff600160801b820416604083015261ffff600160a01b82048116606080850191909152600160b01b9092048116608090930192909252820151919250166122945760405162461bcd60e51b815260206004820152601660248201527f47616d6520646f65736e277420657869737420796574000000000000000000006044820152606401610955565b6000828152600760205260409020600201546001600160a01b0316156122fc5760405162461bcd60e51b815260206004820152601560248201527f47616d6520616c72656164792066696e697368656400000000000000000000006044820152606401610955565b600061230b82604001516110f4565b9050801561235b5760405162461bcd60e51b815260206004820152601360248201527f47616d6520616c726561647920736565646564000000000000000000000000006044820152606401610955565b61236642603c613d59565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316633c099fce6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156123c4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123e89190613da0565b116124355760405162461bcd60e51b815260206004820181905260248201527f5365656420696d6d696e656e743b207369676e2d757020697320636c6f7365646044820152606401610955565b33600090815260096020526040902061244e908461343e565b1561249b5760405162461bcd60e51b815260206004820152600e60248201527f416c7265616479206a6f696e65640000000000000000000000000000000000006044820152606401610955565b608082015160008481526008602052604090205461ffff9091161180156124f057506006546124d790600160901b900461ffff16612710613e7a565b60008481526008602052604090205461ffff9190911610155b61253c5760405162461bcd60e51b815260206004820152601060248201527f546f6f206d616e7920706c6179657273000000000000000000000000000000006044820152606401610955565b60065460208301516000916127109161256091600160901b900461ffff1690613ddb565b61256a9190613e0a565b6001600160801b0316905080600360008282546125879190613d59565b909155505060208301516040517f23b872dd0000000000000000000000000000000000000000000000000000000081523360048201523060248201526001600160801b0390911660448201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906323b872dd906064016020604051808303816000875af1158015612626573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061264a9190613db9565b506000848152600860209081526040808320805460018101825590845282842001805473ffffffffffffffffffffffffffffffffffffffff19163390811790915583526009909152902061269e9085613456565b50604051339085907fdd5a0e5e0c7946c099f2ed766c0b633dd2eb1e1e10743bab89f871e8038b080b90600090a350505050565b600254600090600160a01b900460ff16156127225760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b6044820152606401610955565b336000805b6001600160a01b038316600090815260096020526040902061274890613322565b811015612801576001600160a01b0383166000908152600960205260408120612771908361332c565b905061277d8482611613565b156127a15760008181526007602052604090206001015461279e9084613d59565b92505b6000818152600760205260409020600201546001600160a01b0316156127ed576001600160a01b03841660009081526009602052604090206127e39082612f92565b50600091506127fb565b816127f781613d87565b9250505b50612727565b5060405163a9059cbb60e01b8152336004820152602481018290527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063a9059cbb906044016020604051808303816000875af115801561286f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906128939190613db9565b5091505090565b600081815260016020526040812061090390613322565b6110dc8282613462565b6002546001600160a01b031633146129155760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610955565b6000600354116129675760405162461bcd60e51b815260206004820152601360248201527f4e6f7468696e6720746f207769746864726177000000000000000000000000006044820152606401610955565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663a9059cbb6129a86002546001600160a01b031690565b6003546040516001600160e01b031960e085901b1681526001600160a01b03909216600483015260248201526044016020604051808303816000875af11580156129f6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612a1a9190613db9565b506000600355565b7fe1dcbdb91df27212a29bc27177c840cf2f819ecf2187432e1fac86c2dd5dfca9612a4d81336133c0565b600060045411612a9f5760405162461bcd60e51b815260206004820152601360248201527f4e6f7468696e6720746f207769746864726177000000000000000000000000006044820152606401610955565b6004805460405163a9059cbb60e01b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169263a9059cbb92612b21927f000000000000000000000000000000000000000000000000000000000000000092016001600160a01b03929092168252602082015260400190565b6020604051808303816000875af1158015612b40573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612b649190613db9565b50506000600455565b6002546001600160a01b03163314612bc75760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610955565b6006805463ffffffff60a01b1916600160a01b61ffff9586160261ffff60b01b191617600160b01b93851693909302929092177fffffffffffff0000ffffffffffffffffffffffffffffffffffffffffffffffff16600160c01b9190931602919091179055565b6002546001600160a01b03163314612c885760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610955565b6001600160a01b038116612d045760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f64647265737300000000000000000000000000000000000000000000000000006064820152608401610955565b611b33816132c3565b600080805b6001600160a01b0384166000908152600960205260409020612d3390613322565b811015611d6a576001600160a01b0384166000908152600960205260408120612d5c908361332c565b9050612d688582611613565b15612d8c57600081815260076020526040902060010154612d899084613d59565b92505b5080612d9781613d87565b915050612d12565b612da98282613488565b5050565b6000611245836001600160a01b038416613526565b60006001600160e01b031982167f7965db0b00000000000000000000000000000000000000000000000000000000148061090357507f01ffc9a7000000000000000000000000000000000000000000000000000000006001600160e01b0319831614610903565b600082815260208190526040902060010154612e4581336133c0565b6110cd8383613488565b6001600160a01b0381163314612ecd5760405162461bcd60e51b815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201527f20726f6c657320666f722073656c6600000000000000000000000000000000006064820152608401610955565b612da98282613575565b6000611245836001600160a01b0384166135f4565b600254600160a01b900460ff16612f455760405162461bcd60e51b815260206004820152601460248201527f5061757361626c653a206e6f74207061757365640000000000000000000000006044820152606401610955565b6002805460ff60a01b191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa335b6040516001600160a01b03909116815260200160405180910390a1565b600061124583836135f4565b600254600090600160a01b900460ff1615612fee5760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b6044820152606401610955565b6000828152600760205260409020600201546001600160a01b0316156130565760405162461bcd60e51b815260206004820152601560248201527f47616d6520616c72656164792066696e697368656400000000000000000000006044820152606401610955565b60008281526008602090815260408083208151815460c09481028201850190935260a081018381529093919284928491908401828280156130c057602002820191906000526020600020905b81546001600160a01b031681526001909101906020018083116130a2575b5050509183525050600191909101546001600160801b038116602083015263ffffffff600160801b82041660408084019190915261ffff600160a01b830481166060850152600160b01b90920490911660809092019190915281015190915060009061312b906110f4565b90506000811161317d5760405162461bcd60e51b815260206004820152601360248201527f47616d65206e6f742073656564656420796574000000000000000000000000006044820152606401610955565b815151600211156131d05760405162461bcd60e51b815260206004820152601760248201527f4e656564206174206c65617374203220706c61796572730000000000000000006044820152606401610955565b60006131e0836000015183611f2c565b606084015190915061ffff1660005b811561323c57604080516020810183905290810185905282906060016040516020818303038152906040528051906020012060001c8161323157613231613d19565b0691506001016131ef565b600083845160018461324e9190613e30565b6132589190613d2f565b8151811061326857613268613d71565b60209081029190910181015160008a81526007909252604090912060028101805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b039093169290921790915594855550929450505050505b919050565b600280546001600160a01b0383811673ffffffffffffffffffffffffffffffffffffffff19831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6000610903825490565b600061124583836136e7565b600254600160a01b900460ff16156133855760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b6044820152606401610955565b6002805460ff60a01b1916600160a01b1790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258612f753390565b6000828152602081815260408083206001600160a01b038516845290915290205460ff16612da9576133fc816001600160a01b03166014613711565b613407836020613711565b604051602001613418929190613ebf565b60408051601f198184030181529082905262461bcd60e51b825261095591600401613f40565b60008181526001830160205260408120541515611245565b60006112458383613526565b60008281526020819052604090206001015461347e81336133c0565b6110cd8383613575565b6000828152602081815260408083206001600160a01b038516845290915290205460ff16612da9576000828152602081815260408083206001600160a01b03851684529091529020805460ff191660011790556134e23390565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b600081815260018301602052604081205461356d57508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610903565b506000610903565b6000828152602081815260408083206001600160a01b038516845290915290205460ff1615612da9576000828152602081815260408083206001600160a01b0385168085529252808320805460ff1916905551339285917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a45050565b600081815260018301602052604081205480156136dd576000613618600183613e30565b855490915060009061362c90600190613e30565b905081811461369157600086600001828154811061364c5761364c613d71565b906000526020600020015490508087600001848154811061366f5761366f613d71565b6000918252602080832090910192909255918252600188019052604090208390555b85548690806136a2576136a2613f73565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050610903565b6000915050610903565b60008260000182815481106136fe576136fe613d71565b9060005260206000200154905092915050565b60606000613720836002613e47565b61372b906002613d59565b67ffffffffffffffff81111561374357613743613bfe565b6040519080825280601f01601f19166020018201604052801561376d576020820181803683370190505b5090507f3000000000000000000000000000000000000000000000000000000000000000816000815181106137a4576137a4613d71565b60200101906001600160f81b031916908160001a9053507f7800000000000000000000000000000000000000000000000000000000000000816001815181106137ef576137ef613d71565b60200101906001600160f81b031916908160001a9053506000613813846002613e47565b61381e906001613d59565b90505b60018111156138a3577f303132333435363738396162636465660000000000000000000000000000000085600f166010811061385f5761385f613d71565b1a60f81b82828151811061387557613875613d71565b60200101906001600160f81b031916908160001a90535060049490941c9361389c81613f89565b9050613821565b5083156112455760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e746044820152606401610955565b60006020828403121561390457600080fd5b81356001600160e01b03198116811461124557600080fd5b80356001600160a01b03811681146132be57600080fd5b80356001600160801b03811681146132be57600080fd5b803561ffff811681146132be57600080fd5b803563ffffffff811681146132be57600080fd5b600080600080600060a0868803121561398857600080fd5b6139918661391c565b945061399f60208701613933565b93506139ad6040870161394a565b92506139bb6060870161394a565b91506139c96080870161395c565b90509295509295909350565b6000602082840312156139e757600080fd5b5035919050565b6020808252825182820181905260009190848201906040850190845b81811015613a2657835183529284019291840191600101613a0a565b50909695505050505050565b60008060408385031215613a4557600080fd5b82359150613a556020840161391c565b90509250929050565b600060208284031215613a7057600080fd5b6112458261395c565b600060208284031215613a8b57600080fd5b6112458261394a565b600080600060608486031215613aa957600080fd5b613ab284613933565b9250613ac060208501613933565b9150613ace60408501613933565b90509250925092565b600081518084526020808501945080840160005b83811015613b105781516001600160a01b031687529582019590820190600101613aeb565b509495945050505050565b6020815260006112456020830184613ad7565b60008060408385031215613b4157600080fd5b613b4a8361391c565b946020939093013593505050565b602081526000825160a06020840152613b7460c0840182613ad7565b90506001600160801b03602085015116604084015263ffffffff6040850151166060840152606084015161ffff80821660808601528060808701511660a086015250508091505092915050565b600060208284031215613bd357600080fd5b6112458261391c565b60008060408385031215613bef57600080fd5b50508035926020909101359150565b634e487b7160e01b600052604160045260246000fd5b60008060408385031215613c2757600080fd5b823567ffffffffffffffff80821115613c3f57600080fd5b818501915085601f830112613c5357600080fd5b8135602082821115613c6757613c67613bfe565b8160051b604051601f19603f83011681018181108682111715613c8c57613c8c613bfe565b604052928352818301935084810182019289841115613caa57600080fd5b948201945b83861015613ccf57613cc08661391c565b85529482019493820193613caf565b9997909101359750505050505050565b600080600060608486031215613cf457600080fd5b613cfd8461394a565b9250613d0b6020850161394a565b9150613ace6040850161394a565b634e487b7160e01b600052601260045260246000fd5b600082613d3e57613d3e613d19565b500690565b634e487b7160e01b600052601160045260246000fd5b60008219821115613d6c57613d6c613d43565b500190565b634e487b7160e01b600052603260045260246000fd5b600060018201613d9957613d99613d43565b5060010190565b600060208284031215613db257600080fd5b5051919050565b600060208284031215613dcb57600080fd5b8151801515811461124557600080fd5b60006001600160801b0380831681851681830481118215151615613e0157613e01613d43565b02949350505050565b60006001600160801b0380841680613e2457613e24613d19565b92169190910492915050565b600082821015613e4257613e42613d43565b500390565b6000816000190483118215151615613e6157613e61613d43565b500290565b600082613e7557613e75613d19565b500490565b600061ffff80841680613e2457613e24613d19565b60005b83811015613eaa578181015183820152602001613e92565b83811115613eb9576000848401525b50505050565b7f416363657373436f6e74726f6c3a206163636f756e7420000000000000000000815260008351613ef7816017850160208801613e8f565b7f206973206d697373696e6720726f6c65200000000000000000000000000000006017918401918201528351613f34816028840160208801613e8f565b01602801949350505050565b6020815260008251806020840152613f5f816040850160208701613e8f565b601f01601f19169190910160400192915050565b634e487b7160e01b600052603160045260246000fd5b600081613f9857613f98613d43565b50600019019056fea2646970667358221220829ae7ffda8a41063e45d28da9dcb400457a6b50ac8c310e0f1134a1658f8daa64736f6c634300080d0033000000000000000000000000cfef8857e9c80e3440a823971420f7fa5f62f020000000000000000000000000d9bc167e6c37b29f65e708c4bb1d299937dff718000000000000000000000000cf2d2da4c2f9b0675a197febc6708704834f9c24
Deployed Bytecode
0x608060405234801561001057600080fd5b506004361061036d5760003560e01c8063715018a6116101d35780639f20829d11610104578063d11a57ec116100a2578063dfa20f0a1161007c578063dfa20f0a14610884578063f18a065e1461088c578063f2fde38b1461089f578063f6ed2017146108b257600080fd5b8063d11a57ec14610842578063d547741f14610869578063d98011461461087c57600080fd5b8063bf474766116100de578063bf474766146107ff578063c7b8981c14610812578063ca15c8731461081a578063cc32d1761461082d57600080fd5b80639f20829d146107d1578063a217fddf146107e4578063a652db49146107ec57600080fd5b80638f468988116101715780639619367d1161014b5780639619367d1461076f57806397bebf9d146107825780639e609005146107955780639e9ed821146107bc57600080fd5b80638f4689881461071d5780639010d07c1461072557806391d148541461073857600080fd5b80637aa8977f116101ad5780637aa8977f146106d45780638456cb59146106e75780638a19c8bc146106ef5780638da5cb5b1461070c57600080fd5b8063715018a61461065757806373931bbf1461065f5780637559b8811461067f57600080fd5b80633ce4f515116102ad5780635c975abb1161024b578063684931ed11610225578063684931ed146105cc57806368f46b62146105f35780636d6b0eb3146106065780636e8539251461064457600080fd5b80635c975abb14610572578063608ac8d51461058457806361d027b31461058d57600080fd5b80634c223a82116102875780634c223a8214610519578063556bc85e1461052c57806359fe289e1461053f5780635a744c4d1461055257600080fd5b80633ce4f515146104e95780633f4ba83a146104fc57806342dc6b8b1461050457600080fd5b80632ad9bf951161031a5780632f2ff15d116102f45780632f2ff15d146104a3578063345d9a8d146104b857806336568abe146104cd578063368acb09146104e057600080fd5b80632ad9bf95146104495780632c0c4af9146104515780632e5b21681461047157600080fd5b8063230669e51161034b578063230669e5146103e3578063248a9ca3146103f857806328119fb81461041b57600080fd5b806301b654961461037257806301ffc9a71461039f57806312c61d3f146103c2575b600080fd5b60065461038790600160b01b900461ffff1681565b60405161ffff90911681526020015b60405180910390f35b6103b26103ad3660046138f2565b6108c5565b6040519015158152602001610396565b6103d56103d0366004613970565b610909565b604051908152602001610396565b60065461038790600160a01b900461ffff1681565b6103d56104063660046139d5565b60009081526020819052604090206001015490565b6103b26104293660046139d5565b6000908152600760205260409020600201546001600160a01b0316151590565b6103d5610d56565b61046461045f3660046139d5565b610db6565b60405161039691906139ee565b60055461048b90600160801b90046001600160801b031681565b6040516001600160801b039091168152602001610396565b6104b66104b1366004613a32565b6110ab565b005b60065461038790600160c01b900461ffff1681565b6104b66104db366004613a32565b6110d2565b6103d560045481565b6103d56104f7366004613a5e565b6110f4565b6104b661124c565b60065461038790600160901b900461ffff1681565b6104b6610527366004613a79565b6112b0565b6104b661053a366004613a79565b611346565b6104b661054d366004613a94565b6113dc565b6105656105603660046139d5565b611483565b6040516103969190613b1b565b600254600160a01b900460ff166103b2565b6103d560035481565b6105b47f000000000000000000000000cf2d2da4c2f9b0675a197febc6708704834f9c2481565b6040516001600160a01b039091168152602001610396565b6105b47f000000000000000000000000d9bc167e6c37b29f65e708c4bb1d299937dff71881565b6103b2610601366004613b2e565b611613565b6106196106143660046139d5565b61165c565b604080518251815260208084015190820152918101516001600160a01b031690820152606001610396565b6104b66106523660046139d5565b6116cb565b6104b6611b36565b61067261066d3660046139d5565b611b9a565b6040516103969190613b58565b6103d561068d366004613b2e565b6040516bffffffffffffffffffffffff19606084901b1660208201526034810182905260009060540160405160208183030381529060405280519060200120905092915050565b6104646106e2366004613bc1565b611c85565b6104b6611d71565b6106f7611dd3565b60405163ffffffff9091168152602001610396565b6002546001600160a01b03166105b4565b6103d5611e57565b6105b4610733366004613bdc565b611f14565b6103b2610746366004613a32565b6000918252602082815260408084206001600160a01b0393909316845291905290205460ff1690565b60055461048b906001600160801b031681565b60065461048b906001600160801b031681565b6105b47f000000000000000000000000cfef8857e9c80e3440a823971420f7fa5f62f02081565b60065461038790600160d01b900461ffff1681565b6105656107df366004613c14565b611f2c565b6103d5600081565b6104b66107fa366004613a79565b612074565b6104b661080d3660046139d5565b612132565b6103d56126d2565b6103d56108283660046139d5565b61289a565b60065461038790600160801b900461ffff1681565b6103d57fe1dcbdb91df27212a29bc27177c840cf2f819ecf2187432e1fac86c2dd5dfca981565b6104b6610877366004613a32565b6128b1565b6104b66128bb565b6104b6612a22565b6104b661089a366004613cdf565b612b6d565b6104b66108ad366004613bc1565b612c2e565b6103d56108c0366004613bc1565b612d0d565b60006001600160e01b031982167f5a05180f000000000000000000000000000000000000000000000000000000001480610903575061090382612dc2565b92915050565b600254600090600160a01b900460ff161561095e5760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b60448201526064015b60405180910390fd5b8361ffff1660000361097b57600654600160c01b900461ffff1693505b846001600160801b031660000361099b576006546001600160801b031694505b60028361ffff1610156109b957600654600160d01b900461ffff1692505b60006109c4836110f4565b90508015610a145760405162461bcd60e51b815260206004820152601360248201527f47616d6520616c726561647920736565646564000000000000000000000000006044820152606401610955565b610a1c611dd3565b63ffffffff168363ffffffff161015610a775760405162461bcd60e51b815260206004820152601e60248201527f43616e2774206372656174652067616d657320696e20746865207061737400006044820152606401610955565b6005546001600160801b0390811690871610801590610aac57506005546001600160801b03600160801b909104811690871611155b610af85760405162461bcd60e51b815260206004820152601760248201527f426574206f757473696465206c6567616c2072616e67650000000000000000006044820152606401610955565b60065461ffff600160a01b909104811690861610801590610b2a575060065461ffff600160b01b909104811690861611155b610b765760405162461bcd60e51b815260206004820152601e60248201527f537461727420726f6c6c206f757473696465206c6567616c2072616e676500006044820152606401610955565b6001600160a01b038716331480610be357506001600160a01b03871630148015610bad57506006546001600160801b038781169116145b8015610bc8575060065461ffff868116600160c01b90920416145b8015610be3575060065461ffff858116600160d01b90920416145b610bec57600080fd5b6000610c40888563ffffffff166040516bffffffffffffffffffffffff19606084901b1660208201526034810182905260009060540160405160208183030381529060405280519060200120905092915050565b6000818152600760205260409020600201549091506001600160a01b031615610cab5760405162461bcd60e51b815260206004820152601560248201527f47616d6520616c72656164792066696e697368656400000000000000000000006044820152606401610955565b60008181526008602052604080822060010180546001600160801b038b1673ffffffffffffffffffffffffffffffffffffffff1990911617600160801b63ffffffff8916021763ffffffff60a01b1916600160a01b61ffff8b81169190910261ffff60b01b191691909117600160b01b918a16919091021790555182917f7195cf6f05afbbfa979e2346d841dcb24356d5956eec907794f47ff7acaf701291a2979650505050505050565b6000610db130610d64611dd3565b63ffffffff166040516bffffffffffffffffffffffff19606084901b1660208201526034810182905260009060540160405160208183030381529060405280519060200120905092915050565b905090565b60008181526008602090815260408083208151815460c09481028201850190935260a081018381526060959491938492849190840182828015610e2257602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311610e04575b5050509183525050600191909101546001600160801b038116602083015263ffffffff600160801b82041660408084019190915261ffff600160a01b830481166060850152600160b01b909204909116608090920191909152810151909150600090610e8d906110f4565b905060008111610edf5760405162461bcd60e51b815260206004820152601360248201527f47616d65206e6f742073656564656420796574000000000000000000000000006044820152606401610955565b81515160021115610f325760405162461bcd60e51b815260206004820152601760248201527f4e656564206174206c65617374203220706c61796572730000000000000000006044820152606401610955565b6000826060015161ffff1667ffffffffffffffff811115610f5557610f55613bfe565b604051908082528060200260200182016040528015610f7e578160200160208202803683370190505b50606084015190915061ffff1660005b81156110035760408051602080820184905281830187905282518083038401815260609092019092528051910120610fc7908390613d2f565b9150610fd4826001613d59565b838281518110610fe657610fe6613d71565b602090810291909101015280610ffb81613d87565b915050610f8e565b60008167ffffffffffffffff81111561101e5761101e613bfe565b604051908082528060200260200182016040528015611047578160200160208202803683370190505b50905060005b815181101561109f5784818151811061106857611068613d71565b602002602001015182828151811061108257611082613d71565b60209081029190910101528061109781613d87565b91505061104d565b50979650505050505050565b6110b58282612e29565b60008281526001602052604090206110cd9082612dad565b505050565b6110dc8282612e4f565b60008281526001602052604090206110cd9082612ed7565b6040517f591c0e1c00000000000000000000000000000000000000000000000000000000815263ffffffff8216600482015260009081906001600160a01b037f000000000000000000000000d9bc167e6c37b29f65e708c4bb1d299937dff718169063591c0e1c90602401602060405180830381865afa15801561117c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111a09190613da0565b6040517f05b19402000000000000000000000000000000000000000000000000000000008152600481018290529091507f000000000000000000000000d9bc167e6c37b29f65e708c4bb1d299937dff7186001600160a01b0316906305b1940290602401602060405180830381865afa158015611221573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112459190613da0565b9392505050565b6002546001600160a01b031633146112a65760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610955565b6112ae612eec565b565b6002546001600160a01b0316331461130a5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610955565b6006805461ffff909216600160d01b027fffffffff0000ffffffffffffffffffffffffffffffffffffffffffffffffffff909216919091179055565b6002546001600160a01b031633146113a05760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610955565b6006805461ffff909216600160901b027fffffffffffffffffffffffff0000ffffffffffffffffffffffffffffffffffff909216919091179055565b6002546001600160a01b031633146114365760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610955565b6001600160801b03928316600160801b9284169290920291909117600555600680547fffffffffffffffffffffffffffffffff000000000000000000000000000000001691909216179055565b60008181526008602090815260408083208151815460c09481028201850190935260a0810183815260609594919384928491908401828280156114ef57602002820191906000526020600020905b81546001600160a01b031681526001909101906020018083116114d1575b5050509183525050600191909101546001600160801b038116602083015263ffffffff600160801b82041660408084019190915261ffff600160a01b830481166060850152600160b01b90920490911660809092019190915281015190915060009061155a906110f4565b9050600081116115ac5760405162461bcd60e51b815260206004820152601360248201527f47616d65206e6f742073656564656420796574000000000000000000000000006044820152606401610955565b815151600211156115ff5760405162461bcd60e51b815260206004820152601760248201527f4e656564206174206c65617374203220706c61796572730000000000000000006044820152606401610955565b815161160b9082611f2c565b949350505050565b6000818152600760205260408120600201546001600160a01b0316151580156112455750506000908152600760205260409020600201546001600160a01b039081169116141590565b6116896040518060600160405280600081526020016000815260200160006001600160a01b031681525090565b50600090815260076020908152604091829020825160608101845281548152600182015492810192909252600201546001600160a01b03169181019190915290565b600254600160a01b900460ff16156117185760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b6044820152606401610955565b60008181526008602090815260408083208151815460c09481028201850190935260a0810183815290939192849284919084018282801561178257602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311611764575b5050509183525050600191909101546001600160801b038116602083015263ffffffff600160801b820416604083015261ffff600160a01b820481166060840152600160b01b909104166080909101528051519091506118245760405162461bcd60e51b815260206004820152601660248201527f4e6f20706c617965727320696e207468652067616d65000000000000000000006044820152606401610955565b805151600103611954577f000000000000000000000000cfef8857e9c80e3440a823971420f7fa5f62f0206001600160a01b031663a9059cbb826000015160008151811061187457611874613d71565b602002602001015183602001516040518363ffffffff1660e01b81526004016118bb9291906001600160a01b039290921682526001600160801b0316602082015260400190565b6020604051808303816000875af11580156118da573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118fe9190613db9565b506110cd8260096000846000015160008151811061191e5761191e613d71565b60200260200101516001600160a01b03166001600160a01b03168152602001908152602001600020612f9290919063ffffffff16565b600061195f83612f9e565b6000848152600760205260409020600201549091506001600160a01b03166119c95760405162461bcd60e51b815260206004820152601e60248201527f47616d65206e6f742066696e69736865642061667465722073696d756c2e00006044820152606401610955565b60028101546001600160a01b0316611a235760405162461bcd60e51b815260206004820152601a60248201527f46696e69736865642067616d6520686173206e6f206c6f7365720000000000006044820152606401610955565b60028101546040516001600160a01b039091169084907fd5a82ebfa8edb5cbec605a5fe6ef6469bb00d282b0d42748e6434ced9617b5b090600090a3600654602083015160009161271091611a8391600160901b900461ffff1690613ddb565b611a8d9190613e0a565b6001600160801b0316905060008184602001516001600160801b0316611ab39190613e30565b60065490915060009061271090611ad590600160801b900461ffff1684613e47565b611adf9190613e66565b90508060046000828254611af39190613d59565b9091555050845151611b0790600190613e30565b611b118284613e30565b611b1b9190613e66565b611b259083613d59565b846001018190555050505050505b50565b6002546001600160a01b03163314611b905760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610955565b6112ae60006132c3565b6040805160a0810182526060808252600060208301819052928201839052810182905260808101919091526000828152600860209081526040918290208251815460c09381028201840190945260a081018481529093919284928491840182828015611c2f57602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311611c11575b5050509183525050600191909101546001600160801b038116602083015263ffffffff600160801b820416604083015261ffff600160a01b820481166060840152600160b01b9091041660809091015292915050565b6001600160a01b038116600090815260096020526040812060609190611caa90613322565b67ffffffffffffffff811115611cc257611cc2613bfe565b604051908082528060200260200182016040528015611ceb578160200160208202803683370190505b50905060005b6001600160a01b0384166000908152600960205260409020611d1290613322565b811015611d6a576001600160a01b0384166000908152600960205260409020611d3b908261332c565b828281518110611d4d57611d4d613d71565b602090810291909101015280611d6281613d87565b915050611cf1565b5092915050565b6002546001600160a01b03163314611dcb5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610955565b6112ae613338565b60007f000000000000000000000000d9bc167e6c37b29f65e708c4bb1d299937dff7186001600160a01b0316633b1fee6c6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611e33573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610db19190613da0565b600254600090600160a01b900460ff1615611ea75760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b6044820152606401610955565b6000611eb1610d56565b600081815260086020526040812060010154919250600160a01b90910461ffff169003611f0b57600654611f099030906001600160801b0381169061ffff600160c01b8204811691600160d01b9004166103d0611dd3565b505b610db181612132565b6000828152600160205260408120611245908361332c565b606082600080805b865181101561206957808751611f4a9190613e30565b878281518110611f5c57611f5c613d71565b602002602001015187604051602001611f9392919060609290921b6bffffffffffffffffffffffff19168252601482015260340190565b6040516020818303038152906040528051906020012060001c611fb69190613d2f565b9150838181518110611fca57611fca613d71565b60200260200101519250838282611fe19190613d59565b81518110611ff157611ff1613d71565b602002602001015184828151811061200b5761200b613d71565b6001600160a01b0390921660209283029190910190910152828461202f8484613d59565b8151811061203f5761203f613d71565b6001600160a01b03909216602092830291909101909101528061206181613d87565b915050611f34565b509195945050505050565b7fe1dcbdb91df27212a29bc27177c840cf2f819ecf2187432e1fac86c2dd5dfca961209f81336133c0565b610bb88261ffff1611156120f55760405162461bcd60e51b815260206004820181905260248201527f4c6574207468652067616d626c6572732067616d626c6520696e2070656163656044820152606401610955565b506006805461ffff909216600160801b027fffffffffffffffffffffffffffff0000ffffffffffffffffffffffffffffffff909216919091179055565b600254600160a01b900460ff161561217f5760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b6044820152606401610955565b60008181526008602090815260408083208151815460c09481028201850190935260a081018381529093919284928491908401828280156121e957602002820191906000526020600020905b81546001600160a01b031681526001909101906020018083116121cb575b5050509183525050600191909101546001600160801b038116602083015263ffffffff600160801b820416604083015261ffff600160a01b82048116606080850191909152600160b01b9092048116608090930192909252820151919250166122945760405162461bcd60e51b815260206004820152601660248201527f47616d6520646f65736e277420657869737420796574000000000000000000006044820152606401610955565b6000828152600760205260409020600201546001600160a01b0316156122fc5760405162461bcd60e51b815260206004820152601560248201527f47616d6520616c72656164792066696e697368656400000000000000000000006044820152606401610955565b600061230b82604001516110f4565b9050801561235b5760405162461bcd60e51b815260206004820152601360248201527f47616d6520616c726561647920736565646564000000000000000000000000006044820152606401610955565b61236642603c613d59565b7f000000000000000000000000d9bc167e6c37b29f65e708c4bb1d299937dff7186001600160a01b0316633c099fce6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156123c4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123e89190613da0565b116124355760405162461bcd60e51b815260206004820181905260248201527f5365656420696d6d696e656e743b207369676e2d757020697320636c6f7365646044820152606401610955565b33600090815260096020526040902061244e908461343e565b1561249b5760405162461bcd60e51b815260206004820152600e60248201527f416c7265616479206a6f696e65640000000000000000000000000000000000006044820152606401610955565b608082015160008481526008602052604090205461ffff9091161180156124f057506006546124d790600160901b900461ffff16612710613e7a565b60008481526008602052604090205461ffff9190911610155b61253c5760405162461bcd60e51b815260206004820152601060248201527f546f6f206d616e7920706c6179657273000000000000000000000000000000006044820152606401610955565b60065460208301516000916127109161256091600160901b900461ffff1690613ddb565b61256a9190613e0a565b6001600160801b0316905080600360008282546125879190613d59565b909155505060208301516040517f23b872dd0000000000000000000000000000000000000000000000000000000081523360048201523060248201526001600160801b0390911660448201527f000000000000000000000000cfef8857e9c80e3440a823971420f7fa5f62f0206001600160a01b0316906323b872dd906064016020604051808303816000875af1158015612626573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061264a9190613db9565b506000848152600860209081526040808320805460018101825590845282842001805473ffffffffffffffffffffffffffffffffffffffff19163390811790915583526009909152902061269e9085613456565b50604051339085907fdd5a0e5e0c7946c099f2ed766c0b633dd2eb1e1e10743bab89f871e8038b080b90600090a350505050565b600254600090600160a01b900460ff16156127225760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b6044820152606401610955565b336000805b6001600160a01b038316600090815260096020526040902061274890613322565b811015612801576001600160a01b0383166000908152600960205260408120612771908361332c565b905061277d8482611613565b156127a15760008181526007602052604090206001015461279e9084613d59565b92505b6000818152600760205260409020600201546001600160a01b0316156127ed576001600160a01b03841660009081526009602052604090206127e39082612f92565b50600091506127fb565b816127f781613d87565b9250505b50612727565b5060405163a9059cbb60e01b8152336004820152602481018290527f000000000000000000000000cfef8857e9c80e3440a823971420f7fa5f62f0206001600160a01b03169063a9059cbb906044016020604051808303816000875af115801561286f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906128939190613db9565b5091505090565b600081815260016020526040812061090390613322565b6110dc8282613462565b6002546001600160a01b031633146129155760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610955565b6000600354116129675760405162461bcd60e51b815260206004820152601360248201527f4e6f7468696e6720746f207769746864726177000000000000000000000000006044820152606401610955565b7f000000000000000000000000cfef8857e9c80e3440a823971420f7fa5f62f0206001600160a01b031663a9059cbb6129a86002546001600160a01b031690565b6003546040516001600160e01b031960e085901b1681526001600160a01b03909216600483015260248201526044016020604051808303816000875af11580156129f6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612a1a9190613db9565b506000600355565b7fe1dcbdb91df27212a29bc27177c840cf2f819ecf2187432e1fac86c2dd5dfca9612a4d81336133c0565b600060045411612a9f5760405162461bcd60e51b815260206004820152601360248201527f4e6f7468696e6720746f207769746864726177000000000000000000000000006044820152606401610955565b6004805460405163a9059cbb60e01b81526001600160a01b037f000000000000000000000000cfef8857e9c80e3440a823971420f7fa5f62f020169263a9059cbb92612b21927f000000000000000000000000cf2d2da4c2f9b0675a197febc6708704834f9c2492016001600160a01b03929092168252602082015260400190565b6020604051808303816000875af1158015612b40573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612b649190613db9565b50506000600455565b6002546001600160a01b03163314612bc75760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610955565b6006805463ffffffff60a01b1916600160a01b61ffff9586160261ffff60b01b191617600160b01b93851693909302929092177fffffffffffff0000ffffffffffffffffffffffffffffffffffffffffffffffff16600160c01b9190931602919091179055565b6002546001600160a01b03163314612c885760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610955565b6001600160a01b038116612d045760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f64647265737300000000000000000000000000000000000000000000000000006064820152608401610955565b611b33816132c3565b600080805b6001600160a01b0384166000908152600960205260409020612d3390613322565b811015611d6a576001600160a01b0384166000908152600960205260408120612d5c908361332c565b9050612d688582611613565b15612d8c57600081815260076020526040902060010154612d899084613d59565b92505b5080612d9781613d87565b915050612d12565b612da98282613488565b5050565b6000611245836001600160a01b038416613526565b60006001600160e01b031982167f7965db0b00000000000000000000000000000000000000000000000000000000148061090357507f01ffc9a7000000000000000000000000000000000000000000000000000000006001600160e01b0319831614610903565b600082815260208190526040902060010154612e4581336133c0565b6110cd8383613488565b6001600160a01b0381163314612ecd5760405162461bcd60e51b815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201527f20726f6c657320666f722073656c6600000000000000000000000000000000006064820152608401610955565b612da98282613575565b6000611245836001600160a01b0384166135f4565b600254600160a01b900460ff16612f455760405162461bcd60e51b815260206004820152601460248201527f5061757361626c653a206e6f74207061757365640000000000000000000000006044820152606401610955565b6002805460ff60a01b191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa335b6040516001600160a01b03909116815260200160405180910390a1565b600061124583836135f4565b600254600090600160a01b900460ff1615612fee5760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b6044820152606401610955565b6000828152600760205260409020600201546001600160a01b0316156130565760405162461bcd60e51b815260206004820152601560248201527f47616d6520616c72656164792066696e697368656400000000000000000000006044820152606401610955565b60008281526008602090815260408083208151815460c09481028201850190935260a081018381529093919284928491908401828280156130c057602002820191906000526020600020905b81546001600160a01b031681526001909101906020018083116130a2575b5050509183525050600191909101546001600160801b038116602083015263ffffffff600160801b82041660408084019190915261ffff600160a01b830481166060850152600160b01b90920490911660809092019190915281015190915060009061312b906110f4565b90506000811161317d5760405162461bcd60e51b815260206004820152601360248201527f47616d65206e6f742073656564656420796574000000000000000000000000006044820152606401610955565b815151600211156131d05760405162461bcd60e51b815260206004820152601760248201527f4e656564206174206c65617374203220706c61796572730000000000000000006044820152606401610955565b60006131e0836000015183611f2c565b606084015190915061ffff1660005b811561323c57604080516020810183905290810185905282906060016040516020818303038152906040528051906020012060001c8161323157613231613d19565b0691506001016131ef565b600083845160018461324e9190613e30565b6132589190613d2f565b8151811061326857613268613d71565b60209081029190910181015160008a81526007909252604090912060028101805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b039093169290921790915594855550929450505050505b919050565b600280546001600160a01b0383811673ffffffffffffffffffffffffffffffffffffffff19831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6000610903825490565b600061124583836136e7565b600254600160a01b900460ff16156133855760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b6044820152606401610955565b6002805460ff60a01b1916600160a01b1790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258612f753390565b6000828152602081815260408083206001600160a01b038516845290915290205460ff16612da9576133fc816001600160a01b03166014613711565b613407836020613711565b604051602001613418929190613ebf565b60408051601f198184030181529082905262461bcd60e51b825261095591600401613f40565b60008181526001830160205260408120541515611245565b60006112458383613526565b60008281526020819052604090206001015461347e81336133c0565b6110cd8383613575565b6000828152602081815260408083206001600160a01b038516845290915290205460ff16612da9576000828152602081815260408083206001600160a01b03851684529091529020805460ff191660011790556134e23390565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b600081815260018301602052604081205461356d57508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610903565b506000610903565b6000828152602081815260408083206001600160a01b038516845290915290205460ff1615612da9576000828152602081815260408083206001600160a01b0385168085529252808320805460ff1916905551339285917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a45050565b600081815260018301602052604081205480156136dd576000613618600183613e30565b855490915060009061362c90600190613e30565b905081811461369157600086600001828154811061364c5761364c613d71565b906000526020600020015490508087600001848154811061366f5761366f613d71565b6000918252602080832090910192909255918252600188019052604090208390555b85548690806136a2576136a2613f73565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050610903565b6000915050610903565b60008260000182815481106136fe576136fe613d71565b9060005260206000200154905092915050565b60606000613720836002613e47565b61372b906002613d59565b67ffffffffffffffff81111561374357613743613bfe565b6040519080825280601f01601f19166020018201604052801561376d576020820181803683370190505b5090507f3000000000000000000000000000000000000000000000000000000000000000816000815181106137a4576137a4613d71565b60200101906001600160f81b031916908160001a9053507f7800000000000000000000000000000000000000000000000000000000000000816001815181106137ef576137ef613d71565b60200101906001600160f81b031916908160001a9053506000613813846002613e47565b61381e906001613d59565b90505b60018111156138a3577f303132333435363738396162636465660000000000000000000000000000000085600f166010811061385f5761385f613d71565b1a60f81b82828151811061387557613875613d71565b60200101906001600160f81b031916908160001a90535060049490941c9361389c81613f89565b9050613821565b5083156112455760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e746044820152606401610955565b60006020828403121561390457600080fd5b81356001600160e01b03198116811461124557600080fd5b80356001600160a01b03811681146132be57600080fd5b80356001600160801b03811681146132be57600080fd5b803561ffff811681146132be57600080fd5b803563ffffffff811681146132be57600080fd5b600080600080600060a0868803121561398857600080fd5b6139918661391c565b945061399f60208701613933565b93506139ad6040870161394a565b92506139bb6060870161394a565b91506139c96080870161395c565b90509295509295909350565b6000602082840312156139e757600080fd5b5035919050565b6020808252825182820181905260009190848201906040850190845b81811015613a2657835183529284019291840191600101613a0a565b50909695505050505050565b60008060408385031215613a4557600080fd5b82359150613a556020840161391c565b90509250929050565b600060208284031215613a7057600080fd5b6112458261395c565b600060208284031215613a8b57600080fd5b6112458261394a565b600080600060608486031215613aa957600080fd5b613ab284613933565b9250613ac060208501613933565b9150613ace60408501613933565b90509250925092565b600081518084526020808501945080840160005b83811015613b105781516001600160a01b031687529582019590820190600101613aeb565b509495945050505050565b6020815260006112456020830184613ad7565b60008060408385031215613b4157600080fd5b613b4a8361391c565b946020939093013593505050565b602081526000825160a06020840152613b7460c0840182613ad7565b90506001600160801b03602085015116604084015263ffffffff6040850151166060840152606084015161ffff80821660808601528060808701511660a086015250508091505092915050565b600060208284031215613bd357600080fd5b6112458261391c565b60008060408385031215613bef57600080fd5b50508035926020909101359150565b634e487b7160e01b600052604160045260246000fd5b60008060408385031215613c2757600080fd5b823567ffffffffffffffff80821115613c3f57600080fd5b818501915085601f830112613c5357600080fd5b8135602082821115613c6757613c67613bfe565b8160051b604051601f19603f83011681018181108682111715613c8c57613c8c613bfe565b604052928352818301935084810182019289841115613caa57600080fd5b948201945b83861015613ccf57613cc08661391c565b85529482019493820193613caf565b9997909101359750505050505050565b600080600060608486031215613cf457600080fd5b613cfd8461394a565b9250613d0b6020850161394a565b9150613ace6040850161394a565b634e487b7160e01b600052601260045260246000fd5b600082613d3e57613d3e613d19565b500690565b634e487b7160e01b600052601160045260246000fd5b60008219821115613d6c57613d6c613d43565b500190565b634e487b7160e01b600052603260045260246000fd5b600060018201613d9957613d99613d43565b5060010190565b600060208284031215613db257600080fd5b5051919050565b600060208284031215613dcb57600080fd5b8151801515811461124557600080fd5b60006001600160801b0380831681851681830481118215151615613e0157613e01613d43565b02949350505050565b60006001600160801b0380841680613e2457613e24613d19565b92169190910492915050565b600082821015613e4257613e42613d43565b500390565b6000816000190483118215151615613e6157613e61613d43565b500290565b600082613e7557613e75613d19565b500490565b600061ffff80841680613e2457613e24613d19565b60005b83811015613eaa578181015183820152602001613e92565b83811115613eb9576000848401525b50505050565b7f416363657373436f6e74726f6c3a206163636f756e7420000000000000000000815260008351613ef7816017850160208801613e8f565b7f206973206d697373696e6720726f6c65200000000000000000000000000000006017918401918201528351613f34816028840160208801613e8f565b01602801949350505050565b6020815260008251806020840152613f5f816040850160208701613e8f565b601f01601f19169190910160400192915050565b634e487b7160e01b600052603160045260246000fd5b600081613f9857613f98613d43565b50600019019056fea2646970667358221220829ae7ffda8a41063e45d28da9dcb400457a6b50ac8c310e0f1134a1658f8daa64736f6c634300080d0033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000cfef8857e9c80e3440a823971420f7fa5f62f020000000000000000000000000d9bc167e6c37b29f65e708c4bb1d299937dff718000000000000000000000000cf2d2da4c2f9b0675a197febc6708704834f9c24
-----Decoded View---------------
Arg [0] : confetti_ (address): 0xCfef8857E9C80e3440A823971420F7Fa5F62f020
Arg [1] : seeder_ (address): 0xD9bc167E6C37b29F65E708C4Bb1D299937dFF718
Arg [2] : treasury_ (address): 0xcF2D2dA4c2F9B0675A197FEbC6708704834f9c24
-----Encoded View---------------
3 Constructor Arguments found :
Arg [0] : 000000000000000000000000cfef8857e9c80e3440a823971420f7fa5f62f020
Arg [1] : 000000000000000000000000d9bc167e6c37b29f65e708c4bb1d299937dff718
Arg [2] : 000000000000000000000000cf2d2da4c2f9b0675a197febc6708704834f9c24
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.