Source Code
Overview
ETH Balance
0 ETH
More Info
ContractCreator
Multichain Info
N/A
Loading...
Loading
This contract may be a proxy contract. Click on More Options and select Is this a proxy? to confirm and enable the "Read as Proxy" & "Write as Proxy" tabs.
Contract Name:
DAOContract
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
pragma solidity ^0.8.12;
import "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol";
import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";
import "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol";
import "@openzeppelin/contracts/utils/Strings.sol";
import "./daoProvider.sol";
import "./daoStructures.sol";
//import "hardhat/console.sol";
contract DAOContract is Initializable, OwnableUpgradeable, UUPSUpgradeable {
uint256 voteInitiateThreshold;
mapping(string => uint256) private voteEndHeight;
mapping(string => uint256) public currentYesVotes;
mapping(string => uint256) public currentNoVotes;
mapping(string => bool) private alreadyVoted;
mapping(string => mapping(address => uint256)) private noVotesFromCaller;
mapping(string => mapping(address => uint256)) private yesVotesFromCaller;
mapping(string => string) private voteTitles;
mapping(string => string) private voteDescriptions;
mapping(string => string) private voteLinks;
mapping(string => address) private voteInitiators;
uint counter;
DAOProvider daoProvider;
string[] private votes;
function initialize(address daoProviderAddress) external initializer onlyProxy {
__Ownable_init();
voteInitiateThreshold = 1000000000000000000;
daoProvider = DAOProvider(daoProviderAddress);
counter = 0;
}
function registerVote(string memory title, string memory desc, string memory link) public {
string memory initiator = addressToString(tx.origin);
string memory voteId = string.concat(initiator, "_");
voteId = string.concat(voteId, Strings.toString(counter));
require(getDAOPowerOfUser(msg.sender) >= voteInitiateThreshold, "User has not been active enough on the platform!");
voteEndHeight[voteId] = block.number + 7200 * 30;
voteTitles[voteId] = title;
voteDescriptions[voteId] = desc;
voteLinks[voteId] = link;
voteInitiators[voteId] = msg.sender;
currentYesVotes[voteId] = 0;
currentNoVotes[voteId] = 0;
votes.push(voteId);
counter ++;
}
function yes(string memory voteId) public {
require(getCurrentYesVotesForId(voteId) >= 0, "Vote not found!");
require(getVoteEndHeight(voteId) <= block.number, "Vote no longer active!");
require(!getAlreadyVoted(voteId, msg.sender), "User already voted!");
uint256 daoPowerOfUser = getDAOPowerOfUser(msg.sender);
currentYesVotes[voteId] += daoPowerOfUser;
alreadyVoted[voteIdAndUser(voteId, msg.sender)] = true;
yesVotesFromCaller[voteId][msg.sender] = daoPowerOfUser;
}
function no(string memory voteId) public {
require(getCurrentNoVotesForId(voteId) >= 0, "Vote not found!");
require(getVoteEndHeight(voteId) <= block.number, "Vote no longer active!");
require(!getAlreadyVoted(voteId, msg.sender), "Address already voted!");
uint256 daoPowerOfUser = getDAOPowerOfUser(msg.sender);
currentNoVotes[voteId] += daoPowerOfUser;
alreadyVoted[voteIdAndUser(voteId, msg.sender)] = true;
noVotesFromCaller[voteId][msg.sender] = daoPowerOfUser;
}
function retractVote(string memory voteId) public {
require(getCurrentYesVotesForId(voteId) >= 0 && getCurrentNoVotesForId(voteId) >= 0, "No active vote for this vote id!");
require(getVoteEndHeight(voteId) <= block.number, "Vote no longer active!");
require(noVotesFromCaller[voteId][msg.sender] > 0 || yesVotesFromCaller[voteId][msg.sender] > 0, "Users has not voted for this vote!");
currentNoVotes[voteId] -= noVotesFromCaller[voteId][msg.sender];
currentYesVotes[voteId] -= yesVotesFromCaller[voteId][msg.sender];
noVotesFromCaller[voteId][msg.sender] = 0;
yesVotesFromCaller[voteId][msg.sender] = 0;
alreadyVoted[voteIdAndUser(voteId, msg.sender)] = false;
}
function voteIdAndUser(string memory voteId, address user) private pure returns (string memory) {
return string(abi.encodePacked(voteId, "_", addressToString(user)));
}
function getLastCounter() external view returns (uint) {
return counter - 1;
}
function addressToString(address addr) public pure returns (string memory) {
return Strings.toHexString(uint256(uint160(addr)), 20);
}
function getVoteEndHeight(string memory voteId) public view returns (uint256) {
return voteEndHeight[voteId];
}
function getDAOPowerOfUser(address user) public view returns (uint256) {
return daoProvider.getDaoParticipationForUser(addressToString(user));
}
function getAlreadyVoted(string memory voteId, address user) public view returns (bool) {
return alreadyVoted[voteIdAndUser(voteId, user)];
}
function getCurrentYesVotesForId(string memory voteId) public view returns (uint256) {
return currentYesVotes[voteId];
}
function getCurrentNoVotesForId(string memory voteId) public view returns (uint256) {
return currentNoVotes[voteId];
}
function getVoteIds() external view returns (string[] memory) {
return votes;
}
function getVotes() external view returns (Vote[] memory) {
Vote memory vote;
Vote[] memory allVotes = new Vote[](votes.length);
string memory voteId;
for (uint i = 0; i < votes.length; i++) {
voteId = votes[i];
vote = Vote({
title: voteTitles[voteId],
description: voteDescriptions[voteId],
link: voteLinks[voteId],
endHeight: voteEndHeight[voteId],
currentYesVotes: currentYesVotes[voteId],
currentNoVotes: currentNoVotes[voteId],
initiator: voteInitiators[voteId],
id: voteId
});
allVotes[i] = vote;
}
return allVotes;
}
function getVoteTitle(string memory voteId) external view returns (string memory) {
return voteTitles[voteId];
}
function getVoteDescription(string memory voteId) external view returns (string memory) {
return voteDescriptions[voteId];
}
function getLinkForVote(string memory voteId) external view returns (string memory) {
return voteLinks[voteId];
}
function _authorizeUpgrade(address newImplementation) internal override onlyOwner {}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable.sol)
pragma solidity ^0.8.0;
import "../utils/ContextUpgradeable.sol";
import "../proxy/utils/Initializable.sol";
/**
* @dev Contract module which provides a basic access control mechanism, where
* there is an account (an owner) that can be granted exclusive access to
* specific functions.
*
* By default, the owner account will be the one that deploys the contract. This
* can later be changed with {transferOwnership}.
*
* This module is used through inheritance. It will make available the modifier
* `onlyOwner`, which can be applied to your functions to restrict their use to
* the owner.
*/
abstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {
address private _owner;
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
/**
* @dev Initializes the contract setting the deployer as the initial owner.
*/
function __Ownable_init() internal onlyInitializing {
__Ownable_init_unchained();
}
function __Ownable_init_unchained() internal onlyInitializing {
_transferOwnership(_msgSender());
}
/**
* @dev Throws if called by any account other than the owner.
*/
modifier onlyOwner() {
_checkOwner();
_;
}
/**
* @dev Returns the address of the current owner.
*/
function owner() public view virtual returns (address) {
return _owner;
}
/**
* @dev Throws if the sender is not the owner.
*/
function _checkOwner() internal view virtual {
require(owner() == _msgSender(), "Ownable: caller is not the owner");
}
/**
* @dev Leaves the contract without owner. It will not be possible to call
* `onlyOwner` functions. Can only be called by the current owner.
*
* NOTE: Renouncing ownership will leave the contract without an owner,
* thereby disabling any functionality that is only available to the owner.
*/
function renounceOwnership() public virtual onlyOwner {
_transferOwnership(address(0));
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Can only be called by the current owner.
*/
function transferOwnership(address newOwner) public virtual onlyOwner {
require(newOwner != address(0), "Ownable: new owner is the zero address");
_transferOwnership(newOwner);
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Internal function without access restriction.
*/
function _transferOwnership(address newOwner) internal virtual {
address oldOwner = _owner;
_owner = newOwner;
emit OwnershipTransferred(oldOwner, newOwner);
}
/**
* @dev This empty reserved space is put in place to allow future versions to add new
* variables without shifting down storage in the inheritance chain.
* See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps
*/
uint256[49] private __gap;
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.5.0) (interfaces/draft-IERC1822.sol)
pragma solidity ^0.8.0;
/**
* @dev ERC1822: Universal Upgradeable Proxy Standard (UUPS) documents a method for upgradeability through a simplified
* proxy whose upgrades are fully controlled by the current implementation.
*/
interface IERC1822ProxiableUpgradeable {
/**
* @dev Returns the storage slot that the proxiable contract assumes is being used to store the implementation
* address.
*
* IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks
* bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this
* function revert if invoked through a proxy.
*/
function proxiableUUID() external view returns (bytes32);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (interfaces/IERC1967.sol)
pragma solidity ^0.8.0;
/**
* @dev ERC-1967: Proxy Storage Slots. This interface contains the events defined in the ERC.
*
* _Available since v4.8.3._
*/
interface IERC1967Upgradeable {
/**
* @dev Emitted when the implementation is upgraded.
*/
event Upgraded(address indexed implementation);
/**
* @dev Emitted when the admin account has changed.
*/
event AdminChanged(address previousAdmin, address newAdmin);
/**
* @dev Emitted when the beacon is changed.
*/
event BeaconUpgraded(address indexed beacon);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (proxy/beacon/IBeacon.sol)
pragma solidity ^0.8.0;
/**
* @dev This is the interface that {BeaconProxy} expects of its beacon.
*/
interface IBeaconUpgradeable {
/**
* @dev Must return an address that can be used as a delegate call target.
*
* {BeaconProxy} will check that this address is a contract.
*/
function implementation() external view returns (address);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (proxy/ERC1967/ERC1967Upgrade.sol)
pragma solidity ^0.8.2;
import "../beacon/IBeaconUpgradeable.sol";
import "../../interfaces/IERC1967Upgradeable.sol";
import "../../interfaces/draft-IERC1822Upgradeable.sol";
import "../../utils/AddressUpgradeable.sol";
import "../../utils/StorageSlotUpgradeable.sol";
import "../utils/Initializable.sol";
/**
* @dev This abstract contract provides getters and event emitting update functions for
* https://eips.ethereum.org/EIPS/eip-1967[EIP1967] slots.
*
* _Available since v4.1._
*/
abstract contract ERC1967UpgradeUpgradeable is Initializable, IERC1967Upgradeable {
function __ERC1967Upgrade_init() internal onlyInitializing {
}
function __ERC1967Upgrade_init_unchained() internal onlyInitializing {
}
// This is the keccak-256 hash of "eip1967.proxy.rollback" subtracted by 1
bytes32 private constant _ROLLBACK_SLOT = 0x4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd9143;
/**
* @dev Storage slot with the address of the current implementation.
* This is the keccak-256 hash of "eip1967.proxy.implementation" subtracted by 1, and is
* validated in the constructor.
*/
bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;
/**
* @dev Returns the current implementation address.
*/
function _getImplementation() internal view returns (address) {
return StorageSlotUpgradeable.getAddressSlot(_IMPLEMENTATION_SLOT).value;
}
/**
* @dev Stores a new address in the EIP1967 implementation slot.
*/
function _setImplementation(address newImplementation) private {
require(AddressUpgradeable.isContract(newImplementation), "ERC1967: new implementation is not a contract");
StorageSlotUpgradeable.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;
}
/**
* @dev Perform implementation upgrade
*
* Emits an {Upgraded} event.
*/
function _upgradeTo(address newImplementation) internal {
_setImplementation(newImplementation);
emit Upgraded(newImplementation);
}
/**
* @dev Perform implementation upgrade with additional setup call.
*
* Emits an {Upgraded} event.
*/
function _upgradeToAndCall(address newImplementation, bytes memory data, bool forceCall) internal {
_upgradeTo(newImplementation);
if (data.length > 0 || forceCall) {
AddressUpgradeable.functionDelegateCall(newImplementation, data);
}
}
/**
* @dev Perform implementation upgrade with security checks for UUPS proxies, and additional setup call.
*
* Emits an {Upgraded} event.
*/
function _upgradeToAndCallUUPS(address newImplementation, bytes memory data, bool forceCall) internal {
// Upgrades from old implementations will perform a rollback test. This test requires the new
// implementation to upgrade back to the old, non-ERC1822 compliant, implementation. Removing
// this special case will break upgrade paths from old UUPS implementation to new ones.
if (StorageSlotUpgradeable.getBooleanSlot(_ROLLBACK_SLOT).value) {
_setImplementation(newImplementation);
} else {
try IERC1822ProxiableUpgradeable(newImplementation).proxiableUUID() returns (bytes32 slot) {
require(slot == _IMPLEMENTATION_SLOT, "ERC1967Upgrade: unsupported proxiableUUID");
} catch {
revert("ERC1967Upgrade: new implementation is not UUPS");
}
_upgradeToAndCall(newImplementation, data, forceCall);
}
}
/**
* @dev Storage slot with the admin of the contract.
* This is the keccak-256 hash of "eip1967.proxy.admin" subtracted by 1, and is
* validated in the constructor.
*/
bytes32 internal constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;
/**
* @dev Returns the current admin.
*/
function _getAdmin() internal view returns (address) {
return StorageSlotUpgradeable.getAddressSlot(_ADMIN_SLOT).value;
}
/**
* @dev Stores a new address in the EIP1967 admin slot.
*/
function _setAdmin(address newAdmin) private {
require(newAdmin != address(0), "ERC1967: new admin is the zero address");
StorageSlotUpgradeable.getAddressSlot(_ADMIN_SLOT).value = newAdmin;
}
/**
* @dev Changes the admin of the proxy.
*
* Emits an {AdminChanged} event.
*/
function _changeAdmin(address newAdmin) internal {
emit AdminChanged(_getAdmin(), newAdmin);
_setAdmin(newAdmin);
}
/**
* @dev The storage slot of the UpgradeableBeacon contract which defines the implementation for this proxy.
* This is bytes32(uint256(keccak256('eip1967.proxy.beacon')) - 1)) and is validated in the constructor.
*/
bytes32 internal constant _BEACON_SLOT = 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50;
/**
* @dev Returns the current beacon.
*/
function _getBeacon() internal view returns (address) {
return StorageSlotUpgradeable.getAddressSlot(_BEACON_SLOT).value;
}
/**
* @dev Stores a new beacon in the EIP1967 beacon slot.
*/
function _setBeacon(address newBeacon) private {
require(AddressUpgradeable.isContract(newBeacon), "ERC1967: new beacon is not a contract");
require(
AddressUpgradeable.isContract(IBeaconUpgradeable(newBeacon).implementation()),
"ERC1967: beacon implementation is not a contract"
);
StorageSlotUpgradeable.getAddressSlot(_BEACON_SLOT).value = newBeacon;
}
/**
* @dev Perform beacon upgrade with additional setup call. Note: This upgrades the address of the beacon, it does
* not upgrade the implementation contained in the beacon (see {UpgradeableBeacon-_setImplementation} for that).
*
* Emits a {BeaconUpgraded} event.
*/
function _upgradeBeaconToAndCall(address newBeacon, bytes memory data, bool forceCall) internal {
_setBeacon(newBeacon);
emit BeaconUpgraded(newBeacon);
if (data.length > 0 || forceCall) {
AddressUpgradeable.functionDelegateCall(IBeaconUpgradeable(newBeacon).implementation(), data);
}
}
/**
* @dev This empty reserved space is put in place to allow future versions to add new
* variables without shifting down storage in the inheritance chain.
* See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps
*/
uint256[50] private __gap;
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (proxy/utils/Initializable.sol)
pragma solidity ^0.8.2;
import "../../utils/AddressUpgradeable.sol";
/**
* @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed
* behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an
* external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer
* function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.
*
* The initialization functions use a version number. Once a version number is used, it is consumed and cannot be
* reused. This mechanism prevents re-execution of each "step" but allows the creation of new initialization steps in
* case an upgrade adds a module that needs to be initialized.
*
* For example:
*
* [.hljs-theme-light.nopadding]
* ```solidity
* contract MyToken is ERC20Upgradeable {
* function initialize() initializer public {
* __ERC20_init("MyToken", "MTK");
* }
* }
*
* contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {
* function initializeV2() reinitializer(2) public {
* __ERC20Permit_init("MyToken");
* }
* }
* ```
*
* TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as
* possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.
*
* CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure
* that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.
*
* [CAUTION]
* ====
* Avoid leaving a contract uninitialized.
*
* An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation
* contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke
* the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:
*
* [.hljs-theme-light.nopadding]
* ```
* /// @custom:oz-upgrades-unsafe-allow constructor
* constructor() {
* _disableInitializers();
* }
* ```
* ====
*/
abstract contract Initializable {
/**
* @dev Indicates that the contract has been initialized.
* @custom:oz-retyped-from bool
*/
uint8 private _initialized;
/**
* @dev Indicates that the contract is in the process of being initialized.
*/
bool private _initializing;
/**
* @dev Triggered when the contract has been initialized or reinitialized.
*/
event Initialized(uint8 version);
/**
* @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,
* `onlyInitializing` functions can be used to initialize parent contracts.
*
* Similar to `reinitializer(1)`, except that functions marked with `initializer` can be nested in the context of a
* constructor.
*
* Emits an {Initialized} event.
*/
modifier initializer() {
bool isTopLevelCall = !_initializing;
require(
(isTopLevelCall && _initialized < 1) || (!AddressUpgradeable.isContract(address(this)) && _initialized == 1),
"Initializable: contract is already initialized"
);
_initialized = 1;
if (isTopLevelCall) {
_initializing = true;
}
_;
if (isTopLevelCall) {
_initializing = false;
emit Initialized(1);
}
}
/**
* @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the
* contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be
* used to initialize parent contracts.
*
* A reinitializer may be used after the original initialization step. This is essential to configure modules that
* are added through upgrades and that require initialization.
*
* When `version` is 1, this modifier is similar to `initializer`, except that functions marked with `reinitializer`
* cannot be nested. If one is invoked in the context of another, execution will revert.
*
* Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in
* a contract, executing them in the right order is up to the developer or operator.
*
* WARNING: setting the version to 255 will prevent any future reinitialization.
*
* Emits an {Initialized} event.
*/
modifier reinitializer(uint8 version) {
require(!_initializing && _initialized < version, "Initializable: contract is already initialized");
_initialized = version;
_initializing = true;
_;
_initializing = false;
emit Initialized(version);
}
/**
* @dev Modifier to protect an initialization function so that it can only be invoked by functions with the
* {initializer} and {reinitializer} modifiers, directly or indirectly.
*/
modifier onlyInitializing() {
require(_initializing, "Initializable: contract is not initializing");
_;
}
/**
* @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.
* Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized
* to any version. It is recommended to use this to lock implementation contracts that are designed to be called
* through proxies.
*
* Emits an {Initialized} event the first time it is successfully executed.
*/
function _disableInitializers() internal virtual {
require(!_initializing, "Initializable: contract is initializing");
if (_initialized != type(uint8).max) {
_initialized = type(uint8).max;
emit Initialized(type(uint8).max);
}
}
/**
* @dev Returns the highest version that has been initialized. See {reinitializer}.
*/
function _getInitializedVersion() internal view returns (uint8) {
return _initialized;
}
/**
* @dev Returns `true` if the contract is currently initializing. See {onlyInitializing}.
*/
function _isInitializing() internal view returns (bool) {
return _initializing;
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (proxy/utils/UUPSUpgradeable.sol)
pragma solidity ^0.8.0;
import "../../interfaces/draft-IERC1822Upgradeable.sol";
import "../ERC1967/ERC1967UpgradeUpgradeable.sol";
import "./Initializable.sol";
/**
* @dev An upgradeability mechanism designed for UUPS proxies. The functions included here can perform an upgrade of an
* {ERC1967Proxy}, when this contract is set as the implementation behind such a proxy.
*
* A security mechanism ensures that an upgrade does not turn off upgradeability accidentally, although this risk is
* reinstated if the upgrade retains upgradeability but removes the security mechanism, e.g. by replacing
* `UUPSUpgradeable` with a custom implementation of upgrades.
*
* The {_authorizeUpgrade} function must be overridden to include access restriction to the upgrade mechanism.
*
* _Available since v4.1._
*/
abstract contract UUPSUpgradeable is Initializable, IERC1822ProxiableUpgradeable, ERC1967UpgradeUpgradeable {
function __UUPSUpgradeable_init() internal onlyInitializing {
}
function __UUPSUpgradeable_init_unchained() internal onlyInitializing {
}
/// @custom:oz-upgrades-unsafe-allow state-variable-immutable state-variable-assignment
address private immutable __self = address(this);
/**
* @dev Check that the execution is being performed through a delegatecall call and that the execution context is
* a proxy contract with an implementation (as defined in ERC1967) pointing to self. This should only be the case
* for UUPS and transparent proxies that are using the current contract as their implementation. Execution of a
* function through ERC1167 minimal proxies (clones) would not normally pass this test, but is not guaranteed to
* fail.
*/
modifier onlyProxy() {
require(address(this) != __self, "Function must be called through delegatecall");
require(_getImplementation() == __self, "Function must be called through active proxy");
_;
}
/**
* @dev Check that the execution is not being performed through a delegate call. This allows a function to be
* callable on the implementing contract but not through proxies.
*/
modifier notDelegated() {
require(address(this) == __self, "UUPSUpgradeable: must not be called through delegatecall");
_;
}
/**
* @dev Implementation of the ERC1822 {proxiableUUID} function. This returns the storage slot used by the
* implementation. It is used to validate the implementation's compatibility when performing an upgrade.
*
* IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks
* bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this
* function revert if invoked through a proxy. This is guaranteed by the `notDelegated` modifier.
*/
function proxiableUUID() external view virtual override notDelegated returns (bytes32) {
return _IMPLEMENTATION_SLOT;
}
/**
* @dev Upgrade the implementation of the proxy to `newImplementation`.
*
* Calls {_authorizeUpgrade}.
*
* Emits an {Upgraded} event.
*
* @custom:oz-upgrades-unsafe-allow-reachable delegatecall
*/
function upgradeTo(address newImplementation) public virtual onlyProxy {
_authorizeUpgrade(newImplementation);
_upgradeToAndCallUUPS(newImplementation, new bytes(0), false);
}
/**
* @dev Upgrade the implementation of the proxy to `newImplementation`, and subsequently execute the function call
* encoded in `data`.
*
* Calls {_authorizeUpgrade}.
*
* Emits an {Upgraded} event.
*
* @custom:oz-upgrades-unsafe-allow-reachable delegatecall
*/
function upgradeToAndCall(address newImplementation, bytes memory data) public payable virtual onlyProxy {
_authorizeUpgrade(newImplementation);
_upgradeToAndCallUUPS(newImplementation, data, true);
}
/**
* @dev Function that should revert when `msg.sender` is not authorized to upgrade the contract. Called by
* {upgradeTo} and {upgradeToAndCall}.
*
* Normally, this function will use an xref:access.adoc[access control] modifier such as {Ownable-onlyOwner}.
*
* ```solidity
* function _authorizeUpgrade(address) internal override onlyOwner {}
* ```
*/
function _authorizeUpgrade(address newImplementation) internal virtual;
/**
* @dev This empty reserved space is put in place to allow future versions to add new
* variables without shifting down storage in the inheritance chain.
* See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps
*/
uint256[50] private __gap;
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol)
pragma solidity ^0.8.1;
/**
* @dev Collection of functions related to the address type
*/
library AddressUpgradeable {
/**
* @dev Returns true if `account` is a contract.
*
* [IMPORTANT]
* ====
* It is unsafe to assume that an address for which this function returns
* false is an externally-owned account (EOA) and not a contract.
*
* Among others, `isContract` will return false for the following
* types of addresses:
*
* - an externally-owned account
* - a contract in construction
* - an address where a contract will be created
* - an address where a contract lived, but was destroyed
*
* Furthermore, `isContract` will also return true if the target contract within
* the same transaction is already scheduled for destruction by `SELFDESTRUCT`,
* which only has an effect at the end of a transaction.
* ====
*
* [IMPORTANT]
* ====
* You shouldn't rely on `isContract` to protect against flash loan attacks!
*
* Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets
* like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract
* constructor.
* ====
*/
function isContract(address account) internal view returns (bool) {
// This method relies on extcodesize/address.code.length, which returns 0
// for contracts in construction, since the code is only stored at the end
// of the constructor execution.
return account.code.length > 0;
}
/**
* @dev Replacement for Solidity's `transfer`: sends `amount` wei to
* `recipient`, forwarding all available gas and reverting on errors.
*
* https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost
* of certain opcodes, possibly making contracts go over the 2300 gas limit
* imposed by `transfer`, making them unable to receive funds via
* `transfer`. {sendValue} removes this limitation.
*
* https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more].
*
* IMPORTANT: because control is transferred to `recipient`, care must be
* taken to not create reentrancy vulnerabilities. Consider using
* {ReentrancyGuard} or the
* https://solidity.readthedocs.io/en/v0.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].
*/
function sendValue(address payable recipient, uint256 amount) internal {
require(address(this).balance >= amount, "Address: insufficient balance");
(bool success, ) = recipient.call{value: amount}("");
require(success, "Address: unable to send value, recipient may have reverted");
}
/**
* @dev Performs a Solidity function call using a low level `call`. A
* plain `call` is an unsafe replacement for a function call: use this
* function instead.
*
* If `target` reverts with a revert reason, it is bubbled up by this
* function (like regular Solidity function calls).
*
* Returns the raw returned data. To convert to the expected return value,
* use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].
*
* Requirements:
*
* - `target` must be a contract.
* - calling `target` with `data` must not revert.
*
* _Available since v3.1._
*/
function functionCall(address target, bytes memory data) internal returns (bytes memory) {
return functionCallWithValue(target, data, 0, "Address: low-level call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with
* `errorMessage` as a fallback revert reason when `target` reverts.
*
* _Available since v3.1._
*/
function functionCall(
address target,
bytes memory data,
string memory errorMessage
) internal returns (bytes memory) {
return functionCallWithValue(target, data, 0, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but also transferring `value` wei to `target`.
*
* Requirements:
*
* - the calling contract must have an ETH balance of at least `value`.
* - the called Solidity function must be `payable`.
*
* _Available since v3.1._
*/
function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {
return functionCallWithValue(target, data, value, "Address: low-level call with value failed");
}
/**
* @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but
* with `errorMessage` as a fallback revert reason when `target` reverts.
*
* _Available since v3.1._
*/
function functionCallWithValue(
address target,
bytes memory data,
uint256 value,
string memory errorMessage
) internal returns (bytes memory) {
require(address(this).balance >= value, "Address: insufficient balance for call");
(bool success, bytes memory returndata) = target.call{value: value}(data);
return verifyCallResultFromTarget(target, success, returndata, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but performing a static call.
*
* _Available since v3.3._
*/
function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
return functionStaticCall(target, data, "Address: low-level static call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
* but performing a static call.
*
* _Available since v3.3._
*/
function functionStaticCall(
address target,
bytes memory data,
string memory errorMessage
) internal view returns (bytes memory) {
(bool success, bytes memory returndata) = target.staticcall(data);
return verifyCallResultFromTarget(target, success, returndata, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but performing a delegate call.
*
* _Available since v3.4._
*/
function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
return functionDelegateCall(target, data, "Address: low-level delegate call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
* but performing a delegate call.
*
* _Available since v3.4._
*/
function functionDelegateCall(
address target,
bytes memory data,
string memory errorMessage
) internal returns (bytes memory) {
(bool success, bytes memory returndata) = target.delegatecall(data);
return verifyCallResultFromTarget(target, success, returndata, errorMessage);
}
/**
* @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling
* the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.
*
* _Available since v4.8._
*/
function verifyCallResultFromTarget(
address target,
bool success,
bytes memory returndata,
string memory errorMessage
) internal view returns (bytes memory) {
if (success) {
if (returndata.length == 0) {
// only check isContract if the call was successful and the return data is empty
// otherwise we already know that it was a contract
require(isContract(target), "Address: call to non-contract");
}
return returndata;
} else {
_revert(returndata, errorMessage);
}
}
/**
* @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the
* revert reason or using the provided one.
*
* _Available since v4.3._
*/
function verifyCallResult(
bool success,
bytes memory returndata,
string memory errorMessage
) internal pure returns (bytes memory) {
if (success) {
return returndata;
} else {
_revert(returndata, errorMessage);
}
}
function _revert(bytes memory returndata, string memory errorMessage) private pure {
// Look for revert reason and bubble it up if present
if (returndata.length > 0) {
// The easiest way to bubble the revert reason is using memory via assembly
/// @solidity memory-safe-assembly
assembly {
let returndata_size := mload(returndata)
revert(add(32, returndata), returndata_size)
}
} else {
revert(errorMessage);
}
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)
pragma solidity ^0.8.0;
import "../proxy/utils/Initializable.sol";
/**
* @dev Provides information about the current execution context, including the
* sender of the transaction and its data. While these are generally available
* via msg.sender and msg.data, they should not be accessed in such a direct
* manner, since when dealing with meta-transactions the account sending and
* paying for execution may not be the actual sender (as far as an application
* is concerned).
*
* This contract is only required for intermediate, library-like contracts.
*/
abstract contract ContextUpgradeable is Initializable {
function __Context_init() internal onlyInitializing {
}
function __Context_init_unchained() internal onlyInitializing {
}
function _msgSender() internal view virtual returns (address) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes calldata) {
return msg.data;
}
/**
* @dev This empty reserved space is put in place to allow future versions to add new
* variables without shifting down storage in the inheritance chain.
* See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps
*/
uint256[50] private __gap;
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (utils/StorageSlot.sol)
// This file was procedurally generated from scripts/generate/templates/StorageSlot.js.
pragma solidity ^0.8.0;
/**
* @dev Library for reading and writing primitive types to specific storage slots.
*
* Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts.
* This library helps with reading and writing to such slots without the need for inline assembly.
*
* The functions in this library return Slot structs that contain a `value` member that can be used to read or write.
*
* Example usage to set ERC1967 implementation slot:
* ```solidity
* contract ERC1967 {
* bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;
*
* function _getImplementation() internal view returns (address) {
* return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;
* }
*
* function _setImplementation(address newImplementation) internal {
* require(Address.isContract(newImplementation), "ERC1967: new implementation is not a contract");
* StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;
* }
* }
* ```
*
* _Available since v4.1 for `address`, `bool`, `bytes32`, `uint256`._
* _Available since v4.9 for `string`, `bytes`._
*/
library StorageSlotUpgradeable {
struct AddressSlot {
address value;
}
struct BooleanSlot {
bool value;
}
struct Bytes32Slot {
bytes32 value;
}
struct Uint256Slot {
uint256 value;
}
struct StringSlot {
string value;
}
struct BytesSlot {
bytes value;
}
/**
* @dev Returns an `AddressSlot` with member `value` located at `slot`.
*/
function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) {
/// @solidity memory-safe-assembly
assembly {
r.slot := slot
}
}
/**
* @dev Returns an `BooleanSlot` with member `value` located at `slot`.
*/
function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) {
/// @solidity memory-safe-assembly
assembly {
r.slot := slot
}
}
/**
* @dev Returns an `Bytes32Slot` with member `value` located at `slot`.
*/
function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) {
/// @solidity memory-safe-assembly
assembly {
r.slot := slot
}
}
/**
* @dev Returns an `Uint256Slot` with member `value` located at `slot`.
*/
function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) {
/// @solidity memory-safe-assembly
assembly {
r.slot := slot
}
}
/**
* @dev Returns an `StringSlot` with member `value` located at `slot`.
*/
function getStringSlot(bytes32 slot) internal pure returns (StringSlot storage r) {
/// @solidity memory-safe-assembly
assembly {
r.slot := slot
}
}
/**
* @dev Returns an `StringSlot` representation of the string storage pointer `store`.
*/
function getStringSlot(string storage store) internal pure returns (StringSlot storage r) {
/// @solidity memory-safe-assembly
assembly {
r.slot := store.slot
}
}
/**
* @dev Returns an `BytesSlot` with member `value` located at `slot`.
*/
function getBytesSlot(bytes32 slot) internal pure returns (BytesSlot storage r) {
/// @solidity memory-safe-assembly
assembly {
r.slot := slot
}
}
/**
* @dev Returns an `BytesSlot` representation of the bytes storage pointer `store`.
*/
function getBytesSlot(bytes storage store) internal pure returns (BytesSlot storage r) {
/// @solidity memory-safe-assembly
assembly {
r.slot := store.slot
}
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (utils/math/Math.sol)
pragma solidity ^0.8.0;
/**
* @dev Standard math utilities missing in the Solidity language.
*/
library Math {
enum Rounding {
Down, // Toward negative infinity
Up, // Toward infinity
Zero // Toward zero
}
/**
* @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 == 0 ? 0 : (a - 1) / b + 1;
}
/**
* @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0
* @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv)
* with further edits by Uniswap Labs also under MIT license.
*/
function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) {
unchecked {
// 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use
// use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256
// variables such that product = prod1 * 2^256 + prod0.
uint256 prod0; // Least significant 256 bits of the product
uint256 prod1; // Most significant 256 bits of the product
assembly {
let mm := mulmod(x, y, not(0))
prod0 := mul(x, y)
prod1 := sub(sub(mm, prod0), lt(mm, prod0))
}
// Handle non-overflow cases, 256 by 256 division.
if (prod1 == 0) {
// Solidity will revert if denominator == 0, unlike the div opcode on its own.
// The surrounding unchecked block does not change this fact.
// See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic.
return prod0 / denominator;
}
// Make sure the result is less than 2^256. Also prevents denominator == 0.
require(denominator > prod1, "Math: mulDiv overflow");
///////////////////////////////////////////////
// 512 by 256 division.
///////////////////////////////////////////////
// Make division exact by subtracting the remainder from [prod1 prod0].
uint256 remainder;
assembly {
// Compute remainder using mulmod.
remainder := mulmod(x, y, denominator)
// Subtract 256 bit number from 512 bit number.
prod1 := sub(prod1, gt(remainder, prod0))
prod0 := sub(prod0, remainder)
}
// Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1.
// See https://cs.stackexchange.com/q/138556/92363.
// Does not overflow because the denominator cannot be zero at this stage in the function.
uint256 twos = denominator & (~denominator + 1);
assembly {
// Divide denominator by twos.
denominator := div(denominator, twos)
// Divide [prod1 prod0] by twos.
prod0 := div(prod0, twos)
// Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.
twos := add(div(sub(0, twos), twos), 1)
}
// Shift in bits from prod1 into prod0.
prod0 |= prod1 * twos;
// Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such
// that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for
// four bits. That is, denominator * inv = 1 mod 2^4.
uint256 inverse = (3 * denominator) ^ 2;
// Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works
// in modular arithmetic, doubling the correct bits in each step.
inverse *= 2 - denominator * inverse; // inverse mod 2^8
inverse *= 2 - denominator * inverse; // inverse mod 2^16
inverse *= 2 - denominator * inverse; // inverse mod 2^32
inverse *= 2 - denominator * inverse; // inverse mod 2^64
inverse *= 2 - denominator * inverse; // inverse mod 2^128
inverse *= 2 - denominator * inverse; // inverse mod 2^256
// Because the division is now exact we can divide by multiplying with the modular inverse of denominator.
// This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is
// less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1
// is no longer required.
result = prod0 * inverse;
return result;
}
}
/**
* @notice Calculates x * y / denominator with full precision, following the selected rounding direction.
*/
function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) {
uint256 result = mulDiv(x, y, denominator);
if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {
result += 1;
}
return result;
}
/**
* @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down.
*
* Inspired by Henry S. Warren, Jr.'s "Hacker's Delight" (Chapter 11).
*/
function sqrt(uint256 a) internal pure returns (uint256) {
if (a == 0) {
return 0;
}
// For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.
//
// We know that the "msb" (most significant bit) of our target number `a` is a power of 2 such that we have
// `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`.
//
// This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)`
// → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))`
// → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)`
//
// Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit.
uint256 result = 1 << (log2(a) >> 1);
// At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,
// since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at
// every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision
// into the expected uint128 result.
unchecked {
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
return min(result, a / result);
}
}
/**
* @notice Calculates sqrt(a), following the selected rounding direction.
*/
function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {
unchecked {
uint256 result = sqrt(a);
return result + (rounding == Rounding.Up && result * result < a ? 1 : 0);
}
}
/**
* @dev Return the log in base 2, rounded down, of a positive value.
* Returns 0 if given 0.
*/
function log2(uint256 value) internal pure returns (uint256) {
uint256 result = 0;
unchecked {
if (value >> 128 > 0) {
value >>= 128;
result += 128;
}
if (value >> 64 > 0) {
value >>= 64;
result += 64;
}
if (value >> 32 > 0) {
value >>= 32;
result += 32;
}
if (value >> 16 > 0) {
value >>= 16;
result += 16;
}
if (value >> 8 > 0) {
value >>= 8;
result += 8;
}
if (value >> 4 > 0) {
value >>= 4;
result += 4;
}
if (value >> 2 > 0) {
value >>= 2;
result += 2;
}
if (value >> 1 > 0) {
result += 1;
}
}
return result;
}
/**
* @dev Return the log in base 2, following the selected rounding direction, of a positive value.
* Returns 0 if given 0.
*/
function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {
unchecked {
uint256 result = log2(value);
return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0);
}
}
/**
* @dev Return the log in base 10, rounded down, of a positive value.
* Returns 0 if given 0.
*/
function log10(uint256 value) internal pure returns (uint256) {
uint256 result = 0;
unchecked {
if (value >= 10 ** 64) {
value /= 10 ** 64;
result += 64;
}
if (value >= 10 ** 32) {
value /= 10 ** 32;
result += 32;
}
if (value >= 10 ** 16) {
value /= 10 ** 16;
result += 16;
}
if (value >= 10 ** 8) {
value /= 10 ** 8;
result += 8;
}
if (value >= 10 ** 4) {
value /= 10 ** 4;
result += 4;
}
if (value >= 10 ** 2) {
value /= 10 ** 2;
result += 2;
}
if (value >= 10 ** 1) {
result += 1;
}
}
return result;
}
/**
* @dev Return the log in base 10, following the selected rounding direction, of a positive value.
* Returns 0 if given 0.
*/
function log10(uint256 value, Rounding rounding) internal pure returns (uint256) {
unchecked {
uint256 result = log10(value);
return result + (rounding == Rounding.Up && 10 ** result < value ? 1 : 0);
}
}
/**
* @dev Return the log in base 256, rounded down, of a positive value.
* Returns 0 if given 0.
*
* Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string.
*/
function log256(uint256 value) internal pure returns (uint256) {
uint256 result = 0;
unchecked {
if (value >> 128 > 0) {
value >>= 128;
result += 16;
}
if (value >> 64 > 0) {
value >>= 64;
result += 8;
}
if (value >> 32 > 0) {
value >>= 32;
result += 4;
}
if (value >> 16 > 0) {
value >>= 16;
result += 2;
}
if (value >> 8 > 0) {
result += 1;
}
}
return result;
}
/**
* @dev Return the log in base 256, following the selected rounding direction, of a positive value.
* Returns 0 if given 0.
*/
function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {
unchecked {
uint256 result = log256(value);
return result + (rounding == Rounding.Up && 1 << (result << 3) < value ? 1 : 0);
}
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SignedMath.sol)
pragma solidity ^0.8.0;
/**
* @dev Standard signed math utilities missing in the Solidity language.
*/
library SignedMath {
/**
* @dev Returns the largest of two signed numbers.
*/
function max(int256 a, int256 b) internal pure returns (int256) {
return a > b ? a : b;
}
/**
* @dev Returns the smallest of two signed numbers.
*/
function min(int256 a, int256 b) internal pure returns (int256) {
return a < b ? a : b;
}
/**
* @dev Returns the average of two signed numbers without overflow.
* The result is rounded towards zero.
*/
function average(int256 a, int256 b) internal pure returns (int256) {
// Formula from the book "Hacker's Delight"
int256 x = (a & b) + ((a ^ b) >> 1);
return x + (int256(uint256(x) >> 255) & (a ^ b));
}
/**
* @dev Returns the absolute unsigned value of a signed value.
*/
function abs(int256 n) internal pure returns (uint256) {
unchecked {
// must be unchecked in order to support `n = type(int256).min`
return uint256(n >= 0 ? n : -n);
}
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (utils/Strings.sol)
pragma solidity ^0.8.0;
import "./math/Math.sol";
import "./math/SignedMath.sol";
/**
* @dev String operations.
*/
library Strings {
bytes16 private constant _SYMBOLS = "0123456789abcdef";
uint8 private constant _ADDRESS_LENGTH = 20;
/**
* @dev Converts a `uint256` to its ASCII `string` decimal representation.
*/
function toString(uint256 value) internal pure returns (string memory) {
unchecked {
uint256 length = Math.log10(value) + 1;
string memory buffer = new string(length);
uint256 ptr;
/// @solidity memory-safe-assembly
assembly {
ptr := add(buffer, add(32, length))
}
while (true) {
ptr--;
/// @solidity memory-safe-assembly
assembly {
mstore8(ptr, byte(mod(value, 10), _SYMBOLS))
}
value /= 10;
if (value == 0) break;
}
return buffer;
}
}
/**
* @dev Converts a `int256` to its ASCII `string` decimal representation.
*/
function toString(int256 value) internal pure returns (string memory) {
return string(abi.encodePacked(value < 0 ? "-" : "", toString(SignedMath.abs(value))));
}
/**
* @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.
*/
function toHexString(uint256 value) internal pure returns (string memory) {
unchecked {
return toHexString(value, Math.log256(value) + 1);
}
}
/**
* @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] = _SYMBOLS[value & 0xf];
value >>= 4;
}
require(value == 0, "Strings: hex length insufficient");
return string(buffer);
}
/**
* @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.
*/
function toHexString(address addr) internal pure returns (string memory) {
return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);
}
/**
* @dev Returns true if the two strings are equal.
*/
function equal(string memory a, string memory b) internal pure returns (bool) {
return keccak256(bytes(a)) == keccak256(bytes(b));
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.12;
interface DAOProvider {
function getDaoParticipationForUser(string memory addr) external view returns (uint256);
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.7;
struct Vote {
string title;
string description;
string link;
uint256 endHeight;
uint256 currentYesVotes;
uint256 currentNoVotes;
address initiator;
string id;
}{
"optimizer": {
"enabled": false,
"runs": 200
},
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"devdoc",
"userdoc",
"metadata",
"abi"
]
}
},
"libraries": {}
}Contract ABI
API[{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"previousAdmin","type":"address"},{"indexed":false,"internalType":"address","name":"newAdmin","type":"address"}],"name":"AdminChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"beacon","type":"address"}],"name":"BeaconUpgraded","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint8","name":"version","type":"uint8"}],"name":"Initialized","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"implementation","type":"address"}],"name":"Upgraded","type":"event"},{"inputs":[{"internalType":"address","name":"addr","type":"address"}],"name":"addressToString","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"string","name":"","type":"string"}],"name":"currentNoVotes","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"","type":"string"}],"name":"currentYesVotes","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"voteId","type":"string"},{"internalType":"address","name":"user","type":"address"}],"name":"getAlreadyVoted","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"voteId","type":"string"}],"name":"getCurrentNoVotesForId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"voteId","type":"string"}],"name":"getCurrentYesVotesForId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"}],"name":"getDAOPowerOfUser","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getLastCounter","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"voteId","type":"string"}],"name":"getLinkForVote","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"voteId","type":"string"}],"name":"getVoteDescription","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"voteId","type":"string"}],"name":"getVoteEndHeight","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getVoteIds","outputs":[{"internalType":"string[]","name":"","type":"string[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"voteId","type":"string"}],"name":"getVoteTitle","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getVotes","outputs":[{"components":[{"internalType":"string","name":"title","type":"string"},{"internalType":"string","name":"description","type":"string"},{"internalType":"string","name":"link","type":"string"},{"internalType":"uint256","name":"endHeight","type":"uint256"},{"internalType":"uint256","name":"currentYesVotes","type":"uint256"},{"internalType":"uint256","name":"currentNoVotes","type":"uint256"},{"internalType":"address","name":"initiator","type":"address"},{"internalType":"string","name":"id","type":"string"}],"internalType":"struct Vote[]","name":"","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"daoProviderAddress","type":"address"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"voteId","type":"string"}],"name":"no","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"proxiableUUID","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"title","type":"string"},{"internalType":"string","name":"desc","type":"string"},{"internalType":"string","name":"link","type":"string"}],"name":"registerVote","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"voteId","type":"string"}],"name":"retractVote","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newImplementation","type":"address"}],"name":"upgradeTo","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newImplementation","type":"address"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"upgradeToAndCall","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"string","name":"voteId","type":"string"}],"name":"yes","outputs":[],"stateMutability":"nonpayable","type":"function"}]Contract Creation Code
60a06040523073ffffffffffffffffffffffffffffffffffffffff1660809073ffffffffffffffffffffffffffffffffffffffff1681525034801561004357600080fd5b50608051614416610089600039600081816110f601528181611185015281816112be0152818161134d01528181611425015281816117ac015261183b01526144166000f3fe6080604052600436106101665760003560e01c8063715018a6116100d1578063cbb8bf9b1161008a578063eb2891d911610064578063eb2891d914610567578063f2fde38b146105a4578063f4b033a8146105cd578063ff64df321461060a57610166565b8063cbb8bf9b146104d6578063ce90fdcf146104ff578063d370c7a71461052a57610166565b8063715018a6146103b45780637897fa0a146103cb5780638a8f802a146104085780638da5cb5b146104455780639bf0ad7814610470578063c4d66de8146104ad57610166565b80633659cfe6116101235780633659cfe61461028d57806348db39bf146102b65780634f1ef286146102f357806350ea0b101461030f57806352d1902d1461034c5780635e57966d1461037757610166565b80630dc960151461016b5780630f7aebb91461019657806311b928bd146101c157806319d78250146101ea578063273bb1cf14610227578063282f49e814610250575b600080fd5b34801561017757600080fd5b50610180610633565b60405161018d9190612ef8565b60405180910390f35b3480156101a257600080fd5b506101ab610a6d565b6040516101b89190612f29565b60405180910390f35b3480156101cd57600080fd5b506101e860048036038101906101e3919061308d565b610a83565b005b3480156101f657600080fd5b50610211600480360381019061020c9190613102565b610e58565b60405161021e9190612f29565b60405180910390f35b34801561023357600080fd5b5061024e6004803603810190610249919061308d565b610f05565b005b34801561025c57600080fd5b506102776004803603810190610272919061308d565b6110cc565b6040516102849190612f29565b60405180910390f35b34801561029957600080fd5b506102b460048036038101906102af9190613102565b6110f4565b005b3480156102c257600080fd5b506102dd60048036038101906102d8919061312f565b61127d565b6040516102ea91906131a6565b60405180910390f35b61030d60048036038101906103089190613262565b6112bc565b005b34801561031b57600080fd5b506103366004803603810190610331919061308d565b6113f9565b6040516103439190612f29565b60405180910390f35b34801561035857600080fd5b50610361611421565b60405161036e91906132d7565b60405180910390f35b34801561038357600080fd5b5061039e60048036038101906103999190613102565b6114da565b6040516103ab919061333c565b60405180910390f35b3480156103c057600080fd5b506103c9611504565b005b3480156103d757600080fd5b506103f260048036038101906103ed919061308d565b611518565b6040516103ff919061333c565b60405180910390f35b34801561041457600080fd5b5061042f600480360381019061042a919061308d565b6115c8565b60405161043c919061333c565b60405180910390f35b34801561045157600080fd5b5061045a611678565b604051610467919061336d565b60405180910390f35b34801561047c57600080fd5b506104976004803603810190610492919061308d565b6116a2565b6040516104a49190612f29565b60405180910390f35b3480156104b957600080fd5b506104d460048036038101906104cf9190613102565b6116d0565b005b3480156104e257600080fd5b506104fd60048036038101906104f8919061308d565b61198b565b005b34801561050b57600080fd5b50610514611b52565b604051610521919061344a565b60405180910390f35b34801561053657600080fd5b50610551600480360381019061054c919061308d565b611c2b565b60405161055e9190612f29565b60405180910390f35b34801561057357600080fd5b5061058e6004803603810190610589919061308d565b611c59565b60405161059b9190612f29565b60405180910390f35b3480156105b057600080fd5b506105cb60048036038101906105c69190613102565b611c81565b005b3480156105d957600080fd5b506105f460048036038101906105ef919061308d565b611d05565b604051610601919061333c565b60405180910390f35b34801561061657600080fd5b50610631600480360381019061062c919061346c565b611db5565b005b606061063d612b80565b600060d68054905067ffffffffffffffff81111561065e5761065d612f62565b5b60405190808252806020026020018201604052801561069757816020015b610684612b80565b81526020019060019003908161067c5790505b509050606060005b60d680549050811015610a635760d681815481106106c0576106bf613513565b5b9060005260206000200180546106d590613571565b80601f016020809104026020016040519081016040528092919081815260200182805461070190613571565b801561074e5780601f106107235761010080835404028352916020019161074e565b820191906000526020600020905b81548152906001019060200180831161073157829003601f168201915b5050505050915060405180610100016040528060d08460405161077191906135df565b9081526020016040518091039020805461078a90613571565b80601f01602080910402602001604051908101604052809291908181526020018280546107b690613571565b80156108035780601f106107d857610100808354040283529160200191610803565b820191906000526020600020905b8154815290600101906020018083116107e657829003601f168201915b5050505050815260200160d18460405161081d91906135df565b9081526020016040518091039020805461083690613571565b80601f016020809104026020016040519081016040528092919081815260200182805461086290613571565b80156108af5780601f10610884576101008083540402835291602001916108af565b820191906000526020600020905b81548152906001019060200180831161089257829003601f168201915b5050505050815260200160d2846040516108c991906135df565b908152602001604051809103902080546108e290613571565b80601f016020809104026020016040519081016040528092919081815260200182805461090e90613571565b801561095b5780601f106109305761010080835404028352916020019161095b565b820191906000526020600020905b81548152906001019060200180831161093e57829003601f168201915b5050505050815260200160ca8460405161097591906135df565b908152602001604051809103902054815260200160cb8460405161099991906135df565b908152602001604051809103902054815260200160cc846040516109bd91906135df565b908152602001604051809103902054815260200160d3846040516109e191906135df565b908152602001604051809103902060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200183815250935083838281518110610a4557610a44613513565b5b60200260200101819052508080610a5b90613625565b91505061069f565b5081935050505090565b6000600160d454610a7e919061366e565b905090565b6000610a8e826110cc565b10158015610aa557506000610aa2826113f9565b10155b610ae4576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610adb906136ee565b60405180910390fd5b43610aee82611c59565b1115610b2f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b269061375a565b60405180910390fd5b600060ce82604051610b4191906135df565b908152602001604051809103902060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020541180610bf45750600060cf82604051610ba691906135df565b908152602001604051809103902060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054115b610c33576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c2a906137ec565b60405180910390fd5b60ce81604051610c4391906135df565b908152602001604051809103902060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205460cc82604051610c9f91906135df565b90815260200160405180910390206000828254610cbc919061366e565b9250508190555060cf81604051610cd391906135df565b908152602001604051809103902060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205460cb82604051610d2f91906135df565b90815260200160405180910390206000828254610d4c919061366e565b92505081905550600060ce82604051610d6591906135df565b908152602001604051809103902060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550600060cf82604051610dc691906135df565b908152602001604051809103902060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550600060cd610e23833361202b565b604051610e3091906135df565b908152602001604051809103902060006101000a81548160ff02191690831515021790555050565b600060d560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663b5e72a57610ea1846114da565b6040518263ffffffff1660e01b8152600401610ebd919061333c565b602060405180830381865afa158015610eda573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610efe9190613838565b9050919050565b6000610f10826110cc565b1015610f51576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f48906138b1565b60405180910390fd5b43610f5b82611c59565b1115610f9c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f939061375a565b60405180910390fd5b610fa6813361127d565b15610fe6576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610fdd9061391d565b60405180910390fd5b6000610ff133610e58565b90508060cb8360405161100491906135df565b90815260200160405180910390206000828254611021919061393d565b92505081905550600160cd611036843361202b565b60405161104391906135df565b908152602001604051809103902060006101000a81548160ff0219169083151502179055508060cf8360405161107991906135df565b908152602001604051809103902060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055505050565b600060cb826040516110de91906135df565b9081526020016040518091039020549050919050565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff163073ffffffffffffffffffffffffffffffffffffffff161415611183576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161117a90613a05565b60405180910390fd5b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166111c261205f565b73ffffffffffffffffffffffffffffffffffffffff1614611218576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161120f90613a97565b60405180910390fd5b611221816120b6565b61127a81600067ffffffffffffffff8111156112405761123f612f62565b5b6040519080825280601f01601f1916602001820160405280156112725781602001600182028036833780820191505090505b5060006120c1565b50565b600060cd61128b848461202b565b60405161129891906135df565b908152602001604051809103902060009054906101000a900460ff16905092915050565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff163073ffffffffffffffffffffffffffffffffffffffff16141561134b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161134290613a05565b60405180910390fd5b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1661138a61205f565b73ffffffffffffffffffffffffffffffffffffffff16146113e0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016113d790613a97565b60405180910390fd5b6113e9826120b6565b6113f5828260016120c1565b5050565b600060cc8260405161140b91906135df565b9081526020016040518091039020549050919050565b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff163073ffffffffffffffffffffffffffffffffffffffff16146114b1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016114a890613b29565b60405180910390fd5b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc60001b905090565b60606114fd8273ffffffffffffffffffffffffffffffffffffffff16601461222f565b9050919050565b61150c61246b565b61151660006124e9565b565b606060d28260405161152a91906135df565b9081526020016040518091039020805461154390613571565b80601f016020809104026020016040519081016040528092919081815260200182805461156f90613571565b80156115bc5780601f10611591576101008083540402835291602001916115bc565b820191906000526020600020905b81548152906001019060200180831161159f57829003601f168201915b50505050509050919050565b606060d1826040516115da91906135df565b908152602001604051809103902080546115f390613571565b80601f016020809104026020016040519081016040528092919081815260200182805461161f90613571565b801561166c5780601f106116415761010080835404028352916020019161166c565b820191906000526020600020905b81548152906001019060200180831161164f57829003601f168201915b50505050509050919050565b6000603360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b60cb818051602081018201805184825260208301602085012081835280955050505050506000915090505481565b60008060019054906101000a900460ff161590508080156117015750600160008054906101000a900460ff1660ff16105b8061172e5750611710306125af565b15801561172d5750600160008054906101000a900460ff1660ff16145b5b61176d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161176490613bbb565b60405180910390fd5b60016000806101000a81548160ff021916908360ff16021790555080156117aa576001600060016101000a81548160ff0219169083151502179055505b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff163073ffffffffffffffffffffffffffffffffffffffff161415611839576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161183090613a05565b60405180910390fd5b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1661187861205f565b73ffffffffffffffffffffffffffffffffffffffff16146118ce576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016118c590613a97565b60405180910390fd5b6118d66125d2565b670de0b6b3a764000060c9819055508160d560006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550600060d48190555080156119875760008060016101000a81548160ff0219169083151502179055507f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498600160405161197e9190613c2d565b60405180910390a15b5050565b6000611996826113f9565b10156119d7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016119ce906138b1565b60405180910390fd5b436119e182611c59565b1115611a22576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611a199061375a565b60405180910390fd5b611a2c813361127d565b15611a6c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611a6390613c94565b60405180910390fd5b6000611a7733610e58565b90508060cc83604051611a8a91906135df565b90815260200160405180910390206000828254611aa7919061393d565b92505081905550600160cd611abc843361202b565b604051611ac991906135df565b908152602001604051809103902060006101000a81548160ff0219169083151502179055508060ce83604051611aff91906135df565b908152602001604051809103902060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055505050565b606060d6805480602002602001604051908101604052809291908181526020016000905b82821015611c22578382906000526020600020018054611b9590613571565b80601f0160208091040260200160405190810160405280929190818152602001828054611bc190613571565b8015611c0e5780601f10611be357610100808354040283529160200191611c0e565b820191906000526020600020905b815481529060010190602001808311611bf157829003601f168201915b505050505081526020019060010190611b76565b50505050905090565b60cc818051602081018201805184825260208301602085012081835280955050505050506000915090505481565b600060ca82604051611c6b91906135df565b9081526020016040518091039020549050919050565b611c8961246b565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415611cf9576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611cf090613d26565b60405180910390fd5b611d02816124e9565b50565b606060d082604051611d1791906135df565b90815260200160405180910390208054611d3090613571565b80601f0160208091040260200160405190810160405280929190818152602001828054611d5c90613571565b8015611da95780601f10611d7e57610100808354040283529160200191611da9565b820191906000526020600020905b815481529060010190602001808311611d8c57829003601f168201915b50505050509050919050565b6000611dc0326114da565b9050600081604051602001611dd59190613d6c565b604051602081830303815290604052905080611df260d45461262b565b604051602001611e03929190613d92565b604051602081830303815290604052905060c954611e2033610e58565b1015611e61576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611e5890613e28565b60405180910390fd5b62034bc043611e70919061393d565b60ca82604051611e8091906135df565b9081526020016040518091039020819055508460d082604051611ea391906135df565b90815260200160405180910390209080519060200190611ec4929190612bdb565b508360d182604051611ed691906135df565b90815260200160405180910390209080519060200190611ef7929190612bdb565b508260d282604051611f0991906135df565b90815260200160405180910390209080519060200190611f2a929190612bdb565b503360d382604051611f3c91906135df565b908152602001604051809103902060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550600060cb82604051611f9a91906135df565b908152602001604051809103902081905550600060cc82604051611fbe91906135df565b90815260200160405180910390208190555060d68190806001815401808255809150506001900390600052602060002001600090919091909150908051906020019061200b929190612bdb565b5060d4600081548092919061201f90613625565b91905055505050505050565b606082612037836114da565b604051602001612048929190613e94565b604051602081830303815290604052905092915050565b600061208d7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc60001b612703565b60000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6120be61246b565b50565b6120ed7f4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd914360001b61270d565b60000160009054906101000a900460ff16156121115761210c83612717565b61222a565b8273ffffffffffffffffffffffffffffffffffffffff166352d1902d6040518163ffffffff1660e01b8152600401602060405180830381865afa92505050801561217957506040513d601f19601f820116820180604052508101906121769190613eef565b60015b6121b8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016121af90613f8e565b60405180910390fd5b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc60001b811461221d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161221490614020565b60405180910390fd5b506122298383836127d0565b5b505050565b6060600060028360026122429190614040565b61224c919061393d565b67ffffffffffffffff81111561226557612264612f62565b5b6040519080825280601f01601f1916602001820160405280156122975781602001600182028036833780820191505090505b5090507f3000000000000000000000000000000000000000000000000000000000000000816000815181106122cf576122ce613513565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053507f78000000000000000000000000000000000000000000000000000000000000008160018151811061233357612332613513565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600060018460026123739190614040565b61237d919061393d565b90505b600181111561241d577f3031323334353637383961626364656600000000000000000000000000000000600f8616601081106123bf576123be613513565b5b1a60f81b8282815181106123d6576123d5613513565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600485901c9450806124169061409a565b9050612380565b5060008414612461576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161245890614110565b60405180910390fd5b8091505092915050565b6124736127fc565b73ffffffffffffffffffffffffffffffffffffffff16612491611678565b73ffffffffffffffffffffffffffffffffffffffff16146124e7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016124de9061417c565b60405180910390fd5b565b6000603360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081603360006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b600060019054906101000a900460ff16612621576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016126189061420e565b60405180910390fd5b612629612804565b565b60606000600161263a84612865565b01905060008167ffffffffffffffff81111561265957612658612f62565b5b6040519080825280601f01601f19166020018201604052801561268b5781602001600182028036833780820191505090505b509050600082602001820190505b6001156126f8578080600190039150507f3031323334353637383961626364656600000000000000000000000000000000600a86061a8153600a85816126e2576126e161422e565b5b04945060008514156126f3576126f8565b612699565b819350505050919050565b6000819050919050565b6000819050919050565b612720816125af565b61275f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612756906142cf565b60405180910390fd5b8061278c7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc60001b612703565b60000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b6127d9836129b8565b6000825111806127e65750805b156127f7576127f58383612a07565b505b505050565b600033905090565b600060019054906101000a900460ff16612853576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161284a9061420e565b60405180910390fd5b61286361285e6127fc565b6124e9565b565b600080600090507a184f03e93ff9f4daa797ed6e38ed64bf6a1f01000000000000000083106128c3577a184f03e93ff9f4daa797ed6e38ed64bf6a1f01000000000000000083816128b9576128b861422e565b5b0492506040810190505b6d04ee2d6d415b85acef81000000008310612900576d04ee2d6d415b85acef810000000083816128f6576128f561422e565b5b0492506020810190505b662386f26fc10000831061292f57662386f26fc1000083816129255761292461422e565b5b0492506010810190505b6305f5e1008310612958576305f5e100838161294e5761294d61422e565b5b0492506008810190505b612710831061297d5761271083816129735761297261422e565b5b0492506004810190505b606483106129a057606483816129965761299561422e565b5b0492506002810190505b600a83106129af576001810190505b80915050919050565b6129c181612717565b8073ffffffffffffffffffffffffffffffffffffffff167fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b60405160405180910390a250565b6060612a2c83836040518060600160405280602781526020016143ba60279139612a34565b905092915050565b60606000808573ffffffffffffffffffffffffffffffffffffffff1685604051612a5e9190614336565b600060405180830381855af49150503d8060008114612a99576040519150601f19603f3d011682016040523d82523d6000602084013e612a9e565b606091505b5091509150612aaf86838387612aba565b925050509392505050565b60608315612b1d57600083511415612b1557612ad5856125af565b612b14576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612b0b90614399565b60405180910390fd5b5b829050612b28565b612b278383612b30565b5b949350505050565b600082511115612b435781518083602001fd5b806040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612b77919061333c565b60405180910390fd5b604051806101000160405280606081526020016060815260200160608152602001600081526020016000815260200160008152602001600073ffffffffffffffffffffffffffffffffffffffff168152602001606081525090565b828054612be790613571565b90600052602060002090601f016020900481019282612c095760008555612c50565b82601f10612c2257805160ff1916838001178555612c50565b82800160010185558215612c50579182015b82811115612c4f578251825591602001919060010190612c34565b5b509050612c5d9190612c61565b5090565b5b80821115612c7a576000816000905550600101612c62565b5090565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b600081519050919050565b600082825260208201905092915050565b60005b83811015612ce4578082015181840152602081019050612cc9565b83811115612cf3576000848401525b50505050565b6000601f19601f8301169050919050565b6000612d1582612caa565b612d1f8185612cb5565b9350612d2f818560208601612cc6565b612d3881612cf9565b840191505092915050565b6000819050919050565b612d5681612d43565b82525050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000612d8782612d5c565b9050919050565b612d9781612d7c565b82525050565b6000610100830160008301518482036000860152612dbb8282612d0a565b91505060208301518482036020860152612dd58282612d0a565b91505060408301518482036040860152612def8282612d0a565b9150506060830151612e046060860182612d4d565b506080830151612e176080860182612d4d565b5060a0830151612e2a60a0860182612d4d565b5060c0830151612e3d60c0860182612d8e565b5060e083015184820360e0860152612e558282612d0a565b9150508091505092915050565b6000612e6e8383612d9d565b905092915050565b6000602082019050919050565b6000612e8e82612c7e565b612e988185612c89565b935083602082028501612eaa85612c9a565b8060005b85811015612ee65784840389528151612ec78582612e62565b9450612ed283612e76565b925060208a01995050600181019050612eae565b50829750879550505050505092915050565b60006020820190508181036000830152612f128184612e83565b905092915050565b612f2381612d43565b82525050565b6000602082019050612f3e6000830184612f1a565b92915050565b6000604051905090565b600080fd5b600080fd5b600080fd5b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b612f9a82612cf9565b810181811067ffffffffffffffff82111715612fb957612fb8612f62565b5b80604052505050565b6000612fcc612f44565b9050612fd88282612f91565b919050565b600067ffffffffffffffff821115612ff857612ff7612f62565b5b61300182612cf9565b9050602081019050919050565b82818337600083830152505050565b600061303061302b84612fdd565b612fc2565b90508281526020810184848401111561304c5761304b612f5d565b5b61305784828561300e565b509392505050565b600082601f83011261307457613073612f58565b5b813561308484826020860161301d565b91505092915050565b6000602082840312156130a3576130a2612f4e565b5b600082013567ffffffffffffffff8111156130c1576130c0612f53565b5b6130cd8482850161305f565b91505092915050565b6130df81612d7c565b81146130ea57600080fd5b50565b6000813590506130fc816130d6565b92915050565b60006020828403121561311857613117612f4e565b5b6000613126848285016130ed565b91505092915050565b6000806040838503121561314657613145612f4e565b5b600083013567ffffffffffffffff81111561316457613163612f53565b5b6131708582860161305f565b9250506020613181858286016130ed565b9150509250929050565b60008115159050919050565b6131a08161318b565b82525050565b60006020820190506131bb6000830184613197565b92915050565b600067ffffffffffffffff8211156131dc576131db612f62565b5b6131e582612cf9565b9050602081019050919050565b6000613205613200846131c1565b612fc2565b90508281526020810184848401111561322157613220612f5d565b5b61322c84828561300e565b509392505050565b600082601f83011261324957613248612f58565b5b81356132598482602086016131f2565b91505092915050565b6000806040838503121561327957613278612f4e565b5b6000613287858286016130ed565b925050602083013567ffffffffffffffff8111156132a8576132a7612f53565b5b6132b485828601613234565b9150509250929050565b6000819050919050565b6132d1816132be565b82525050565b60006020820190506132ec60008301846132c8565b92915050565b600082825260208201905092915050565b600061330e82612caa565b61331881856132f2565b9350613328818560208601612cc6565b61333181612cf9565b840191505092915050565b600060208201905081810360008301526133568184613303565b905092915050565b61336781612d7c565b82525050565b6000602082019050613382600083018461335e565b92915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b60006133c08383612d0a565b905092915050565b6000602082019050919050565b60006133e082613388565b6133ea8185613393565b9350836020820285016133fc856133a4565b8060005b85811015613438578484038952815161341985826133b4565b9450613424836133c8565b925060208a01995050600181019050613400565b50829750879550505050505092915050565b6000602082019050818103600083015261346481846133d5565b905092915050565b60008060006060848603121561348557613484612f4e565b5b600084013567ffffffffffffffff8111156134a3576134a2612f53565b5b6134af8682870161305f565b935050602084013567ffffffffffffffff8111156134d0576134cf612f53565b5b6134dc8682870161305f565b925050604084013567ffffffffffffffff8111156134fd576134fc612f53565b5b6135098682870161305f565b9150509250925092565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b6000600282049050600182168061358957607f821691505b6020821081141561359d5761359c613542565b5b50919050565b600081905092915050565b60006135b982612caa565b6135c381856135a3565b93506135d3818560208601612cc6565b80840191505092915050565b60006135eb82846135ae565b915081905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600061363082612d43565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff821415613663576136626135f6565b5b600182019050919050565b600061367982612d43565b915061368483612d43565b925082821015613697576136966135f6565b5b828203905092915050565b7f4e6f2061637469766520766f746520666f72207468697320766f746520696421600082015250565b60006136d86020836132f2565b91506136e3826136a2565b602082019050919050565b60006020820190508181036000830152613707816136cb565b9050919050565b7f566f7465206e6f206c6f6e676572206163746976652100000000000000000000600082015250565b60006137446016836132f2565b915061374f8261370e565b602082019050919050565b6000602082019050818103600083015261377381613737565b9050919050565b7f557365727320686173206e6f7420766f74656420666f72207468697320766f7460008201527f6521000000000000000000000000000000000000000000000000000000000000602082015250565b60006137d66022836132f2565b91506137e18261377a565b604082019050919050565b60006020820190508181036000830152613805816137c9565b9050919050565b61381581612d43565b811461382057600080fd5b50565b6000815190506138328161380c565b92915050565b60006020828403121561384e5761384d612f4e565b5b600061385c84828501613823565b91505092915050565b7f566f7465206e6f7420666f756e64210000000000000000000000000000000000600082015250565b600061389b600f836132f2565b91506138a682613865565b602082019050919050565b600060208201905081810360008301526138ca8161388e565b9050919050565b7f5573657220616c726561647920766f7465642100000000000000000000000000600082015250565b60006139076013836132f2565b9150613912826138d1565b602082019050919050565b60006020820190508181036000830152613936816138fa565b9050919050565b600061394882612d43565b915061395383612d43565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff03821115613988576139876135f6565b5b828201905092915050565b7f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060008201527f64656c656761746563616c6c0000000000000000000000000000000000000000602082015250565b60006139ef602c836132f2565b91506139fa82613993565b604082019050919050565b60006020820190508181036000830152613a1e816139e2565b9050919050565b7f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060008201527f6163746976652070726f78790000000000000000000000000000000000000000602082015250565b6000613a81602c836132f2565b9150613a8c82613a25565b604082019050919050565b60006020820190508181036000830152613ab081613a74565b9050919050565b7f555550535570677261646561626c653a206d757374206e6f742062652063616c60008201527f6c6564207468726f7567682064656c656761746563616c6c0000000000000000602082015250565b6000613b136038836132f2565b9150613b1e82613ab7565b604082019050919050565b60006020820190508181036000830152613b4281613b06565b9050919050565b7f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160008201527f647920696e697469616c697a6564000000000000000000000000000000000000602082015250565b6000613ba5602e836132f2565b9150613bb082613b49565b604082019050919050565b60006020820190508181036000830152613bd481613b98565b9050919050565b6000819050919050565b600060ff82169050919050565b6000819050919050565b6000613c17613c12613c0d84613bdb565b613bf2565b613be5565b9050919050565b613c2781613bfc565b82525050565b6000602082019050613c426000830184613c1e565b92915050565b7f4164647265737320616c726561647920766f7465642100000000000000000000600082015250565b6000613c7e6016836132f2565b9150613c8982613c48565b602082019050919050565b60006020820190508181036000830152613cad81613c71565b9050919050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b6000613d106026836132f2565b9150613d1b82613cb4565b604082019050919050565b60006020820190508181036000830152613d3f81613d03565b9050919050565b7f5f00000000000000000000000000000000000000000000000000000000000000815250565b6000613d7882846135ae565b9150613d8382613d46565b60018201915081905092915050565b6000613d9e82856135ae565b9150613daa82846135ae565b91508190509392505050565b7f5573657220686173206e6f74206265656e2061637469766520656e6f7567682060008201527f6f6e2074686520706c6174666f726d2100000000000000000000000000000000602082015250565b6000613e126030836132f2565b9150613e1d82613db6565b604082019050919050565b60006020820190508181036000830152613e4181613e05565b9050919050565b7f5f00000000000000000000000000000000000000000000000000000000000000600082015250565b6000613e7e6001836135a3565b9150613e8982613e48565b600182019050919050565b6000613ea082856135ae565b9150613eab82613e71565b9150613eb782846135ae565b91508190509392505050565b613ecc816132be565b8114613ed757600080fd5b50565b600081519050613ee981613ec3565b92915050565b600060208284031215613f0557613f04612f4e565b5b6000613f1384828501613eda565b91505092915050565b7f45524331393637557067726164653a206e657720696d706c656d656e7461746960008201527f6f6e206973206e6f742055555053000000000000000000000000000000000000602082015250565b6000613f78602e836132f2565b9150613f8382613f1c565b604082019050919050565b60006020820190508181036000830152613fa781613f6b565b9050919050565b7f45524331393637557067726164653a20756e737570706f727465642070726f7860008201527f6961626c65555549440000000000000000000000000000000000000000000000602082015250565b600061400a6029836132f2565b915061401582613fae565b604082019050919050565b6000602082019050818103600083015261403981613ffd565b9050919050565b600061404b82612d43565b915061405683612d43565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048311821515161561408f5761408e6135f6565b5b828202905092915050565b60006140a582612d43565b915060008214156140b9576140b86135f6565b5b600182039050919050565b7f537472696e67733a20686578206c656e67746820696e73756666696369656e74600082015250565b60006140fa6020836132f2565b9150614105826140c4565b602082019050919050565b60006020820190508181036000830152614129816140ed565b9050919050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b60006141666020836132f2565b915061417182614130565b602082019050919050565b6000602082019050818103600083015261419581614159565b9050919050565b7f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960008201527f6e697469616c697a696e67000000000000000000000000000000000000000000602082015250565b60006141f8602b836132f2565b91506142038261419c565b604082019050919050565b60006020820190508181036000830152614227816141eb565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b7f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60008201527f6f74206120636f6e747261637400000000000000000000000000000000000000602082015250565b60006142b9602d836132f2565b91506142c48261425d565b604082019050919050565b600060208201905081810360008301526142e8816142ac565b9050919050565b600081519050919050565b600081905092915050565b6000614310826142ef565b61431a81856142fa565b935061432a818560208601612cc6565b80840191505092915050565b60006143428284614305565b915081905092915050565b7f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000600082015250565b6000614383601d836132f2565b915061438e8261434d565b602082019050919050565b600060208201905081810360008301526143b281614376565b905091905056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220b4bf925201e6678de241226d32892a5fd5f5b14ef6544a9632a6c4c083a0c33b64736f6c634300080c0033
Deployed Bytecode
0x6080604052600436106101665760003560e01c8063715018a6116100d1578063cbb8bf9b1161008a578063eb2891d911610064578063eb2891d914610567578063f2fde38b146105a4578063f4b033a8146105cd578063ff64df321461060a57610166565b8063cbb8bf9b146104d6578063ce90fdcf146104ff578063d370c7a71461052a57610166565b8063715018a6146103b45780637897fa0a146103cb5780638a8f802a146104085780638da5cb5b146104455780639bf0ad7814610470578063c4d66de8146104ad57610166565b80633659cfe6116101235780633659cfe61461028d57806348db39bf146102b65780634f1ef286146102f357806350ea0b101461030f57806352d1902d1461034c5780635e57966d1461037757610166565b80630dc960151461016b5780630f7aebb91461019657806311b928bd146101c157806319d78250146101ea578063273bb1cf14610227578063282f49e814610250575b600080fd5b34801561017757600080fd5b50610180610633565b60405161018d9190612ef8565b60405180910390f35b3480156101a257600080fd5b506101ab610a6d565b6040516101b89190612f29565b60405180910390f35b3480156101cd57600080fd5b506101e860048036038101906101e3919061308d565b610a83565b005b3480156101f657600080fd5b50610211600480360381019061020c9190613102565b610e58565b60405161021e9190612f29565b60405180910390f35b34801561023357600080fd5b5061024e6004803603810190610249919061308d565b610f05565b005b34801561025c57600080fd5b506102776004803603810190610272919061308d565b6110cc565b6040516102849190612f29565b60405180910390f35b34801561029957600080fd5b506102b460048036038101906102af9190613102565b6110f4565b005b3480156102c257600080fd5b506102dd60048036038101906102d8919061312f565b61127d565b6040516102ea91906131a6565b60405180910390f35b61030d60048036038101906103089190613262565b6112bc565b005b34801561031b57600080fd5b506103366004803603810190610331919061308d565b6113f9565b6040516103439190612f29565b60405180910390f35b34801561035857600080fd5b50610361611421565b60405161036e91906132d7565b60405180910390f35b34801561038357600080fd5b5061039e60048036038101906103999190613102565b6114da565b6040516103ab919061333c565b60405180910390f35b3480156103c057600080fd5b506103c9611504565b005b3480156103d757600080fd5b506103f260048036038101906103ed919061308d565b611518565b6040516103ff919061333c565b60405180910390f35b34801561041457600080fd5b5061042f600480360381019061042a919061308d565b6115c8565b60405161043c919061333c565b60405180910390f35b34801561045157600080fd5b5061045a611678565b604051610467919061336d565b60405180910390f35b34801561047c57600080fd5b506104976004803603810190610492919061308d565b6116a2565b6040516104a49190612f29565b60405180910390f35b3480156104b957600080fd5b506104d460048036038101906104cf9190613102565b6116d0565b005b3480156104e257600080fd5b506104fd60048036038101906104f8919061308d565b61198b565b005b34801561050b57600080fd5b50610514611b52565b604051610521919061344a565b60405180910390f35b34801561053657600080fd5b50610551600480360381019061054c919061308d565b611c2b565b60405161055e9190612f29565b60405180910390f35b34801561057357600080fd5b5061058e6004803603810190610589919061308d565b611c59565b60405161059b9190612f29565b60405180910390f35b3480156105b057600080fd5b506105cb60048036038101906105c69190613102565b611c81565b005b3480156105d957600080fd5b506105f460048036038101906105ef919061308d565b611d05565b604051610601919061333c565b60405180910390f35b34801561061657600080fd5b50610631600480360381019061062c919061346c565b611db5565b005b606061063d612b80565b600060d68054905067ffffffffffffffff81111561065e5761065d612f62565b5b60405190808252806020026020018201604052801561069757816020015b610684612b80565b81526020019060019003908161067c5790505b509050606060005b60d680549050811015610a635760d681815481106106c0576106bf613513565b5b9060005260206000200180546106d590613571565b80601f016020809104026020016040519081016040528092919081815260200182805461070190613571565b801561074e5780601f106107235761010080835404028352916020019161074e565b820191906000526020600020905b81548152906001019060200180831161073157829003601f168201915b5050505050915060405180610100016040528060d08460405161077191906135df565b9081526020016040518091039020805461078a90613571565b80601f01602080910402602001604051908101604052809291908181526020018280546107b690613571565b80156108035780601f106107d857610100808354040283529160200191610803565b820191906000526020600020905b8154815290600101906020018083116107e657829003601f168201915b5050505050815260200160d18460405161081d91906135df565b9081526020016040518091039020805461083690613571565b80601f016020809104026020016040519081016040528092919081815260200182805461086290613571565b80156108af5780601f10610884576101008083540402835291602001916108af565b820191906000526020600020905b81548152906001019060200180831161089257829003601f168201915b5050505050815260200160d2846040516108c991906135df565b908152602001604051809103902080546108e290613571565b80601f016020809104026020016040519081016040528092919081815260200182805461090e90613571565b801561095b5780601f106109305761010080835404028352916020019161095b565b820191906000526020600020905b81548152906001019060200180831161093e57829003601f168201915b5050505050815260200160ca8460405161097591906135df565b908152602001604051809103902054815260200160cb8460405161099991906135df565b908152602001604051809103902054815260200160cc846040516109bd91906135df565b908152602001604051809103902054815260200160d3846040516109e191906135df565b908152602001604051809103902060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200183815250935083838281518110610a4557610a44613513565b5b60200260200101819052508080610a5b90613625565b91505061069f565b5081935050505090565b6000600160d454610a7e919061366e565b905090565b6000610a8e826110cc565b10158015610aa557506000610aa2826113f9565b10155b610ae4576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610adb906136ee565b60405180910390fd5b43610aee82611c59565b1115610b2f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b269061375a565b60405180910390fd5b600060ce82604051610b4191906135df565b908152602001604051809103902060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020541180610bf45750600060cf82604051610ba691906135df565b908152602001604051809103902060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054115b610c33576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c2a906137ec565b60405180910390fd5b60ce81604051610c4391906135df565b908152602001604051809103902060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205460cc82604051610c9f91906135df565b90815260200160405180910390206000828254610cbc919061366e565b9250508190555060cf81604051610cd391906135df565b908152602001604051809103902060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205460cb82604051610d2f91906135df565b90815260200160405180910390206000828254610d4c919061366e565b92505081905550600060ce82604051610d6591906135df565b908152602001604051809103902060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550600060cf82604051610dc691906135df565b908152602001604051809103902060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550600060cd610e23833361202b565b604051610e3091906135df565b908152602001604051809103902060006101000a81548160ff02191690831515021790555050565b600060d560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663b5e72a57610ea1846114da565b6040518263ffffffff1660e01b8152600401610ebd919061333c565b602060405180830381865afa158015610eda573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610efe9190613838565b9050919050565b6000610f10826110cc565b1015610f51576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f48906138b1565b60405180910390fd5b43610f5b82611c59565b1115610f9c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f939061375a565b60405180910390fd5b610fa6813361127d565b15610fe6576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610fdd9061391d565b60405180910390fd5b6000610ff133610e58565b90508060cb8360405161100491906135df565b90815260200160405180910390206000828254611021919061393d565b92505081905550600160cd611036843361202b565b60405161104391906135df565b908152602001604051809103902060006101000a81548160ff0219169083151502179055508060cf8360405161107991906135df565b908152602001604051809103902060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055505050565b600060cb826040516110de91906135df565b9081526020016040518091039020549050919050565b7f0000000000000000000000009dda895d0ad30dbbe978e25adfc80bbd9ea2e1c173ffffffffffffffffffffffffffffffffffffffff163073ffffffffffffffffffffffffffffffffffffffff161415611183576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161117a90613a05565b60405180910390fd5b7f0000000000000000000000009dda895d0ad30dbbe978e25adfc80bbd9ea2e1c173ffffffffffffffffffffffffffffffffffffffff166111c261205f565b73ffffffffffffffffffffffffffffffffffffffff1614611218576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161120f90613a97565b60405180910390fd5b611221816120b6565b61127a81600067ffffffffffffffff8111156112405761123f612f62565b5b6040519080825280601f01601f1916602001820160405280156112725781602001600182028036833780820191505090505b5060006120c1565b50565b600060cd61128b848461202b565b60405161129891906135df565b908152602001604051809103902060009054906101000a900460ff16905092915050565b7f0000000000000000000000009dda895d0ad30dbbe978e25adfc80bbd9ea2e1c173ffffffffffffffffffffffffffffffffffffffff163073ffffffffffffffffffffffffffffffffffffffff16141561134b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161134290613a05565b60405180910390fd5b7f0000000000000000000000009dda895d0ad30dbbe978e25adfc80bbd9ea2e1c173ffffffffffffffffffffffffffffffffffffffff1661138a61205f565b73ffffffffffffffffffffffffffffffffffffffff16146113e0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016113d790613a97565b60405180910390fd5b6113e9826120b6565b6113f5828260016120c1565b5050565b600060cc8260405161140b91906135df565b9081526020016040518091039020549050919050565b60007f0000000000000000000000009dda895d0ad30dbbe978e25adfc80bbd9ea2e1c173ffffffffffffffffffffffffffffffffffffffff163073ffffffffffffffffffffffffffffffffffffffff16146114b1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016114a890613b29565b60405180910390fd5b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc60001b905090565b60606114fd8273ffffffffffffffffffffffffffffffffffffffff16601461222f565b9050919050565b61150c61246b565b61151660006124e9565b565b606060d28260405161152a91906135df565b9081526020016040518091039020805461154390613571565b80601f016020809104026020016040519081016040528092919081815260200182805461156f90613571565b80156115bc5780601f10611591576101008083540402835291602001916115bc565b820191906000526020600020905b81548152906001019060200180831161159f57829003601f168201915b50505050509050919050565b606060d1826040516115da91906135df565b908152602001604051809103902080546115f390613571565b80601f016020809104026020016040519081016040528092919081815260200182805461161f90613571565b801561166c5780601f106116415761010080835404028352916020019161166c565b820191906000526020600020905b81548152906001019060200180831161164f57829003601f168201915b50505050509050919050565b6000603360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b60cb818051602081018201805184825260208301602085012081835280955050505050506000915090505481565b60008060019054906101000a900460ff161590508080156117015750600160008054906101000a900460ff1660ff16105b8061172e5750611710306125af565b15801561172d5750600160008054906101000a900460ff1660ff16145b5b61176d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161176490613bbb565b60405180910390fd5b60016000806101000a81548160ff021916908360ff16021790555080156117aa576001600060016101000a81548160ff0219169083151502179055505b7f0000000000000000000000009dda895d0ad30dbbe978e25adfc80bbd9ea2e1c173ffffffffffffffffffffffffffffffffffffffff163073ffffffffffffffffffffffffffffffffffffffff161415611839576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161183090613a05565b60405180910390fd5b7f0000000000000000000000009dda895d0ad30dbbe978e25adfc80bbd9ea2e1c173ffffffffffffffffffffffffffffffffffffffff1661187861205f565b73ffffffffffffffffffffffffffffffffffffffff16146118ce576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016118c590613a97565b60405180910390fd5b6118d66125d2565b670de0b6b3a764000060c9819055508160d560006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550600060d48190555080156119875760008060016101000a81548160ff0219169083151502179055507f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498600160405161197e9190613c2d565b60405180910390a15b5050565b6000611996826113f9565b10156119d7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016119ce906138b1565b60405180910390fd5b436119e182611c59565b1115611a22576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611a199061375a565b60405180910390fd5b611a2c813361127d565b15611a6c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611a6390613c94565b60405180910390fd5b6000611a7733610e58565b90508060cc83604051611a8a91906135df565b90815260200160405180910390206000828254611aa7919061393d565b92505081905550600160cd611abc843361202b565b604051611ac991906135df565b908152602001604051809103902060006101000a81548160ff0219169083151502179055508060ce83604051611aff91906135df565b908152602001604051809103902060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055505050565b606060d6805480602002602001604051908101604052809291908181526020016000905b82821015611c22578382906000526020600020018054611b9590613571565b80601f0160208091040260200160405190810160405280929190818152602001828054611bc190613571565b8015611c0e5780601f10611be357610100808354040283529160200191611c0e565b820191906000526020600020905b815481529060010190602001808311611bf157829003601f168201915b505050505081526020019060010190611b76565b50505050905090565b60cc818051602081018201805184825260208301602085012081835280955050505050506000915090505481565b600060ca82604051611c6b91906135df565b9081526020016040518091039020549050919050565b611c8961246b565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415611cf9576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611cf090613d26565b60405180910390fd5b611d02816124e9565b50565b606060d082604051611d1791906135df565b90815260200160405180910390208054611d3090613571565b80601f0160208091040260200160405190810160405280929190818152602001828054611d5c90613571565b8015611da95780601f10611d7e57610100808354040283529160200191611da9565b820191906000526020600020905b815481529060010190602001808311611d8c57829003601f168201915b50505050509050919050565b6000611dc0326114da565b9050600081604051602001611dd59190613d6c565b604051602081830303815290604052905080611df260d45461262b565b604051602001611e03929190613d92565b604051602081830303815290604052905060c954611e2033610e58565b1015611e61576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611e5890613e28565b60405180910390fd5b62034bc043611e70919061393d565b60ca82604051611e8091906135df565b9081526020016040518091039020819055508460d082604051611ea391906135df565b90815260200160405180910390209080519060200190611ec4929190612bdb565b508360d182604051611ed691906135df565b90815260200160405180910390209080519060200190611ef7929190612bdb565b508260d282604051611f0991906135df565b90815260200160405180910390209080519060200190611f2a929190612bdb565b503360d382604051611f3c91906135df565b908152602001604051809103902060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550600060cb82604051611f9a91906135df565b908152602001604051809103902081905550600060cc82604051611fbe91906135df565b90815260200160405180910390208190555060d68190806001815401808255809150506001900390600052602060002001600090919091909150908051906020019061200b929190612bdb565b5060d4600081548092919061201f90613625565b91905055505050505050565b606082612037836114da565b604051602001612048929190613e94565b604051602081830303815290604052905092915050565b600061208d7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc60001b612703565b60000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6120be61246b565b50565b6120ed7f4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd914360001b61270d565b60000160009054906101000a900460ff16156121115761210c83612717565b61222a565b8273ffffffffffffffffffffffffffffffffffffffff166352d1902d6040518163ffffffff1660e01b8152600401602060405180830381865afa92505050801561217957506040513d601f19601f820116820180604052508101906121769190613eef565b60015b6121b8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016121af90613f8e565b60405180910390fd5b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc60001b811461221d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161221490614020565b60405180910390fd5b506122298383836127d0565b5b505050565b6060600060028360026122429190614040565b61224c919061393d565b67ffffffffffffffff81111561226557612264612f62565b5b6040519080825280601f01601f1916602001820160405280156122975781602001600182028036833780820191505090505b5090507f3000000000000000000000000000000000000000000000000000000000000000816000815181106122cf576122ce613513565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053507f78000000000000000000000000000000000000000000000000000000000000008160018151811061233357612332613513565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600060018460026123739190614040565b61237d919061393d565b90505b600181111561241d577f3031323334353637383961626364656600000000000000000000000000000000600f8616601081106123bf576123be613513565b5b1a60f81b8282815181106123d6576123d5613513565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600485901c9450806124169061409a565b9050612380565b5060008414612461576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161245890614110565b60405180910390fd5b8091505092915050565b6124736127fc565b73ffffffffffffffffffffffffffffffffffffffff16612491611678565b73ffffffffffffffffffffffffffffffffffffffff16146124e7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016124de9061417c565b60405180910390fd5b565b6000603360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081603360006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b600060019054906101000a900460ff16612621576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016126189061420e565b60405180910390fd5b612629612804565b565b60606000600161263a84612865565b01905060008167ffffffffffffffff81111561265957612658612f62565b5b6040519080825280601f01601f19166020018201604052801561268b5781602001600182028036833780820191505090505b509050600082602001820190505b6001156126f8578080600190039150507f3031323334353637383961626364656600000000000000000000000000000000600a86061a8153600a85816126e2576126e161422e565b5b04945060008514156126f3576126f8565b612699565b819350505050919050565b6000819050919050565b6000819050919050565b612720816125af565b61275f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612756906142cf565b60405180910390fd5b8061278c7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc60001b612703565b60000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b6127d9836129b8565b6000825111806127e65750805b156127f7576127f58383612a07565b505b505050565b600033905090565b600060019054906101000a900460ff16612853576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161284a9061420e565b60405180910390fd5b61286361285e6127fc565b6124e9565b565b600080600090507a184f03e93ff9f4daa797ed6e38ed64bf6a1f01000000000000000083106128c3577a184f03e93ff9f4daa797ed6e38ed64bf6a1f01000000000000000083816128b9576128b861422e565b5b0492506040810190505b6d04ee2d6d415b85acef81000000008310612900576d04ee2d6d415b85acef810000000083816128f6576128f561422e565b5b0492506020810190505b662386f26fc10000831061292f57662386f26fc1000083816129255761292461422e565b5b0492506010810190505b6305f5e1008310612958576305f5e100838161294e5761294d61422e565b5b0492506008810190505b612710831061297d5761271083816129735761297261422e565b5b0492506004810190505b606483106129a057606483816129965761299561422e565b5b0492506002810190505b600a83106129af576001810190505b80915050919050565b6129c181612717565b8073ffffffffffffffffffffffffffffffffffffffff167fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b60405160405180910390a250565b6060612a2c83836040518060600160405280602781526020016143ba60279139612a34565b905092915050565b60606000808573ffffffffffffffffffffffffffffffffffffffff1685604051612a5e9190614336565b600060405180830381855af49150503d8060008114612a99576040519150601f19603f3d011682016040523d82523d6000602084013e612a9e565b606091505b5091509150612aaf86838387612aba565b925050509392505050565b60608315612b1d57600083511415612b1557612ad5856125af565b612b14576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612b0b90614399565b60405180910390fd5b5b829050612b28565b612b278383612b30565b5b949350505050565b600082511115612b435781518083602001fd5b806040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612b77919061333c565b60405180910390fd5b604051806101000160405280606081526020016060815260200160608152602001600081526020016000815260200160008152602001600073ffffffffffffffffffffffffffffffffffffffff168152602001606081525090565b828054612be790613571565b90600052602060002090601f016020900481019282612c095760008555612c50565b82601f10612c2257805160ff1916838001178555612c50565b82800160010185558215612c50579182015b82811115612c4f578251825591602001919060010190612c34565b5b509050612c5d9190612c61565b5090565b5b80821115612c7a576000816000905550600101612c62565b5090565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b600081519050919050565b600082825260208201905092915050565b60005b83811015612ce4578082015181840152602081019050612cc9565b83811115612cf3576000848401525b50505050565b6000601f19601f8301169050919050565b6000612d1582612caa565b612d1f8185612cb5565b9350612d2f818560208601612cc6565b612d3881612cf9565b840191505092915050565b6000819050919050565b612d5681612d43565b82525050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000612d8782612d5c565b9050919050565b612d9781612d7c565b82525050565b6000610100830160008301518482036000860152612dbb8282612d0a565b91505060208301518482036020860152612dd58282612d0a565b91505060408301518482036040860152612def8282612d0a565b9150506060830151612e046060860182612d4d565b506080830151612e176080860182612d4d565b5060a0830151612e2a60a0860182612d4d565b5060c0830151612e3d60c0860182612d8e565b5060e083015184820360e0860152612e558282612d0a565b9150508091505092915050565b6000612e6e8383612d9d565b905092915050565b6000602082019050919050565b6000612e8e82612c7e565b612e988185612c89565b935083602082028501612eaa85612c9a565b8060005b85811015612ee65784840389528151612ec78582612e62565b9450612ed283612e76565b925060208a01995050600181019050612eae565b50829750879550505050505092915050565b60006020820190508181036000830152612f128184612e83565b905092915050565b612f2381612d43565b82525050565b6000602082019050612f3e6000830184612f1a565b92915050565b6000604051905090565b600080fd5b600080fd5b600080fd5b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b612f9a82612cf9565b810181811067ffffffffffffffff82111715612fb957612fb8612f62565b5b80604052505050565b6000612fcc612f44565b9050612fd88282612f91565b919050565b600067ffffffffffffffff821115612ff857612ff7612f62565b5b61300182612cf9565b9050602081019050919050565b82818337600083830152505050565b600061303061302b84612fdd565b612fc2565b90508281526020810184848401111561304c5761304b612f5d565b5b61305784828561300e565b509392505050565b600082601f83011261307457613073612f58565b5b813561308484826020860161301d565b91505092915050565b6000602082840312156130a3576130a2612f4e565b5b600082013567ffffffffffffffff8111156130c1576130c0612f53565b5b6130cd8482850161305f565b91505092915050565b6130df81612d7c565b81146130ea57600080fd5b50565b6000813590506130fc816130d6565b92915050565b60006020828403121561311857613117612f4e565b5b6000613126848285016130ed565b91505092915050565b6000806040838503121561314657613145612f4e565b5b600083013567ffffffffffffffff81111561316457613163612f53565b5b6131708582860161305f565b9250506020613181858286016130ed565b9150509250929050565b60008115159050919050565b6131a08161318b565b82525050565b60006020820190506131bb6000830184613197565b92915050565b600067ffffffffffffffff8211156131dc576131db612f62565b5b6131e582612cf9565b9050602081019050919050565b6000613205613200846131c1565b612fc2565b90508281526020810184848401111561322157613220612f5d565b5b61322c84828561300e565b509392505050565b600082601f83011261324957613248612f58565b5b81356132598482602086016131f2565b91505092915050565b6000806040838503121561327957613278612f4e565b5b6000613287858286016130ed565b925050602083013567ffffffffffffffff8111156132a8576132a7612f53565b5b6132b485828601613234565b9150509250929050565b6000819050919050565b6132d1816132be565b82525050565b60006020820190506132ec60008301846132c8565b92915050565b600082825260208201905092915050565b600061330e82612caa565b61331881856132f2565b9350613328818560208601612cc6565b61333181612cf9565b840191505092915050565b600060208201905081810360008301526133568184613303565b905092915050565b61336781612d7c565b82525050565b6000602082019050613382600083018461335e565b92915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b60006133c08383612d0a565b905092915050565b6000602082019050919050565b60006133e082613388565b6133ea8185613393565b9350836020820285016133fc856133a4565b8060005b85811015613438578484038952815161341985826133b4565b9450613424836133c8565b925060208a01995050600181019050613400565b50829750879550505050505092915050565b6000602082019050818103600083015261346481846133d5565b905092915050565b60008060006060848603121561348557613484612f4e565b5b600084013567ffffffffffffffff8111156134a3576134a2612f53565b5b6134af8682870161305f565b935050602084013567ffffffffffffffff8111156134d0576134cf612f53565b5b6134dc8682870161305f565b925050604084013567ffffffffffffffff8111156134fd576134fc612f53565b5b6135098682870161305f565b9150509250925092565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b6000600282049050600182168061358957607f821691505b6020821081141561359d5761359c613542565b5b50919050565b600081905092915050565b60006135b982612caa565b6135c381856135a3565b93506135d3818560208601612cc6565b80840191505092915050565b60006135eb82846135ae565b915081905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600061363082612d43565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff821415613663576136626135f6565b5b600182019050919050565b600061367982612d43565b915061368483612d43565b925082821015613697576136966135f6565b5b828203905092915050565b7f4e6f2061637469766520766f746520666f72207468697320766f746520696421600082015250565b60006136d86020836132f2565b91506136e3826136a2565b602082019050919050565b60006020820190508181036000830152613707816136cb565b9050919050565b7f566f7465206e6f206c6f6e676572206163746976652100000000000000000000600082015250565b60006137446016836132f2565b915061374f8261370e565b602082019050919050565b6000602082019050818103600083015261377381613737565b9050919050565b7f557365727320686173206e6f7420766f74656420666f72207468697320766f7460008201527f6521000000000000000000000000000000000000000000000000000000000000602082015250565b60006137d66022836132f2565b91506137e18261377a565b604082019050919050565b60006020820190508181036000830152613805816137c9565b9050919050565b61381581612d43565b811461382057600080fd5b50565b6000815190506138328161380c565b92915050565b60006020828403121561384e5761384d612f4e565b5b600061385c84828501613823565b91505092915050565b7f566f7465206e6f7420666f756e64210000000000000000000000000000000000600082015250565b600061389b600f836132f2565b91506138a682613865565b602082019050919050565b600060208201905081810360008301526138ca8161388e565b9050919050565b7f5573657220616c726561647920766f7465642100000000000000000000000000600082015250565b60006139076013836132f2565b9150613912826138d1565b602082019050919050565b60006020820190508181036000830152613936816138fa565b9050919050565b600061394882612d43565b915061395383612d43565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff03821115613988576139876135f6565b5b828201905092915050565b7f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060008201527f64656c656761746563616c6c0000000000000000000000000000000000000000602082015250565b60006139ef602c836132f2565b91506139fa82613993565b604082019050919050565b60006020820190508181036000830152613a1e816139e2565b9050919050565b7f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060008201527f6163746976652070726f78790000000000000000000000000000000000000000602082015250565b6000613a81602c836132f2565b9150613a8c82613a25565b604082019050919050565b60006020820190508181036000830152613ab081613a74565b9050919050565b7f555550535570677261646561626c653a206d757374206e6f742062652063616c60008201527f6c6564207468726f7567682064656c656761746563616c6c0000000000000000602082015250565b6000613b136038836132f2565b9150613b1e82613ab7565b604082019050919050565b60006020820190508181036000830152613b4281613b06565b9050919050565b7f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160008201527f647920696e697469616c697a6564000000000000000000000000000000000000602082015250565b6000613ba5602e836132f2565b9150613bb082613b49565b604082019050919050565b60006020820190508181036000830152613bd481613b98565b9050919050565b6000819050919050565b600060ff82169050919050565b6000819050919050565b6000613c17613c12613c0d84613bdb565b613bf2565b613be5565b9050919050565b613c2781613bfc565b82525050565b6000602082019050613c426000830184613c1e565b92915050565b7f4164647265737320616c726561647920766f7465642100000000000000000000600082015250565b6000613c7e6016836132f2565b9150613c8982613c48565b602082019050919050565b60006020820190508181036000830152613cad81613c71565b9050919050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b6000613d106026836132f2565b9150613d1b82613cb4565b604082019050919050565b60006020820190508181036000830152613d3f81613d03565b9050919050565b7f5f00000000000000000000000000000000000000000000000000000000000000815250565b6000613d7882846135ae565b9150613d8382613d46565b60018201915081905092915050565b6000613d9e82856135ae565b9150613daa82846135ae565b91508190509392505050565b7f5573657220686173206e6f74206265656e2061637469766520656e6f7567682060008201527f6f6e2074686520706c6174666f726d2100000000000000000000000000000000602082015250565b6000613e126030836132f2565b9150613e1d82613db6565b604082019050919050565b60006020820190508181036000830152613e4181613e05565b9050919050565b7f5f00000000000000000000000000000000000000000000000000000000000000600082015250565b6000613e7e6001836135a3565b9150613e8982613e48565b600182019050919050565b6000613ea082856135ae565b9150613eab82613e71565b9150613eb782846135ae565b91508190509392505050565b613ecc816132be565b8114613ed757600080fd5b50565b600081519050613ee981613ec3565b92915050565b600060208284031215613f0557613f04612f4e565b5b6000613f1384828501613eda565b91505092915050565b7f45524331393637557067726164653a206e657720696d706c656d656e7461746960008201527f6f6e206973206e6f742055555053000000000000000000000000000000000000602082015250565b6000613f78602e836132f2565b9150613f8382613f1c565b604082019050919050565b60006020820190508181036000830152613fa781613f6b565b9050919050565b7f45524331393637557067726164653a20756e737570706f727465642070726f7860008201527f6961626c65555549440000000000000000000000000000000000000000000000602082015250565b600061400a6029836132f2565b915061401582613fae565b604082019050919050565b6000602082019050818103600083015261403981613ffd565b9050919050565b600061404b82612d43565b915061405683612d43565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048311821515161561408f5761408e6135f6565b5b828202905092915050565b60006140a582612d43565b915060008214156140b9576140b86135f6565b5b600182039050919050565b7f537472696e67733a20686578206c656e67746820696e73756666696369656e74600082015250565b60006140fa6020836132f2565b9150614105826140c4565b602082019050919050565b60006020820190508181036000830152614129816140ed565b9050919050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b60006141666020836132f2565b915061417182614130565b602082019050919050565b6000602082019050818103600083015261419581614159565b9050919050565b7f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960008201527f6e697469616c697a696e67000000000000000000000000000000000000000000602082015250565b60006141f8602b836132f2565b91506142038261419c565b604082019050919050565b60006020820190508181036000830152614227816141eb565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b7f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60008201527f6f74206120636f6e747261637400000000000000000000000000000000000000602082015250565b60006142b9602d836132f2565b91506142c48261425d565b604082019050919050565b600060208201905081810360008301526142e8816142ac565b9050919050565b600081519050919050565b600081905092915050565b6000614310826142ef565b61431a81856142fa565b935061432a818560208601612cc6565b80840191505092915050565b60006143428284614305565b915081905092915050565b7f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000600082015250565b6000614383601d836132f2565b915061438e8261434d565b602082019050919050565b600060208201905081810360008301526143b281614376565b905091905056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220b4bf925201e6678de241226d32892a5fd5f5b14ef6544a9632a6c4c083a0c33b64736f6c634300080c0033
Loading...
Loading
Loading...
Loading
Loading...
Loading
Loading...
Loading
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.