More Info
Private Name Tags
ContractCreator
Latest 25 from a total of 38 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Release | 18916000 | 305 days ago | IN | 0 ETH | 0.00117254 | ||||
Release | 18695018 | 336 days ago | IN | 0 ETH | 0.00317489 | ||||
Release | 18590820 | 351 days ago | IN | 0 ETH | 0.00245272 | ||||
Release | 18480692 | 366 days ago | IN | 0 ETH | 0.00315686 | ||||
Release | 18259122 | 397 days ago | IN | 0 ETH | 0.00072156 | ||||
Release | 18045128 | 427 days ago | IN | 0 ETH | 0.00099215 | ||||
Release | 17823593 | 458 days ago | IN | 0 ETH | 0.0020745 | ||||
Release | 17602618 | 489 days ago | IN | 0 ETH | 0.00144313 | ||||
Release | 17389363 | 519 days ago | IN | 0 ETH | 0.00252548 | ||||
Release | 17169395 | 550 days ago | IN | 0 ETH | 0.00577254 | ||||
Release | 16957716 | 580 days ago | IN | 0 ETH | 0.00153333 | ||||
Release | 16737188 | 611 days ago | IN | 0 ETH | 0.00252548 | ||||
Release | 16537406 | 639 days ago | IN | 0 ETH | 0.0021647 | ||||
Release | 16320560 | 669 days ago | IN | 0 ETH | 0.00234509 | ||||
Release | 16315361 | 670 days ago | IN | 0 ETH | 0.00153333 | ||||
Release | 16093396 | 701 days ago | IN | 0 ETH | 0.00117254 | ||||
Release | 15878618 | 731 days ago | IN | 0 ETH | 0.00108235 | ||||
Release | 15656735 | 762 days ago | IN | 0 ETH | 0.00054117 | ||||
Release | 15455881 | 792 days ago | IN | 0 ETH | 0.00135294 | ||||
Release | 15259746 | 823 days ago | IN | 0 ETH | 0.0020745 | ||||
Release | 15059680 | 854 days ago | IN | 0 ETH | 0.00198431 | ||||
Release | 14891641 | 884 days ago | IN | 0 ETH | 0.0045098 | ||||
Release | 14887796 | 884 days ago | IN | 0 ETH | 0.00333725 | ||||
Release | 14875536 | 886 days ago | IN | 0 ETH | 0.00351764 | ||||
Release | 14875129 | 886 days ago | IN | 0 ETH | 0.00333725 |
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
Contract Name:
VestingWalletMultiLinear
Compiler Version
v0.8.12+commit.f00d7308
Optimization Enabled:
No with 200 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT // Unagi Contracts v1.0.0 (VestingWalletMultiLinear.sol) pragma solidity 0.8.12; import "@openzeppelin/contracts/finance/VestingWallet.sol"; import "@openzeppelin/contracts/utils/structs/EnumerableMap.sol"; import "@openzeppelin/contracts/token/ERC777/IERC777Recipient.sol"; import "@openzeppelin/contracts/utils/introspection/IERC1820Registry.sol"; import "@openzeppelin/contracts/security/Pausable.sol"; import "@openzeppelin/contracts/access/AccessControlEnumerable.sol"; import "./Lockable.sol"; /** * @title VestingWalletMultiLinear * @dev This contract handles the vesting of Eth and ERC20 tokens for a given beneficiary. Custody of multiple tokens * can be given to this contract, which will release the token to the beneficiary following a given vesting schedule. * The vesting schedule is customizable through the schedule functions: {addToSchedule} and {resetSchedule}. * * Any token transferred to this contract will follow the vesting schedule as if they were locked from the beginning. * Consequently, if the vesting has already started, any amount of tokens sent to this contract will (at least partly) * be immediately releasable. * * Each schedule step defines how many token will be released for a given duration. * For a step, the release is a linear vesting curve. * * The contract can be paused by PAUSER_ROLE. When contract is paused, token can't be released. * The beneficiary is editable by BENEFICIARY_MANAGER_ROLE. * The schedule is editable by SCHEDULE_MANAGER_ROLE when the contract is not locked. * * @custom:security-contact [email protected] */ contract VestingWalletMultiLinear is VestingWallet, IERC777Recipient, Pausable, AccessControlEnumerable, Lockable { bytes32 public constant PAUSER_ROLE = keccak256("PAUSER_ROLE"); bytes32 public constant SCHEDULE_MANAGER_ROLE = keccak256("SCHEDULE_MANAGER_ROLE"); bytes32 public constant BENEFICIARY_MANAGER_ROLE = keccak256("BENEFICIARY_MANAGER_ROLE"); IERC1820Registry internal constant _ERC1820_REGISTRY = IERC1820Registry(0x1820a4B7618BdE71Dce8cdc73aAB6C95905faD24); bytes32 private constant _TOKENS_RECIPIENT_INTERFACE_HASH = keccak256("ERC777TokensRecipient"); struct ScheduleStep { uint8 percent; uint256 start; uint64 duration; } ScheduleStep[] private _sortedSchedule; uint8 private _stepPercentSum; address private _beneficiary; uint64 private _duration; /** * @dev Set the beneficiary, start timestamp and vesting duration of the vesting wallet. * Register ERC1820 interface implementer * Setup roles */ constructor(address beneficiaryAddress, uint64 startTimestamp) VestingWallet(beneficiaryAddress, startTimestamp, 0) { _ERC1820_REGISTRY.setInterfaceImplementer( address(this), _TOKENS_RECIPIENT_INTERFACE_HASH, address(this) ); _grantRole(DEFAULT_ADMIN_ROLE, msg.sender); _grantRole(PAUSER_ROLE, msg.sender); _grantRole(SCHEDULE_MANAGER_ROLE, msg.sender); _grantRole(BENEFICIARY_MANAGER_ROLE, msg.sender); setBeneficiary(beneficiaryAddress); } /** * @dev See {IERC777Recipient-tokensReceived}. */ function tokensReceived( address, address, address, uint256, bytes calldata, bytes calldata ) external override {} /** * @dev Pause token releases. */ function pause() external onlyRole(PAUSER_ROLE) { _pause(); } /** * @dev Unpause token releases. * * Requirements: * * - Caller must have role PAUSER_ROLE. */ function unpause() external onlyRole(PAUSER_ROLE) { _unpause(); } /** * @dev Lock schedule edition for a duration. * * Requirements: * * - Caller must have role DEFAULT_ADMIN_ROLE. */ function lock(uint256 lockDuration) external onlyRole(DEFAULT_ADMIN_ROLE) { _lock(lockDuration); } /** * @dev Permanently lock schedule edition. * * Requirements: * * - Caller must have role DEFAULT_ADMIN_ROLE. */ function permanentLock() external onlyRole(DEFAULT_ADMIN_ROLE) { _permanentLock(); } /** * @dev Getter for the beneficiary address. */ function beneficiary() public view override returns (address) { return _beneficiary; } /** * @dev Setter for the beneficiary address. * Emits a {BeneficiaryEdited} event. * * Requirements: * * - Caller must have role BENEFICIARY_MANAGER_ROLE. */ function setBeneficiary(address beneficiaryAddress) public onlyRole(BENEFICIARY_MANAGER_ROLE) { require( beneficiaryAddress != address(0), "VestingWalletMultiLinear: beneficiary is zero address" ); _beneficiary = beneficiaryAddress; emit BeneficiaryEdited(beneficiaryAddress); } /** * @dev Add a step to the schedule. * Emits a {ScheduleStepAdded} event. * * Requirements: * * - Caller must have role SCHEDULE_MANAGER_ROLE. * - step percent sum should not go above 100. */ function addToSchedule(uint8 stepPercent, uint64 stepDuration) external onlyRole(SCHEDULE_MANAGER_ROLE) whenNotLocked { require( _stepPercentSum + stepPercent <= 100, "VestingWalletMultiLinear: stepPercentSum above 100. Double check schedule and/or rebuild it." ); _sortedSchedule.push( ScheduleStep(stepPercent, start() + duration(), stepDuration) ); _stepPercentSum += stepPercent; _duration += stepDuration; emit ScheduleStepAdded(stepPercent, stepDuration); } /** * @dev Delete all steps of the schedule. * Emits a {ScheduleReset} event. * * Requirements: * * - Caller must have role SCHEDULE_MANAGER_ROLE. * - The contract must not be locked. */ function resetSchedule() external onlyRole(SCHEDULE_MANAGER_ROLE) whenNotLocked { delete _sortedSchedule; _stepPercentSum = 0; _duration = 0; emit ScheduleReset(); } /** * @dev Getter for the step percent sum. */ function stepPercentSum() external view returns (uint8) { return _stepPercentSum; } /** * @dev Getter for the vesting duration. */ function duration() public view override returns (uint256) { return _duration; } /** * @dev Release the native token (ether) that have already vested. * * Emits a {TokensReleased} event. * * Requirements: * * - The contract must not be paused. */ function release() public override whenNotPaused { super.release(); } /** * @dev Release the tokens that have already vested. * * Emits a {TokensReleased} event. * * Requirements: * * - The contract must not be paused. */ function release(address token) public override whenNotPaused { super.release(token); } /** * @dev Implementation of the vesting formula. This returns the amount vested, * as a function of time, for an asset given its total historical allocation. */ function _vestingSchedule(uint256 totalAllocation, uint64 timestamp) internal view override returns (uint256) { require( _sortedSchedule.length > 0, "VestingWalletMultiLinear: Schedule is empty. Call addToSchedule(uint8 stepPercent, uint64 stepDuration) first." ); uint256 amountVested = 0; uint256 index = 0; ScheduleStep storage currentStep; do { currentStep = _sortedSchedule[index]; amountVested += _vestingScheduleAtStep( currentStep, totalAllocation, timestamp ); index += 1; } while ( timestamp > currentStep.start && index < _sortedSchedule.length ); return amountVested; } /** * @dev Implementation of the vesting formula for a given step. This returns the amount vested, * as a linear function of time, for an asset given its total historical allocation. */ function _vestingScheduleAtStep( ScheduleStep storage step, uint256 totalAllocation, uint64 timestamp ) private view returns (uint256) { uint256 stepAllocation = (totalAllocation * step.percent) / 100; if (timestamp < step.start) { return 0; } else if (timestamp >= step.start + step.duration) { return stepAllocation; } else { return (stepAllocation * (timestamp - step.start)) / step.duration; } } event BeneficiaryEdited(address beneficiaryAddress); event ScheduleReset(); event ScheduleStepAdded(uint8 stepPercent, uint64 stepDuration); }
// SPDX-License-Identifier: MIT // Unagi Contracts v1.0.0 (Lockable.sol) pragma solidity 0.8.12; import "@openzeppelin/contracts/utils/Context.sol"; /** * @dev Contract module which allows children to implement a lock * mechanism that can be triggered by an authorized account. * * This module is used through inheritance. It will make available the * modifiers `whenNotLocked` and `whenLocked`, which can be applied to * the functions of your contract. Note that they will not be lockable by * simply including this module, only once the modifiers are put in place. */ abstract contract Lockable is Context { /** * @dev Emitted when the lock is triggered by `account` for `duration`. */ event Locked(address account, uint256 duration); /** * @dev Emitted when the lock is triggered by `account` permanently. */ event PermanentlyLocked(address account); bool private _permanentlyLocked; uint256 private _lockEnd; /** * @dev Initializes the contract in unlocked state. */ constructor() { _permanentlyLocked = false; _lockEnd = 0; } /** * @dev Getter for the permanently locked. */ function permanentlyLocked() public view virtual returns (bool) { return _permanentlyLocked; } /** * @dev Returns true if the contract is locked, and false otherwise. */ function locked() public view virtual returns (bool) { return permanentlyLocked() || _lockEnd > block.timestamp; } /** * @dev Modifier to make a function callable only when the contract is not locked. * * Requirements: * * - The contract must not be locked. */ modifier whenNotLocked() { require(!locked(), "Lockable: locked"); _; } /** * @dev Modifier to make a function callable only when the contract is locked. * * Requirements: * * - The contract must be locked. */ modifier whenLocked() { require(locked(), "Lockable: not locked"); _; } /** * @dev Getter for the lock end. * * Requirements: * * - The contract must be temporary locked. */ function lockEnd() external view virtual whenLocked returns (uint256) { require(!permanentlyLocked(), "Lockable: not temporary locked"); return _lockEnd; } /** * @dev Triggers locked state for a defined duration. * * Requirements: * * - The contract must not be locked. */ function _lock(uint256 duration) internal virtual whenNotLocked { _lockEnd = block.timestamp + duration; emit Locked(_msgSender(), duration); } /** * @dev Triggers locked state permanently. * * Requirements: * * - The contract must not be locked. */ function _permanentLock() internal virtual whenNotLocked { _permanentlyLocked = true; emit PermanentlyLocked(_msgSender()); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/structs/EnumerableSet.sol) pragma solidity ^0.8.0; /** * @dev Library for managing * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive * types. * * Sets have the following properties: * * - Elements are added, removed, and checked for existence in constant time * (O(1)). * - Elements are enumerated in O(n). No guarantees are made on the ordering. * * ``` * contract Example { * // Add the library methods * using EnumerableSet for EnumerableSet.AddressSet; * * // Declare a set state variable * EnumerableSet.AddressSet private mySet; * } * ``` * * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`) * and `uint256` (`UintSet`) are supported. */ library EnumerableSet { // To implement this library for multiple types with as little code // repetition as possible, we write it in terms of a generic Set type with // bytes32 values. // The Set implementation uses private functions, and user-facing // implementations (such as AddressSet) are just wrappers around the // underlying Set. // This means that we can only create new EnumerableSets for types that fit // in bytes32. struct Set { // Storage of set values bytes32[] _values; // Position of the value in the `values` array, plus 1 because index 0 // means a value is not in the set. mapping(bytes32 => uint256) _indexes; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function _add(Set storage set, bytes32 value) private returns (bool) { if (!_contains(set, value)) { set._values.push(value); // The value is stored at length-1, but we add 1 to all indexes // and use 0 as a sentinel value set._indexes[value] = set._values.length; return true; } else { return false; } } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function _remove(Set storage set, bytes32 value) private returns (bool) { // We read and store the value's index to prevent multiple reads from the same storage slot uint256 valueIndex = set._indexes[value]; if (valueIndex != 0) { // Equivalent to contains(set, value) // To delete an element from the _values array in O(1), we swap the element to delete with the last one in // the array, and then remove the last element (sometimes called as 'swap and pop'). // This modifies the order of the array, as noted in {at}. uint256 toDeleteIndex = valueIndex - 1; uint256 lastIndex = set._values.length - 1; if (lastIndex != toDeleteIndex) { bytes32 lastvalue = set._values[lastIndex]; // Move the last value to the index where the value to delete is set._values[toDeleteIndex] = lastvalue; // Update the index for the moved value set._indexes[lastvalue] = valueIndex; // Replace lastvalue's index to valueIndex } // Delete the slot where the moved value was stored set._values.pop(); // Delete the index for the deleted slot delete set._indexes[value]; return true; } else { return false; } } /** * @dev Returns true if the value is in the set. O(1). */ function _contains(Set storage set, bytes32 value) private view returns (bool) { return set._indexes[value] != 0; } /** * @dev Returns the number of values on the set. O(1). */ function _length(Set storage set) private view returns (uint256) { return set._values.length; } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function _at(Set storage set, uint256 index) private view returns (bytes32) { return set._values[index]; } /** * @dev Return the entire set in an array * * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that * this function has an unbounded cost, and using it as part of a state-changing function may render the function * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block. */ function _values(Set storage set) private view returns (bytes32[] memory) { return set._values; } // Bytes32Set struct Bytes32Set { Set _inner; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function add(Bytes32Set storage set, bytes32 value) internal returns (bool) { return _add(set._inner, value); } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) { return _remove(set._inner, value); } /** * @dev Returns true if the value is in the set. O(1). */ function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) { return _contains(set._inner, value); } /** * @dev Returns the number of values in the set. O(1). */ function length(Bytes32Set storage set) internal view returns (uint256) { return _length(set._inner); } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) { return _at(set._inner, index); } /** * @dev Return the entire set in an array * * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that * this function has an unbounded cost, and using it as part of a state-changing function may render the function * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block. */ function values(Bytes32Set storage set) internal view returns (bytes32[] memory) { return _values(set._inner); } // AddressSet struct AddressSet { Set _inner; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function add(AddressSet storage set, address value) internal returns (bool) { return _add(set._inner, bytes32(uint256(uint160(value)))); } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function remove(AddressSet storage set, address value) internal returns (bool) { return _remove(set._inner, bytes32(uint256(uint160(value)))); } /** * @dev Returns true if the value is in the set. O(1). */ function contains(AddressSet storage set, address value) internal view returns (bool) { return _contains(set._inner, bytes32(uint256(uint160(value)))); } /** * @dev Returns the number of values in the set. O(1). */ function length(AddressSet storage set) internal view returns (uint256) { return _length(set._inner); } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function at(AddressSet storage set, uint256 index) internal view returns (address) { return address(uint160(uint256(_at(set._inner, index)))); } /** * @dev Return the entire set in an array * * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that * this function has an unbounded cost, and using it as part of a state-changing function may render the function * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block. */ function values(AddressSet storage set) internal view returns (address[] memory) { bytes32[] memory store = _values(set._inner); address[] memory result; assembly { result := store } return result; } // UintSet struct UintSet { Set _inner; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function add(UintSet storage set, uint256 value) internal returns (bool) { return _add(set._inner, bytes32(value)); } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function remove(UintSet storage set, uint256 value) internal returns (bool) { return _remove(set._inner, bytes32(value)); } /** * @dev Returns true if the value is in the set. O(1). */ function contains(UintSet storage set, uint256 value) internal view returns (bool) { return _contains(set._inner, bytes32(value)); } /** * @dev Returns the number of values on the set. O(1). */ function length(UintSet storage set) internal view returns (uint256) { return _length(set._inner); } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function at(UintSet storage set, uint256 index) internal view returns (uint256) { return uint256(_at(set._inner, index)); } /** * @dev Return the entire set in an array * * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that * this function has an unbounded cost, and using it as part of a state-changing function may render the function * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block. */ function values(UintSet storage set) internal view returns (uint256[] memory) { bytes32[] memory store = _values(set._inner); uint256[] memory result; assembly { result := store } return result; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/structs/EnumerableMap.sol) pragma solidity ^0.8.0; import "./EnumerableSet.sol"; /** * @dev Library for managing an enumerable variant of Solidity's * https://solidity.readthedocs.io/en/latest/types.html#mapping-types[`mapping`] * type. * * Maps have the following properties: * * - Entries are added, removed, and checked for existence in constant time * (O(1)). * - Entries are enumerated in O(n). No guarantees are made on the ordering. * * ``` * contract Example { * // Add the library methods * using EnumerableMap for EnumerableMap.UintToAddressMap; * * // Declare a set state variable * EnumerableMap.UintToAddressMap private myMap; * } * ``` * * As of v3.0.0, only maps of type `uint256 -> address` (`UintToAddressMap`) are * supported. */ library EnumerableMap { using EnumerableSet for EnumerableSet.Bytes32Set; // To implement this library for multiple types with as little code // repetition as possible, we write it in terms of a generic Map type with // bytes32 keys and values. // The Map implementation uses private functions, and user-facing // implementations (such as Uint256ToAddressMap) are just wrappers around // the underlying Map. // This means that we can only create new EnumerableMaps for types that fit // in bytes32. struct Map { // Storage of keys EnumerableSet.Bytes32Set _keys; mapping(bytes32 => bytes32) _values; } /** * @dev Adds a key-value pair to a map, or updates the value for an existing * key. O(1). * * Returns true if the key was added to the map, that is if it was not * already present. */ function _set( Map storage map, bytes32 key, bytes32 value ) private returns (bool) { map._values[key] = value; return map._keys.add(key); } /** * @dev Removes a key-value pair from a map. O(1). * * Returns true if the key was removed from the map, that is if it was present. */ function _remove(Map storage map, bytes32 key) private returns (bool) { delete map._values[key]; return map._keys.remove(key); } /** * @dev Returns true if the key is in the map. O(1). */ function _contains(Map storage map, bytes32 key) private view returns (bool) { return map._keys.contains(key); } /** * @dev Returns the number of key-value pairs in the map. O(1). */ function _length(Map storage map) private view returns (uint256) { return map._keys.length(); } /** * @dev Returns the key-value pair stored at position `index` in the map. O(1). * * Note that there are no guarantees on the ordering of entries inside the * array, and it may change when more entries are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function _at(Map storage map, uint256 index) private view returns (bytes32, bytes32) { bytes32 key = map._keys.at(index); return (key, map._values[key]); } /** * @dev Tries to returns the value associated with `key`. O(1). * Does not revert if `key` is not in the map. */ function _tryGet(Map storage map, bytes32 key) private view returns (bool, bytes32) { bytes32 value = map._values[key]; if (value == bytes32(0)) { return (_contains(map, key), bytes32(0)); } else { return (true, value); } } /** * @dev Returns the value associated with `key`. O(1). * * Requirements: * * - `key` must be in the map. */ function _get(Map storage map, bytes32 key) private view returns (bytes32) { bytes32 value = map._values[key]; require(value != 0 || _contains(map, key), "EnumerableMap: nonexistent key"); return value; } /** * @dev Same as {_get}, with a custom error message when `key` is not in the map. * * CAUTION: This function is deprecated because it requires allocating memory for the error * message unnecessarily. For custom revert reasons use {_tryGet}. */ function _get( Map storage map, bytes32 key, string memory errorMessage ) private view returns (bytes32) { bytes32 value = map._values[key]; require(value != 0 || _contains(map, key), errorMessage); return value; } // UintToAddressMap struct UintToAddressMap { Map _inner; } /** * @dev Adds a key-value pair to a map, or updates the value for an existing * key. O(1). * * Returns true if the key was added to the map, that is if it was not * already present. */ function set( UintToAddressMap storage map, uint256 key, address value ) internal returns (bool) { return _set(map._inner, bytes32(key), bytes32(uint256(uint160(value)))); } /** * @dev Removes a value from a set. O(1). * * Returns true if the key was removed from the map, that is if it was present. */ function remove(UintToAddressMap storage map, uint256 key) internal returns (bool) { return _remove(map._inner, bytes32(key)); } /** * @dev Returns true if the key is in the map. O(1). */ function contains(UintToAddressMap storage map, uint256 key) internal view returns (bool) { return _contains(map._inner, bytes32(key)); } /** * @dev Returns the number of elements in the map. O(1). */ function length(UintToAddressMap storage map) internal view returns (uint256) { return _length(map._inner); } /** * @dev Returns the element stored at position `index` in the set. O(1). * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function at(UintToAddressMap storage map, uint256 index) internal view returns (uint256, address) { (bytes32 key, bytes32 value) = _at(map._inner, index); return (uint256(key), address(uint160(uint256(value)))); } /** * @dev Tries to returns the value associated with `key`. O(1). * Does not revert if `key` is not in the map. * * _Available since v3.4._ */ function tryGet(UintToAddressMap storage map, uint256 key) internal view returns (bool, address) { (bool success, bytes32 value) = _tryGet(map._inner, bytes32(key)); return (success, address(uint160(uint256(value)))); } /** * @dev Returns the value associated with `key`. O(1). * * Requirements: * * - `key` must be in the map. */ function get(UintToAddressMap storage map, uint256 key) internal view returns (address) { return address(uint160(uint256(_get(map._inner, bytes32(key))))); } /** * @dev Same as {get}, with a custom error message when `key` is not in the map. * * CAUTION: This function is deprecated because it requires allocating memory for the error * message unnecessarily. For custom revert reasons use {tryGet}. */ function get( UintToAddressMap storage map, uint256 key, string memory errorMessage ) internal view returns (address) { return address(uint160(uint256(_get(map._inner, bytes32(key), errorMessage)))); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.5.0) (utils/math/Math.sol) pragma solidity ^0.8.0; /** * @dev Standard math utilities missing in the Solidity language. */ library Math { /** * @dev Returns the largest of two numbers. */ function max(uint256 a, uint256 b) internal pure returns (uint256) { return a >= b ? a : b; } /** * @dev Returns the smallest of two numbers. */ function min(uint256 a, uint256 b) internal pure returns (uint256) { return a < b ? a : b; } /** * @dev Returns the average of two numbers. The result is rounded towards * zero. */ function average(uint256 a, uint256 b) internal pure returns (uint256) { // (a + b) / 2 can overflow. return (a & b) + (a ^ b) / 2; } /** * @dev Returns the ceiling of the division of two numbers. * * This differs from standard division with `/` in that it rounds up instead * of rounding down. */ function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) { // (a + b - 1) / b can overflow on addition, so we distribute. return a / b + (a % b == 0 ? 0 : 1); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC1820Registry.sol) pragma solidity ^0.8.0; /** * @dev Interface of the global ERC1820 Registry, as defined in the * https://eips.ethereum.org/EIPS/eip-1820[EIP]. Accounts may register * implementers for interfaces in this registry, as well as query support. * * Implementers may be shared by multiple accounts, and can also implement more * than a single interface for each account. Contracts can implement interfaces * for themselves, but externally-owned accounts (EOA) must delegate this to a * contract. * * {IERC165} interfaces can also be queried via the registry. * * For an in-depth explanation and source code analysis, see the EIP text. */ interface IERC1820Registry { /** * @dev Sets `newManager` as the manager for `account`. A manager of an * account is able to set interface implementers for it. * * By default, each account is its own manager. Passing a value of `0x0` in * `newManager` will reset the manager to this initial state. * * Emits a {ManagerChanged} event. * * Requirements: * * - the caller must be the current manager for `account`. */ function setManager(address account, address newManager) external; /** * @dev Returns the manager for `account`. * * See {setManager}. */ function getManager(address account) external view returns (address); /** * @dev Sets the `implementer` contract as ``account``'s implementer for * `interfaceHash`. * * `account` being the zero address is an alias for the caller's address. * The zero address can also be used in `implementer` to remove an old one. * * See {interfaceHash} to learn how these are created. * * Emits an {InterfaceImplementerSet} event. * * Requirements: * * - the caller must be the current manager for `account`. * - `interfaceHash` must not be an {IERC165} interface id (i.e. it must not * end in 28 zeroes). * - `implementer` must implement {IERC1820Implementer} and return true when * queried for support, unless `implementer` is the caller. See * {IERC1820Implementer-canImplementInterfaceForAddress}. */ function setInterfaceImplementer( address account, bytes32 _interfaceHash, address implementer ) external; /** * @dev Returns the implementer of `interfaceHash` for `account`. If no such * implementer is registered, returns the zero address. * * If `interfaceHash` is an {IERC165} interface id (i.e. it ends with 28 * zeroes), `account` will be queried for support of it. * * `account` being the zero address is an alias for the caller's address. */ function getInterfaceImplementer(address account, bytes32 _interfaceHash) external view returns (address); /** * @dev Returns the interface hash for an `interfaceName`, as defined in the * corresponding * https://eips.ethereum.org/EIPS/eip-1820#interface-name[section of the EIP]. */ function interfaceHash(string calldata interfaceName) external pure returns (bytes32); /** * @notice Updates the cache with whether the contract implements an ERC165 interface or not. * @param account Address of the contract for which to update the cache. * @param interfaceId ERC165 interface for which to update the cache. */ function updateERC165Cache(address account, bytes4 interfaceId) external; /** * @notice Checks whether a contract implements an ERC165 interface or not. * If the result is not cached a direct lookup on the contract address is performed. * If the result is not cached or the cached value is out-of-date, the cache MUST be updated manually by calling * {updateERC165Cache} with the contract address. * @param account Address of the contract to check. * @param interfaceId ERC165 interface to check. * @return True if `account` implements `interfaceId`, false otherwise. */ function implementsERC165Interface(address account, bytes4 interfaceId) external view returns (bool); /** * @notice Checks whether a contract implements an ERC165 interface or not without using nor updating the cache. * @param account Address of the contract to check. * @param interfaceId ERC165 interface to check. * @return True if `account` implements `interfaceId`, false otherwise. */ function implementsERC165InterfaceNoCache(address account, bytes4 interfaceId) external view returns (bool); event InterfaceImplementerSet(address indexed account, bytes32 indexed interfaceHash, address indexed implementer); event ManagerChanged(address indexed account, address indexed newManager); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC165 standard, as defined in the * https://eips.ethereum.org/EIPS/eip-165[EIP]. * * Implementers can declare support of contract interfaces, which can then be * queried by others ({ERC165Checker}). * * For an implementation, see {ERC165}. */ interface IERC165 { /** * @dev Returns true if this contract implements the interface defined by * `interfaceId`. See the corresponding * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] * to learn more about how these ids are created. * * This function call must use less than 30 000 gas. */ function supportsInterface(bytes4 interfaceId) external view returns (bool); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol) pragma solidity ^0.8.0; import "./IERC165.sol"; /** * @dev Implementation of the {IERC165} interface. * * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check * for the additional interface id that will be supported. For example: * * ```solidity * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId); * } * ``` * * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation. */ abstract contract ERC165 is IERC165 { /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { return interfaceId == type(IERC165).interfaceId; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/Strings.sol) pragma solidity ^0.8.0; /** * @dev String operations. */ library Strings { bytes16 private constant _HEX_SYMBOLS = "0123456789abcdef"; /** * @dev Converts a `uint256` to its ASCII `string` decimal representation. */ function toString(uint256 value) internal pure returns (string memory) { // Inspired by OraclizeAPI's implementation - MIT licence // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol if (value == 0) { return "0"; } uint256 temp = value; uint256 digits; while (temp != 0) { digits++; temp /= 10; } bytes memory buffer = new bytes(digits); while (value != 0) { digits -= 1; buffer[digits] = bytes1(uint8(48 + uint256(value % 10))); value /= 10; } return string(buffer); } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation. */ function toHexString(uint256 value) internal pure returns (string memory) { if (value == 0) { return "0x00"; } uint256 temp = value; uint256 length = 0; while (temp != 0) { length++; temp >>= 8; } return toHexString(value, length); } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length. */ function toHexString(uint256 value, uint256 length) internal pure returns (string memory) { bytes memory buffer = new bytes(2 * length + 2); buffer[0] = "0"; buffer[1] = "x"; for (uint256 i = 2 * length + 1; i > 1; --i) { buffer[i] = _HEX_SYMBOLS[value & 0xf]; value >>= 4; } require(value == 0, "Strings: hex length insufficient"); return string(buffer); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/Context.sol) pragma solidity ^0.8.0; /** * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ abstract contract Context { function _msgSender() internal view virtual returns (address) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { return msg.data; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol) pragma solidity ^0.8.1; /** * @dev Collection of functions related to the address type */ library Address { /** * @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 * ==== * * [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://diligence.consensys.net/posts/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.5.11/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 functionCall(target, data, "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"); require(isContract(target), "Address: call to non-contract"); (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResult(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) { require(isContract(target), "Address: static call to non-contract"); (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResult(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) { require(isContract(target), "Address: delegate call to non-contract"); (bool success, bytes memory returndata) = target.delegatecall(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason 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 { // 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 assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (token/ERC777/IERC777Recipient.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC777TokensRecipient standard as defined in the EIP. * * Accounts can be notified of {IERC777} tokens being sent to them by having a * contract implement this interface (contract holders can be their own * implementer) and registering it on the * https://eips.ethereum.org/EIPS/eip-1820[ERC1820 global registry]. * * See {IERC1820Registry} and {ERC1820Implementer}. */ interface IERC777Recipient { /** * @dev Called by an {IERC777} token contract whenever tokens are being * moved or created into a registered account (`to`). The type of operation * is conveyed by `from` being the zero address or not. * * This call occurs _after_ the token contract's state is updated, so * {IERC777-balanceOf}, etc., can be used to query the post-operation state. * * This function may revert to prevent the operation from being executed. */ function tokensReceived( address operator, address from, address to, uint256 amount, bytes calldata userData, bytes calldata operatorData ) external; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (token/ERC20/utils/SafeERC20.sol) pragma solidity ^0.8.0; import "../IERC20.sol"; import "../../../utils/Address.sol"; /** * @title SafeERC20 * @dev Wrappers around ERC20 operations that throw on failure (when the token * contract returns false). Tokens that return no value (and instead revert or * throw on failure) are also supported, non-reverting calls are assumed to be * successful. * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract, * which allows you to call the safe operations as `token.safeTransfer(...)`, etc. */ library SafeERC20 { using Address for address; function safeTransfer( IERC20 token, address to, uint256 value ) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value)); } function safeTransferFrom( IERC20 token, address from, address to, uint256 value ) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value)); } /** * @dev Deprecated. This function has issues similar to the ones found in * {IERC20-approve}, and its usage is discouraged. * * Whenever possible, use {safeIncreaseAllowance} and * {safeDecreaseAllowance} instead. */ function safeApprove( IERC20 token, address spender, uint256 value ) internal { // safeApprove should only be called when setting an initial allowance, // or when resetting it to zero. To increase and decrease it, use // 'safeIncreaseAllowance' and 'safeDecreaseAllowance' require( (value == 0) || (token.allowance(address(this), spender) == 0), "SafeERC20: approve from non-zero to non-zero allowance" ); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value)); } function safeIncreaseAllowance( IERC20 token, address spender, uint256 value ) internal { uint256 newAllowance = token.allowance(address(this), spender) + value; _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); } function safeDecreaseAllowance( IERC20 token, address spender, uint256 value ) internal { unchecked { uint256 oldAllowance = token.allowance(address(this), spender); require(oldAllowance >= value, "SafeERC20: decreased allowance below zero"); uint256 newAllowance = oldAllowance - value; _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); } } /** * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement * on the return value: the return value is optional (but if data is returned, it must not be false). * @param token The token targeted by the call. * @param data The call data (encoded using abi.encode or one of its variants). */ function _callOptionalReturn(IERC20 token, bytes memory data) private { // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that // the target address contains contract code and also asserts for success in the low-level call. bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed"); if (returndata.length > 0) { // Return data is optional require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed"); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/IERC20.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20 { /** * @dev Returns the amount of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the amount of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves `amount` tokens from the caller's account to `to`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address to, uint256 amount) external returns (bool); /** * @dev Returns the remaining number of tokens that `spender` will be * allowed to spend on behalf of `owner` through {transferFrom}. This is * zero by default. * * This value changes when {approve} or {transferFrom} are called. */ function allowance(address owner, address spender) external view returns (uint256); /** * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. * * Returns a boolean value indicating whether the operation succeeded. * * IMPORTANT: Beware that changing an allowance with this method brings the risk * that someone may use both the old and the new allowance by unfortunate * transaction ordering. One possible solution to mitigate this race * condition is to first reduce the spender's allowance to 0 and set the * desired value afterwards: * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 * * Emits an {Approval} event. */ function approve(address spender, uint256 amount) external returns (bool); /** * @dev Moves `amount` tokens from `from` to `to` using the * allowance mechanism. `amount` is then deducted from the caller's * allowance. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transferFrom( address from, address to, uint256 amount ) external returns (bool); /** * @dev Emitted when `value` tokens are moved from one account (`from`) to * another (`to`). * * Note that `value` may be zero. */ event Transfer(address indexed from, address indexed to, uint256 value); /** * @dev Emitted when the allowance of a `spender` for an `owner` is set by * a call to {approve}. `value` is the new allowance. */ event Approval(address indexed owner, address indexed spender, uint256 value); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (security/Pausable.sol) pragma solidity ^0.8.0; import "../utils/Context.sol"; /** * @dev Contract module which allows children to implement an emergency stop * mechanism that can be triggered by an authorized account. * * This module is used through inheritance. It will make available the * modifiers `whenNotPaused` and `whenPaused`, which can be applied to * the functions of your contract. Note that they will not be pausable by * simply including this module, only once the modifiers are put in place. */ abstract contract Pausable is Context { /** * @dev Emitted when the pause is triggered by `account`. */ event Paused(address account); /** * @dev Emitted when the pause is lifted by `account`. */ event Unpaused(address account); bool private _paused; /** * @dev Initializes the contract in unpaused state. */ constructor() { _paused = false; } /** * @dev Returns true if the contract is paused, and false otherwise. */ function paused() public view virtual returns (bool) { return _paused; } /** * @dev Modifier to make a function callable only when the contract is not paused. * * Requirements: * * - The contract must not be paused. */ modifier whenNotPaused() { require(!paused(), "Pausable: paused"); _; } /** * @dev Modifier to make a function callable only when the contract is paused. * * Requirements: * * - The contract must be paused. */ modifier whenPaused() { require(paused(), "Pausable: not paused"); _; } /** * @dev Triggers stopped state. * * Requirements: * * - The contract must not be paused. */ function _pause() internal virtual whenNotPaused { _paused = true; emit Paused(_msgSender()); } /** * @dev Returns to normal state. * * Requirements: * * - The contract must be paused. */ function _unpause() internal virtual whenPaused { _paused = false; emit Unpaused(_msgSender()); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (finance/VestingWallet.sol) pragma solidity ^0.8.0; import "../token/ERC20/utils/SafeERC20.sol"; import "../utils/Address.sol"; import "../utils/Context.sol"; import "../utils/math/Math.sol"; /** * @title VestingWallet * @dev This contract handles the vesting of Eth and ERC20 tokens for a given beneficiary. Custody of multiple tokens * can be given to this contract, which will release the token to the beneficiary following a given vesting schedule. * The vesting schedule is customizable through the {vestedAmount} function. * * Any token transferred to this contract will follow the vesting schedule as if they were locked from the beginning. * Consequently, if the vesting has already started, any amount of tokens sent to this contract will (at least partly) * be immediately releasable. */ contract VestingWallet is Context { event EtherReleased(uint256 amount); event ERC20Released(address indexed token, uint256 amount); uint256 private _released; mapping(address => uint256) private _erc20Released; address private immutable _beneficiary; uint64 private immutable _start; uint64 private immutable _duration; /** * @dev Set the beneficiary, start timestamp and vesting duration of the vesting wallet. */ constructor( address beneficiaryAddress, uint64 startTimestamp, uint64 durationSeconds ) { require(beneficiaryAddress != address(0), "VestingWallet: beneficiary is zero address"); _beneficiary = beneficiaryAddress; _start = startTimestamp; _duration = durationSeconds; } /** * @dev The contract should be able to receive Eth. */ receive() external payable virtual {} /** * @dev Getter for the beneficiary address. */ function beneficiary() public view virtual returns (address) { return _beneficiary; } /** * @dev Getter for the start timestamp. */ function start() public view virtual returns (uint256) { return _start; } /** * @dev Getter for the vesting duration. */ function duration() public view virtual returns (uint256) { return _duration; } /** * @dev Amount of eth already released */ function released() public view virtual returns (uint256) { return _released; } /** * @dev Amount of token already released */ function released(address token) public view virtual returns (uint256) { return _erc20Released[token]; } /** * @dev Release the native token (ether) that have already vested. * * Emits a {TokensReleased} event. */ function release() public virtual { uint256 releasable = vestedAmount(uint64(block.timestamp)) - released(); _released += releasable; emit EtherReleased(releasable); Address.sendValue(payable(beneficiary()), releasable); } /** * @dev Release the tokens that have already vested. * * Emits a {TokensReleased} event. */ function release(address token) public virtual { uint256 releasable = vestedAmount(token, uint64(block.timestamp)) - released(token); _erc20Released[token] += releasable; emit ERC20Released(token, releasable); SafeERC20.safeTransfer(IERC20(token), beneficiary(), releasable); } /** * @dev Calculates the amount of ether that has already vested. Default implementation is a linear vesting curve. */ function vestedAmount(uint64 timestamp) public view virtual returns (uint256) { return _vestingSchedule(address(this).balance + released(), timestamp); } /** * @dev Calculates the amount of tokens that has already vested. Default implementation is a linear vesting curve. */ function vestedAmount(address token, uint64 timestamp) public view virtual returns (uint256) { return _vestingSchedule(IERC20(token).balanceOf(address(this)) + released(token), timestamp); } /** * @dev Virtual implementation of the vesting formula. This returns the amout vested, as a function of time, for * an asset given its total historical allocation. */ function _vestingSchedule(uint256 totalAllocation, uint64 timestamp) internal view virtual returns (uint256) { if (timestamp < start()) { return 0; } else if (timestamp > start() + duration()) { return totalAllocation; } else { return (totalAllocation * (timestamp - start())) / duration(); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (access/IAccessControlEnumerable.sol) pragma solidity ^0.8.0; import "./IAccessControl.sol"; /** * @dev External interface of AccessControlEnumerable declared to support ERC165 detection. */ interface IAccessControlEnumerable is IAccessControl { /** * @dev Returns one of the accounts that have `role`. `index` must be a * value between 0 and {getRoleMemberCount}, non-inclusive. * * Role bearers are not sorted in any particular way, and their ordering may * change at any point. * * WARNING: When using {getRoleMember} and {getRoleMemberCount}, make sure * you perform all queries on the same block. See the following * https://forum.openzeppelin.com/t/iterating-over-elements-on-enumerableset-in-openzeppelin-contracts/2296[forum post] * for more information. */ function getRoleMember(bytes32 role, uint256 index) external view returns (address); /** * @dev Returns the number of accounts that have `role`. Can be used * together with {getRoleMember} to enumerate all bearers of a role. */ function getRoleMemberCount(bytes32 role) external view returns (uint256); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (access/IAccessControl.sol) pragma solidity ^0.8.0; /** * @dev External interface of AccessControl declared to support ERC165 detection. */ interface IAccessControl { /** * @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole` * * `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite * {RoleAdminChanged} not being emitted signaling this. * * _Available since v3.1._ */ event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole); /** * @dev Emitted when `account` is granted `role`. * * `sender` is the account that originated the contract call, an admin role * bearer except when using {AccessControl-_setupRole}. */ event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender); /** * @dev Emitted when `account` is revoked `role`. * * `sender` is the account that originated the contract call: * - if using `revokeRole`, it is the admin role bearer * - if using `renounceRole`, it is the role bearer (i.e. `account`) */ event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender); /** * @dev Returns `true` if `account` has been granted `role`. */ function hasRole(bytes32 role, address account) external view returns (bool); /** * @dev Returns the admin role that controls `role`. See {grantRole} and * {revokeRole}. * * To change a role's admin, use {AccessControl-_setRoleAdmin}. */ function getRoleAdmin(bytes32 role) external view returns (bytes32); /** * @dev Grants `role` to `account`. * * If `account` had not been already granted `role`, emits a {RoleGranted} * event. * * Requirements: * * - the caller must have ``role``'s admin role. */ function grantRole(bytes32 role, address account) external; /** * @dev Revokes `role` from `account`. * * If `account` had been granted `role`, emits a {RoleRevoked} event. * * Requirements: * * - the caller must have ``role``'s admin role. */ function revokeRole(bytes32 role, address account) external; /** * @dev Revokes `role` from the calling account. * * Roles are often managed via {grantRole} and {revokeRole}: this function's * purpose is to provide a mechanism for accounts to lose their privileges * if they are compromised (such as when a trusted device is misplaced). * * If the calling account had been granted `role`, emits a {RoleRevoked} * event. * * Requirements: * * - the caller must be `account`. */ function renounceRole(bytes32 role, address account) external; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.5.0) (access/AccessControlEnumerable.sol) pragma solidity ^0.8.0; import "./IAccessControlEnumerable.sol"; import "./AccessControl.sol"; import "../utils/structs/EnumerableSet.sol"; /** * @dev Extension of {AccessControl} that allows enumerating the members of each role. */ abstract contract AccessControlEnumerable is IAccessControlEnumerable, AccessControl { using EnumerableSet for EnumerableSet.AddressSet; mapping(bytes32 => EnumerableSet.AddressSet) private _roleMembers; /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { return interfaceId == type(IAccessControlEnumerable).interfaceId || super.supportsInterface(interfaceId); } /** * @dev Returns one of the accounts that have `role`. `index` must be a * value between 0 and {getRoleMemberCount}, non-inclusive. * * Role bearers are not sorted in any particular way, and their ordering may * change at any point. * * WARNING: When using {getRoleMember} and {getRoleMemberCount}, make sure * you perform all queries on the same block. See the following * https://forum.openzeppelin.com/t/iterating-over-elements-on-enumerableset-in-openzeppelin-contracts/2296[forum post] * for more information. */ function getRoleMember(bytes32 role, uint256 index) public view virtual override returns (address) { return _roleMembers[role].at(index); } /** * @dev Returns the number of accounts that have `role`. Can be used * together with {getRoleMember} to enumerate all bearers of a role. */ function getRoleMemberCount(bytes32 role) public view virtual override returns (uint256) { return _roleMembers[role].length(); } /** * @dev Overload {_grantRole} to track enumerable memberships */ function _grantRole(bytes32 role, address account) internal virtual override { super._grantRole(role, account); _roleMembers[role].add(account); } /** * @dev Overload {_revokeRole} to track enumerable memberships */ function _revokeRole(bytes32 role, address account) internal virtual override { super._revokeRole(role, account); _roleMembers[role].remove(account); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.5.0) (access/AccessControl.sol) pragma solidity ^0.8.0; import "./IAccessControl.sol"; import "../utils/Context.sol"; import "../utils/Strings.sol"; import "../utils/introspection/ERC165.sol"; /** * @dev Contract module that allows children to implement role-based access * control mechanisms. This is a lightweight version that doesn't allow enumerating role * members except through off-chain means by accessing the contract event logs. Some * applications may benefit from on-chain enumerability, for those cases see * {AccessControlEnumerable}. * * Roles are referred to by their `bytes32` identifier. These should be exposed * in the external API and be unique. The best way to achieve this is by * using `public constant` hash digests: * * ``` * bytes32 public constant MY_ROLE = keccak256("MY_ROLE"); * ``` * * Roles can be used to represent a set of permissions. To restrict access to a * function call, use {hasRole}: * * ``` * function foo() public { * require(hasRole(MY_ROLE, msg.sender)); * ... * } * ``` * * Roles can be granted and revoked dynamically via the {grantRole} and * {revokeRole} functions. Each role has an associated admin role, and only * accounts that have a role's admin role can call {grantRole} and {revokeRole}. * * By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means * that only accounts with this role will be able to grant or revoke other * roles. More complex role relationships can be created by using * {_setRoleAdmin}. * * WARNING: The `DEFAULT_ADMIN_ROLE` is also its own admin: it has permission to * grant and revoke this role. Extra precautions should be taken to secure * accounts that have been granted it. */ abstract contract AccessControl is Context, IAccessControl, ERC165 { struct RoleData { mapping(address => bool) members; bytes32 adminRole; } mapping(bytes32 => RoleData) private _roles; bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00; /** * @dev Modifier that checks that an account has a specific role. Reverts * with a standardized message including the required role. * * The format of the revert reason is given by the following regular expression: * * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/ * * _Available since v4.1._ */ modifier onlyRole(bytes32 role) { _checkRole(role, _msgSender()); _; } /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { return interfaceId == type(IAccessControl).interfaceId || super.supportsInterface(interfaceId); } /** * @dev Returns `true` if `account` has been granted `role`. */ function hasRole(bytes32 role, address account) public view virtual override returns (bool) { return _roles[role].members[account]; } /** * @dev Revert with a standard message if `account` is missing `role`. * * The format of the revert reason is given by the following regular expression: * * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/ */ function _checkRole(bytes32 role, address account) internal view virtual { if (!hasRole(role, account)) { revert( string( abi.encodePacked( "AccessControl: account ", Strings.toHexString(uint160(account), 20), " is missing role ", Strings.toHexString(uint256(role), 32) ) ) ); } } /** * @dev Returns the admin role that controls `role`. See {grantRole} and * {revokeRole}. * * To change a role's admin, use {_setRoleAdmin}. */ function getRoleAdmin(bytes32 role) public view virtual override returns (bytes32) { return _roles[role].adminRole; } /** * @dev Grants `role` to `account`. * * If `account` had not been already granted `role`, emits a {RoleGranted} * event. * * Requirements: * * - the caller must have ``role``'s admin role. */ function grantRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) { _grantRole(role, account); } /** * @dev Revokes `role` from `account`. * * If `account` had been granted `role`, emits a {RoleRevoked} event. * * Requirements: * * - the caller must have ``role``'s admin role. */ function revokeRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) { _revokeRole(role, account); } /** * @dev Revokes `role` from the calling account. * * Roles are often managed via {grantRole} and {revokeRole}: this function's * purpose is to provide a mechanism for accounts to lose their privileges * if they are compromised (such as when a trusted device is misplaced). * * If the calling account had been revoked `role`, emits a {RoleRevoked} * event. * * Requirements: * * - the caller must be `account`. */ function renounceRole(bytes32 role, address account) public virtual override { require(account == _msgSender(), "AccessControl: can only renounce roles for self"); _revokeRole(role, account); } /** * @dev Grants `role` to `account`. * * If `account` had not been already granted `role`, emits a {RoleGranted} * event. Note that unlike {grantRole}, this function doesn't perform any * checks on the calling account. * * [WARNING] * ==== * This function should only be called from the constructor when setting * up the initial roles for the system. * * Using this function in any other way is effectively circumventing the admin * system imposed by {AccessControl}. * ==== * * NOTE: This function is deprecated in favor of {_grantRole}. */ function _setupRole(bytes32 role, address account) internal virtual { _grantRole(role, account); } /** * @dev Sets `adminRole` as ``role``'s admin role. * * Emits a {RoleAdminChanged} event. */ function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual { bytes32 previousAdminRole = getRoleAdmin(role); _roles[role].adminRole = adminRole; emit RoleAdminChanged(role, previousAdminRole, adminRole); } /** * @dev Grants `role` to `account`. * * Internal function without access restriction. */ function _grantRole(bytes32 role, address account) internal virtual { if (!hasRole(role, account)) { _roles[role].members[account] = true; emit RoleGranted(role, account, _msgSender()); } } /** * @dev Revokes `role` from `account`. * * Internal function without access restriction. */ function _revokeRole(bytes32 role, address account) internal virtual { if (hasRole(role, account)) { _roles[role].members[account] = false; emit RoleRevoked(role, account, _msgSender()); } } }
{ "remappings": [], "optimizer": { "enabled": false, "runs": 200 }, "evmVersion": "london", "libraries": {}, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"address","name":"beneficiaryAddress","type":"address"},{"internalType":"uint64","name":"startTimestamp","type":"uint64"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"beneficiaryAddress","type":"address"}],"name":"BeneficiaryEdited","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"token","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"ERC20Released","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"EtherReleased","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"uint256","name":"duration","type":"uint256"}],"name":"Locked","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Paused","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"PermanentlyLocked","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"previousAdminRole","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"newAdminRole","type":"bytes32"}],"name":"RoleAdminChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleGranted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleRevoked","type":"event"},{"anonymous":false,"inputs":[],"name":"ScheduleReset","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint8","name":"stepPercent","type":"uint8"},{"indexed":false,"internalType":"uint64","name":"stepDuration","type":"uint64"}],"name":"ScheduleStepAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Unpaused","type":"event"},{"inputs":[],"name":"BENEFICIARY_MANAGER_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"DEFAULT_ADMIN_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PAUSER_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"SCHEDULE_MANAGER_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint8","name":"stepPercent","type":"uint8"},{"internalType":"uint64","name":"stepDuration","type":"uint64"}],"name":"addToSchedule","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"beneficiary","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"duration","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"getRoleAdmin","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"getRoleMember","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"getRoleMemberCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"grantRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"hasRole","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"lockDuration","type":"uint256"}],"name":"lock","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"lockEnd","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"locked","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"permanentLock","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"permanentlyLocked","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"release","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"release","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"released","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"released","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"renounceRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"resetSchedule","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"revokeRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"beneficiaryAddress","type":"address"}],"name":"setBeneficiary","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"start","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"stepPercentSum","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"bytes","name":"","type":"bytes"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"tokensReceived","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"unpause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint64","name":"timestamp","type":"uint64"}],"name":"vestedAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint64","name":"timestamp","type":"uint64"}],"name":"vestedAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"stateMutability":"payable","type":"receive"}]
Contract Creation Code
60e06040523480156200001157600080fd5b506040516200495438038062004954833981810160405281019062000037919062000a48565b818160008073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415620000ad576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401620000a49062000b16565b60405180910390fd5b8273ffffffffffffffffffffffffffffffffffffffff1660808173ffffffffffffffffffffffffffffffffffffffff16815250508167ffffffffffffffff1660a08167ffffffffffffffff16815250508067ffffffffffffffff1660c08167ffffffffffffffff16815250505050506000600260006101000a81548160ff0219169083151502179055506000600560006101000a81548160ff0219169083151502179055506000600681905550731820a4b7618bde71dce8cdc73aab6c95905fad2473ffffffffffffffffffffffffffffffffffffffff166329965a1d307fb281fc8c12954d22544db45de3159a39272895b169a852b314f9cc762e44c53b306040518463ffffffff1660e01b8152600401620001cd9392919062000b64565b600060405180830381600087803b158015620001e857600080fd5b505af1158015620001fd573d6000803e3d6000fd5b50505050620002166000801b33620002c560201b60201c565b620002487f65d7a28e3265b37a6474929f336521b332c1681b933f6cb9f3376673440d862a33620002c560201b60201c565b6200027a7f54217f7b85353d04ece159ebd69a45e9b8287dd2043746eaca469996a3d91aee33620002c560201b60201c565b620002ac7fc59ec23d1c349d9976a1aba1c27c681cc250eafcb2aaf5c7c3be1d0e6827bfb133620002c560201b60201c565b620002bd826200030d60201b60201c565b505062001027565b620002dc82826200044060201b620012f71760201c565b6200030881600460008581526020019081526020016000206200053260201b620013d81790919060201c565b505050565b7fc59ec23d1c349d9976a1aba1c27c681cc250eafcb2aaf5c7c3be1d0e6827bfb16200034f81620003436200056a60201b60201c565b6200057260201b60201c565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415620003c2576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401620003b99062000c17565b60405180910390fd5b81600860016101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507f446c2ff852422a9988931e1b4eed7290482a93fa1eff1e2fc9295efde537ffb08260405162000434919062000c39565b60405180910390a15050565b6200045282826200063660201b60201c565b6200052e5760016003600084815260200190815260200160002060000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908315150217905550620004d36200056a60201b60201c565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45b5050565b600062000562836000018373ffffffffffffffffffffffffffffffffffffffff1660001b620006a160201b60201c565b905092915050565b600033905090565b6200058482826200063660201b60201c565b6200063257620005b78173ffffffffffffffffffffffffffffffffffffffff1660146200071b60201b620014081760201c565b620005d28360001c60206200071b60201b620014081760201c565b604051602001620005e592919062000d79565b6040516020818303038152906040526040517f08c379a000000000000000000000000000000000000000000000000000000000815260040162000629919062000e0d565b60405180910390fd5b5050565b60006003600084815260200190815260200160002060000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b6000620006b583836200097660201b60201c565b6200071057826000018290806001815401808255809150506001900390600052602060002001600090919091909150558260000180549050836001016000848152602001908152602001600020819055506001905062000715565b600090505b92915050565b60606000600283600262000730919062000e6a565b6200073c919062000ecb565b67ffffffffffffffff81111562000758576200075762000f28565b5b6040519080825280601f01601f1916602001820160405280156200078b5781602001600182028036833780820191505090505b5090507f300000000000000000000000000000000000000000000000000000000000000081600081518110620007c657620007c562000f57565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053507f7800000000000000000000000000000000000000000000000000000000000000816001815181106200082d576200082c62000f57565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600060018460026200086f919062000e6a565b6200087b919062000ecb565b90505b600181111562000925577f3031323334353637383961626364656600000000000000000000000000000000600f861660108110620008c157620008c062000f57565b5b1a60f81b828281518110620008db57620008da62000f57565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600485901c9450806200091d9062000f86565b90506200087e565b50600084146200096c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401620009639062001005565b60405180910390fd5b8091505092915050565b600080836001016000848152602001908152602001600020541415905092915050565b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000620009cb826200099e565b9050919050565b620009dd81620009be565b8114620009e957600080fd5b50565b600081519050620009fd81620009d2565b92915050565b600067ffffffffffffffff82169050919050565b62000a228162000a03565b811462000a2e57600080fd5b50565b60008151905062000a428162000a17565b92915050565b6000806040838503121562000a625762000a6162000999565b5b600062000a7285828601620009ec565b925050602062000a858582860162000a31565b9150509250929050565b600082825260208201905092915050565b7f56657374696e6757616c6c65743a2062656e6566696369617279206973207a6560008201527f726f206164647265737300000000000000000000000000000000000000000000602082015250565b600062000afe602a8362000a8f565b915062000b0b8262000aa0565b604082019050919050565b6000602082019050818103600083015262000b318162000aef565b9050919050565b62000b4381620009be565b82525050565b6000819050919050565b62000b5e8162000b49565b82525050565b600060608201905062000b7b600083018662000b38565b62000b8a602083018562000b53565b62000b99604083018462000b38565b949350505050565b7f56657374696e6757616c6c65744d756c74694c696e6561723a2062656e65666960008201527f6369617279206973207a65726f20616464726573730000000000000000000000602082015250565b600062000bff60358362000a8f565b915062000c0c8262000ba1565b604082019050919050565b6000602082019050818103600083015262000c328162000bf0565b9050919050565b600060208201905062000c50600083018462000b38565b92915050565b600081905092915050565b7f416363657373436f6e74726f6c3a206163636f756e7420000000000000000000600082015250565b600062000c9960178362000c56565b915062000ca68262000c61565b601782019050919050565b600081519050919050565b60005b8381101562000cdc57808201518184015260208101905062000cbf565b8381111562000cec576000848401525b50505050565b600062000cff8262000cb1565b62000d0b818562000c56565b935062000d1d81856020860162000cbc565b80840191505092915050565b7f206973206d697373696e6720726f6c6520000000000000000000000000000000600082015250565b600062000d6160118362000c56565b915062000d6e8262000d29565b601182019050919050565b600062000d868262000c8a565b915062000d94828562000cf2565b915062000da18262000d52565b915062000daf828462000cf2565b91508190509392505050565b6000601f19601f8301169050919050565b600062000dd98262000cb1565b62000de5818562000a8f565b935062000df781856020860162000cbc565b62000e028162000dbb565b840191505092915050565b6000602082019050818103600083015262000e29818462000dcc565b905092915050565b6000819050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600062000e778262000e31565b915062000e848362000e31565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048311821515161562000ec05762000ebf62000e3b565b5b828202905092915050565b600062000ed88262000e31565b915062000ee58362000e31565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0382111562000f1d5762000f1c62000e3b565b5b828201905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600062000f938262000e31565b9150600082141562000faa5762000fa962000e3b565b5b600182039050919050565b7f537472696e67733a20686578206c656e67746820696e73756666696369656e74600082015250565b600062000fed60208362000a8f565b915062000ffa8262000fb5565b602082019050919050565b60006020820190508181036000830152620010208162000fde565b9050919050565b60805160a05160c05161390362001051600039600050506000610fb90152600050506139036000f3fe6080604052600436106101fc5760003560e01c806386d1a69f1161010d578063a66d1f05116100a0578063cf3090121161006f578063cf30901214610709578063d547741f14610734578063dd4670641461075d578063e63ab1e914610786578063ee5bafbe146107b157610203565b8063a66d1f0514610673578063bd2404be1461068a578063be9a6555146106a1578063ca15c873146106cc57610203565b806396132521116100dc57806396132521146105b55780639852595c146105e0578063a0ee45011461061d578063a217fddf1461064857610203565b806386d1a69f146104f95780639010d07c146105105780639051c5971461054d57806391d148541461057857610203565b806336568abe116101905780633f4ba83a1161015f5780633f4ba83a146104385780635c975abb1461044f5780635de43aec1461047a578063810ec23b146104a55780638456cb59146104e257610203565b806336568abe1461038e57806336f9820d146103b7578063371d4b7c146103e257806338af3eed1461040d57610203565b806319165587116101cc57806319165587146102d65780631c31f710146102ff578063248a9ca3146103285780632f2ff15d1461036557610203565b806223de291461020857806301ffc9a7146102315780630a17b06b1461026e5780630fb5a6b4146102ab57610203565b3661020357005b600080fd5b34801561021457600080fd5b5061022f600480360381019061022a919061266b565b6107da565b005b34801561023d57600080fd5b5061025860048036038101906102539190612792565b6107e4565b60405161026591906127da565b60405180910390f35b34801561027a57600080fd5b5061029560048036038101906102909190612835565b61085e565b6040516102a29190612871565b60405180910390f35b3480156102b757600080fd5b506102c0610883565b6040516102cd9190612871565b60405180910390f35b3480156102e257600080fd5b506102fd60048036038101906102f8919061288c565b6108ab565b005b34801561030b57600080fd5b506103266004803603810190610321919061288c565b6108ff565b005b34801561033457600080fd5b5061034f600480360381019061034a91906128ef565b610a1d565b60405161035c919061292b565b60405180910390f35b34801561037157600080fd5b5061038c60048036038101906103879190612946565b610a3d565b005b34801561039a57600080fd5b506103b560048036038101906103b09190612946565b610a66565b005b3480156103c357600080fd5b506103cc610ae9565b6040516103d9919061292b565b60405180910390f35b3480156103ee57600080fd5b506103f7610b0d565b60405161040491906129a2565b60405180910390f35b34801561041957600080fd5b50610422610b24565b60405161042f91906129cc565b60405180910390f35b34801561044457600080fd5b5061044d610b4e565b005b34801561045b57600080fd5b50610464610b8b565b60405161047191906127da565b60405180910390f35b34801561048657600080fd5b5061048f610ba2565b60405161049c919061292b565b60405180910390f35b3480156104b157600080fd5b506104cc60048036038101906104c791906129e7565b610bc6565b6040516104d99190612871565b60405180910390f35b3480156104ee57600080fd5b506104f7610c66565b005b34801561050557600080fd5b5061050e610ca3565b005b34801561051c57600080fd5b5061053760048036038101906105329190612a27565b610cf5565b60405161054491906129cc565b60405180910390f35b34801561055957600080fd5b50610562610d24565b60405161056f91906127da565b60405180910390f35b34801561058457600080fd5b5061059f600480360381019061059a9190612946565b610d3b565b6040516105ac91906127da565b60405180910390f35b3480156105c157600080fd5b506105ca610da6565b6040516105d79190612871565b60405180910390f35b3480156105ec57600080fd5b506106076004803603810190610602919061288c565b610daf565b6040516106149190612871565b60405180910390f35b34801561062957600080fd5b50610632610df8565b60405161063f9190612871565b60405180910390f35b34801561065457600080fd5b5061065d610e91565b60405161066a919061292b565b60405180910390f35b34801561067f57600080fd5b50610688610e98565b005b34801561069657600080fd5b5061069f610eb8565b005b3480156106ad57600080fd5b506106b6610fb5565b6040516106c39190612871565b60405180910390f35b3480156106d857600080fd5b506106f360048036038101906106ee91906128ef565b610fe7565b6040516107009190612871565b60405180910390f35b34801561071557600080fd5b5061071e61100b565b60405161072b91906127da565b60405180910390f35b34801561074057600080fd5b5061075b60048036038101906107569190612946565b611026565b005b34801561076957600080fd5b50610784600480360381019061077f9190612a67565b61104f565b005b34801561079257600080fd5b5061079b611071565b6040516107a8919061292b565b60405180910390f35b3480156107bd57600080fd5b506107d860048036038101906107d39190612ac0565b611095565b005b5050505050505050565b60007f5a05180f000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480610857575061085682611644565b5b9050919050565b600061087c61086b610da6565b476108769190612b2f565b836116be565b9050919050565b6000600860159054906101000a900467ffffffffffffffff1667ffffffffffffffff16905090565b6108b3610b8b565b156108f3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108ea90612be2565b60405180910390fd5b6108fc81611789565b50565b7fc59ec23d1c349d9976a1aba1c27c681cc250eafcb2aaf5c7c3be1d0e6827bfb16109318161092c611864565b61186c565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614156109a1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161099890612c74565b60405180910390fd5b81600860016101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507f446c2ff852422a9988931e1b4eed7290482a93fa1eff1e2fc9295efde537ffb082604051610a1191906129cc565b60405180910390a15050565b600060036000838152602001908152602001600020600101549050919050565b610a4682610a1d565b610a5781610a52611864565b61186c565b610a618383611909565b505050565b610a6e611864565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610adb576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ad290612d06565b60405180910390fd5b610ae5828261193d565b5050565b7f54217f7b85353d04ece159ebd69a45e9b8287dd2043746eaca469996a3d91aee81565b6000600860009054906101000a900460ff16905090565b6000600860019054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b7f65d7a28e3265b37a6474929f336521b332c1681b933f6cb9f3376673440d862a610b8081610b7b611864565b61186c565b610b88611971565b50565b6000600260009054906101000a900460ff16905090565b7fc59ec23d1c349d9976a1aba1c27c681cc250eafcb2aaf5c7c3be1d0e6827bfb181565b6000610c5e610bd484610daf565b8473ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b8152600401610c0d91906129cc565b602060405180830381865afa158015610c2a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c4e9190612d3b565b610c589190612b2f565b836116be565b905092915050565b7f65d7a28e3265b37a6474929f336521b332c1681b933f6cb9f3376673440d862a610c9881610c93611864565b61186c565b610ca0611a13565b50565b610cab610b8b565b15610ceb576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ce290612be2565b60405180910390fd5b610cf3611ab6565b565b6000610d1c8260046000868152602001908152602001600020611b3890919063ffffffff16565b905092915050565b6000600560009054906101000a900460ff16905090565b60006003600084815260200190815260200160002060000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b60008054905090565b6000600160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b6000610e0261100b565b610e41576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e3890612db4565b60405180910390fd5b610e49610d24565b15610e89576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e8090612e20565b60405180910390fd5b600654905090565b6000801b81565b6000801b610ead81610ea8611864565b61186c565b610eb5611b52565b50565b7f54217f7b85353d04ece159ebd69a45e9b8287dd2043746eaca469996a3d91aee610eea81610ee5611864565b61186c565b610ef261100b565b15610f32576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f2990612e8c565b60405180910390fd5b60076000610f4091906124f6565b6000600860006101000a81548160ff021916908360ff1602179055506000600860156101000a81548167ffffffffffffffff021916908367ffffffffffffffff1602179055507f145deea571fed01c02d67148dbd971d8f6daf03869c1b8094831bf4e3b2bf40e60405160405180910390a150565b60007f000000000000000000000000000000000000000000000000000000000000000067ffffffffffffffff16905090565b600061100460046000848152602001908152602001600020611bf5565b9050919050565b6000611015610d24565b80611021575042600654115b905090565b61102f82610a1d565b6110408161103b611864565b61186c565b61104a838361193d565b505050565b6000801b6110648161105f611864565b61186c565b61106d82611c0a565b5050565b7f65d7a28e3265b37a6474929f336521b332c1681b933f6cb9f3376673440d862a81565b7f54217f7b85353d04ece159ebd69a45e9b8287dd2043746eaca469996a3d91aee6110c7816110c2611864565b61186c565b6110cf61100b565b1561110f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161110690612e8c565b60405180910390fd5b606483600860009054906101000a900460ff1661112c9190612eac565b60ff161115611170576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161116790612f7b565b60405180910390fd5b600760405180606001604052808560ff16815260200161118e610883565b611196610fb5565b6111a09190612b2f565b81526020018467ffffffffffffffff16815250908060018154018082558091505060019003906000526020600020906003020160009091909190915060008201518160000160006101000a81548160ff021916908360ff1602179055506020820151816001015560408201518160020160006101000a81548167ffffffffffffffff021916908367ffffffffffffffff160217905550505082600860008282829054906101000a900460ff166112569190612eac565b92506101000a81548160ff021916908360ff16021790555081600860158282829054906101000a900467ffffffffffffffff166112939190612f9b565b92506101000a81548167ffffffffffffffff021916908367ffffffffffffffff1602179055507f9126313d5e85a57af5bf04159f331340677115f459ea598e9c41936fff80b42e83836040516112ea929190612fe8565b60405180910390a1505050565b6113018282610d3b565b6113d45760016003600084815260200190815260200160002060000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908315150217905550611379611864565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45b5050565b6000611400836000018373ffffffffffffffffffffffffffffffffffffffff1660001b611ca7565b905092915050565b60606000600283600261141b9190613011565b6114259190612b2f565b67ffffffffffffffff81111561143e5761143d61306b565b5b6040519080825280601f01601f1916602001820160405280156114705781602001600182028036833780820191505090505b5090507f3000000000000000000000000000000000000000000000000000000000000000816000815181106114a8576114a761309a565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053507f78000000000000000000000000000000000000000000000000000000000000008160018151811061150c5761150b61309a565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053506000600184600261154c9190613011565b6115569190612b2f565b90505b60018111156115f6577f3031323334353637383961626364656600000000000000000000000000000000600f8616601081106115985761159761309a565b5b1a60f81b8282815181106115af576115ae61309a565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600485901c9450806115ef906130c9565b9050611559565b506000841461163a576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116319061313f565b60405180910390fd5b8091505092915050565b60007f7965db0b000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614806116b757506116b682611d17565b5b9050919050565b60008060078054905011611707576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116fe9061321d565b60405180910390fd5b60008060005b600782815481106117215761172061309a565b5b9060005260206000209060030201905061173c818787611d81565b836117479190612b2f565b92506001826117569190612b2f565b915080600101548567ffffffffffffffff16118015611779575060078054905082105b61170d5782935050505092915050565b600061179482610daf565b61179e8342610bc6565b6117a8919061323d565b905080600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546117f99190612b2f565b925050819055508173ffffffffffffffffffffffffffffffffffffffff167fc0e523490dd523c33b1878c9eb14ff46991e3f5b2cd33710918618f2a39cba1b826040516118469190612871565b60405180910390a26118608261185a610b24565b83611e7a565b5050565b600033905090565b6118768282610d3b565b6119055761189b8173ffffffffffffffffffffffffffffffffffffffff166014611408565b6118a98360001c6020611408565b6040516020016118ba929190613383565b6040516020818303038152906040526040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016118fc9190613407565b60405180910390fd5b5050565b61191382826112f7565b61193881600460008581526020019081526020016000206113d890919063ffffffff16565b505050565b6119478282611f00565b61196c8160046000858152602001908152602001600020611fe290919063ffffffff16565b505050565b611979610b8b565b6119b8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016119af90613475565b60405180910390fd5b6000600260006101000a81548160ff0219169083151502179055507f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa6119fc611864565b604051611a0991906129cc565b60405180910390a1565b611a1b610b8b565b15611a5b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611a5290612be2565b60405180910390fd5b6001600260006101000a81548160ff0219169083151502179055507f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258611a9f611864565b604051611aac91906129cc565b60405180910390a1565b6000611ac0610da6565b611ac94261085e565b611ad3919061323d565b905080600080828254611ae69190612b2f565b925050819055507fda9d4e5f101b8b9b1c5b76d0c5a9f7923571acfc02376aa076b75a8c080c956b81604051611b1c9190612871565b60405180910390a1611b35611b2f610b24565b82612012565b50565b6000611b478360000183612106565b60001c905092915050565b611b5a61100b565b15611b9a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611b9190612e8c565b60405180910390fd5b6001600560006101000a81548160ff0219169083151502179055507fec6267e1ebfb5a47f9aceaa24ea9a743edce3f5159589b9e11239aeec797f2d5611bde611864565b604051611beb91906129cc565b60405180910390a1565b6000611c0382600001612131565b9050919050565b611c1261100b565b15611c52576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611c4990612e8c565b60405180910390fd5b8042611c5e9190612b2f565b6006819055507f9f1ec8c880f76798e7b793325d625e9b60e4082a553c98f42b6cda368dd60008611c8d611864565b82604051611c9c929190613495565b60405180910390a150565b6000611cb38383612142565b611d0c578260000182908060018154018082558091505060019003906000526020600020016000909190919091505582600001805490508360010160008481526020019081526020016000208190555060019050611d11565b600090505b92915050565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b60008060648560000160009054906101000a900460ff1660ff1685611da69190613011565b611db091906134ed565b905084600101548367ffffffffffffffff161015611dd2576000915050611e73565b8460020160009054906101000a900467ffffffffffffffff1667ffffffffffffffff168560010154611e049190612b2f565b8367ffffffffffffffff1610611e1d5780915050611e73565b8460020160009054906101000a900467ffffffffffffffff1667ffffffffffffffff1685600101548467ffffffffffffffff16611e5a919061323d565b82611e659190613011565b611e6f91906134ed565b9150505b9392505050565b611efb8363a9059cbb60e01b8484604051602401611e99929190613495565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050612165565b505050565b611f0a8282610d3b565b15611fde5760006003600084815260200190815260200160002060000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908315150217905550611f83611864565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16837ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b60405160405180910390a45b5050565b600061200a836000018373ffffffffffffffffffffffffffffffffffffffff1660001b61222c565b905092915050565b80471015612055576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161204c9061356a565b60405180910390fd5b60008273ffffffffffffffffffffffffffffffffffffffff168260405161207b906135bb565b60006040518083038185875af1925050503d80600081146120b8576040519150601f19603f3d011682016040523d82523d6000602084013e6120bd565b606091505b5050905080612101576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016120f890613642565b60405180910390fd5b505050565b600082600001828154811061211e5761211d61309a565b5b9060005260206000200154905092915050565b600081600001805490509050919050565b600080836001016000848152602001908152602001600020541415905092915050565b60006121c7826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166123409092919063ffffffff16565b905060008151111561222757808060200190518101906121e7919061368e565b612226576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161221d9061372d565b60405180910390fd5b5b505050565b6000808360010160008481526020019081526020016000205490506000811461233457600060018261225e919061323d565b9050600060018660000180549050612276919061323d565b90508181146122e55760008660000182815481106122975761229661309a565b5b90600052602060002001549050808760000184815481106122bb576122ba61309a565b5b90600052602060002001819055508387600101600083815260200190815260200160002081905550505b856000018054806122f9576122f861374d565b5b60019003818190600052602060002001600090559055856001016000868152602001908152602001600020600090556001935050505061233a565b60009150505b92915050565b606061234f8484600085612358565b90509392505050565b60608247101561239d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612394906137ee565b60405180910390fd5b6123a68561246c565b6123e5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016123dc9061385a565b60405180910390fd5b6000808673ffffffffffffffffffffffffffffffffffffffff16858760405161240e91906138b6565b60006040518083038185875af1925050503d806000811461244b576040519150601f19603f3d011682016040523d82523d6000602084013e612450565b606091505b509150915061246082828661248f565b92505050949350505050565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b6060831561249f578290506124ef565b6000835111156124b25782518084602001fd5b816040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016124e69190613407565b60405180910390fd5b9392505050565b5080546000825560030290600052602060002090810190612517919061251a565b50565b5b8082111561256457600080820160006101000a81549060ff021916905560018201600090556002820160006101000a81549067ffffffffffffffff02191690555060030161251b565b5090565b600080fd5b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600061259d82612572565b9050919050565b6125ad81612592565b81146125b857600080fd5b50565b6000813590506125ca816125a4565b92915050565b6000819050919050565b6125e3816125d0565b81146125ee57600080fd5b50565b600081359050612600816125da565b92915050565b600080fd5b600080fd5b600080fd5b60008083601f84011261262b5761262a612606565b5b8235905067ffffffffffffffff8111156126485761264761260b565b5b60208301915083600182028301111561266457612663612610565b5b9250929050565b60008060008060008060008060c0898b03121561268b5761268a612568565b5b60006126998b828c016125bb565b98505060206126aa8b828c016125bb565b97505060406126bb8b828c016125bb565b96505060606126cc8b828c016125f1565b955050608089013567ffffffffffffffff8111156126ed576126ec61256d565b5b6126f98b828c01612615565b945094505060a089013567ffffffffffffffff81111561271c5761271b61256d565b5b6127288b828c01612615565b92509250509295985092959890939650565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b61276f8161273a565b811461277a57600080fd5b50565b60008135905061278c81612766565b92915050565b6000602082840312156127a8576127a7612568565b5b60006127b68482850161277d565b91505092915050565b60008115159050919050565b6127d4816127bf565b82525050565b60006020820190506127ef60008301846127cb565b92915050565b600067ffffffffffffffff82169050919050565b612812816127f5565b811461281d57600080fd5b50565b60008135905061282f81612809565b92915050565b60006020828403121561284b5761284a612568565b5b600061285984828501612820565b91505092915050565b61286b816125d0565b82525050565b60006020820190506128866000830184612862565b92915050565b6000602082840312156128a2576128a1612568565b5b60006128b0848285016125bb565b91505092915050565b6000819050919050565b6128cc816128b9565b81146128d757600080fd5b50565b6000813590506128e9816128c3565b92915050565b60006020828403121561290557612904612568565b5b6000612913848285016128da565b91505092915050565b612925816128b9565b82525050565b6000602082019050612940600083018461291c565b92915050565b6000806040838503121561295d5761295c612568565b5b600061296b858286016128da565b925050602061297c858286016125bb565b9150509250929050565b600060ff82169050919050565b61299c81612986565b82525050565b60006020820190506129b76000830184612993565b92915050565b6129c681612592565b82525050565b60006020820190506129e160008301846129bd565b92915050565b600080604083850312156129fe576129fd612568565b5b6000612a0c858286016125bb565b9250506020612a1d85828601612820565b9150509250929050565b60008060408385031215612a3e57612a3d612568565b5b6000612a4c858286016128da565b9250506020612a5d858286016125f1565b9150509250929050565b600060208284031215612a7d57612a7c612568565b5b6000612a8b848285016125f1565b91505092915050565b612a9d81612986565b8114612aa857600080fd5b50565b600081359050612aba81612a94565b92915050565b60008060408385031215612ad757612ad6612568565b5b6000612ae585828601612aab565b9250506020612af685828601612820565b9150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000612b3a826125d0565b9150612b45836125d0565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff03821115612b7a57612b79612b00565b5b828201905092915050565b600082825260208201905092915050565b7f5061757361626c653a2070617573656400000000000000000000000000000000600082015250565b6000612bcc601083612b85565b9150612bd782612b96565b602082019050919050565b60006020820190508181036000830152612bfb81612bbf565b9050919050565b7f56657374696e6757616c6c65744d756c74694c696e6561723a2062656e65666960008201527f6369617279206973207a65726f20616464726573730000000000000000000000602082015250565b6000612c5e603583612b85565b9150612c6982612c02565b604082019050919050565b60006020820190508181036000830152612c8d81612c51565b9050919050565b7f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560008201527f20726f6c657320666f722073656c660000000000000000000000000000000000602082015250565b6000612cf0602f83612b85565b9150612cfb82612c94565b604082019050919050565b60006020820190508181036000830152612d1f81612ce3565b9050919050565b600081519050612d35816125da565b92915050565b600060208284031215612d5157612d50612568565b5b6000612d5f84828501612d26565b91505092915050565b7f4c6f636b61626c653a206e6f74206c6f636b6564000000000000000000000000600082015250565b6000612d9e601483612b85565b9150612da982612d68565b602082019050919050565b60006020820190508181036000830152612dcd81612d91565b9050919050565b7f4c6f636b61626c653a206e6f742074656d706f72617279206c6f636b65640000600082015250565b6000612e0a601e83612b85565b9150612e1582612dd4565b602082019050919050565b60006020820190508181036000830152612e3981612dfd565b9050919050565b7f4c6f636b61626c653a206c6f636b656400000000000000000000000000000000600082015250565b6000612e76601083612b85565b9150612e8182612e40565b602082019050919050565b60006020820190508181036000830152612ea581612e69565b9050919050565b6000612eb782612986565b9150612ec283612986565b92508260ff03821115612ed857612ed7612b00565b5b828201905092915050565b7f56657374696e6757616c6c65744d756c74694c696e6561723a2073746570506560008201527f7263656e7453756d2061626f7665203130302e20446f75626c6520636865636b60208201527f207363686564756c6520616e642f6f722072656275696c642069742e00000000604082015250565b6000612f65605c83612b85565b9150612f7082612ee3565b606082019050919050565b60006020820190508181036000830152612f9481612f58565b9050919050565b6000612fa6826127f5565b9150612fb1836127f5565b92508267ffffffffffffffff03821115612fce57612fcd612b00565b5b828201905092915050565b612fe2816127f5565b82525050565b6000604082019050612ffd6000830185612993565b61300a6020830184612fd9565b9392505050565b600061301c826125d0565b9150613027836125d0565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04831182151516156130605761305f612b00565b5b828202905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60006130d4826125d0565b915060008214156130e8576130e7612b00565b5b600182039050919050565b7f537472696e67733a20686578206c656e67746820696e73756666696369656e74600082015250565b6000613129602083612b85565b9150613134826130f3565b602082019050919050565b600060208201905081810360008301526131588161311c565b9050919050565b7f56657374696e6757616c6c65744d756c74694c696e6561723a2053636865647560008201527f6c6520697320656d7074792e2043616c6c20616464546f5363686564756c652860208201527f75696e7438207374657050657263656e742c2075696e7436342073746570447560408201527f726174696f6e292066697273742e000000000000000000000000000000000000606082015250565b6000613207606e83612b85565b91506132128261315f565b608082019050919050565b60006020820190508181036000830152613236816131fa565b9050919050565b6000613248826125d0565b9150613253836125d0565b92508282101561326657613265612b00565b5b828203905092915050565b600081905092915050565b7f416363657373436f6e74726f6c3a206163636f756e7420000000000000000000600082015250565b60006132b2601783613271565b91506132bd8261327c565b601782019050919050565b600081519050919050565b60005b838110156132f15780820151818401526020810190506132d6565b83811115613300576000848401525b50505050565b6000613311826132c8565b61331b8185613271565b935061332b8185602086016132d3565b80840191505092915050565b7f206973206d697373696e6720726f6c6520000000000000000000000000000000600082015250565b600061336d601183613271565b915061337882613337565b601182019050919050565b600061338e826132a5565b915061339a8285613306565b91506133a582613360565b91506133b18284613306565b91508190509392505050565b6000601f19601f8301169050919050565b60006133d9826132c8565b6133e38185612b85565b93506133f38185602086016132d3565b6133fc816133bd565b840191505092915050565b6000602082019050818103600083015261342181846133ce565b905092915050565b7f5061757361626c653a206e6f7420706175736564000000000000000000000000600082015250565b600061345f601483612b85565b915061346a82613429565b602082019050919050565b6000602082019050818103600083015261348e81613452565b9050919050565b60006040820190506134aa60008301856129bd565b6134b76020830184612862565b9392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b60006134f8826125d0565b9150613503836125d0565b925082613513576135126134be565b5b828204905092915050565b7f416464726573733a20696e73756666696369656e742062616c616e6365000000600082015250565b6000613554601d83612b85565b915061355f8261351e565b602082019050919050565b6000602082019050818103600083015261358381613547565b9050919050565b600081905092915050565b50565b60006135a560008361358a565b91506135b082613595565b600082019050919050565b60006135c682613598565b9150819050919050565b7f416464726573733a20756e61626c6520746f2073656e642076616c75652c207260008201527f6563697069656e74206d61792068617665207265766572746564000000000000602082015250565b600061362c603a83612b85565b9150613637826135d0565b604082019050919050565b6000602082019050818103600083015261365b8161361f565b9050919050565b61366b816127bf565b811461367657600080fd5b50565b60008151905061368881613662565b92915050565b6000602082840312156136a4576136a3612568565b5b60006136b284828501613679565b91505092915050565b7f5361666545524332303a204552433230206f7065726174696f6e20646964206e60008201527f6f74207375636365656400000000000000000000000000000000000000000000602082015250565b6000613717602a83612b85565b9150613722826136bb565b604082019050919050565b600060208201905081810360008301526137468161370a565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b7f416464726573733a20696e73756666696369656e742062616c616e636520666f60008201527f722063616c6c0000000000000000000000000000000000000000000000000000602082015250565b60006137d8602683612b85565b91506137e38261377c565b604082019050919050565b60006020820190508181036000830152613807816137cb565b9050919050565b7f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000600082015250565b6000613844601d83612b85565b915061384f8261380e565b602082019050919050565b6000602082019050818103600083015261387381613837565b9050919050565b600081519050919050565b60006138908261387a565b61389a818561358a565b93506138aa8185602086016132d3565b80840191505092915050565b60006138c28284613885565b91508190509291505056fea264697066735822122046f76d56dabb9be3a534ad5dae7053b558f983bb3029749c314dbdf50fe65ec364736f6c634300080c003300000000000000000000000089856f1072885df5c9a65c4d9bff96bc309f2cd300000000000000000000000000000000000000000000000000000000625d6c57
Deployed Bytecode
0x6080604052600436106101fc5760003560e01c806386d1a69f1161010d578063a66d1f05116100a0578063cf3090121161006f578063cf30901214610709578063d547741f14610734578063dd4670641461075d578063e63ab1e914610786578063ee5bafbe146107b157610203565b8063a66d1f0514610673578063bd2404be1461068a578063be9a6555146106a1578063ca15c873146106cc57610203565b806396132521116100dc57806396132521146105b55780639852595c146105e0578063a0ee45011461061d578063a217fddf1461064857610203565b806386d1a69f146104f95780639010d07c146105105780639051c5971461054d57806391d148541461057857610203565b806336568abe116101905780633f4ba83a1161015f5780633f4ba83a146104385780635c975abb1461044f5780635de43aec1461047a578063810ec23b146104a55780638456cb59146104e257610203565b806336568abe1461038e57806336f9820d146103b7578063371d4b7c146103e257806338af3eed1461040d57610203565b806319165587116101cc57806319165587146102d65780631c31f710146102ff578063248a9ca3146103285780632f2ff15d1461036557610203565b806223de291461020857806301ffc9a7146102315780630a17b06b1461026e5780630fb5a6b4146102ab57610203565b3661020357005b600080fd5b34801561021457600080fd5b5061022f600480360381019061022a919061266b565b6107da565b005b34801561023d57600080fd5b5061025860048036038101906102539190612792565b6107e4565b60405161026591906127da565b60405180910390f35b34801561027a57600080fd5b5061029560048036038101906102909190612835565b61085e565b6040516102a29190612871565b60405180910390f35b3480156102b757600080fd5b506102c0610883565b6040516102cd9190612871565b60405180910390f35b3480156102e257600080fd5b506102fd60048036038101906102f8919061288c565b6108ab565b005b34801561030b57600080fd5b506103266004803603810190610321919061288c565b6108ff565b005b34801561033457600080fd5b5061034f600480360381019061034a91906128ef565b610a1d565b60405161035c919061292b565b60405180910390f35b34801561037157600080fd5b5061038c60048036038101906103879190612946565b610a3d565b005b34801561039a57600080fd5b506103b560048036038101906103b09190612946565b610a66565b005b3480156103c357600080fd5b506103cc610ae9565b6040516103d9919061292b565b60405180910390f35b3480156103ee57600080fd5b506103f7610b0d565b60405161040491906129a2565b60405180910390f35b34801561041957600080fd5b50610422610b24565b60405161042f91906129cc565b60405180910390f35b34801561044457600080fd5b5061044d610b4e565b005b34801561045b57600080fd5b50610464610b8b565b60405161047191906127da565b60405180910390f35b34801561048657600080fd5b5061048f610ba2565b60405161049c919061292b565b60405180910390f35b3480156104b157600080fd5b506104cc60048036038101906104c791906129e7565b610bc6565b6040516104d99190612871565b60405180910390f35b3480156104ee57600080fd5b506104f7610c66565b005b34801561050557600080fd5b5061050e610ca3565b005b34801561051c57600080fd5b5061053760048036038101906105329190612a27565b610cf5565b60405161054491906129cc565b60405180910390f35b34801561055957600080fd5b50610562610d24565b60405161056f91906127da565b60405180910390f35b34801561058457600080fd5b5061059f600480360381019061059a9190612946565b610d3b565b6040516105ac91906127da565b60405180910390f35b3480156105c157600080fd5b506105ca610da6565b6040516105d79190612871565b60405180910390f35b3480156105ec57600080fd5b506106076004803603810190610602919061288c565b610daf565b6040516106149190612871565b60405180910390f35b34801561062957600080fd5b50610632610df8565b60405161063f9190612871565b60405180910390f35b34801561065457600080fd5b5061065d610e91565b60405161066a919061292b565b60405180910390f35b34801561067f57600080fd5b50610688610e98565b005b34801561069657600080fd5b5061069f610eb8565b005b3480156106ad57600080fd5b506106b6610fb5565b6040516106c39190612871565b60405180910390f35b3480156106d857600080fd5b506106f360048036038101906106ee91906128ef565b610fe7565b6040516107009190612871565b60405180910390f35b34801561071557600080fd5b5061071e61100b565b60405161072b91906127da565b60405180910390f35b34801561074057600080fd5b5061075b60048036038101906107569190612946565b611026565b005b34801561076957600080fd5b50610784600480360381019061077f9190612a67565b61104f565b005b34801561079257600080fd5b5061079b611071565b6040516107a8919061292b565b60405180910390f35b3480156107bd57600080fd5b506107d860048036038101906107d39190612ac0565b611095565b005b5050505050505050565b60007f5a05180f000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480610857575061085682611644565b5b9050919050565b600061087c61086b610da6565b476108769190612b2f565b836116be565b9050919050565b6000600860159054906101000a900467ffffffffffffffff1667ffffffffffffffff16905090565b6108b3610b8b565b156108f3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108ea90612be2565b60405180910390fd5b6108fc81611789565b50565b7fc59ec23d1c349d9976a1aba1c27c681cc250eafcb2aaf5c7c3be1d0e6827bfb16109318161092c611864565b61186c565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614156109a1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161099890612c74565b60405180910390fd5b81600860016101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507f446c2ff852422a9988931e1b4eed7290482a93fa1eff1e2fc9295efde537ffb082604051610a1191906129cc565b60405180910390a15050565b600060036000838152602001908152602001600020600101549050919050565b610a4682610a1d565b610a5781610a52611864565b61186c565b610a618383611909565b505050565b610a6e611864565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610adb576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ad290612d06565b60405180910390fd5b610ae5828261193d565b5050565b7f54217f7b85353d04ece159ebd69a45e9b8287dd2043746eaca469996a3d91aee81565b6000600860009054906101000a900460ff16905090565b6000600860019054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b7f65d7a28e3265b37a6474929f336521b332c1681b933f6cb9f3376673440d862a610b8081610b7b611864565b61186c565b610b88611971565b50565b6000600260009054906101000a900460ff16905090565b7fc59ec23d1c349d9976a1aba1c27c681cc250eafcb2aaf5c7c3be1d0e6827bfb181565b6000610c5e610bd484610daf565b8473ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b8152600401610c0d91906129cc565b602060405180830381865afa158015610c2a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c4e9190612d3b565b610c589190612b2f565b836116be565b905092915050565b7f65d7a28e3265b37a6474929f336521b332c1681b933f6cb9f3376673440d862a610c9881610c93611864565b61186c565b610ca0611a13565b50565b610cab610b8b565b15610ceb576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ce290612be2565b60405180910390fd5b610cf3611ab6565b565b6000610d1c8260046000868152602001908152602001600020611b3890919063ffffffff16565b905092915050565b6000600560009054906101000a900460ff16905090565b60006003600084815260200190815260200160002060000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b60008054905090565b6000600160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b6000610e0261100b565b610e41576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e3890612db4565b60405180910390fd5b610e49610d24565b15610e89576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e8090612e20565b60405180910390fd5b600654905090565b6000801b81565b6000801b610ead81610ea8611864565b61186c565b610eb5611b52565b50565b7f54217f7b85353d04ece159ebd69a45e9b8287dd2043746eaca469996a3d91aee610eea81610ee5611864565b61186c565b610ef261100b565b15610f32576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f2990612e8c565b60405180910390fd5b60076000610f4091906124f6565b6000600860006101000a81548160ff021916908360ff1602179055506000600860156101000a81548167ffffffffffffffff021916908367ffffffffffffffff1602179055507f145deea571fed01c02d67148dbd971d8f6daf03869c1b8094831bf4e3b2bf40e60405160405180910390a150565b60007f00000000000000000000000000000000000000000000000000000000625d6c5767ffffffffffffffff16905090565b600061100460046000848152602001908152602001600020611bf5565b9050919050565b6000611015610d24565b80611021575042600654115b905090565b61102f82610a1d565b6110408161103b611864565b61186c565b61104a838361193d565b505050565b6000801b6110648161105f611864565b61186c565b61106d82611c0a565b5050565b7f65d7a28e3265b37a6474929f336521b332c1681b933f6cb9f3376673440d862a81565b7f54217f7b85353d04ece159ebd69a45e9b8287dd2043746eaca469996a3d91aee6110c7816110c2611864565b61186c565b6110cf61100b565b1561110f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161110690612e8c565b60405180910390fd5b606483600860009054906101000a900460ff1661112c9190612eac565b60ff161115611170576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161116790612f7b565b60405180910390fd5b600760405180606001604052808560ff16815260200161118e610883565b611196610fb5565b6111a09190612b2f565b81526020018467ffffffffffffffff16815250908060018154018082558091505060019003906000526020600020906003020160009091909190915060008201518160000160006101000a81548160ff021916908360ff1602179055506020820151816001015560408201518160020160006101000a81548167ffffffffffffffff021916908367ffffffffffffffff160217905550505082600860008282829054906101000a900460ff166112569190612eac565b92506101000a81548160ff021916908360ff16021790555081600860158282829054906101000a900467ffffffffffffffff166112939190612f9b565b92506101000a81548167ffffffffffffffff021916908367ffffffffffffffff1602179055507f9126313d5e85a57af5bf04159f331340677115f459ea598e9c41936fff80b42e83836040516112ea929190612fe8565b60405180910390a1505050565b6113018282610d3b565b6113d45760016003600084815260200190815260200160002060000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908315150217905550611379611864565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45b5050565b6000611400836000018373ffffffffffffffffffffffffffffffffffffffff1660001b611ca7565b905092915050565b60606000600283600261141b9190613011565b6114259190612b2f565b67ffffffffffffffff81111561143e5761143d61306b565b5b6040519080825280601f01601f1916602001820160405280156114705781602001600182028036833780820191505090505b5090507f3000000000000000000000000000000000000000000000000000000000000000816000815181106114a8576114a761309a565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053507f78000000000000000000000000000000000000000000000000000000000000008160018151811061150c5761150b61309a565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053506000600184600261154c9190613011565b6115569190612b2f565b90505b60018111156115f6577f3031323334353637383961626364656600000000000000000000000000000000600f8616601081106115985761159761309a565b5b1a60f81b8282815181106115af576115ae61309a565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600485901c9450806115ef906130c9565b9050611559565b506000841461163a576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116319061313f565b60405180910390fd5b8091505092915050565b60007f7965db0b000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614806116b757506116b682611d17565b5b9050919050565b60008060078054905011611707576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116fe9061321d565b60405180910390fd5b60008060005b600782815481106117215761172061309a565b5b9060005260206000209060030201905061173c818787611d81565b836117479190612b2f565b92506001826117569190612b2f565b915080600101548567ffffffffffffffff16118015611779575060078054905082105b61170d5782935050505092915050565b600061179482610daf565b61179e8342610bc6565b6117a8919061323d565b905080600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546117f99190612b2f565b925050819055508173ffffffffffffffffffffffffffffffffffffffff167fc0e523490dd523c33b1878c9eb14ff46991e3f5b2cd33710918618f2a39cba1b826040516118469190612871565b60405180910390a26118608261185a610b24565b83611e7a565b5050565b600033905090565b6118768282610d3b565b6119055761189b8173ffffffffffffffffffffffffffffffffffffffff166014611408565b6118a98360001c6020611408565b6040516020016118ba929190613383565b6040516020818303038152906040526040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016118fc9190613407565b60405180910390fd5b5050565b61191382826112f7565b61193881600460008581526020019081526020016000206113d890919063ffffffff16565b505050565b6119478282611f00565b61196c8160046000858152602001908152602001600020611fe290919063ffffffff16565b505050565b611979610b8b565b6119b8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016119af90613475565b60405180910390fd5b6000600260006101000a81548160ff0219169083151502179055507f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa6119fc611864565b604051611a0991906129cc565b60405180910390a1565b611a1b610b8b565b15611a5b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611a5290612be2565b60405180910390fd5b6001600260006101000a81548160ff0219169083151502179055507f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258611a9f611864565b604051611aac91906129cc565b60405180910390a1565b6000611ac0610da6565b611ac94261085e565b611ad3919061323d565b905080600080828254611ae69190612b2f565b925050819055507fda9d4e5f101b8b9b1c5b76d0c5a9f7923571acfc02376aa076b75a8c080c956b81604051611b1c9190612871565b60405180910390a1611b35611b2f610b24565b82612012565b50565b6000611b478360000183612106565b60001c905092915050565b611b5a61100b565b15611b9a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611b9190612e8c565b60405180910390fd5b6001600560006101000a81548160ff0219169083151502179055507fec6267e1ebfb5a47f9aceaa24ea9a743edce3f5159589b9e11239aeec797f2d5611bde611864565b604051611beb91906129cc565b60405180910390a1565b6000611c0382600001612131565b9050919050565b611c1261100b565b15611c52576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611c4990612e8c565b60405180910390fd5b8042611c5e9190612b2f565b6006819055507f9f1ec8c880f76798e7b793325d625e9b60e4082a553c98f42b6cda368dd60008611c8d611864565b82604051611c9c929190613495565b60405180910390a150565b6000611cb38383612142565b611d0c578260000182908060018154018082558091505060019003906000526020600020016000909190919091505582600001805490508360010160008481526020019081526020016000208190555060019050611d11565b600090505b92915050565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b60008060648560000160009054906101000a900460ff1660ff1685611da69190613011565b611db091906134ed565b905084600101548367ffffffffffffffff161015611dd2576000915050611e73565b8460020160009054906101000a900467ffffffffffffffff1667ffffffffffffffff168560010154611e049190612b2f565b8367ffffffffffffffff1610611e1d5780915050611e73565b8460020160009054906101000a900467ffffffffffffffff1667ffffffffffffffff1685600101548467ffffffffffffffff16611e5a919061323d565b82611e659190613011565b611e6f91906134ed565b9150505b9392505050565b611efb8363a9059cbb60e01b8484604051602401611e99929190613495565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050612165565b505050565b611f0a8282610d3b565b15611fde5760006003600084815260200190815260200160002060000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908315150217905550611f83611864565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16837ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b60405160405180910390a45b5050565b600061200a836000018373ffffffffffffffffffffffffffffffffffffffff1660001b61222c565b905092915050565b80471015612055576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161204c9061356a565b60405180910390fd5b60008273ffffffffffffffffffffffffffffffffffffffff168260405161207b906135bb565b60006040518083038185875af1925050503d80600081146120b8576040519150601f19603f3d011682016040523d82523d6000602084013e6120bd565b606091505b5050905080612101576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016120f890613642565b60405180910390fd5b505050565b600082600001828154811061211e5761211d61309a565b5b9060005260206000200154905092915050565b600081600001805490509050919050565b600080836001016000848152602001908152602001600020541415905092915050565b60006121c7826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166123409092919063ffffffff16565b905060008151111561222757808060200190518101906121e7919061368e565b612226576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161221d9061372d565b60405180910390fd5b5b505050565b6000808360010160008481526020019081526020016000205490506000811461233457600060018261225e919061323d565b9050600060018660000180549050612276919061323d565b90508181146122e55760008660000182815481106122975761229661309a565b5b90600052602060002001549050808760000184815481106122bb576122ba61309a565b5b90600052602060002001819055508387600101600083815260200190815260200160002081905550505b856000018054806122f9576122f861374d565b5b60019003818190600052602060002001600090559055856001016000868152602001908152602001600020600090556001935050505061233a565b60009150505b92915050565b606061234f8484600085612358565b90509392505050565b60608247101561239d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612394906137ee565b60405180910390fd5b6123a68561246c565b6123e5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016123dc9061385a565b60405180910390fd5b6000808673ffffffffffffffffffffffffffffffffffffffff16858760405161240e91906138b6565b60006040518083038185875af1925050503d806000811461244b576040519150601f19603f3d011682016040523d82523d6000602084013e612450565b606091505b509150915061246082828661248f565b92505050949350505050565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b6060831561249f578290506124ef565b6000835111156124b25782518084602001fd5b816040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016124e69190613407565b60405180910390fd5b9392505050565b5080546000825560030290600052602060002090810190612517919061251a565b50565b5b8082111561256457600080820160006101000a81549060ff021916905560018201600090556002820160006101000a81549067ffffffffffffffff02191690555060030161251b565b5090565b600080fd5b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600061259d82612572565b9050919050565b6125ad81612592565b81146125b857600080fd5b50565b6000813590506125ca816125a4565b92915050565b6000819050919050565b6125e3816125d0565b81146125ee57600080fd5b50565b600081359050612600816125da565b92915050565b600080fd5b600080fd5b600080fd5b60008083601f84011261262b5761262a612606565b5b8235905067ffffffffffffffff8111156126485761264761260b565b5b60208301915083600182028301111561266457612663612610565b5b9250929050565b60008060008060008060008060c0898b03121561268b5761268a612568565b5b60006126998b828c016125bb565b98505060206126aa8b828c016125bb565b97505060406126bb8b828c016125bb565b96505060606126cc8b828c016125f1565b955050608089013567ffffffffffffffff8111156126ed576126ec61256d565b5b6126f98b828c01612615565b945094505060a089013567ffffffffffffffff81111561271c5761271b61256d565b5b6127288b828c01612615565b92509250509295985092959890939650565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b61276f8161273a565b811461277a57600080fd5b50565b60008135905061278c81612766565b92915050565b6000602082840312156127a8576127a7612568565b5b60006127b68482850161277d565b91505092915050565b60008115159050919050565b6127d4816127bf565b82525050565b60006020820190506127ef60008301846127cb565b92915050565b600067ffffffffffffffff82169050919050565b612812816127f5565b811461281d57600080fd5b50565b60008135905061282f81612809565b92915050565b60006020828403121561284b5761284a612568565b5b600061285984828501612820565b91505092915050565b61286b816125d0565b82525050565b60006020820190506128866000830184612862565b92915050565b6000602082840312156128a2576128a1612568565b5b60006128b0848285016125bb565b91505092915050565b6000819050919050565b6128cc816128b9565b81146128d757600080fd5b50565b6000813590506128e9816128c3565b92915050565b60006020828403121561290557612904612568565b5b6000612913848285016128da565b91505092915050565b612925816128b9565b82525050565b6000602082019050612940600083018461291c565b92915050565b6000806040838503121561295d5761295c612568565b5b600061296b858286016128da565b925050602061297c858286016125bb565b9150509250929050565b600060ff82169050919050565b61299c81612986565b82525050565b60006020820190506129b76000830184612993565b92915050565b6129c681612592565b82525050565b60006020820190506129e160008301846129bd565b92915050565b600080604083850312156129fe576129fd612568565b5b6000612a0c858286016125bb565b9250506020612a1d85828601612820565b9150509250929050565b60008060408385031215612a3e57612a3d612568565b5b6000612a4c858286016128da565b9250506020612a5d858286016125f1565b9150509250929050565b600060208284031215612a7d57612a7c612568565b5b6000612a8b848285016125f1565b91505092915050565b612a9d81612986565b8114612aa857600080fd5b50565b600081359050612aba81612a94565b92915050565b60008060408385031215612ad757612ad6612568565b5b6000612ae585828601612aab565b9250506020612af685828601612820565b9150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000612b3a826125d0565b9150612b45836125d0565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff03821115612b7a57612b79612b00565b5b828201905092915050565b600082825260208201905092915050565b7f5061757361626c653a2070617573656400000000000000000000000000000000600082015250565b6000612bcc601083612b85565b9150612bd782612b96565b602082019050919050565b60006020820190508181036000830152612bfb81612bbf565b9050919050565b7f56657374696e6757616c6c65744d756c74694c696e6561723a2062656e65666960008201527f6369617279206973207a65726f20616464726573730000000000000000000000602082015250565b6000612c5e603583612b85565b9150612c6982612c02565b604082019050919050565b60006020820190508181036000830152612c8d81612c51565b9050919050565b7f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560008201527f20726f6c657320666f722073656c660000000000000000000000000000000000602082015250565b6000612cf0602f83612b85565b9150612cfb82612c94565b604082019050919050565b60006020820190508181036000830152612d1f81612ce3565b9050919050565b600081519050612d35816125da565b92915050565b600060208284031215612d5157612d50612568565b5b6000612d5f84828501612d26565b91505092915050565b7f4c6f636b61626c653a206e6f74206c6f636b6564000000000000000000000000600082015250565b6000612d9e601483612b85565b9150612da982612d68565b602082019050919050565b60006020820190508181036000830152612dcd81612d91565b9050919050565b7f4c6f636b61626c653a206e6f742074656d706f72617279206c6f636b65640000600082015250565b6000612e0a601e83612b85565b9150612e1582612dd4565b602082019050919050565b60006020820190508181036000830152612e3981612dfd565b9050919050565b7f4c6f636b61626c653a206c6f636b656400000000000000000000000000000000600082015250565b6000612e76601083612b85565b9150612e8182612e40565b602082019050919050565b60006020820190508181036000830152612ea581612e69565b9050919050565b6000612eb782612986565b9150612ec283612986565b92508260ff03821115612ed857612ed7612b00565b5b828201905092915050565b7f56657374696e6757616c6c65744d756c74694c696e6561723a2073746570506560008201527f7263656e7453756d2061626f7665203130302e20446f75626c6520636865636b60208201527f207363686564756c6520616e642f6f722072656275696c642069742e00000000604082015250565b6000612f65605c83612b85565b9150612f7082612ee3565b606082019050919050565b60006020820190508181036000830152612f9481612f58565b9050919050565b6000612fa6826127f5565b9150612fb1836127f5565b92508267ffffffffffffffff03821115612fce57612fcd612b00565b5b828201905092915050565b612fe2816127f5565b82525050565b6000604082019050612ffd6000830185612993565b61300a6020830184612fd9565b9392505050565b600061301c826125d0565b9150613027836125d0565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04831182151516156130605761305f612b00565b5b828202905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60006130d4826125d0565b915060008214156130e8576130e7612b00565b5b600182039050919050565b7f537472696e67733a20686578206c656e67746820696e73756666696369656e74600082015250565b6000613129602083612b85565b9150613134826130f3565b602082019050919050565b600060208201905081810360008301526131588161311c565b9050919050565b7f56657374696e6757616c6c65744d756c74694c696e6561723a2053636865647560008201527f6c6520697320656d7074792e2043616c6c20616464546f5363686564756c652860208201527f75696e7438207374657050657263656e742c2075696e7436342073746570447560408201527f726174696f6e292066697273742e000000000000000000000000000000000000606082015250565b6000613207606e83612b85565b91506132128261315f565b608082019050919050565b60006020820190508181036000830152613236816131fa565b9050919050565b6000613248826125d0565b9150613253836125d0565b92508282101561326657613265612b00565b5b828203905092915050565b600081905092915050565b7f416363657373436f6e74726f6c3a206163636f756e7420000000000000000000600082015250565b60006132b2601783613271565b91506132bd8261327c565b601782019050919050565b600081519050919050565b60005b838110156132f15780820151818401526020810190506132d6565b83811115613300576000848401525b50505050565b6000613311826132c8565b61331b8185613271565b935061332b8185602086016132d3565b80840191505092915050565b7f206973206d697373696e6720726f6c6520000000000000000000000000000000600082015250565b600061336d601183613271565b915061337882613337565b601182019050919050565b600061338e826132a5565b915061339a8285613306565b91506133a582613360565b91506133b18284613306565b91508190509392505050565b6000601f19601f8301169050919050565b60006133d9826132c8565b6133e38185612b85565b93506133f38185602086016132d3565b6133fc816133bd565b840191505092915050565b6000602082019050818103600083015261342181846133ce565b905092915050565b7f5061757361626c653a206e6f7420706175736564000000000000000000000000600082015250565b600061345f601483612b85565b915061346a82613429565b602082019050919050565b6000602082019050818103600083015261348e81613452565b9050919050565b60006040820190506134aa60008301856129bd565b6134b76020830184612862565b9392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b60006134f8826125d0565b9150613503836125d0565b925082613513576135126134be565b5b828204905092915050565b7f416464726573733a20696e73756666696369656e742062616c616e6365000000600082015250565b6000613554601d83612b85565b915061355f8261351e565b602082019050919050565b6000602082019050818103600083015261358381613547565b9050919050565b600081905092915050565b50565b60006135a560008361358a565b91506135b082613595565b600082019050919050565b60006135c682613598565b9150819050919050565b7f416464726573733a20756e61626c6520746f2073656e642076616c75652c207260008201527f6563697069656e74206d61792068617665207265766572746564000000000000602082015250565b600061362c603a83612b85565b9150613637826135d0565b604082019050919050565b6000602082019050818103600083015261365b8161361f565b9050919050565b61366b816127bf565b811461367657600080fd5b50565b60008151905061368881613662565b92915050565b6000602082840312156136a4576136a3612568565b5b60006136b284828501613679565b91505092915050565b7f5361666545524332303a204552433230206f7065726174696f6e20646964206e60008201527f6f74207375636365656400000000000000000000000000000000000000000000602082015250565b6000613717602a83612b85565b9150613722826136bb565b604082019050919050565b600060208201905081810360008301526137468161370a565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b7f416464726573733a20696e73756666696369656e742062616c616e636520666f60008201527f722063616c6c0000000000000000000000000000000000000000000000000000602082015250565b60006137d8602683612b85565b91506137e38261377c565b604082019050919050565b60006020820190508181036000830152613807816137cb565b9050919050565b7f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000600082015250565b6000613844601d83612b85565b915061384f8261380e565b602082019050919050565b6000602082019050818103600083015261387381613837565b9050919050565b600081519050919050565b60006138908261387a565b61389a818561358a565b93506138aa8185602086016132d3565b80840191505092915050565b60006138c28284613885565b91508190509291505056fea264697066735822122046f76d56dabb9be3a534ad5dae7053b558f983bb3029749c314dbdf50fe65ec364736f6c634300080c0033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
00000000000000000000000089856f1072885df5c9a65c4d9bff96bc309f2cd300000000000000000000000000000000000000000000000000000000625d6c57
-----Decoded View---------------
Arg [0] : beneficiaryAddress (address): 0x89856F1072885Df5c9a65c4D9bFf96bc309F2cD3
Arg [1] : startTimestamp (uint64): 1650289751
-----Encoded View---------------
2 Constructor Arguments found :
Arg [0] : 00000000000000000000000089856f1072885df5c9a65c4d9bff96bc309f2cd3
Arg [1] : 00000000000000000000000000000000000000000000000000000000625d6c57
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 30 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
Loading...
Loading
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.