Source Code
Overview
S Balance
More Info
ContractCreator
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Latest 21 internal transactions
Parent Transaction Hash | Block | From | To | |||
---|---|---|---|---|---|---|
16500455 | 13 days ago | 1 S | ||||
16500455 | 13 days ago | 1 S | ||||
16500432 | 13 days ago | 0 S | ||||
16499574 | 13 days ago | 1 S | ||||
16499574 | 13 days ago | 0 S | ||||
16499548 | 13 days ago | 0 S | ||||
16499095 | 13 days ago | 0 S | ||||
16499054 | 13 days ago | 0 S | ||||
16498594 | 13 days ago | 0 S | ||||
16498570 | 13 days ago | 0 S | ||||
16498347 | 13 days ago | 0 S | ||||
16498319 | 13 days ago | 0 S | ||||
16497950 | 13 days ago | 1 S | ||||
16497950 | 13 days ago | 1 S | ||||
16497922 | 13 days ago | 0 S | ||||
16497397 | 13 days ago | 1 S | ||||
16497397 | 13 days ago | 1 S | ||||
16497369 | 13 days ago | 0 S | ||||
16496928 | 13 days ago | 0 S | ||||
16427418 | 13 days ago | 0 S | ||||
16424232 | 13 days ago | 0 S |
Loading...
Loading
Contract Name:
DuckRace
Compiler Version
v0.8.19+commit.7dd6d404
Optimization Enabled:
Yes with 200 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT pragma solidity ^0.8.19; import "../interfaces/IGame.sol"; import "@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol"; import "@openzeppelin/contracts-upgradeable/access/Ownable2StepUpgradeable.sol"; import "@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol"; import "../interfaces/IUniversalCashier.sol"; contract DuckRace is IGame, PausableUpgradeable, Ownable2StepUpgradeable, ReentrancyGuardUpgradeable { // References address public proxyManager; IUniversalCashier public cashier; // Game Configuration uint256 public constant PLAY_COST = 1 ether; // 1 S per duck uint256 public constant MIN_PLAYERS = 2; uint256 public constant MAX_PLAYERS = 100; uint256 public constant COMMIT_DURATION = 60 seconds; uint256 public constant RACE_DURATION = 60 seconds; uint256 public constant COOLDOWN_DURATION = 60 seconds; // Prize distribution uint256 public constant WINNER_SHARE = 90; // 90% to winner uint256 public constant DEV_SHARE = 10; // 10% to dev uint256 public totalFees; // Accumulated dev fees enum RaceState { Waiting, // Waiting for minimum players Committing, // Accepting commits for 60s Racing, // Race in progress for 60s Completed, // Race completed Cooldown // 60s cooldown before next race } struct PreCommitment { uint256 ducksPerRace; uint256 racesRemaining; bytes32 commitHash; bytes32 salt; } // Game State struct Race { uint256 startTime; uint256 commitDeadline; uint256 raceDeadline; uint256 cooldownEnds; uint256 totalPrize; address winner; RaceState state; uint256 playerCount; mapping(address => bytes32) commitments; mapping(address => uint256) reveals; mapping(address => bool) hasRevealed; mapping(address => uint256) duckCounts; address[] players; } uint256 public currentRaceId; mapping(uint256 => Race) public races; mapping(address => PreCommitment) public preCommitments; // Random number generation uint256 private nonce; // Events event RaceCreated(uint256 indexed raceId); event CommitPhaseStarted(uint256 indexed raceId, uint256 deadline); event RaceStarted(uint256 indexed raceId, uint256 deadline); event RaceCompleted(uint256 indexed raceId, address winner, uint256 prize); event PlayerCommitted(uint256 indexed raceId, address indexed player, uint256 duckCount); event PreCommitmentSet(address indexed player, uint256 ducksPerRace, uint256 races); event FeeWithdrawn(uint256 amount); function initialize(address _proxyManager, address _cashier) public initializer { __Pausable_init(); __Ownable2Step_init(); __ReentrancyGuard_init(); proxyManager = _proxyManager; cashier = IUniversalCashier(_cashier); currentRaceId = 0; } // Pre-commit to multiple races function setPreCommitment( uint256 ducksPerRace, uint256 numberOfRaces, bytes32 commitHash, bytes32 salt ) external whenNotPaused nonReentrant { require(ducksPerRace > 0 && ducksPerRace <= 10, "Invalid duck count"); require(numberOfRaces > 0 && numberOfRaces <= 100, "Invalid race count"); uint256 totalCost = PLAY_COST * ducksPerRace * numberOfRaces; require(cashier.getBalance(msg.sender) >= totalCost, "Insufficient balance"); preCommitments[msg.sender] = PreCommitment({ ducksPerRace: ducksPerRace, racesRemaining: numberOfRaces, commitHash: commitHash, salt: salt }); emit PreCommitmentSet(msg.sender, ducksPerRace, numberOfRaces); } // Single race commit function commit(bytes32 commitHash, bytes32 salt, uint256 duckCount) external payable whenNotPaused nonReentrant { require(duckCount > 0 && duckCount <= 10, "Invalid duck count"); uint256 cost = PLAY_COST * duckCount; require(cashier.debitPlayer(msg.sender, cost), "Payment failed"); _processCommit(msg.sender, commitHash, salt, duckCount); } // Process commit (used by both pre-commit and regular commit) function _processCommit( address player, bytes32 commitHash, bytes32 salt, uint256 duckCount ) private { if (currentRaceId == 0 || races[currentRaceId].state == RaceState.Completed) { _createNewRace(); } Race storage race = races[currentRaceId]; require(race.state == RaceState.Waiting || race.state == RaceState.Committing, "Race not accepting commits"); require(race.playerCount < MAX_PLAYERS, "Race full"); if (race.duckCounts[player] == 0) { race.players.push(player); race.playerCount++; } race.commitments[player] = keccak256(abi.encodePacked(commitHash, salt, player)); race.duckCounts[player] += duckCount; race.totalPrize += PLAY_COST * duckCount; // Start commit phase if minimum players reached if (race.playerCount >= MIN_PLAYERS && race.state == RaceState.Waiting) { _startCommitPhase(currentRaceId); } emit PlayerCommitted(currentRaceId, player, duckCount); } // Auto-process pre-commitments function processPreCommitments() external { PreCommitment storage pc = preCommitments[msg.sender]; require(pc.racesRemaining > 0, "No pre-commitments"); require(pc.ducksPerRace > 0, "Invalid pre-commitment"); uint256 cost = PLAY_COST * pc.ducksPerRace; require(cashier.debitPlayer(msg.sender, cost), "Payment failed"); _processCommit(msg.sender, pc.commitHash, pc.salt, pc.ducksPerRace); pc.racesRemaining--; if (pc.racesRemaining == 0) { delete preCommitments[msg.sender]; } } // Reveal phase function reveal(uint256 seed, bytes32 salt) external nonReentrant whenNotPaused { Race storage race = races[currentRaceId]; require(race.state == RaceState.Racing, "Not reveal phase"); require(!race.hasRevealed[msg.sender], "Already revealed"); bytes32 computedHash = keccak256(abi.encodePacked(seed, salt, msg.sender)); require(computedHash == race.commitments[msg.sender], "Invalid reveal"); race.reveals[msg.sender] = seed; race.hasRevealed[msg.sender] = true; } function finalize(uint256 raceId) public { Race storage race = races[raceId]; require(race.state == RaceState.Racing, "Race not in progress"); require(block.timestamp > race.raceDeadline, "Race still in progress"); // Calculate combined seed from all reveals bytes32 combinedSeed; uint256 revealCount; for (uint256 i = 0; i < race.players.length; i++) { address player = race.players[i]; if (race.hasRevealed[player]) { combinedSeed ^= bytes32(race.reveals[player]); revealCount++; } } require(revealCount >= MIN_PLAYERS, "Not enough reveals"); // Generate winner uint256 randomNumber = uint256(keccak256(abi.encodePacked( combinedSeed, block.prevrandao, block.timestamp ))); // Weight by duck count uint256 totalDucks; for (uint256 i = 0; i < race.players.length; i++) { if (race.hasRevealed[race.players[i]]) { totalDucks += race.duckCounts[race.players[i]]; } } uint256 winningNumber = randomNumber % totalDucks; uint256 currentSum; // Find winner for (uint256 i = 0; i < race.players.length; i++) { address player = race.players[i]; if (race.hasRevealed[player]) { currentSum += race.duckCounts[player]; if (winningNumber < currentSum) { race.winner = player; break; } } } // Distribute prize if (race.winner != address(0)) { uint256 winnerPrize = (race.totalPrize * WINNER_SHARE) / 100; uint256 devFee = race.totalPrize - winnerPrize; totalFees += devFee; cashier.creditPlayer{value: winnerPrize}(race.winner, winnerPrize); emit RaceCompleted(raceId, race.winner, winnerPrize); } race.state = RaceState.Cooldown; race.cooldownEnds = block.timestamp + COOLDOWN_DURATION; } // Admin functions function withdrawFees() external onlyOwner { uint256 amount = totalFees; totalFees = 0; (bool success, ) = owner().call{value: amount}(""); require(success, "Fee transfer failed"); emit FeeWithdrawn(amount); } function _createNewRace() private { currentRaceId++; Race storage race = races[currentRaceId]; race.startTime = block.timestamp; race.state = RaceState.Waiting; emit RaceCreated(currentRaceId); } function _startCommitPhase(uint256 raceId) private { Race storage race = races[raceId]; race.state = RaceState.Committing; race.commitDeadline = block.timestamp + COMMIT_DURATION; emit CommitPhaseStarted(raceId, race.commitDeadline); } function _startRace(uint256 raceId) private { Race storage race = races[raceId]; race.state = RaceState.Racing; race.raceDeadline = block.timestamp + RACE_DURATION; emit RaceStarted(raceId, race.raceDeadline); } // View functions function getCurrentRaceState() external view returns ( uint256 raceId, RaceState state, uint256 playerCount, uint256 totalPrize, uint256 deadline ) { Race storage race = races[currentRaceId]; deadline = race.state == RaceState.Committing ? race.commitDeadline : race.state == RaceState.Racing ? race.raceDeadline : race.state == RaceState.Cooldown ? race.cooldownEnds : 0; return ( currentRaceId, race.state, race.playerCount, race.totalPrize, deadline ); } function getRacePlayerInfo(uint256 raceId, address player) external view returns ( uint256 duckCount, bool hasCommitted, bool isWinner ) { Race storage race = races[raceId]; return ( race.duckCounts[player], race.duckCounts[player] > 0, race.winner == player ); } // Add the play function implementation function play(address player, uint256 amount) external payable override { require(msg.sender == proxyManager, "Only proxy manager"); require(amount >= PLAY_COST, "Minimum 1 duck"); uint256 duckCount = amount / PLAY_COST; require(duckCount <= 10, "Maximum 10 ducks per play"); if (currentRaceId == 0 || races[currentRaceId].state == RaceState.Completed) { _createNewRace(); } Race storage race = races[currentRaceId]; require(race.state == RaceState.Waiting || race.state == RaceState.Committing, "Race not accepting commits"); require(race.playerCount < MAX_PLAYERS, "Race full"); if (race.duckCounts[player] == 0) { race.players.push(player); race.playerCount++; } race.duckCounts[player] += duckCount; race.totalPrize += amount; // Start commit phase if minimum players reached if (race.playerCount >= MIN_PLAYERS && race.state == RaceState.Waiting) { _startCommitPhase(currentRaceId); } emit PlayerCommitted(currentRaceId, player, duckCount); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable2Step.sol) pragma solidity ^0.8.0; import "./OwnableUpgradeable.sol"; import {Initializable} from "../proxy/utils/Initializable.sol"; /** * @dev Contract module which provides 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} and {acceptOwnership}. * * This module is used through inheritance. It will make available all functions * from parent (Ownable). */ abstract contract Ownable2StepUpgradeable is Initializable, OwnableUpgradeable { address private _pendingOwner; event OwnershipTransferStarted(address indexed previousOwner, address indexed newOwner); function __Ownable2Step_init() internal onlyInitializing { __Ownable_init_unchained(); } function __Ownable2Step_init_unchained() internal onlyInitializing { } /** * @dev Returns the address of the pending owner. */ function pendingOwner() public view virtual returns (address) { return _pendingOwner; } /** * @dev Starts the ownership transfer of the contract to a new account. Replaces the pending transfer if there is one. * Can only be called by the current owner. */ function transferOwnership(address newOwner) public virtual override onlyOwner { _pendingOwner = newOwner; emit OwnershipTransferStarted(owner(), newOwner); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`) and deletes any pending owner. * Internal function without access restriction. */ function _transferOwnership(address newOwner) internal virtual override { delete _pendingOwner; super._transferOwnership(newOwner); } /** * @dev The new owner accepts the ownership transfer. */ function acceptOwnership() public virtual { address sender = _msgSender(); require(pendingOwner() == sender, "Ownable2Step: caller is not the new owner"); _transferOwnership(sender); } /** * @dev This empty reserved space is put in place to allow future versions to add new * variables without shifting down storage in the inheritance chain. * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps */ uint256[49] private __gap; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable.sol) pragma solidity ^0.8.0; import "../utils/ContextUpgradeable.sol"; import {Initializable} from "../proxy/utils/Initializable.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 OwnableUpgradeable is Initializable, ContextUpgradeable { address private _owner; event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the deployer as the initial owner. */ function __Ownable_init() internal onlyInitializing { __Ownable_init_unchained(); } function __Ownable_init_unchained() internal onlyInitializing { _transferOwnership(_msgSender()); } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { _checkOwner(); _; } /** * @dev Returns the address of the current owner. */ function owner() public view virtual returns (address) { return _owner; } /** * @dev Throws if the sender is not the owner. */ function _checkOwner() internal view virtual { require(owner() == _msgSender(), "Ownable: caller is not the owner"); } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby disabling any functionality that is only available to the owner. */ function renounceOwnership() public virtual onlyOwner { _transferOwnership(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"); _transferOwnership(newOwner); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Internal function without access restriction. */ function _transferOwnership(address newOwner) internal virtual { address oldOwner = _owner; _owner = newOwner; emit OwnershipTransferred(oldOwner, newOwner); } /** * @dev This empty reserved space is put in place to allow future versions to add new * variables without shifting down storage in the inheritance chain. * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps */ uint256[49] private __gap; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (proxy/utils/Initializable.sol) pragma solidity ^0.8.2; import "../../utils/AddressUpgradeable.sol"; /** * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect. * * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be * reused. This mechanism prevents re-execution of each "step" but allows the creation of new initialization steps in * case an upgrade adds a module that needs to be initialized. * * For example: * * [.hljs-theme-light.nopadding] * ```solidity * contract MyToken is ERC20Upgradeable { * function initialize() initializer public { * __ERC20_init("MyToken", "MTK"); * } * } * * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable { * function initializeV2() reinitializer(2) public { * __ERC20Permit_init("MyToken"); * } * } * ``` * * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}. * * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity. * * [CAUTION] * ==== * Avoid leaving a contract uninitialized. * * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed: * * [.hljs-theme-light.nopadding] * ``` * /// @custom:oz-upgrades-unsafe-allow constructor * constructor() { * _disableInitializers(); * } * ``` * ==== */ abstract contract Initializable { /** * @dev Indicates that the contract has been initialized. * @custom:oz-retyped-from bool */ uint8 private _initialized; /** * @dev Indicates that the contract is in the process of being initialized. */ bool private _initializing; /** * @dev Triggered when the contract has been initialized or reinitialized. */ event Initialized(uint8 version); /** * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope, * `onlyInitializing` functions can be used to initialize parent contracts. * * Similar to `reinitializer(1)`, except that functions marked with `initializer` can be nested in the context of a * constructor. * * Emits an {Initialized} event. */ modifier initializer() { bool isTopLevelCall = !_initializing; require( (isTopLevelCall && _initialized < 1) || (!AddressUpgradeable.isContract(address(this)) && _initialized == 1), "Initializable: contract is already initialized" ); _initialized = 1; if (isTopLevelCall) { _initializing = true; } _; if (isTopLevelCall) { _initializing = false; emit Initialized(1); } } /** * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be * used to initialize parent contracts. * * A reinitializer may be used after the original initialization step. This is essential to configure modules that * are added through upgrades and that require initialization. * * When `version` is 1, this modifier is similar to `initializer`, except that functions marked with `reinitializer` * cannot be nested. If one is invoked in the context of another, execution will revert. * * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in * a contract, executing them in the right order is up to the developer or operator. * * WARNING: setting the version to 255 will prevent any future reinitialization. * * Emits an {Initialized} event. */ modifier reinitializer(uint8 version) { require(!_initializing && _initialized < version, "Initializable: contract is already initialized"); _initialized = version; _initializing = true; _; _initializing = false; emit Initialized(version); } /** * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the * {initializer} and {reinitializer} modifiers, directly or indirectly. */ modifier onlyInitializing() { require(_initializing, "Initializable: contract is not initializing"); _; } /** * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call. * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized * to any version. It is recommended to use this to lock implementation contracts that are designed to be called * through proxies. * * Emits an {Initialized} event the first time it is successfully executed. */ function _disableInitializers() internal virtual { require(!_initializing, "Initializable: contract is initializing"); if (_initialized != type(uint8).max) { _initialized = type(uint8).max; emit Initialized(type(uint8).max); } } /** * @dev Returns the highest version that has been initialized. See {reinitializer}. */ function _getInitializedVersion() internal view returns (uint8) { return _initialized; } /** * @dev Returns `true` if the contract is currently initializing. See {onlyInitializing}. */ function _isInitializing() internal view returns (bool) { return _initializing; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (security/Pausable.sol) pragma solidity ^0.8.0; import "../utils/ContextUpgradeable.sol"; import {Initializable} from "../proxy/utils/Initializable.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 PausableUpgradeable is Initializable, ContextUpgradeable { /** * @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. */ function __Pausable_init() internal onlyInitializing { __Pausable_init_unchained(); } function __Pausable_init_unchained() internal onlyInitializing { _paused = false; } /** * @dev Modifier to make a function callable only when the contract is not paused. * * Requirements: * * - The contract must not be paused. */ modifier whenNotPaused() { _requireNotPaused(); _; } /** * @dev Modifier to make a function callable only when the contract is paused. * * Requirements: * * - The contract must be paused. */ modifier whenPaused() { _requirePaused(); _; } /** * @dev Returns true if the contract is paused, and false otherwise. */ function paused() public view virtual returns (bool) { return _paused; } /** * @dev Throws if the contract is paused. */ function _requireNotPaused() internal view virtual { require(!paused(), "Pausable: paused"); } /** * @dev Throws if the contract is not paused. */ function _requirePaused() internal view virtual { 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()); } /** * @dev This empty reserved space is put in place to allow future versions to add new * variables without shifting down storage in the inheritance chain. * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps */ uint256[49] private __gap; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (security/ReentrancyGuard.sol) pragma solidity ^0.8.0; import {Initializable} from "../proxy/utils/Initializable.sol"; /** * @dev Contract module that helps prevent reentrant calls to a function. * * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier * available, which can be applied to functions to make sure there are no nested * (reentrant) calls to them. * * Note that because there is a single `nonReentrant` guard, functions marked as * `nonReentrant` may not call one another. This can be worked around by making * those functions `private`, and then adding `external` `nonReentrant` entry * points to them. * * TIP: If you would like to learn more about reentrancy and alternative ways * to protect against it, check out our blog post * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul]. */ abstract contract ReentrancyGuardUpgradeable is Initializable { // Booleans are more expensive than uint256 or any type that takes up a full // word because each write operation emits an extra SLOAD to first read the // slot's contents, replace the bits taken up by the boolean, and then write // back. This is the compiler's defense against contract upgrades and // pointer aliasing, and it cannot be disabled. // The values being non-zero value makes deployment a bit more expensive, // but in exchange the refund on every call to nonReentrant will be lower in // amount. Since refunds are capped to a percentage of the total // transaction's gas, it is best to keep them low in cases like this one, to // increase the likelihood of the full refund coming into effect. uint256 private constant _NOT_ENTERED = 1; uint256 private constant _ENTERED = 2; uint256 private _status; function __ReentrancyGuard_init() internal onlyInitializing { __ReentrancyGuard_init_unchained(); } function __ReentrancyGuard_init_unchained() internal onlyInitializing { _status = _NOT_ENTERED; } /** * @dev Prevents a contract from calling itself, directly or indirectly. * Calling a `nonReentrant` function from another `nonReentrant` * function is not supported. It is possible to prevent this from happening * by making the `nonReentrant` function external, and making it call a * `private` function that does the actual work. */ modifier nonReentrant() { _nonReentrantBefore(); _; _nonReentrantAfter(); } function _nonReentrantBefore() private { // On the first call to nonReentrant, _status will be _NOT_ENTERED require(_status != _ENTERED, "ReentrancyGuard: reentrant call"); // Any calls to nonReentrant after this point will fail _status = _ENTERED; } function _nonReentrantAfter() private { // By storing the original value once again, a refund is triggered (see // https://eips.ethereum.org/EIPS/eip-2200) _status = _NOT_ENTERED; } /** * @dev Returns true if the reentrancy guard is currently set to "entered", which indicates there is a * `nonReentrant` function in the call stack. */ function _reentrancyGuardEntered() internal view returns (bool) { return _status == _ENTERED; } /** * @dev This empty reserved space is put in place to allow future versions to add new * variables without shifting down storage in the inheritance chain. * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps */ uint256[49] private __gap; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol) pragma solidity ^0.8.1; /** * @dev Collection of functions related to the address type */ library AddressUpgradeable { /** * @dev Returns true if `account` is a contract. * * [IMPORTANT] * ==== * It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. * * Among others, `isContract` will return false for the following * types of addresses: * * - an externally-owned account * - a contract in construction * - an address where a contract will be created * - an address where a contract lived, but was destroyed * * Furthermore, `isContract` will also return true if the target contract within * the same transaction is already scheduled for destruction by `SELFDESTRUCT`, * which only has an effect at the end of a transaction. * ==== * * [IMPORTANT] * ==== * You shouldn't rely on `isContract` to protect against flash loan attacks! * * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract * constructor. * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize/address.code.length, which returns 0 // for contracts in construction, since the code is only stored at the end // of the constructor execution. return account.code.length > 0; } /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); (bool success, ) = recipient.call{value: amount}(""); require(success, "Address: unable to send value, recipient may have reverted"); } /** * @dev Performs a Solidity function call using a low level `call`. A * plain `call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason, it is bubbled up by this * function (like regular Solidity function calls). * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, "Address: low-level call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with * `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. * * _Available since v3.1._ */ function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) { return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); } /** * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value, string memory errorMessage ) internal returns (bytes memory) { require(address(this).balance >= value, "Address: insufficient balance for call"); (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall(target, data, "Address: low-level static call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall( address target, bytes memory data, string memory errorMessage ) internal view returns (bytes memory) { (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { return functionDelegateCall(target, data, "Address: low-level delegate call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { (bool success, bytes memory returndata) = target.delegatecall(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract. * * _Available since v4.8._ */ function verifyCallResultFromTarget( address target, bool success, bytes memory returndata, string memory errorMessage ) internal view returns (bytes memory) { if (success) { if (returndata.length == 0) { // only check isContract if the call was successful and the return data is empty // otherwise we already know that it was a contract require(isContract(target), "Address: call to non-contract"); } return returndata; } else { _revert(returndata, errorMessage); } } /** * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason or using the provided one. * * _Available since v4.3._ */ function verifyCallResult( bool success, bytes memory returndata, string memory errorMessage ) internal pure returns (bytes memory) { if (success) { return returndata; } else { _revert(returndata, errorMessage); } } function _revert(bytes memory returndata, string memory errorMessage) private pure { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly /// @solidity memory-safe-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.4) (utils/Context.sol) pragma solidity ^0.8.0; import {Initializable} from "../proxy/utils/Initializable.sol"; /** * @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 ContextUpgradeable is Initializable { function __Context_init() internal onlyInitializing { } function __Context_init_unchained() internal onlyInitializing { } function _msgSender() internal view virtual returns (address) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { return msg.data; } function _contextSuffixLength() internal view virtual returns (uint256) { return 0; } /** * @dev This empty reserved space is put in place to allow future versions to add new * variables without shifting down storage in the inheritance chain. * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps */ uint256[50] private __gap; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.19; interface IGame { function play(address player, uint256 amount) external payable; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.19; interface IUniversalCashier { function deposit() external payable; function withdraw(uint256 amount) external; function debitPlayer(address player, uint256 amount) external returns (bool); function creditPlayer(address player, uint256 amount) external payable; function getBalance(address player) external view returns (uint256); function authorizeGame(address game, bool status) external; function setTreasury(address _treasury) external; }
{ "optimizer": { "enabled": true, "runs": 200 }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "libraries": {} }
[{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"raceId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"CommitPhaseStarted","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"FeeWithdrawn","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint8","name":"version","type":"uint8"}],"name":"Initialized","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferStarted","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":"uint256","name":"raceId","type":"uint256"},{"indexed":true,"internalType":"address","name":"player","type":"address"},{"indexed":false,"internalType":"uint256","name":"duckCount","type":"uint256"}],"name":"PlayerCommitted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"player","type":"address"},{"indexed":false,"internalType":"uint256","name":"ducksPerRace","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"races","type":"uint256"}],"name":"PreCommitmentSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"raceId","type":"uint256"},{"indexed":false,"internalType":"address","name":"winner","type":"address"},{"indexed":false,"internalType":"uint256","name":"prize","type":"uint256"}],"name":"RaceCompleted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"raceId","type":"uint256"}],"name":"RaceCreated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"raceId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"RaceStarted","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Unpaused","type":"event"},{"inputs":[],"name":"COMMIT_DURATION","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"COOLDOWN_DURATION","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"DEV_SHARE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_PLAYERS","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MIN_PLAYERS","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PLAY_COST","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"RACE_DURATION","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"WINNER_SHARE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"acceptOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"cashier","outputs":[{"internalType":"contract IUniversalCashier","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"commitHash","type":"bytes32"},{"internalType":"bytes32","name":"salt","type":"bytes32"},{"internalType":"uint256","name":"duckCount","type":"uint256"}],"name":"commit","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"currentRaceId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"raceId","type":"uint256"}],"name":"finalize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"getCurrentRaceState","outputs":[{"internalType":"uint256","name":"raceId","type":"uint256"},{"internalType":"enum DuckRace.RaceState","name":"state","type":"uint8"},{"internalType":"uint256","name":"playerCount","type":"uint256"},{"internalType":"uint256","name":"totalPrize","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"raceId","type":"uint256"},{"internalType":"address","name":"player","type":"address"}],"name":"getRacePlayerInfo","outputs":[{"internalType":"uint256","name":"duckCount","type":"uint256"},{"internalType":"bool","name":"hasCommitted","type":"bool"},{"internalType":"bool","name":"isWinner","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_proxyManager","type":"address"},{"internalType":"address","name":"_cashier","type":"address"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pendingOwner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"player","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"play","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"preCommitments","outputs":[{"internalType":"uint256","name":"ducksPerRace","type":"uint256"},{"internalType":"uint256","name":"racesRemaining","type":"uint256"},{"internalType":"bytes32","name":"commitHash","type":"bytes32"},{"internalType":"bytes32","name":"salt","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"processPreCommitments","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"proxyManager","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"races","outputs":[{"internalType":"uint256","name":"startTime","type":"uint256"},{"internalType":"uint256","name":"commitDeadline","type":"uint256"},{"internalType":"uint256","name":"raceDeadline","type":"uint256"},{"internalType":"uint256","name":"cooldownEnds","type":"uint256"},{"internalType":"uint256","name":"totalPrize","type":"uint256"},{"internalType":"address","name":"winner","type":"address"},{"internalType":"enum DuckRace.RaceState","name":"state","type":"uint8"},{"internalType":"uint256","name":"playerCount","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"seed","type":"uint256"},{"internalType":"bytes32","name":"salt","type":"bytes32"}],"name":"reveal","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"ducksPerRace","type":"uint256"},{"internalType":"uint256","name":"numberOfRaces","type":"uint256"},{"internalType":"bytes32","name":"commitHash","type":"bytes32"},{"internalType":"bytes32","name":"salt","type":"bytes32"}],"name":"setPreCommitment","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"totalFees","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":"withdrawFees","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
608060405234801561001057600080fd5b506122e1806100206000396000f3fe6080604052600436106101cd5760003560e01c80637bbc469e116100f7578063b216a6c611610095578063e724596411610064578063e7245964146103c9578063ed740e9714610594578063f0e10c0d146105b4578063f2fde38b146105c757600080fd5b8063b216a6c614610545578063b971e2fd146103c9578063dbe3010c14610561578063e30c39781461057657600080fd5b80638da5cb5b116100d15780638da5cb5b146104b75780638f7f6e89146104e957806396b4ca701461050f5780639ad9d5011461052f57600080fd5b80637bbc469e14610408578063856893101461048d57806385f07bbe146104a257600080fd5b8063485cc9551161016f5780635c975abb1161013e5780635c975abb146103a65780635ec775b0146103c9578063715018a6146103de57806379ba5097146103f357600080fd5b8063485cc955146102f05780634a2e7598146103105780634a7e637e146103235780635088adc31461034357600080fd5b806313114a9d116101ab57806313114a9d146102905780634036778f146102a65780634411b3eb146102c6578063476343ee146102db57600080fd5b8063029dd6ba146101d257806305261aea146101fa5780630e07bff51461021c575b600080fd5b3480156101de57600080fd5b506101e7600a81565b6040519081526020015b60405180910390f35b34801561020657600080fd5b5061021a610215366004611f36565b6105e7565b005b34801561022857600080fd5b50610273610237366004611f6b565b600091825260ff602090815260408084206001600160a01b03938416808652600a82019093529320546005909301549293841515939092161490565b6040805193845291151560208401521515908201526060016101f1565b34801561029c57600080fd5b506101e760fd5481565b3480156102b257600080fd5b5061021a6102c1366004611f97565b610a94565b3480156102d257600080fd5b506101e7606481565b3480156102e757600080fd5b5061021a610c49565b3480156102fc57600080fd5b5061021a61030b366004611fb9565b610d3b565b61021a61031e366004611fe3565b610e93565b34801561032f57600080fd5b5061021a61033e36600461200f565b610fd3565b34801561034f57600080fd5b5061038661035e366004612041565b6101006020526000908152604090208054600182015460028301546003909301549192909184565b6040805194855260208501939093529183015260608201526080016101f1565b3480156103b257600080fd5b5060335460ff1660405190151581526020016101f1565b3480156103d557600080fd5b506101e7603c81565b3480156103ea57600080fd5b5061021a6111f1565b3480156103ff57600080fd5b5061021a611205565b34801561041457600080fd5b50610479610423366004611f36565b60ff602081905260009182526040909120805460018201546002830154600384015460048501546005860154600690960154949693959294919390926001600160a01b03811692600160a01b9091049091169088565b6040516101f198979695949392919061209b565b34801561049957600080fd5b5061021a61127f565b3480156104ae57600080fd5b506101e7600281565b3480156104c357600080fd5b506065546001600160a01b03165b6040516001600160a01b0390911681526020016101f1565b3480156104f557600080fd5b506104fe61144a565b6040516101f19594939291906120ee565b34801561051b57600080fd5b5060fb546104d1906001600160a01b031681565b34801561053b57600080fd5b506101e760fe5481565b34801561055157600080fd5b506101e7670de0b6b3a764000081565b34801561056d57600080fd5b506101e7605a81565b34801561058257600080fd5b506097546001600160a01b03166104d1565b3480156105a057600080fd5b5060fc546104d1906001600160a01b031681565b61021a6105c236600461211e565b611526565b3480156105d357600080fd5b5061021a6105e2366004612041565b61189a565b600081815260ff6020526040902060026005820154600160a01b900460ff16600481111561061757610617612063565b146106605760405162461bcd60e51b815260206004820152601460248201527352616365206e6f7420696e2070726f677265737360601b60448201526064015b60405180910390fd5b806002015442116106ac5760405162461bcd60e51b815260206004820152601660248201527552616365207374696c6c20696e2070726f677265737360501b6044820152606401610657565b60008060005b600b84015481101561074857600084600b0182815481106106d5576106d5612148565b60009182526020808320909101546001600160a01b03168083526009880190915260409091205490915060ff1615610735576001600160a01b038116600090815260088601602052604090205493909318928261073181612174565b9350505b508061074081612174565b9150506106b2565b50600281101561078f5760405162461bcd60e51b81526020600482015260126024820152714e6f7420656e6f7567682072657665616c7360701b6044820152606401610657565b60408051602080820185905244828401524260608084019190915283518084039091018152608090920190925280519101206000805b600b8601548110156108785785600901600087600b0183815481106107ec576107ec612148565b60009182526020808320909101546001600160a01b0316835282019290925260400190205460ff16156108665785600a01600087600b01838154811061083457610834612148565b60009182526020808320909101546001600160a01b03168352820192909252604001902054610863908361218d565b91505b8061087081612174565b9150506107c5565b50600061088582846121bc565b90506000805b600b88015481101561094957600088600b0182815481106108ae576108ae612148565b60009182526020808320909101546001600160a01b031680835260098c0190915260409091205490915060ff1615610936576001600160a01b0381166000908152600a8a016020526040902054610905908461218d565b925082841015610936576005890180546001600160a01b0319166001600160a01b0392909216919091179055610949565b508061094181612174565b91505061088b565b5060058701546001600160a01b031615610a625760006064605a896004015461097291906121d0565b61097c91906121e7565b9050600081896004015461099091906121fb565b90508060fd60008282546109a4919061218d565b909155505060fc5460058a01546040516339c255ad60e11b81526001600160a01b03918216600482015260248101859052911690637384ab5a9084906044016000604051808303818588803b1580156109fc57600080fd5b505af1158015610a10573d6000803e3d6000fd5b5050505060058a0154604080516001600160a01b039092168252602082018590528c92507fe36b67fec2742bf0400545705e6f61c6b71ad23cda3cdc1c80f1d8fdd37875eb910160405180910390a250505b60058701805460ff60a01b1916600160a21b179055610a82603c4261218d565b87600301819055505050505050505050565b610a9c61190b565b610aa4611964565b60fe54600090815260ff6020526040902060026005820154600160a01b900460ff166004811115610ad757610ad7612063565b14610b175760405162461bcd60e51b815260206004820152601060248201526f4e6f742072657665616c20706861736560801b6044820152606401610657565b33600090815260098201602052604090205460ff1615610b6c5760405162461bcd60e51b815260206004820152601060248201526f105b1c9958591e481c995d99585b195960821b6044820152606401610657565b6000838333604051602001610ba693929190928352602083019190915260601b6bffffffffffffffffffffffff1916604082015260540190565b60408051601f198184030181529181528151602092830120336000908152600786019093529120549091508114610c105760405162461bcd60e51b815260206004820152600e60248201526d125b9d985b1a59081c995d99585b60921b6044820152606401610657565b5033600090815260088201602090815260408083208690556009909301905220805460ff19166001179055610c45600160c955565b5050565b610c516119b1565b60fd805460009182905590610c6e6065546001600160a01b031690565b6001600160a01b03168260405160006040518083038185875af1925050503d8060008114610cb8576040519150601f19603f3d011682016040523d82523d6000602084013e610cbd565b606091505b5050905080610d045760405162461bcd60e51b8152602060048201526013602482015272119959481d1c985b9cd9995c8819985a5b1959606a1b6044820152606401610657565b6040518281527fb7eeacba6b133788365610e83d3f130d07b6ef6e78877961f25b3f61fcba07529060200160405180910390a15050565b600054610100900460ff1615808015610d5b5750600054600160ff909116105b80610d755750303b158015610d75575060005460ff166001145b610dd85760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b6064820152608401610657565b6000805460ff191660011790558015610dfb576000805461ff0019166101001790555b610e03611a0b565b610e0b611a3a565b610e13611a69565b60fb80546001600160a01b038086166001600160a01b03199283161790925560fc805492851692909116919091179055600060fe558015610e8e576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b505050565b610e9b611964565b610ea361190b565b600081118015610eb45750600a8111155b610ef55760405162461bcd60e51b8152602060048201526012602482015271125b9d985b1a5908191d58dac818dbdd5b9d60721b6044820152606401610657565b6000610f0982670de0b6b3a76400006121d0565b60fc5460405163026ff28360e61b8152336004820152602481018390529192506001600160a01b031690639bfca0c0906044016020604051808303816000875af1158015610f5b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f7f919061220e565b610fbc5760405162461bcd60e51b815260206004820152600e60248201526d14185e5b595b9d0819985a5b195960921b6044820152606401610657565b610fc833858585611a98565b50610e8e600160c955565b610fdb611964565b610fe361190b565b600084118015610ff45750600a8411155b6110355760405162461bcd60e51b8152602060048201526012602482015271125b9d985b1a5908191d58dac818dbdd5b9d60721b6044820152606401610657565b600083118015611046575060648311155b6110875760405162461bcd60e51b8152602060048201526012602482015271125b9d985b1a59081c9858d94818dbdd5b9d60721b6044820152606401610657565b60008361109c86670de0b6b3a76400006121d0565b6110a691906121d0565b60fc5460405163f8b2cb4f60e01b815233600482015291925082916001600160a01b039091169063f8b2cb4f90602401602060405180830381865afa1580156110f3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111179190612230565b101561115c5760405162461bcd60e51b8152602060048201526014602482015273496e73756666696369656e742062616c616e636560601b6044820152606401610657565b60408051608081018252868152602080820187815282840187815260608401878152336000818152610100865287902095518655925160018601559051600285015551600390930192909255825188815290810187905290917ff8e6eecb54666e6632f533f4cca758e324ba047691ad9d6c6d4304d8a43f7581910160405180910390a2506111eb600160c955565b50505050565b6111f96119b1565b6112036000611d6d565b565b60975433906001600160a01b031681146112735760405162461bcd60e51b815260206004820152602960248201527f4f776e61626c6532537465703a2063616c6c6572206973206e6f7420746865206044820152683732bb9037bbb732b960b91b6064820152608401610657565b61127c81611d6d565b50565b3360009081526101006020526040902060018101546112d55760405162461bcd60e51b81526020600482015260126024820152714e6f207072652d636f6d6d69746d656e747360701b6044820152606401610657565b805461131c5760405162461bcd60e51b8152602060048201526016602482015275125b9d985b1a59081c1c994b58dbdb5b5a5d1b595b9d60521b6044820152606401610657565b805460009061133390670de0b6b3a76400006121d0565b60fc5460405163026ff28360e61b8152336004820152602481018390529192506001600160a01b031690639bfca0c0906044016020604051808303816000875af1158015611385573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113a9919061220e565b6113e65760405162461bcd60e51b815260206004820152600e60248201526d14185e5b595b9d0819985a5b195960921b6044820152606401610657565b6113fe33836002015484600301548560000154611a98565b60018201805490600061141083612249565b91905055508160010154600003610c4557336000908152610100602052604081208181556001810182905560028101829055600301555050565b60fe54600090815260ff60205260408120819081908190819060016005820154600160a01b900460ff16600481111561148557611485612063565b146114f35760026005820154600160a01b900460ff1660048111156114ac576114ac612063565b146114e95760046005820154600160a01b900460ff1660048111156114d3576114d3612063565b146114df5760006114f9565b80600301546114f9565b80600201546114f9565b80600101545b60fe54600583015460068401546004909401549199600160a01b90910460ff169850929650945092509050565b60fb546001600160a01b031633146115755760405162461bcd60e51b815260206004820152601260248201527127b7363c90383937bc3c9036b0b730b3b2b960711b6044820152606401610657565b670de0b6b3a76400008110156115be5760405162461bcd60e51b815260206004820152600e60248201526d4d696e696d756d2031206475636b60901b6044820152606401610657565b60006115d2670de0b6b3a7640000836121e7565b9050600a8111156116255760405162461bcd60e51b815260206004820152601960248201527f4d6178696d756d203130206475636b732070657220706c6179000000000000006044820152606401610657565b60fe5415806116645750600360fe54600090815260ff6020819052604090912060050154600160a01b900416600481111561166257611662612063565b145b1561167157611671611d86565b60fe54600090815260ff60205260408120906005820154600160a01b900460ff1660048111156116a3576116a3612063565b14806116ce575060016005820154600160a01b900460ff1660048111156116cc576116cc612063565b145b61171a5760405162461bcd60e51b815260206004820152601a60248201527f52616365206e6f7420616363657074696e6720636f6d6d6974730000000000006044820152606401610657565b606481600601541061175a5760405162461bcd60e51b8152602060048201526009602482015268149858d948199d5b1b60ba1b6044820152606401610657565b6001600160a01b0384166000908152600a8201602052604081205490036117c057600b810180546001810182556000918252602082200180546001600160a01b0319166001600160a01b038716179055600682018054916117ba83612174565b91905055505b6001600160a01b0384166000908152600a82016020526040812080548492906117ea90849061218d565b9250508190555082816004016000828254611805919061218d565b9091555050600681015460021180159061183e575060006005820154600160a01b900460ff16600481111561183c5761183c612063565b145b1561184e5761184e60fe54611dec565b836001600160a01b031660fe547fe2de6d4e065ffb08e16ed34dfa1c449370f8012a3a03ba4384f0d1390aa0a7168460405161188c91815260200190565b60405180910390a350505050565b6118a26119b1565b609780546001600160a01b0383166001600160a01b031990911681179091556118d36065546001600160a01b031690565b6001600160a01b03167f38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e2270060405160405180910390a350565b600260c9540361195d5760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610657565b600260c955565b60335460ff16156112035760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b6044820152606401610657565b600160c955565b6065546001600160a01b031633146112035760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610657565b600054610100900460ff16611a325760405162461bcd60e51b815260040161065790612260565b611203611e5a565b600054610100900460ff16611a615760405162461bcd60e51b815260040161065790612260565b611203611e8d565b600054610100900460ff16611a905760405162461bcd60e51b815260040161065790612260565b611203611ebd565b60fe541580611ad75750600360fe54600090815260ff6020819052604090912060050154600160a01b9004166004811115611ad557611ad5612063565b145b15611ae457611ae4611d86565b60fe54600090815260ff60205260408120906005820154600160a01b900460ff166004811115611b1657611b16612063565b1480611b41575060016005820154600160a01b900460ff166004811115611b3f57611b3f612063565b145b611b8d5760405162461bcd60e51b815260206004820152601a60248201527f52616365206e6f7420616363657074696e6720636f6d6d6974730000000000006044820152606401610657565b6064816006015410611bcd5760405162461bcd60e51b8152602060048201526009602482015268149858d948199d5b1b60ba1b6044820152606401610657565b6001600160a01b0385166000908152600a820160205260408120549003611c3357600b810180546001810182556000918252602082200180546001600160a01b0319166001600160a01b03881617905560068201805491611c2d83612174565b91905055505b6040805160208101869052908101849052606086811b6bffffffffffffffffffffffff19169082015260740160408051601f1981840301815291815281516020928301206001600160a01b038816600090815260078501845282812091909155600a840190925281208054849290611cac90849061218d565b90915550611cc4905082670de0b6b3a76400006121d0565b816004016000828254611cd7919061218d565b90915550506006810154600211801590611d10575060006005820154600160a01b900460ff166004811115611d0e57611d0e612063565b145b15611d2057611d2060fe54611dec565b846001600160a01b031660fe547fe2de6d4e065ffb08e16ed34dfa1c449370f8012a3a03ba4384f0d1390aa0a71684604051611d5e91815260200190565b60405180910390a35050505050565b609780546001600160a01b031916905561127c81611ee4565b60fe8054906000611d9683612174565b909155505060fe8054600090815260ff602052604080822042815560058101805460ff60a01b191690559254905190917f5a691e0655b3e3b2995fd900bfeeeccf635a465b0b798b9d4d49a75a1ce4a9cc91a250565b600081815260ff6020526040902060058101805460ff60a01b1916600160a01b179055611e1a603c4261218d565b6001820181905560405190815282907fca320d5325ac490d02db3ee19e4449fa70ec50b6c89db38cc29fba981a77733e9060200160405180910390a25050565b600054610100900460ff16611e815760405162461bcd60e51b815260040161065790612260565b6033805460ff19169055565b600054610100900460ff16611eb45760405162461bcd60e51b815260040161065790612260565b61120333611d6d565b600054610100900460ff166119aa5760405162461bcd60e51b815260040161065790612260565b606580546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b600060208284031215611f4857600080fd5b5035919050565b80356001600160a01b0381168114611f6657600080fd5b919050565b60008060408385031215611f7e57600080fd5b82359150611f8e60208401611f4f565b90509250929050565b60008060408385031215611faa57600080fd5b50508035926020909101359150565b60008060408385031215611fcc57600080fd5b611fd583611f4f565b9150611f8e60208401611f4f565b600080600060608486031215611ff857600080fd5b505081359360208301359350604090920135919050565b6000806000806080858703121561202557600080fd5b5050823594602084013594506040840135936060013592509050565b60006020828403121561205357600080fd5b61205c82611f4f565b9392505050565b634e487b7160e01b600052602160045260246000fd5b6005811061209757634e487b7160e01b600052602160045260246000fd5b9052565b888152602081018890526040810187905260608101869052608081018590526001600160a01b03841660a082015261010081016120db60c0830185612079565b8260e08301529998505050505050505050565b85815260a081016121026020830187612079565b8460408301528360608301528260808301529695505050505050565b6000806040838503121561213157600080fd5b61213a83611f4f565b946020939093013593505050565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b6000600182016121865761218661215e565b5060010190565b808201808211156121a0576121a061215e565b92915050565b634e487b7160e01b600052601260045260246000fd5b6000826121cb576121cb6121a6565b500690565b80820281158282048414176121a0576121a061215e565b6000826121f6576121f66121a6565b500490565b818103818111156121a0576121a061215e565b60006020828403121561222057600080fd5b8151801515811461205c57600080fd5b60006020828403121561224257600080fd5b5051919050565b6000816122585761225861215e565b506000190190565b6020808252602b908201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960408201526a6e697469616c697a696e6760a81b60608201526080019056fea264697066735822122027f06f61438fa6d94fc96b13c8ef5e084e2721758ed80f6696da4c9d955f926464736f6c63430008130033
Deployed Bytecode
0x6080604052600436106101cd5760003560e01c80637bbc469e116100f7578063b216a6c611610095578063e724596411610064578063e7245964146103c9578063ed740e9714610594578063f0e10c0d146105b4578063f2fde38b146105c757600080fd5b8063b216a6c614610545578063b971e2fd146103c9578063dbe3010c14610561578063e30c39781461057657600080fd5b80638da5cb5b116100d15780638da5cb5b146104b75780638f7f6e89146104e957806396b4ca701461050f5780639ad9d5011461052f57600080fd5b80637bbc469e14610408578063856893101461048d57806385f07bbe146104a257600080fd5b8063485cc9551161016f5780635c975abb1161013e5780635c975abb146103a65780635ec775b0146103c9578063715018a6146103de57806379ba5097146103f357600080fd5b8063485cc955146102f05780634a2e7598146103105780634a7e637e146103235780635088adc31461034357600080fd5b806313114a9d116101ab57806313114a9d146102905780634036778f146102a65780634411b3eb146102c6578063476343ee146102db57600080fd5b8063029dd6ba146101d257806305261aea146101fa5780630e07bff51461021c575b600080fd5b3480156101de57600080fd5b506101e7600a81565b6040519081526020015b60405180910390f35b34801561020657600080fd5b5061021a610215366004611f36565b6105e7565b005b34801561022857600080fd5b50610273610237366004611f6b565b600091825260ff602090815260408084206001600160a01b03938416808652600a82019093529320546005909301549293841515939092161490565b6040805193845291151560208401521515908201526060016101f1565b34801561029c57600080fd5b506101e760fd5481565b3480156102b257600080fd5b5061021a6102c1366004611f97565b610a94565b3480156102d257600080fd5b506101e7606481565b3480156102e757600080fd5b5061021a610c49565b3480156102fc57600080fd5b5061021a61030b366004611fb9565b610d3b565b61021a61031e366004611fe3565b610e93565b34801561032f57600080fd5b5061021a61033e36600461200f565b610fd3565b34801561034f57600080fd5b5061038661035e366004612041565b6101006020526000908152604090208054600182015460028301546003909301549192909184565b6040805194855260208501939093529183015260608201526080016101f1565b3480156103b257600080fd5b5060335460ff1660405190151581526020016101f1565b3480156103d557600080fd5b506101e7603c81565b3480156103ea57600080fd5b5061021a6111f1565b3480156103ff57600080fd5b5061021a611205565b34801561041457600080fd5b50610479610423366004611f36565b60ff602081905260009182526040909120805460018201546002830154600384015460048501546005860154600690960154949693959294919390926001600160a01b03811692600160a01b9091049091169088565b6040516101f198979695949392919061209b565b34801561049957600080fd5b5061021a61127f565b3480156104ae57600080fd5b506101e7600281565b3480156104c357600080fd5b506065546001600160a01b03165b6040516001600160a01b0390911681526020016101f1565b3480156104f557600080fd5b506104fe61144a565b6040516101f19594939291906120ee565b34801561051b57600080fd5b5060fb546104d1906001600160a01b031681565b34801561053b57600080fd5b506101e760fe5481565b34801561055157600080fd5b506101e7670de0b6b3a764000081565b34801561056d57600080fd5b506101e7605a81565b34801561058257600080fd5b506097546001600160a01b03166104d1565b3480156105a057600080fd5b5060fc546104d1906001600160a01b031681565b61021a6105c236600461211e565b611526565b3480156105d357600080fd5b5061021a6105e2366004612041565b61189a565b600081815260ff6020526040902060026005820154600160a01b900460ff16600481111561061757610617612063565b146106605760405162461bcd60e51b815260206004820152601460248201527352616365206e6f7420696e2070726f677265737360601b60448201526064015b60405180910390fd5b806002015442116106ac5760405162461bcd60e51b815260206004820152601660248201527552616365207374696c6c20696e2070726f677265737360501b6044820152606401610657565b60008060005b600b84015481101561074857600084600b0182815481106106d5576106d5612148565b60009182526020808320909101546001600160a01b03168083526009880190915260409091205490915060ff1615610735576001600160a01b038116600090815260088601602052604090205493909318928261073181612174565b9350505b508061074081612174565b9150506106b2565b50600281101561078f5760405162461bcd60e51b81526020600482015260126024820152714e6f7420656e6f7567682072657665616c7360701b6044820152606401610657565b60408051602080820185905244828401524260608084019190915283518084039091018152608090920190925280519101206000805b600b8601548110156108785785600901600087600b0183815481106107ec576107ec612148565b60009182526020808320909101546001600160a01b0316835282019290925260400190205460ff16156108665785600a01600087600b01838154811061083457610834612148565b60009182526020808320909101546001600160a01b03168352820192909252604001902054610863908361218d565b91505b8061087081612174565b9150506107c5565b50600061088582846121bc565b90506000805b600b88015481101561094957600088600b0182815481106108ae576108ae612148565b60009182526020808320909101546001600160a01b031680835260098c0190915260409091205490915060ff1615610936576001600160a01b0381166000908152600a8a016020526040902054610905908461218d565b925082841015610936576005890180546001600160a01b0319166001600160a01b0392909216919091179055610949565b508061094181612174565b91505061088b565b5060058701546001600160a01b031615610a625760006064605a896004015461097291906121d0565b61097c91906121e7565b9050600081896004015461099091906121fb565b90508060fd60008282546109a4919061218d565b909155505060fc5460058a01546040516339c255ad60e11b81526001600160a01b03918216600482015260248101859052911690637384ab5a9084906044016000604051808303818588803b1580156109fc57600080fd5b505af1158015610a10573d6000803e3d6000fd5b5050505060058a0154604080516001600160a01b039092168252602082018590528c92507fe36b67fec2742bf0400545705e6f61c6b71ad23cda3cdc1c80f1d8fdd37875eb910160405180910390a250505b60058701805460ff60a01b1916600160a21b179055610a82603c4261218d565b87600301819055505050505050505050565b610a9c61190b565b610aa4611964565b60fe54600090815260ff6020526040902060026005820154600160a01b900460ff166004811115610ad757610ad7612063565b14610b175760405162461bcd60e51b815260206004820152601060248201526f4e6f742072657665616c20706861736560801b6044820152606401610657565b33600090815260098201602052604090205460ff1615610b6c5760405162461bcd60e51b815260206004820152601060248201526f105b1c9958591e481c995d99585b195960821b6044820152606401610657565b6000838333604051602001610ba693929190928352602083019190915260601b6bffffffffffffffffffffffff1916604082015260540190565b60408051601f198184030181529181528151602092830120336000908152600786019093529120549091508114610c105760405162461bcd60e51b815260206004820152600e60248201526d125b9d985b1a59081c995d99585b60921b6044820152606401610657565b5033600090815260088201602090815260408083208690556009909301905220805460ff19166001179055610c45600160c955565b5050565b610c516119b1565b60fd805460009182905590610c6e6065546001600160a01b031690565b6001600160a01b03168260405160006040518083038185875af1925050503d8060008114610cb8576040519150601f19603f3d011682016040523d82523d6000602084013e610cbd565b606091505b5050905080610d045760405162461bcd60e51b8152602060048201526013602482015272119959481d1c985b9cd9995c8819985a5b1959606a1b6044820152606401610657565b6040518281527fb7eeacba6b133788365610e83d3f130d07b6ef6e78877961f25b3f61fcba07529060200160405180910390a15050565b600054610100900460ff1615808015610d5b5750600054600160ff909116105b80610d755750303b158015610d75575060005460ff166001145b610dd85760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b6064820152608401610657565b6000805460ff191660011790558015610dfb576000805461ff0019166101001790555b610e03611a0b565b610e0b611a3a565b610e13611a69565b60fb80546001600160a01b038086166001600160a01b03199283161790925560fc805492851692909116919091179055600060fe558015610e8e576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b505050565b610e9b611964565b610ea361190b565b600081118015610eb45750600a8111155b610ef55760405162461bcd60e51b8152602060048201526012602482015271125b9d985b1a5908191d58dac818dbdd5b9d60721b6044820152606401610657565b6000610f0982670de0b6b3a76400006121d0565b60fc5460405163026ff28360e61b8152336004820152602481018390529192506001600160a01b031690639bfca0c0906044016020604051808303816000875af1158015610f5b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f7f919061220e565b610fbc5760405162461bcd60e51b815260206004820152600e60248201526d14185e5b595b9d0819985a5b195960921b6044820152606401610657565b610fc833858585611a98565b50610e8e600160c955565b610fdb611964565b610fe361190b565b600084118015610ff45750600a8411155b6110355760405162461bcd60e51b8152602060048201526012602482015271125b9d985b1a5908191d58dac818dbdd5b9d60721b6044820152606401610657565b600083118015611046575060648311155b6110875760405162461bcd60e51b8152602060048201526012602482015271125b9d985b1a59081c9858d94818dbdd5b9d60721b6044820152606401610657565b60008361109c86670de0b6b3a76400006121d0565b6110a691906121d0565b60fc5460405163f8b2cb4f60e01b815233600482015291925082916001600160a01b039091169063f8b2cb4f90602401602060405180830381865afa1580156110f3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111179190612230565b101561115c5760405162461bcd60e51b8152602060048201526014602482015273496e73756666696369656e742062616c616e636560601b6044820152606401610657565b60408051608081018252868152602080820187815282840187815260608401878152336000818152610100865287902095518655925160018601559051600285015551600390930192909255825188815290810187905290917ff8e6eecb54666e6632f533f4cca758e324ba047691ad9d6c6d4304d8a43f7581910160405180910390a2506111eb600160c955565b50505050565b6111f96119b1565b6112036000611d6d565b565b60975433906001600160a01b031681146112735760405162461bcd60e51b815260206004820152602960248201527f4f776e61626c6532537465703a2063616c6c6572206973206e6f7420746865206044820152683732bb9037bbb732b960b91b6064820152608401610657565b61127c81611d6d565b50565b3360009081526101006020526040902060018101546112d55760405162461bcd60e51b81526020600482015260126024820152714e6f207072652d636f6d6d69746d656e747360701b6044820152606401610657565b805461131c5760405162461bcd60e51b8152602060048201526016602482015275125b9d985b1a59081c1c994b58dbdb5b5a5d1b595b9d60521b6044820152606401610657565b805460009061133390670de0b6b3a76400006121d0565b60fc5460405163026ff28360e61b8152336004820152602481018390529192506001600160a01b031690639bfca0c0906044016020604051808303816000875af1158015611385573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113a9919061220e565b6113e65760405162461bcd60e51b815260206004820152600e60248201526d14185e5b595b9d0819985a5b195960921b6044820152606401610657565b6113fe33836002015484600301548560000154611a98565b60018201805490600061141083612249565b91905055508160010154600003610c4557336000908152610100602052604081208181556001810182905560028101829055600301555050565b60fe54600090815260ff60205260408120819081908190819060016005820154600160a01b900460ff16600481111561148557611485612063565b146114f35760026005820154600160a01b900460ff1660048111156114ac576114ac612063565b146114e95760046005820154600160a01b900460ff1660048111156114d3576114d3612063565b146114df5760006114f9565b80600301546114f9565b80600201546114f9565b80600101545b60fe54600583015460068401546004909401549199600160a01b90910460ff169850929650945092509050565b60fb546001600160a01b031633146115755760405162461bcd60e51b815260206004820152601260248201527127b7363c90383937bc3c9036b0b730b3b2b960711b6044820152606401610657565b670de0b6b3a76400008110156115be5760405162461bcd60e51b815260206004820152600e60248201526d4d696e696d756d2031206475636b60901b6044820152606401610657565b60006115d2670de0b6b3a7640000836121e7565b9050600a8111156116255760405162461bcd60e51b815260206004820152601960248201527f4d6178696d756d203130206475636b732070657220706c6179000000000000006044820152606401610657565b60fe5415806116645750600360fe54600090815260ff6020819052604090912060050154600160a01b900416600481111561166257611662612063565b145b1561167157611671611d86565b60fe54600090815260ff60205260408120906005820154600160a01b900460ff1660048111156116a3576116a3612063565b14806116ce575060016005820154600160a01b900460ff1660048111156116cc576116cc612063565b145b61171a5760405162461bcd60e51b815260206004820152601a60248201527f52616365206e6f7420616363657074696e6720636f6d6d6974730000000000006044820152606401610657565b606481600601541061175a5760405162461bcd60e51b8152602060048201526009602482015268149858d948199d5b1b60ba1b6044820152606401610657565b6001600160a01b0384166000908152600a8201602052604081205490036117c057600b810180546001810182556000918252602082200180546001600160a01b0319166001600160a01b038716179055600682018054916117ba83612174565b91905055505b6001600160a01b0384166000908152600a82016020526040812080548492906117ea90849061218d565b9250508190555082816004016000828254611805919061218d565b9091555050600681015460021180159061183e575060006005820154600160a01b900460ff16600481111561183c5761183c612063565b145b1561184e5761184e60fe54611dec565b836001600160a01b031660fe547fe2de6d4e065ffb08e16ed34dfa1c449370f8012a3a03ba4384f0d1390aa0a7168460405161188c91815260200190565b60405180910390a350505050565b6118a26119b1565b609780546001600160a01b0383166001600160a01b031990911681179091556118d36065546001600160a01b031690565b6001600160a01b03167f38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e2270060405160405180910390a350565b600260c9540361195d5760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610657565b600260c955565b60335460ff16156112035760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b6044820152606401610657565b600160c955565b6065546001600160a01b031633146112035760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610657565b600054610100900460ff16611a325760405162461bcd60e51b815260040161065790612260565b611203611e5a565b600054610100900460ff16611a615760405162461bcd60e51b815260040161065790612260565b611203611e8d565b600054610100900460ff16611a905760405162461bcd60e51b815260040161065790612260565b611203611ebd565b60fe541580611ad75750600360fe54600090815260ff6020819052604090912060050154600160a01b9004166004811115611ad557611ad5612063565b145b15611ae457611ae4611d86565b60fe54600090815260ff60205260408120906005820154600160a01b900460ff166004811115611b1657611b16612063565b1480611b41575060016005820154600160a01b900460ff166004811115611b3f57611b3f612063565b145b611b8d5760405162461bcd60e51b815260206004820152601a60248201527f52616365206e6f7420616363657074696e6720636f6d6d6974730000000000006044820152606401610657565b6064816006015410611bcd5760405162461bcd60e51b8152602060048201526009602482015268149858d948199d5b1b60ba1b6044820152606401610657565b6001600160a01b0385166000908152600a820160205260408120549003611c3357600b810180546001810182556000918252602082200180546001600160a01b0319166001600160a01b03881617905560068201805491611c2d83612174565b91905055505b6040805160208101869052908101849052606086811b6bffffffffffffffffffffffff19169082015260740160408051601f1981840301815291815281516020928301206001600160a01b038816600090815260078501845282812091909155600a840190925281208054849290611cac90849061218d565b90915550611cc4905082670de0b6b3a76400006121d0565b816004016000828254611cd7919061218d565b90915550506006810154600211801590611d10575060006005820154600160a01b900460ff166004811115611d0e57611d0e612063565b145b15611d2057611d2060fe54611dec565b846001600160a01b031660fe547fe2de6d4e065ffb08e16ed34dfa1c449370f8012a3a03ba4384f0d1390aa0a71684604051611d5e91815260200190565b60405180910390a35050505050565b609780546001600160a01b031916905561127c81611ee4565b60fe8054906000611d9683612174565b909155505060fe8054600090815260ff602052604080822042815560058101805460ff60a01b191690559254905190917f5a691e0655b3e3b2995fd900bfeeeccf635a465b0b798b9d4d49a75a1ce4a9cc91a250565b600081815260ff6020526040902060058101805460ff60a01b1916600160a01b179055611e1a603c4261218d565b6001820181905560405190815282907fca320d5325ac490d02db3ee19e4449fa70ec50b6c89db38cc29fba981a77733e9060200160405180910390a25050565b600054610100900460ff16611e815760405162461bcd60e51b815260040161065790612260565b6033805460ff19169055565b600054610100900460ff16611eb45760405162461bcd60e51b815260040161065790612260565b61120333611d6d565b600054610100900460ff166119aa5760405162461bcd60e51b815260040161065790612260565b606580546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b600060208284031215611f4857600080fd5b5035919050565b80356001600160a01b0381168114611f6657600080fd5b919050565b60008060408385031215611f7e57600080fd5b82359150611f8e60208401611f4f565b90509250929050565b60008060408385031215611faa57600080fd5b50508035926020909101359150565b60008060408385031215611fcc57600080fd5b611fd583611f4f565b9150611f8e60208401611f4f565b600080600060608486031215611ff857600080fd5b505081359360208301359350604090920135919050565b6000806000806080858703121561202557600080fd5b5050823594602084013594506040840135936060013592509050565b60006020828403121561205357600080fd5b61205c82611f4f565b9392505050565b634e487b7160e01b600052602160045260246000fd5b6005811061209757634e487b7160e01b600052602160045260246000fd5b9052565b888152602081018890526040810187905260608101869052608081018590526001600160a01b03841660a082015261010081016120db60c0830185612079565b8260e08301529998505050505050505050565b85815260a081016121026020830187612079565b8460408301528360608301528260808301529695505050505050565b6000806040838503121561213157600080fd5b61213a83611f4f565b946020939093013593505050565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b6000600182016121865761218661215e565b5060010190565b808201808211156121a0576121a061215e565b92915050565b634e487b7160e01b600052601260045260246000fd5b6000826121cb576121cb6121a6565b500690565b80820281158282048414176121a0576121a061215e565b6000826121f6576121f66121a6565b500490565b818103818111156121a0576121a061215e565b60006020828403121561222057600080fd5b8151801515811461205c57600080fd5b60006020828403121561224257600080fd5b5051919050565b6000816122585761225861215e565b506000190190565b6020808252602b908201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960408201526a6e697469616c697a696e6760a81b60608201526080019056fea264697066735822122027f06f61438fa6d94fc96b13c8ef5e084e2721758ed80f6696da4c9d955f926464736f6c63430008130033
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 30 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
[ 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.