Source Code
Overview
S Balance
0 S
More Info
ContractCreator
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
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); event PaymentProcessed(address indexed player, uint256 amount); event PaymentFailed(address indexed player, uint256 amount, string reason); 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"); // Lock the funds cashier.lockBalance(msg.sender, totalCost); preCommitments[msg.sender] = PreCommitment({ ducksPerRace: ducksPerRace, racesRemaining: numberOfRaces, commitHash: commitHash, salt: salt }); emit PreCommitmentSet(msg.sender, ducksPerRace, numberOfRaces); } // Auto-process pre-commitments function processPreCommitments() external whenNotPaused nonReentrant { PreCommitment storage pc = preCommitments[msg.sender]; require(pc.racesRemaining > 0, "No pre-commitments"); require(pc.ducksPerRace > 0, "Invalid pre-commitment"); // Calculate cost uint256 cost = PLAY_COST * pc.ducksPerRace; // Try to debit the player through cashier bool success = cashier.debitPlayer(msg.sender, cost); require(success, "Payment failed"); // Get current race 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"); // Add player to race if (race.duckCounts[msg.sender] == 0) { race.players.push(msg.sender); race.playerCount++; } race.commitments[msg.sender] = keccak256(abi.encodePacked(pc.commitHash, pc.salt, msg.sender)); race.duckCounts[msg.sender] += pc.ducksPerRace; race.totalPrize += cost; // Start commit phase if minimum players reached if (race.playerCount >= MIN_PLAYERS && race.state == RaceState.Waiting) { _startCommitPhase(currentRaceId); } pc.racesRemaining--; if (pc.racesRemaining == 0) { delete preCommitments[msg.sender]; } emit PlayerCommitted(currentRaceId, msg.sender, pc.ducksPerRace); emit PaymentProcessed(msg.sender, cost); } // 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) external whenNotPaused nonReentrant { 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(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); } // Add function to update cashier address (if needed) function setCashier(address _cashier) external onlyOwner { require(_cashier != address(0), "Invalid cashier address"); cashier = IUniversalCashier(_cashier); } }
// 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 { // Core functions function deposit() external payable; function withdraw(uint256 amount) external; function getBalance(address player) external view returns (uint256); // Game interactions function debitPlayer(address player, uint256 amount) external returns (bool); function creditPlayer(address player, uint256 amount) external; // Balance locking function lockBalance(address player, uint256 amount) external; function unlockBalance(address player, uint256 amount) external; function getLockedBalance(address player) external view returns (uint256); function getAvailableBalance(address player) external view returns (uint256); // Game authorization function authorizeGame(address game) external; function unauthorizeGame(address game) external; // Admin 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":"address","name":"player","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"string","name":"reason","type":"string"}],"name":"PaymentFailed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"player","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"PaymentProcessed","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":[],"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":"address","name":"_cashier","type":"address"}],"name":"setCashier","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
608060405234801561001057600080fd5b5061228a806100206000396000f3fe6080604052600436106101cd5760003560e01c806385689310116100f7578063b216a6c611610095578063e724596411610064578063e7245964146103b6578063ed740e97146105a1578063f0e10c0d146105c1578063f2fde38b146105d457600080fd5b8063b216a6c614610552578063b971e2fd146103b6578063dbe3010c1461056e578063e30c39781461058357600080fd5b80638f7f6e89116100d15780638f7f6e89146104d657806396b4ca70146104fc5780639ad9d5011461051c578063b02ad48f1461053257600080fd5b8063856893101461047a57806385f07bbe1461048f5780638da5cb5b146104a457600080fd5b8063485cc9551161016f5780635ec775b01161013e5780635ec775b0146103b6578063715018a6146103cb57806379ba5097146103e05780637bbc469e146103f557600080fd5b8063485cc955146102f05780634a7e637e146103105780635088adc3146103305780635c975abb1461039357600080fd5b806313114a9d116101ab57806313114a9d146102905780634036778f146102a65780634411b3eb146102c6578063476343ee146102db57600080fd5b8063029dd6ba146101d257806305261aea146101fa5780630e07bff51461021c575b600080fd5b3480156101de57600080fd5b506101e7600a81565b6040519081526020015b60405180910390f35b34801561020657600080fd5b5061021a610215366004611f0b565b6105f4565b005b34801561022857600080fd5b50610273610237366004611f40565b600091825260ff602090815260408084206001600160a01b03938416808652600a82019093529320546005909301549293841515939092161490565b6040805193845291151560208401521515908201526060016101f1565b34801561029c57600080fd5b506101e760fd5481565b3480156102b257600080fd5b5061021a6102c1366004611f6c565b610ab9565b3480156102d257600080fd5b506101e7606481565b3480156102e757600080fd5b5061021a610c6e565b3480156102fc57600080fd5b5061021a61030b366004611f8e565b610d60565b34801561031c57600080fd5b5061021a61032b366004611fb8565b610eb8565b34801561033c57600080fd5b5061037361034b366004611fea565b6101006020526000908152604090208054600182015460028301546003909301549192909184565b6040805194855260208501939093529183015260608201526080016101f1565b34801561039f57600080fd5b5060335460ff1660405190151581526020016101f1565b3480156103c257600080fd5b506101e7603c81565b3480156103d757600080fd5b5061021a61113a565b3480156103ec57600080fd5b5061021a61114e565b34801561040157600080fd5b50610466610410366004611f0b565b60ff602081905260009182526040909120805460018201546002830154600384015460048501546005860154600690960154949693959294919390926001600160a01b03811692600160a01b9091049091169088565b6040516101f1989796959493929190612044565b34801561048657600080fd5b5061021a6111c5565b34801561049b57600080fd5b506101e7600281565b3480156104b057600080fd5b506065546001600160a01b03165b6040516001600160a01b0390911681526020016101f1565b3480156104e257600080fd5b506104eb611674565b6040516101f1959493929190612097565b34801561050857600080fd5b5060fb546104be906001600160a01b031681565b34801561052857600080fd5b506101e760fe5481565b34801561053e57600080fd5b5061021a61054d366004611fea565b611750565b34801561055e57600080fd5b506101e7670de0b6b3a764000081565b34801561057a57600080fd5b506101e7605a81565b34801561058f57600080fd5b506097546001600160a01b03166104be565b3480156105ad57600080fd5b5060fc546104be906001600160a01b031681565b61021a6105cf3660046120c7565b6117d0565b3480156105e057600080fd5b5061021a6105ef366004611fea565b611b44565b6105fc611bb5565b610604611bfb565b600081815260ff6020526040902060026005820154600160a01b900460ff1660048111156106345761063461200c565b1461067d5760405162461bcd60e51b815260206004820152601460248201527352616365206e6f7420696e2070726f677265737360601b60448201526064015b60405180910390fd5b806002015442116106c95760405162461bcd60e51b815260206004820152601660248201527552616365207374696c6c20696e2070726f677265737360501b6044820152606401610674565b60008060005b600b84015481101561076557600084600b0182815481106106f2576106f26120f1565b60009182526020808320909101546001600160a01b03168083526009880190915260409091205490915060ff1615610752576001600160a01b038116600090815260088601602052604090205493909318928261074e8161211d565b9350505b508061075d8161211d565b9150506106cf565b5060028110156107ac5760405162461bcd60e51b81526020600482015260126024820152714e6f7420656e6f7567682072657665616c7360701b6044820152606401610674565b60408051602080820185905244828401524260608084019190915283518084039091018152608090920190925280519101206000805b600b8601548110156108955785600901600087600b018381548110610809576108096120f1565b60009182526020808320909101546001600160a01b0316835282019290925260400190205460ff16156108835785600a01600087600b018381548110610851576108516120f1565b60009182526020808320909101546001600160a01b031683528201929092526040019020546108809083612136565b91505b8061088d8161211d565b9150506107e2565b5060006108a28284612165565b90506000805b600b88015481101561096657600088600b0182815481106108cb576108cb6120f1565b60009182526020808320909101546001600160a01b031680835260098c0190915260409091205490915060ff1615610953576001600160a01b0381166000908152600a8a0160205260409020546109229084612136565b925082841015610953576005890180546001600160a01b0319166001600160a01b0392909216919091179055610966565b508061095e8161211d565b9150506108a8565b5060058701546001600160a01b031615610a7d5760006064605a896004015461098f9190612179565b6109999190612190565b905060008189600401546109ad91906121a4565b90508060fd60008282546109c19190612136565b909155505060fc5460058a01546040516339c255ad60e11b81526001600160a01b03918216600482015260248101859052911690637384ab5a90604401600060405180830381600087803b158015610a1857600080fd5b505af1158015610a2c573d6000803e3d6000fd5b505050506005890154604080516001600160a01b039092168252602082018490528b917fe36b67fec2742bf0400545705e6f61c6b71ad23cda3cdc1c80f1d8fdd37875eb910160405180910390a250505b60058701805460ff60a01b1916600160a21b179055610a9d603c42612136565b876003018190555050505050505050610ab6600160c955565b50565b610ac1611bfb565b610ac9611bb5565b60fe54600090815260ff6020526040902060026005820154600160a01b900460ff166004811115610afc57610afc61200c565b14610b3c5760405162461bcd60e51b815260206004820152601060248201526f4e6f742072657665616c20706861736560801b6044820152606401610674565b33600090815260098201602052604090205460ff1615610b915760405162461bcd60e51b815260206004820152601060248201526f105b1c9958591e481c995d99585b195960821b6044820152606401610674565b6000838333604051602001610bcb93929190928352602083019190915260601b6bffffffffffffffffffffffff1916604082015260540190565b60408051601f198184030181529181528151602092830120336000908152600786019093529120549091508114610c355760405162461bcd60e51b815260206004820152600e60248201526d125b9d985b1a59081c995d99585b60921b6044820152606401610674565b5033600090815260088201602090815260408083208690556009909301905220805460ff19166001179055610c6a600160c955565b5050565b610c76611c5b565b60fd805460009182905590610c936065546001600160a01b031690565b6001600160a01b03168260405160006040518083038185875af1925050503d8060008114610cdd576040519150601f19603f3d011682016040523d82523d6000602084013e610ce2565b606091505b5050905080610d295760405162461bcd60e51b8152602060048201526013602482015272119959481d1c985b9cd9995c8819985a5b1959606a1b6044820152606401610674565b6040518281527fb7eeacba6b133788365610e83d3f130d07b6ef6e78877961f25b3f61fcba07529060200160405180910390a15050565b600054610100900460ff1615808015610d805750600054600160ff909116105b80610d9a5750303b158015610d9a575060005460ff166001145b610dfd5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b6064820152608401610674565b6000805460ff191660011790558015610e20576000805461ff0019166101001790555b610e28611cb5565b610e30611ce4565b610e38611d13565b60fb80546001600160a01b038086166001600160a01b03199283161790925560fc805492851692909116919091179055600060fe558015610eb3576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b505050565b610ec0611bb5565b610ec8611bfb565b600084118015610ed95750600a8411155b610f1a5760405162461bcd60e51b8152602060048201526012602482015271125b9d985b1a5908191d58dac818dbdd5b9d60721b6044820152606401610674565b600083118015610f2b575060648311155b610f6c5760405162461bcd60e51b8152602060048201526012602482015271125b9d985b1a59081c9858d94818dbdd5b9d60721b6044820152606401610674565b600083610f8186670de0b6b3a7640000612179565b610f8b9190612179565b60fc5460405163f8b2cb4f60e01b815233600482015291925082916001600160a01b039091169063f8b2cb4f90602401602060405180830381865afa158015610fd8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ffc91906121b7565b10156110415760405162461bcd60e51b8152602060048201526014602482015273496e73756666696369656e742062616c616e636560601b6044820152606401610674565b60fc546040516307837e1760e41b8152336004820152602481018390526001600160a01b0390911690637837e17090604401600060405180830381600087803b15801561108d57600080fd5b505af11580156110a1573d6000803e3d6000fd5b50506040805160808101825288815260208082018981528284018981526060840189815233600081815261010086528790209551865592516001860155905160028501555160039093019290925582518a81529081018990529093507ff8e6eecb54666e6632f533f4cca758e324ba047691ad9d6c6d4304d8a43f758192500160405180910390a250611134600160c955565b50505050565b611142611c5b565b61114c6000611d42565b565b60975433906001600160a01b031681146111bc5760405162461bcd60e51b815260206004820152602960248201527f4f776e61626c6532537465703a2063616c6c6572206973206e6f7420746865206044820152683732bb9037bbb732b960b91b6064820152608401610674565b610ab681611d42565b6111cd611bb5565b6111d5611bfb565b33600090815261010060205260409020600181015461122b5760405162461bcd60e51b81526020600482015260126024820152714e6f207072652d636f6d6d69746d656e747360701b6044820152606401610674565b80546112725760405162461bcd60e51b8152602060048201526016602482015275125b9d985b1a59081c1c994b58dbdb5b5a5d1b595b9d60521b6044820152606401610674565b805460009061128990670de0b6b3a7640000612179565b60fc5460405163026ff28360e61b8152336004820152602481018390529192506000916001600160a01b0390911690639bfca0c0906044016020604051808303816000875af11580156112e0573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061130491906121d0565b9050806113445760405162461bcd60e51b815260206004820152600e60248201526d14185e5b595b9d0819985a5b195960921b6044820152606401610674565b60fe5415806113835750600360fe54600090815260ff6020819052604090912060050154600160a01b90041660048111156113815761138161200c565b145b1561139057611390611d5b565b60fe54600090815260ff60205260408120906005820154600160a01b900460ff1660048111156113c2576113c261200c565b14806113ed575060016005820154600160a01b900460ff1660048111156113eb576113eb61200c565b145b6114395760405162461bcd60e51b815260206004820152601a60248201527f52616365206e6f7420616363657074696e6720636f6d6d6974730000000000006044820152606401610674565b60648160060154106114795760405162461bcd60e51b8152602060048201526009602482015268149858d948199d5b1b60ba1b6044820152606401610674565b336000908152600a8201602052604081205490036114cd57600b810180546001810182556000918252602082200180546001600160a01b03191633179055600682018054916114c78361211d565b91905055505b6002840154600385015460408051602081019390935282015233606090811b6bffffffffffffffffffffffff19169082015260740160408051601f198184030181529181528151602092830120336000908152600785018452828120919091558654600a85019093529081208054909190611549908490612136565b92505081905550828160040160008282546115649190612136565b9091555050600681015460021180159061159d575060006005820154600160a01b900460ff16600481111561159b5761159b61200c565b145b156115ad576115ad60fe54611dc1565b6001840180549060006115bf836121f2565b919050555083600101546000036115f657336000908152610100602052604081208181556001810182905560028101829055600301555b60fe5484546040519081523391907fe2de6d4e065ffb08e16ed34dfa1c449370f8012a3a03ba4384f0d1390aa0a7169060200160405180910390a360405183815233907fa5957fefb5b0f981554450d4d8dde003083cd202e3d5a2992e09c88ad1f0d7919060200160405180910390a25050505061114c600160c955565b60fe54600090815260ff60205260408120819081908190819060016005820154600160a01b900460ff1660048111156116af576116af61200c565b1461171d5760026005820154600160a01b900460ff1660048111156116d6576116d661200c565b146117135760046005820154600160a01b900460ff1660048111156116fd576116fd61200c565b14611709576000611723565b8060030154611723565b8060020154611723565b80600101545b60fe54600583015460068401546004909401549199600160a01b90910460ff169850929650945092509050565b611758611c5b565b6001600160a01b0381166117ae5760405162461bcd60e51b815260206004820152601760248201527f496e76616c6964206361736869657220616464726573730000000000000000006044820152606401610674565b60fc80546001600160a01b0319166001600160a01b0392909216919091179055565b60fb546001600160a01b0316331461181f5760405162461bcd60e51b815260206004820152601260248201527127b7363c90383937bc3c9036b0b730b3b2b960711b6044820152606401610674565b670de0b6b3a76400008110156118685760405162461bcd60e51b815260206004820152600e60248201526d4d696e696d756d2031206475636b60901b6044820152606401610674565b600061187c670de0b6b3a764000083612190565b9050600a8111156118cf5760405162461bcd60e51b815260206004820152601960248201527f4d6178696d756d203130206475636b732070657220706c6179000000000000006044820152606401610674565b60fe54158061190e5750600360fe54600090815260ff6020819052604090912060050154600160a01b900416600481111561190c5761190c61200c565b145b1561191b5761191b611d5b565b60fe54600090815260ff60205260408120906005820154600160a01b900460ff16600481111561194d5761194d61200c565b1480611978575060016005820154600160a01b900460ff1660048111156119765761197661200c565b145b6119c45760405162461bcd60e51b815260206004820152601a60248201527f52616365206e6f7420616363657074696e6720636f6d6d6974730000000000006044820152606401610674565b6064816006015410611a045760405162461bcd60e51b8152602060048201526009602482015268149858d948199d5b1b60ba1b6044820152606401610674565b6001600160a01b0384166000908152600a820160205260408120549003611a6a57600b810180546001810182556000918252602082200180546001600160a01b0319166001600160a01b03871617905560068201805491611a648361211d565b91905055505b6001600160a01b0384166000908152600a8201602052604081208054849290611a94908490612136565b9250508190555082816004016000828254611aaf9190612136565b90915550506006810154600211801590611ae8575060006005820154600160a01b900460ff166004811115611ae657611ae661200c565b145b15611af857611af860fe54611dc1565b836001600160a01b031660fe547fe2de6d4e065ffb08e16ed34dfa1c449370f8012a3a03ba4384f0d1390aa0a71684604051611b3691815260200190565b60405180910390a350505050565b611b4c611c5b565b609780546001600160a01b0383166001600160a01b03199091168117909155611b7d6065546001600160a01b031690565b6001600160a01b03167f38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e2270060405160405180910390a350565b60335460ff161561114c5760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b6044820152606401610674565b600260c95403611c4d5760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610674565b600260c955565b600160c955565b6065546001600160a01b0316331461114c5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610674565b600054610100900460ff16611cdc5760405162461bcd60e51b815260040161067490612209565b61114c611e2f565b600054610100900460ff16611d0b5760405162461bcd60e51b815260040161067490612209565b61114c611e62565b600054610100900460ff16611d3a5760405162461bcd60e51b815260040161067490612209565b61114c611e92565b609780546001600160a01b0319169055610ab681611eb9565b60fe8054906000611d6b8361211d565b909155505060fe8054600090815260ff602052604080822042815560058101805460ff60a01b191690559254905190917f5a691e0655b3e3b2995fd900bfeeeccf635a465b0b798b9d4d49a75a1ce4a9cc91a250565b600081815260ff6020526040902060058101805460ff60a01b1916600160a01b179055611def603c42612136565b6001820181905560405190815282907fca320d5325ac490d02db3ee19e4449fa70ec50b6c89db38cc29fba981a77733e9060200160405180910390a25050565b600054610100900460ff16611e565760405162461bcd60e51b815260040161067490612209565b6033805460ff19169055565b600054610100900460ff16611e895760405162461bcd60e51b815260040161067490612209565b61114c33611d42565b600054610100900460ff16611c545760405162461bcd60e51b815260040161067490612209565b606580546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b600060208284031215611f1d57600080fd5b5035919050565b80356001600160a01b0381168114611f3b57600080fd5b919050565b60008060408385031215611f5357600080fd5b82359150611f6360208401611f24565b90509250929050565b60008060408385031215611f7f57600080fd5b50508035926020909101359150565b60008060408385031215611fa157600080fd5b611faa83611f24565b9150611f6360208401611f24565b60008060008060808587031215611fce57600080fd5b5050823594602084013594506040840135936060013592509050565b600060208284031215611ffc57600080fd5b61200582611f24565b9392505050565b634e487b7160e01b600052602160045260246000fd5b6005811061204057634e487b7160e01b600052602160045260246000fd5b9052565b888152602081018890526040810187905260608101869052608081018590526001600160a01b03841660a0820152610100810161208460c0830185612022565b8260e08301529998505050505050505050565b85815260a081016120ab6020830187612022565b8460408301528360608301528260808301529695505050505050565b600080604083850312156120da57600080fd5b6120e383611f24565b946020939093013593505050565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b60006001820161212f5761212f612107565b5060010190565b8082018082111561214957612149612107565b92915050565b634e487b7160e01b600052601260045260246000fd5b6000826121745761217461214f565b500690565b808202811582820484141761214957612149612107565b60008261219f5761219f61214f565b500490565b8181038181111561214957612149612107565b6000602082840312156121c957600080fd5b5051919050565b6000602082840312156121e257600080fd5b8151801515811461200557600080fd5b60008161220157612201612107565b506000190190565b6020808252602b908201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960408201526a6e697469616c697a696e6760a81b60608201526080019056fea2646970667358221220b8dcef65acf24c32b32ccf847a1b5c4b0b9b371e3d6ea6782c842c531930179a64736f6c63430008130033
Deployed Bytecode
0x6080604052600436106101cd5760003560e01c806385689310116100f7578063b216a6c611610095578063e724596411610064578063e7245964146103b6578063ed740e97146105a1578063f0e10c0d146105c1578063f2fde38b146105d457600080fd5b8063b216a6c614610552578063b971e2fd146103b6578063dbe3010c1461056e578063e30c39781461058357600080fd5b80638f7f6e89116100d15780638f7f6e89146104d657806396b4ca70146104fc5780639ad9d5011461051c578063b02ad48f1461053257600080fd5b8063856893101461047a57806385f07bbe1461048f5780638da5cb5b146104a457600080fd5b8063485cc9551161016f5780635ec775b01161013e5780635ec775b0146103b6578063715018a6146103cb57806379ba5097146103e05780637bbc469e146103f557600080fd5b8063485cc955146102f05780634a7e637e146103105780635088adc3146103305780635c975abb1461039357600080fd5b806313114a9d116101ab57806313114a9d146102905780634036778f146102a65780634411b3eb146102c6578063476343ee146102db57600080fd5b8063029dd6ba146101d257806305261aea146101fa5780630e07bff51461021c575b600080fd5b3480156101de57600080fd5b506101e7600a81565b6040519081526020015b60405180910390f35b34801561020657600080fd5b5061021a610215366004611f0b565b6105f4565b005b34801561022857600080fd5b50610273610237366004611f40565b600091825260ff602090815260408084206001600160a01b03938416808652600a82019093529320546005909301549293841515939092161490565b6040805193845291151560208401521515908201526060016101f1565b34801561029c57600080fd5b506101e760fd5481565b3480156102b257600080fd5b5061021a6102c1366004611f6c565b610ab9565b3480156102d257600080fd5b506101e7606481565b3480156102e757600080fd5b5061021a610c6e565b3480156102fc57600080fd5b5061021a61030b366004611f8e565b610d60565b34801561031c57600080fd5b5061021a61032b366004611fb8565b610eb8565b34801561033c57600080fd5b5061037361034b366004611fea565b6101006020526000908152604090208054600182015460028301546003909301549192909184565b6040805194855260208501939093529183015260608201526080016101f1565b34801561039f57600080fd5b5060335460ff1660405190151581526020016101f1565b3480156103c257600080fd5b506101e7603c81565b3480156103d757600080fd5b5061021a61113a565b3480156103ec57600080fd5b5061021a61114e565b34801561040157600080fd5b50610466610410366004611f0b565b60ff602081905260009182526040909120805460018201546002830154600384015460048501546005860154600690960154949693959294919390926001600160a01b03811692600160a01b9091049091169088565b6040516101f1989796959493929190612044565b34801561048657600080fd5b5061021a6111c5565b34801561049b57600080fd5b506101e7600281565b3480156104b057600080fd5b506065546001600160a01b03165b6040516001600160a01b0390911681526020016101f1565b3480156104e257600080fd5b506104eb611674565b6040516101f1959493929190612097565b34801561050857600080fd5b5060fb546104be906001600160a01b031681565b34801561052857600080fd5b506101e760fe5481565b34801561053e57600080fd5b5061021a61054d366004611fea565b611750565b34801561055e57600080fd5b506101e7670de0b6b3a764000081565b34801561057a57600080fd5b506101e7605a81565b34801561058f57600080fd5b506097546001600160a01b03166104be565b3480156105ad57600080fd5b5060fc546104be906001600160a01b031681565b61021a6105cf3660046120c7565b6117d0565b3480156105e057600080fd5b5061021a6105ef366004611fea565b611b44565b6105fc611bb5565b610604611bfb565b600081815260ff6020526040902060026005820154600160a01b900460ff1660048111156106345761063461200c565b1461067d5760405162461bcd60e51b815260206004820152601460248201527352616365206e6f7420696e2070726f677265737360601b60448201526064015b60405180910390fd5b806002015442116106c95760405162461bcd60e51b815260206004820152601660248201527552616365207374696c6c20696e2070726f677265737360501b6044820152606401610674565b60008060005b600b84015481101561076557600084600b0182815481106106f2576106f26120f1565b60009182526020808320909101546001600160a01b03168083526009880190915260409091205490915060ff1615610752576001600160a01b038116600090815260088601602052604090205493909318928261074e8161211d565b9350505b508061075d8161211d565b9150506106cf565b5060028110156107ac5760405162461bcd60e51b81526020600482015260126024820152714e6f7420656e6f7567682072657665616c7360701b6044820152606401610674565b60408051602080820185905244828401524260608084019190915283518084039091018152608090920190925280519101206000805b600b8601548110156108955785600901600087600b018381548110610809576108096120f1565b60009182526020808320909101546001600160a01b0316835282019290925260400190205460ff16156108835785600a01600087600b018381548110610851576108516120f1565b60009182526020808320909101546001600160a01b031683528201929092526040019020546108809083612136565b91505b8061088d8161211d565b9150506107e2565b5060006108a28284612165565b90506000805b600b88015481101561096657600088600b0182815481106108cb576108cb6120f1565b60009182526020808320909101546001600160a01b031680835260098c0190915260409091205490915060ff1615610953576001600160a01b0381166000908152600a8a0160205260409020546109229084612136565b925082841015610953576005890180546001600160a01b0319166001600160a01b0392909216919091179055610966565b508061095e8161211d565b9150506108a8565b5060058701546001600160a01b031615610a7d5760006064605a896004015461098f9190612179565b6109999190612190565b905060008189600401546109ad91906121a4565b90508060fd60008282546109c19190612136565b909155505060fc5460058a01546040516339c255ad60e11b81526001600160a01b03918216600482015260248101859052911690637384ab5a90604401600060405180830381600087803b158015610a1857600080fd5b505af1158015610a2c573d6000803e3d6000fd5b505050506005890154604080516001600160a01b039092168252602082018490528b917fe36b67fec2742bf0400545705e6f61c6b71ad23cda3cdc1c80f1d8fdd37875eb910160405180910390a250505b60058701805460ff60a01b1916600160a21b179055610a9d603c42612136565b876003018190555050505050505050610ab6600160c955565b50565b610ac1611bfb565b610ac9611bb5565b60fe54600090815260ff6020526040902060026005820154600160a01b900460ff166004811115610afc57610afc61200c565b14610b3c5760405162461bcd60e51b815260206004820152601060248201526f4e6f742072657665616c20706861736560801b6044820152606401610674565b33600090815260098201602052604090205460ff1615610b915760405162461bcd60e51b815260206004820152601060248201526f105b1c9958591e481c995d99585b195960821b6044820152606401610674565b6000838333604051602001610bcb93929190928352602083019190915260601b6bffffffffffffffffffffffff1916604082015260540190565b60408051601f198184030181529181528151602092830120336000908152600786019093529120549091508114610c355760405162461bcd60e51b815260206004820152600e60248201526d125b9d985b1a59081c995d99585b60921b6044820152606401610674565b5033600090815260088201602090815260408083208690556009909301905220805460ff19166001179055610c6a600160c955565b5050565b610c76611c5b565b60fd805460009182905590610c936065546001600160a01b031690565b6001600160a01b03168260405160006040518083038185875af1925050503d8060008114610cdd576040519150601f19603f3d011682016040523d82523d6000602084013e610ce2565b606091505b5050905080610d295760405162461bcd60e51b8152602060048201526013602482015272119959481d1c985b9cd9995c8819985a5b1959606a1b6044820152606401610674565b6040518281527fb7eeacba6b133788365610e83d3f130d07b6ef6e78877961f25b3f61fcba07529060200160405180910390a15050565b600054610100900460ff1615808015610d805750600054600160ff909116105b80610d9a5750303b158015610d9a575060005460ff166001145b610dfd5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b6064820152608401610674565b6000805460ff191660011790558015610e20576000805461ff0019166101001790555b610e28611cb5565b610e30611ce4565b610e38611d13565b60fb80546001600160a01b038086166001600160a01b03199283161790925560fc805492851692909116919091179055600060fe558015610eb3576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b505050565b610ec0611bb5565b610ec8611bfb565b600084118015610ed95750600a8411155b610f1a5760405162461bcd60e51b8152602060048201526012602482015271125b9d985b1a5908191d58dac818dbdd5b9d60721b6044820152606401610674565b600083118015610f2b575060648311155b610f6c5760405162461bcd60e51b8152602060048201526012602482015271125b9d985b1a59081c9858d94818dbdd5b9d60721b6044820152606401610674565b600083610f8186670de0b6b3a7640000612179565b610f8b9190612179565b60fc5460405163f8b2cb4f60e01b815233600482015291925082916001600160a01b039091169063f8b2cb4f90602401602060405180830381865afa158015610fd8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ffc91906121b7565b10156110415760405162461bcd60e51b8152602060048201526014602482015273496e73756666696369656e742062616c616e636560601b6044820152606401610674565b60fc546040516307837e1760e41b8152336004820152602481018390526001600160a01b0390911690637837e17090604401600060405180830381600087803b15801561108d57600080fd5b505af11580156110a1573d6000803e3d6000fd5b50506040805160808101825288815260208082018981528284018981526060840189815233600081815261010086528790209551865592516001860155905160028501555160039093019290925582518a81529081018990529093507ff8e6eecb54666e6632f533f4cca758e324ba047691ad9d6c6d4304d8a43f758192500160405180910390a250611134600160c955565b50505050565b611142611c5b565b61114c6000611d42565b565b60975433906001600160a01b031681146111bc5760405162461bcd60e51b815260206004820152602960248201527f4f776e61626c6532537465703a2063616c6c6572206973206e6f7420746865206044820152683732bb9037bbb732b960b91b6064820152608401610674565b610ab681611d42565b6111cd611bb5565b6111d5611bfb565b33600090815261010060205260409020600181015461122b5760405162461bcd60e51b81526020600482015260126024820152714e6f207072652d636f6d6d69746d656e747360701b6044820152606401610674565b80546112725760405162461bcd60e51b8152602060048201526016602482015275125b9d985b1a59081c1c994b58dbdb5b5a5d1b595b9d60521b6044820152606401610674565b805460009061128990670de0b6b3a7640000612179565b60fc5460405163026ff28360e61b8152336004820152602481018390529192506000916001600160a01b0390911690639bfca0c0906044016020604051808303816000875af11580156112e0573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061130491906121d0565b9050806113445760405162461bcd60e51b815260206004820152600e60248201526d14185e5b595b9d0819985a5b195960921b6044820152606401610674565b60fe5415806113835750600360fe54600090815260ff6020819052604090912060050154600160a01b90041660048111156113815761138161200c565b145b1561139057611390611d5b565b60fe54600090815260ff60205260408120906005820154600160a01b900460ff1660048111156113c2576113c261200c565b14806113ed575060016005820154600160a01b900460ff1660048111156113eb576113eb61200c565b145b6114395760405162461bcd60e51b815260206004820152601a60248201527f52616365206e6f7420616363657074696e6720636f6d6d6974730000000000006044820152606401610674565b60648160060154106114795760405162461bcd60e51b8152602060048201526009602482015268149858d948199d5b1b60ba1b6044820152606401610674565b336000908152600a8201602052604081205490036114cd57600b810180546001810182556000918252602082200180546001600160a01b03191633179055600682018054916114c78361211d565b91905055505b6002840154600385015460408051602081019390935282015233606090811b6bffffffffffffffffffffffff19169082015260740160408051601f198184030181529181528151602092830120336000908152600785018452828120919091558654600a85019093529081208054909190611549908490612136565b92505081905550828160040160008282546115649190612136565b9091555050600681015460021180159061159d575060006005820154600160a01b900460ff16600481111561159b5761159b61200c565b145b156115ad576115ad60fe54611dc1565b6001840180549060006115bf836121f2565b919050555083600101546000036115f657336000908152610100602052604081208181556001810182905560028101829055600301555b60fe5484546040519081523391907fe2de6d4e065ffb08e16ed34dfa1c449370f8012a3a03ba4384f0d1390aa0a7169060200160405180910390a360405183815233907fa5957fefb5b0f981554450d4d8dde003083cd202e3d5a2992e09c88ad1f0d7919060200160405180910390a25050505061114c600160c955565b60fe54600090815260ff60205260408120819081908190819060016005820154600160a01b900460ff1660048111156116af576116af61200c565b1461171d5760026005820154600160a01b900460ff1660048111156116d6576116d661200c565b146117135760046005820154600160a01b900460ff1660048111156116fd576116fd61200c565b14611709576000611723565b8060030154611723565b8060020154611723565b80600101545b60fe54600583015460068401546004909401549199600160a01b90910460ff169850929650945092509050565b611758611c5b565b6001600160a01b0381166117ae5760405162461bcd60e51b815260206004820152601760248201527f496e76616c6964206361736869657220616464726573730000000000000000006044820152606401610674565b60fc80546001600160a01b0319166001600160a01b0392909216919091179055565b60fb546001600160a01b0316331461181f5760405162461bcd60e51b815260206004820152601260248201527127b7363c90383937bc3c9036b0b730b3b2b960711b6044820152606401610674565b670de0b6b3a76400008110156118685760405162461bcd60e51b815260206004820152600e60248201526d4d696e696d756d2031206475636b60901b6044820152606401610674565b600061187c670de0b6b3a764000083612190565b9050600a8111156118cf5760405162461bcd60e51b815260206004820152601960248201527f4d6178696d756d203130206475636b732070657220706c6179000000000000006044820152606401610674565b60fe54158061190e5750600360fe54600090815260ff6020819052604090912060050154600160a01b900416600481111561190c5761190c61200c565b145b1561191b5761191b611d5b565b60fe54600090815260ff60205260408120906005820154600160a01b900460ff16600481111561194d5761194d61200c565b1480611978575060016005820154600160a01b900460ff1660048111156119765761197661200c565b145b6119c45760405162461bcd60e51b815260206004820152601a60248201527f52616365206e6f7420616363657074696e6720636f6d6d6974730000000000006044820152606401610674565b6064816006015410611a045760405162461bcd60e51b8152602060048201526009602482015268149858d948199d5b1b60ba1b6044820152606401610674565b6001600160a01b0384166000908152600a820160205260408120549003611a6a57600b810180546001810182556000918252602082200180546001600160a01b0319166001600160a01b03871617905560068201805491611a648361211d565b91905055505b6001600160a01b0384166000908152600a8201602052604081208054849290611a94908490612136565b9250508190555082816004016000828254611aaf9190612136565b90915550506006810154600211801590611ae8575060006005820154600160a01b900460ff166004811115611ae657611ae661200c565b145b15611af857611af860fe54611dc1565b836001600160a01b031660fe547fe2de6d4e065ffb08e16ed34dfa1c449370f8012a3a03ba4384f0d1390aa0a71684604051611b3691815260200190565b60405180910390a350505050565b611b4c611c5b565b609780546001600160a01b0383166001600160a01b03199091168117909155611b7d6065546001600160a01b031690565b6001600160a01b03167f38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e2270060405160405180910390a350565b60335460ff161561114c5760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b6044820152606401610674565b600260c95403611c4d5760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610674565b600260c955565b600160c955565b6065546001600160a01b0316331461114c5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610674565b600054610100900460ff16611cdc5760405162461bcd60e51b815260040161067490612209565b61114c611e2f565b600054610100900460ff16611d0b5760405162461bcd60e51b815260040161067490612209565b61114c611e62565b600054610100900460ff16611d3a5760405162461bcd60e51b815260040161067490612209565b61114c611e92565b609780546001600160a01b0319169055610ab681611eb9565b60fe8054906000611d6b8361211d565b909155505060fe8054600090815260ff602052604080822042815560058101805460ff60a01b191690559254905190917f5a691e0655b3e3b2995fd900bfeeeccf635a465b0b798b9d4d49a75a1ce4a9cc91a250565b600081815260ff6020526040902060058101805460ff60a01b1916600160a01b179055611def603c42612136565b6001820181905560405190815282907fca320d5325ac490d02db3ee19e4449fa70ec50b6c89db38cc29fba981a77733e9060200160405180910390a25050565b600054610100900460ff16611e565760405162461bcd60e51b815260040161067490612209565b6033805460ff19169055565b600054610100900460ff16611e895760405162461bcd60e51b815260040161067490612209565b61114c33611d42565b600054610100900460ff16611c545760405162461bcd60e51b815260040161067490612209565b606580546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b600060208284031215611f1d57600080fd5b5035919050565b80356001600160a01b0381168114611f3b57600080fd5b919050565b60008060408385031215611f5357600080fd5b82359150611f6360208401611f24565b90509250929050565b60008060408385031215611f7f57600080fd5b50508035926020909101359150565b60008060408385031215611fa157600080fd5b611faa83611f24565b9150611f6360208401611f24565b60008060008060808587031215611fce57600080fd5b5050823594602084013594506040840135936060013592509050565b600060208284031215611ffc57600080fd5b61200582611f24565b9392505050565b634e487b7160e01b600052602160045260246000fd5b6005811061204057634e487b7160e01b600052602160045260246000fd5b9052565b888152602081018890526040810187905260608101869052608081018590526001600160a01b03841660a0820152610100810161208460c0830185612022565b8260e08301529998505050505050505050565b85815260a081016120ab6020830187612022565b8460408301528360608301528260808301529695505050505050565b600080604083850312156120da57600080fd5b6120e383611f24565b946020939093013593505050565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b60006001820161212f5761212f612107565b5060010190565b8082018082111561214957612149612107565b92915050565b634e487b7160e01b600052601260045260246000fd5b6000826121745761217461214f565b500690565b808202811582820484141761214957612149612107565b60008261219f5761219f61214f565b500490565b8181038181111561214957612149612107565b6000602082840312156121c957600080fd5b5051919050565b6000602082840312156121e257600080fd5b8151801515811461200557600080fd5b60008161220157612201612107565b506000190190565b6020808252602b908201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960408201526a6e697469616c697a696e6760a81b60608201526080019056fea2646970667358221220b8dcef65acf24c32b32ccf847a1b5c4b0b9b371e3d6ea6782c842c531930179a64736f6c63430008130033
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.