Overview
S Balance
S Value
$0.00More Info
Private Name Tags
ContractCreator
Multichain Info
No addresses found
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Latest 1 internal transaction
Parent Transaction Hash | Block | From | To | |||
---|---|---|---|---|---|---|
2898905 | 76 days ago | Contract Creation | 0 S |
Loading...
Loading
Contract Name:
Authorizer
Compiler Version
v0.8.17+commit.8df45f5f
Optimization Enabled:
Yes with 10000 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: GPL-3.0-or-later // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. pragma solidity ^0.8.17; import '@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol'; import '@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol'; import './AuthorizedHelpers.sol'; import './interfaces/IAuthorizer.sol'; /** * @title Authorizer * @dev Authorization mechanism based on permissions */ contract Authorizer is IAuthorizer, AuthorizedHelpers, Initializable, ReentrancyGuardUpgradeable { // Constant used to denote that a permission is open to anyone address public constant ANYONE = address(0xFFfFfFffFFfffFFfFFfFFFFFffFFFffffFfFFFfF); // Constant used to denote that a permission is open to anywhere address public constant ANYWHERE = address(0xFFfFfFffFFfffFFfFFfFFFFFffFFFffffFfFFFfF); // Param logic op types enum Op { NONE, EQ, NEQ, GT, LT, GTE, LTE } /** * @dev Permission information * @param authorized Whether it is authorized or not * @param params List of params defined for each permission */ struct Permission { bool authorized; Param[] params; } /** * @dev Permissions list information * @param count Number of permissions * @param permissions List of permissions indexed by what */ struct PermissionsList { uint256 count; mapping (bytes4 => Permission) permissions; } // List of permissions indexed by who => where mapping (address => mapping (address => PermissionsList)) private _permissionsLists; /** * @dev Creates a new authorizer contract. Note that initializers are disabled at creation time. */ constructor() { _disableInitializers(); } /** * @dev Initialization function. * @param owners List of addresses that will be allowed to authorize and unauthorize permissions */ function initialize(address[] memory owners) external virtual initializer { __ReentrancyGuard_init(); for (uint256 i = 0; i < owners.length; i++) { _authorize(owners[i], address(this), IAuthorizer.authorize.selector, new Param[](0)); _authorize(owners[i], address(this), IAuthorizer.unauthorize.selector, new Param[](0)); } } /** * @dev Tells whether `who` has any permission on `where` * @param who Address asking permission for * @param where Target address asking permission for */ function hasPermissions(address who, address where) external view override returns (bool) { return _permissionsLists[who][where].count > 0; } /** * @dev Tells the number of permissions `who` has on `where` * @param who Address asking permission for * @param where Target address asking permission for */ function getPermissionsLength(address who, address where) external view override returns (uint256) { return _permissionsLists[who][where].count; } /** * @dev Tells whether `who` has permission to call `what` on `where`. Note `how` is not evaluated here, * which means `who` might be authorized on or not depending on the call at the moment of the execution * @param who Address asking permission for * @param where Target address asking permission for * @param what Function selector asking permission for */ function hasPermission(address who, address where, bytes4 what) external view override returns (bool) { return _permissionsLists[who][where].permissions[what].authorized; } /** * @dev Tells whether `who` is allowed to call `what` on `where` with `how` * @param who Address asking permission for * @param where Target address asking permission for * @param what Function selector asking permission for * @param how Params asking permission for */ function isAuthorized(address who, address where, bytes4 what, uint256[] memory how) public view override returns (bool) { if (_isAuthorized(who, where, what, how)) return true; // direct permission if (_isAuthorized(ANYONE, where, what, how)) return true; // anyone is allowed if (_isAuthorized(who, ANYWHERE, what, how)) return true; // direct permission on anywhere if (_isAuthorized(ANYONE, ANYWHERE, what, how)) return true; // anyone allowed anywhere return false; } /** * @dev Tells the params set for a given permission * @param who Address asking permission params of * @param where Target address asking permission params of * @param what Function selector asking permission params of */ function getPermissionParams(address who, address where, bytes4 what) external view override returns (Param[] memory) { return _permissionsLists[who][where].permissions[what].params; } /** * @dev Executes a list of permission changes. Sender must be authorized. * @param changes List of permission changes to be executed */ function changePermissions(PermissionChange[] memory changes) external override { for (uint256 i = 0; i < changes.length; i++) { PermissionChange memory change = changes[i]; for (uint256 j = 0; j < change.grants.length; j++) { GrantPermission memory grant = change.grants[j]; authorize(grant.who, change.where, grant.what, grant.params); } for (uint256 j = 0; j < change.revokes.length; j++) { RevokePermission memory revoke = change.revokes[j]; unauthorize(revoke.who, change.where, revoke.what); } } } /** * @dev Authorizes `who` to call `what` on `where` restricted by `params`. Sender must be authorized. * @param who Address to be authorized * @param where Target address to be granted for * @param what Function selector to be granted * @param params Optional params to restrict a permission attempt */ function authorize(address who, address where, bytes4 what, Param[] memory params) public override nonReentrant { uint256[] memory how = authParams(who, where, what); _authenticate(msg.sender, IAuthorizer.authorize.selector, how); _authorize(who, where, what, params); } /** * @dev Unauthorizes `who` to call `what` on `where`. Sender must be authorized. * @param who Address to be authorized * @param where Target address to be revoked for * @param what Function selector to be revoked */ function unauthorize(address who, address where, bytes4 what) public override nonReentrant { uint256[] memory how = authParams(who, where, what); _authenticate(msg.sender, IAuthorizer.unauthorize.selector, how); _unauthorize(who, where, what); } /** * @dev Validates whether `who` is authorized to call `what` with `how` * @param who Address asking permission for * @param what Function selector asking permission for * @param how Params asking permission for */ function _authenticate(address who, bytes4 what, uint256[] memory how) internal view { bool allowed = isAuthorized(who, address(this), what, how); if (!allowed) revert AuthorizerSenderNotAllowed(who, address(this), what, how); } /** * @dev Tells whether `who` is allowed to call `what` on `where` with `how` * @param who Address asking permission for * @param where Target address asking permission for * @param what Function selector asking permission for * @param how Params asking permission for */ function _isAuthorized(address who, address where, bytes4 what, uint256[] memory how) internal view returns (bool) { Permission storage permission = _permissionsLists[who][where].permissions[what]; return permission.authorized && _evalParams(permission.params, how); } /** * @dev Authorizes `who` to call `what` on `where` restricted by `params` * @param who Address to be authorized * @param where Target address to be granted for * @param what Function selector to be granted * @param params Optional params to restrict a permission attempt */ function _authorize(address who, address where, bytes4 what, Param[] memory params) internal { PermissionsList storage list = _permissionsLists[who][where]; Permission storage permission = list.permissions[what]; if (!permission.authorized) list.count++; permission.authorized = true; delete permission.params; for (uint256 i = 0; i < params.length; i++) permission.params.push(params[i]); emit Authorized(who, where, what, params); } /** * @dev Unauthorizes `who` to call `what` on `where` * @param who Address to be authorized * @param where Target address to be revoked for * @param what Function selector to be revoked */ function _unauthorize(address who, address where, bytes4 what) internal { PermissionsList storage list = _permissionsLists[who][where]; Permission storage permission = list.permissions[what]; if (permission.authorized) list.count--; delete list.permissions[what]; emit Unauthorized(who, where, what); } /** * @dev Evaluates a list of params defined for a permission against a list of values given by a call * @param params List of expected params * @param how List of actual given values * @return True if all the given values hold against the list of params */ function _evalParams(Param[] memory params, uint256[] memory how) private pure returns (bool) { for (uint256 i = 0; i < params.length; i++) { Param memory param = params[i]; if ((i < how.length && !_evalParam(param, how[i])) || (i >= how.length && Op(param.op) != Op.NONE)) { return false; } } return true; } /** * @dev Evaluates a single param defined for a permission against a single value * @param param Expected params * @param how Actual given value * @return True if the given value hold against the expected param */ function _evalParam(Param memory param, uint256 how) private pure returns (bool) { if (Op(param.op) == Op.NONE) return true; if (Op(param.op) == Op.EQ) return how == param.value; if (Op(param.op) == Op.NEQ) return how != param.value; if (Op(param.op) == Op.GT) return how > param.value; if (Op(param.op) == Op.LT) return how < param.value; if (Op(param.op) == Op.GTE) return how >= param.value; if (Op(param.op) == Op.LTE) return how <= param.value; revert AuthorizerInvalidParamOp(param.op); } }
// 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) (security/ReentrancyGuard.sol) pragma solidity ^0.8.0; import "../proxy/utils/Initializable.sol"; /** * @dev Contract module that helps prevent reentrant calls to a function. * * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier * available, which can be applied to functions to make sure there are no nested * (reentrant) calls to them. * * Note that because there is a single `nonReentrant` guard, functions marked as * `nonReentrant` may not call one another. This can be worked around by making * those functions `private`, and then adding `external` `nonReentrant` entry * points to them. * * TIP: If you would like to learn more about reentrancy and alternative ways * to protect against it, check out our blog post * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul]. */ abstract contract ReentrancyGuardUpgradeable is Initializable { // Booleans are more expensive than uint256 or any type that takes up a full // word because each write operation emits an extra SLOAD to first read the // slot's contents, replace the bits taken up by the boolean, and then write // back. This is the compiler's defense against contract upgrades and // pointer aliasing, and it cannot be disabled. // The values being non-zero value makes deployment a bit more expensive, // but in exchange the refund on every call to nonReentrant will be lower in // amount. Since refunds are capped to a percentage of the total // transaction's gas, it is best to keep them low in cases like this one, to // increase the likelihood of the full refund coming into effect. uint256 private constant _NOT_ENTERED = 1; uint256 private constant _ENTERED = 2; uint256 private _status; function __ReentrancyGuard_init() internal onlyInitializing { __ReentrancyGuard_init_unchained(); } function __ReentrancyGuard_init_unchained() internal onlyInitializing { _status = _NOT_ENTERED; } /** * @dev Prevents a contract from calling itself, directly or indirectly. * Calling a `nonReentrant` function from another `nonReentrant` * function is not supported. It is possible to prevent this from happening * by making the `nonReentrant` function external, and making it call a * `private` function that does the actual work. */ modifier nonReentrant() { _nonReentrantBefore(); _; _nonReentrantAfter(); } function _nonReentrantBefore() private { // On the first call to nonReentrant, _status will be _NOT_ENTERED require(_status != _ENTERED, "ReentrancyGuard: reentrant call"); // Any calls to nonReentrant after this point will fail _status = _ENTERED; } function _nonReentrantAfter() private { // By storing the original value once again, a refund is triggered (see // https://eips.ethereum.org/EIPS/eip-2200) _status = _NOT_ENTERED; } /** * @dev Returns true if the reentrancy guard is currently set to "entered", which indicates there is a * `nonReentrant` function in the call stack. */ function _reentrancyGuardEntered() internal view returns (bool) { return _status == _ENTERED; } /** * @dev This empty reserved space is put in place to allow future versions to add new * variables without shifting down storage in the inheritance chain. * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps */ uint256[49] private __gap; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol) pragma solidity ^0.8.1; /** * @dev Collection of functions related to the address type */ library AddressUpgradeable { /** * @dev Returns true if `account` is a contract. * * [IMPORTANT] * ==== * It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. * * Among others, `isContract` will return false for the following * types of addresses: * * - an externally-owned account * - a contract in construction * - an address where a contract will be created * - an address where a contract lived, but was destroyed * * Furthermore, `isContract` will also return true if the target contract within * the same transaction is already scheduled for destruction by `SELFDESTRUCT`, * which only has an effect at the end of a transaction. * ==== * * [IMPORTANT] * ==== * You shouldn't rely on `isContract` to protect against flash loan attacks! * * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract * constructor. * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize/address.code.length, which returns 0 // for contracts in construction, since the code is only stored at the end // of the constructor execution. return account.code.length > 0; } /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); (bool success, ) = recipient.call{value: amount}(""); require(success, "Address: unable to send value, recipient may have reverted"); } /** * @dev Performs a Solidity function call using a low level `call`. A * plain `call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason, it is bubbled up by this * function (like regular Solidity function calls). * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, "Address: low-level call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with * `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. * * _Available since v3.1._ */ function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) { return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); } /** * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value, string memory errorMessage ) internal returns (bytes memory) { require(address(this).balance >= value, "Address: insufficient balance for call"); (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall(target, data, "Address: low-level static call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall( address target, bytes memory data, string memory errorMessage ) internal view returns (bytes memory) { (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { return functionDelegateCall(target, data, "Address: low-level delegate call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { (bool success, bytes memory returndata) = target.delegatecall(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract. * * _Available since v4.8._ */ function verifyCallResultFromTarget( address target, bool success, bytes memory returndata, string memory errorMessage ) internal view returns (bytes memory) { if (success) { if (returndata.length == 0) { // only check isContract if the call was successful and the return data is empty // otherwise we already know that it was a contract require(isContract(target), "Address: call to non-contract"); } return returndata; } else { _revert(returndata, errorMessage); } } /** * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason or using the provided one. * * _Available since v4.3._ */ function verifyCallResult( bool success, bytes memory returndata, string memory errorMessage ) internal pure returns (bytes memory) { if (success) { return returndata; } else { _revert(returndata, errorMessage); } } function _revert(bytes memory returndata, string memory errorMessage) private pure { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly /// @solidity memory-safe-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } }
// SPDX-License-Identifier: GPL-3.0-or-later // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. pragma solidity ^0.8.17; import '@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol'; import './AuthorizedHelpers.sol'; import './interfaces/IAuthorized.sol'; import './interfaces/IAuthorizer.sol'; /** * @title Authorized * @dev Implementation using an authorizer as its access-control mechanism. It offers `auth` and `authP` modifiers to * tag its own functions in order to control who can access them against the authorizer referenced. */ contract Authorized is IAuthorized, Initializable, AuthorizedHelpers { // Authorizer reference address public override authorizer; /** * @dev Modifier that should be used to tag protected functions */ modifier auth() { _authenticate(msg.sender, msg.sig); _; } /** * @dev Modifier that should be used to tag protected functions with params */ modifier authP(uint256[] memory params) { _authenticate(msg.sender, msg.sig, params); _; } /** * @dev Creates a new authorized contract. Note that initializers are disabled at creation time. */ constructor() { _disableInitializers(); } /** * @dev Initializes the authorized contract. It does call upper contracts initializers. * @param _authorizer Address of the authorizer to be set */ function __Authorized_init(address _authorizer) internal onlyInitializing { __Authorized_init_unchained(_authorizer); } /** * @dev Initializes the authorized contract. It does not call upper contracts initializers. * @param _authorizer Address of the authorizer to be set */ function __Authorized_init_unchained(address _authorizer) internal onlyInitializing { authorizer = _authorizer; } /** * @dev Reverts if `who` is not allowed to call `what` * @param who Address to be authenticated * @param what Function selector to be authenticated */ function _authenticate(address who, bytes4 what) internal view { _authenticate(who, what, new uint256[](0)); } /** * @dev Reverts if `who` is not allowed to call `what` with `how` * @param who Address to be authenticated * @param what Function selector to be authenticated * @param how Params to be authenticated */ function _authenticate(address who, bytes4 what, uint256[] memory how) internal view { if (!_isAuthorized(who, what, how)) revert AuthSenderNotAllowed(who, what, how); } /** * @dev Tells whether `who` has any permission on this contract * @param who Address asking permissions for */ function _hasPermissions(address who) internal view returns (bool) { return IAuthorizer(authorizer).hasPermissions(who, address(this)); } /** * @dev Tells whether `who` is allowed to call `what` * @param who Address asking permission for * @param what Function selector asking permission for */ function _isAuthorized(address who, bytes4 what) internal view returns (bool) { return _isAuthorized(who, what, new uint256[](0)); } /** * @dev Tells whether `who` is allowed to call `what` with `how` * @param who Address asking permission for * @param what Function selector asking permission for * @param how Params asking permission for */ function _isAuthorized(address who, bytes4 what, uint256[] memory how) internal view returns (bool) { return IAuthorizer(authorizer).isAuthorized(who, address(this), what, how); } }
// SPDX-License-Identifier: GPL-3.0-or-later // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. pragma solidity ^0.8.17; /** * @title AuthorizedHelpers * @dev Syntax sugar methods to operate with authorizer params easily */ contract AuthorizedHelpers { function authParams(address p1) internal pure returns (uint256[] memory r) { return authParams(uint256(uint160(p1))); } function authParams(bytes32 p1) internal pure returns (uint256[] memory r) { return authParams(uint256(p1)); } function authParams(uint256 p1) internal pure returns (uint256[] memory r) { r = new uint256[](1); r[0] = p1; } function authParams(address p1, bool p2) internal pure returns (uint256[] memory r) { r = new uint256[](2); r[0] = uint256(uint160(p1)); r[1] = p2 ? 1 : 0; } function authParams(address p1, uint256 p2) internal pure returns (uint256[] memory r) { r = new uint256[](2); r[0] = uint256(uint160(p1)); r[1] = p2; } function authParams(address p1, address p2) internal pure returns (uint256[] memory r) { r = new uint256[](2); r[0] = uint256(uint160(p1)); r[1] = uint256(uint160(p2)); } function authParams(bytes32 p1, bytes32 p2) internal pure returns (uint256[] memory r) { r = new uint256[](2); r[0] = uint256(p1); r[1] = uint256(p2); } function authParams(address p1, address p2, uint256 p3) internal pure returns (uint256[] memory r) { r = new uint256[](3); r[0] = uint256(uint160(p1)); r[1] = uint256(uint160(p2)); r[2] = p3; } function authParams(address p1, address p2, address p3) internal pure returns (uint256[] memory r) { r = new uint256[](3); r[0] = uint256(uint160(p1)); r[1] = uint256(uint160(p2)); r[2] = uint256(uint160(p3)); } function authParams(address p1, address p2, bytes4 p3) internal pure returns (uint256[] memory r) { r = new uint256[](3); r[0] = uint256(uint160(p1)); r[1] = uint256(uint160(p2)); r[2] = uint256(uint32(p3)); } function authParams(address p1, uint256 p2, uint256 p3) internal pure returns (uint256[] memory r) { r = new uint256[](3); r[0] = uint256(uint160(p1)); r[1] = p2; r[2] = p3; } function authParams(uint256 p1, uint256 p2, uint256 p3, uint256 p4) internal pure returns (uint256[] memory r) { r = new uint256[](4); r[0] = p1; r[1] = p2; r[2] = p3; r[3] = p4; } function authParams(address p1, address p2, uint256 p3, uint256 p4) internal pure returns (uint256[] memory r) { r = new uint256[](4); r[0] = uint256(uint160(p1)); r[1] = uint256(uint160(p2)); r[2] = p3; r[3] = p4; } function authParams(address p1, uint256 p2, uint256 p3, uint256 p4) internal pure returns (uint256[] memory r) { r = new uint256[](4); r[0] = uint256(uint160(p1)); r[1] = p2; r[2] = p3; r[3] = p4; } function authParams(bytes32 p1, address p2, uint256 p3, bool p4) internal pure returns (uint256[] memory r) { r = new uint256[](4); r[0] = uint256(p1); r[1] = uint256(uint160(p2)); r[2] = p3; r[3] = p4 ? 1 : 0; } function authParams(address p1, uint256 p2, uint256 p3, uint256 p4, uint256 p5) internal pure returns (uint256[] memory r) { r = new uint256[](5); r[0] = uint256(uint160(p1)); r[1] = p2; r[2] = p3; r[3] = p4; r[4] = p5; } }
// SPDX-License-Identifier: GPL-3.0-or-later // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. pragma solidity >=0.8.0; /** * @dev Authorized interface */ interface IAuthorized { /** * @dev Sender `who` is not allowed to call `what` with `how` */ error AuthSenderNotAllowed(address who, bytes4 what, uint256[] how); /** * @dev Tells the address of the authorizer reference */ function authorizer() external view returns (address); }
// SPDX-License-Identifier: GPL-3.0-or-later // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. pragma solidity >=0.8.0; /** * @dev Authorizer interface */ interface IAuthorizer { /** * @dev Permission change * @param where Address of the contract to change a permission for * @param changes List of permission changes to be executed */ struct PermissionChange { address where; GrantPermission[] grants; RevokePermission[] revokes; } /** * @dev Grant permission data * @param who Address to be authorized * @param what Function selector to be authorized * @param params List of params to restrict the given permission */ struct GrantPermission { address who; bytes4 what; Param[] params; } /** * @dev Revoke permission data * @param who Address to be unauthorized * @param what Function selector to be unauthorized */ struct RevokePermission { address who; bytes4 what; } /** * @dev Params used to validate permissions params against * @param op ID of the operation to compute in order to validate a permission param * @param value Comparison value */ struct Param { uint8 op; uint248 value; } /** * @dev Sender is not authorized to call `what` on `where` with `how` */ error AuthorizerSenderNotAllowed(address who, address where, bytes4 what, uint256[] how); /** * @dev The operation param is invalid */ error AuthorizerInvalidParamOp(uint8 op); /** * @dev Emitted every time `who`'s permission to perform `what` on `where` is granted with `params` */ event Authorized(address indexed who, address indexed where, bytes4 indexed what, Param[] params); /** * @dev Emitted every time `who`'s permission to perform `what` on `where` is revoked */ event Unauthorized(address indexed who, address indexed where, bytes4 indexed what); /** * @dev Tells whether `who` has any permission on `where` * @param who Address asking permission for * @param where Target address asking permission for */ function hasPermissions(address who, address where) external view returns (bool); /** * @dev Tells the number of permissions `who` has on `where` * @param who Address asking permission for * @param where Target address asking permission for */ function getPermissionsLength(address who, address where) external view returns (uint256); /** * @dev Tells whether `who` has permission to call `what` on `where`. Note `how` is not evaluated here, * which means `who` might be authorized on or not depending on the call at the moment of the execution * @param who Address asking permission for * @param where Target address asking permission for * @param what Function selector asking permission for */ function hasPermission(address who, address where, bytes4 what) external view returns (bool); /** * @dev Tells whether `who` is allowed to call `what` on `where` with `how` * @param who Address asking permission for * @param where Target address asking permission for * @param what Function selector asking permission for * @param how Params asking permission for */ function isAuthorized(address who, address where, bytes4 what, uint256[] memory how) external view returns (bool); /** * @dev Tells the params set for a given permission * @param who Address asking permission params of * @param where Target address asking permission params of * @param what Function selector asking permission params of */ function getPermissionParams(address who, address where, bytes4 what) external view returns (Param[] memory); /** * @dev Executes a list of permission changes * @param changes List of permission changes to be executed */ function changePermissions(PermissionChange[] memory changes) external; /** * @dev Authorizes `who` to call `what` on `where` restricted by `params` * @param who Address to be authorized * @param where Target address to be granted for * @param what Function selector to be granted * @param params Optional params to restrict a permission attempt */ function authorize(address who, address where, bytes4 what, Param[] memory params) external; /** * @dev Unauthorizes `who` to call `what` on `where`. Sender must be authorized. * @param who Address to be authorized * @param where Target address to be revoked for * @param what Function selector to be revoked */ function unauthorize(address who, address where, bytes4 what) external; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import '../AuthorizedHelpers.sol'; contract AuthorizedHelpersMock is AuthorizedHelpers { function getAuthParams(address p1) external pure returns (uint256[] memory r) { return authParams(p1); } function getAuthParams(bytes32 p1) external pure returns (uint256[] memory r) { return authParams(p1); } function getAuthParams(uint256 p1) external pure returns (uint256[] memory r) { return authParams(p1); } function getAuthParams(address p1, bool p2) external pure returns (uint256[] memory r) { return authParams(p1, p2); } function getAuthParams(address p1, uint256 p2) external pure returns (uint256[] memory r) { return authParams(p1, p2); } function getAuthParams(address p1, address p2) external pure returns (uint256[] memory r) { return authParams(p1, p2); } function getAuthParams(bytes32 p1, bytes32 p2) external pure returns (uint256[] memory r) { return authParams(p1, p2); } function getAuthParams(address p1, address p2, uint256 p3) external pure returns (uint256[] memory r) { return authParams(p1, p2, p3); } function getAuthParams(address p1, address p2, address p3) external pure returns (uint256[] memory r) { return authParams(p1, p2, p3); } function getAuthParams(address p1, address p2, bytes4 p3) external pure returns (uint256[] memory r) { return authParams(p1, p2, p3); } function getAuthParams(address p1, uint256 p2, uint256 p3) external pure returns (uint256[] memory r) { return authParams(p1, p2, p3); } function getAuthParams(address p1, address p2, uint256 p3, uint256 p4) external pure returns (uint256[] memory r) { return authParams(p1, p2, p3, p4); } function getAuthParams(address p1, uint256 p2, uint256 p3, uint256 p4) external pure returns (uint256[] memory r) { return authParams(p1, p2, p3, p4); } function getAuthParams(bytes32 p1, address p2, uint256 p3, bool p4) external pure returns (uint256[] memory r) { return authParams(p1, p2, p3, p4); } function getAuthParams(address p1, uint256 p2, uint256 p3, uint256 p4, uint256 p5) external pure returns (uint256[] memory r) { return authParams(p1, p2, p3, p4, p5); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import '../Authorized.sol'; contract AuthorizedMock is Authorized { event LogUint256(uint256 x); event LogBytes32(bytes32 x); event LogAddress(address x); function initialize(address _authorizer) external virtual initializer { __Authorized_init(_authorizer); } function setUint256(uint256 x) external authP(authParams(x)) { emit LogUint256(x); } function setBytes32(bytes32 x) external authP(authParams(x)) { emit LogBytes32(x); } function setAddress(address x) external authP(authParams(x)) { emit LogAddress(x); } }
{ "optimizer": { "enabled": true, "runs": 10000 }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "libraries": {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"uint8","name":"op","type":"uint8"}],"name":"AuthorizerInvalidParamOp","type":"error"},{"inputs":[{"internalType":"address","name":"who","type":"address"},{"internalType":"address","name":"where","type":"address"},{"internalType":"bytes4","name":"what","type":"bytes4"},{"internalType":"uint256[]","name":"how","type":"uint256[]"}],"name":"AuthorizerSenderNotAllowed","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"who","type":"address"},{"indexed":true,"internalType":"address","name":"where","type":"address"},{"indexed":true,"internalType":"bytes4","name":"what","type":"bytes4"},{"components":[{"internalType":"uint8","name":"op","type":"uint8"},{"internalType":"uint248","name":"value","type":"uint248"}],"indexed":false,"internalType":"struct IAuthorizer.Param[]","name":"params","type":"tuple[]"}],"name":"Authorized","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":"who","type":"address"},{"indexed":true,"internalType":"address","name":"where","type":"address"},{"indexed":true,"internalType":"bytes4","name":"what","type":"bytes4"}],"name":"Unauthorized","type":"event"},{"inputs":[],"name":"ANYONE","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ANYWHERE","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"who","type":"address"},{"internalType":"address","name":"where","type":"address"},{"internalType":"bytes4","name":"what","type":"bytes4"},{"components":[{"internalType":"uint8","name":"op","type":"uint8"},{"internalType":"uint248","name":"value","type":"uint248"}],"internalType":"struct IAuthorizer.Param[]","name":"params","type":"tuple[]"}],"name":"authorize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"where","type":"address"},{"components":[{"internalType":"address","name":"who","type":"address"},{"internalType":"bytes4","name":"what","type":"bytes4"},{"components":[{"internalType":"uint8","name":"op","type":"uint8"},{"internalType":"uint248","name":"value","type":"uint248"}],"internalType":"struct IAuthorizer.Param[]","name":"params","type":"tuple[]"}],"internalType":"struct IAuthorizer.GrantPermission[]","name":"grants","type":"tuple[]"},{"components":[{"internalType":"address","name":"who","type":"address"},{"internalType":"bytes4","name":"what","type":"bytes4"}],"internalType":"struct IAuthorizer.RevokePermission[]","name":"revokes","type":"tuple[]"}],"internalType":"struct IAuthorizer.PermissionChange[]","name":"changes","type":"tuple[]"}],"name":"changePermissions","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"who","type":"address"},{"internalType":"address","name":"where","type":"address"},{"internalType":"bytes4","name":"what","type":"bytes4"}],"name":"getPermissionParams","outputs":[{"components":[{"internalType":"uint8","name":"op","type":"uint8"},{"internalType":"uint248","name":"value","type":"uint248"}],"internalType":"struct IAuthorizer.Param[]","name":"","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"who","type":"address"},{"internalType":"address","name":"where","type":"address"}],"name":"getPermissionsLength","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"who","type":"address"},{"internalType":"address","name":"where","type":"address"},{"internalType":"bytes4","name":"what","type":"bytes4"}],"name":"hasPermission","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"who","type":"address"},{"internalType":"address","name":"where","type":"address"}],"name":"hasPermissions","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"owners","type":"address[]"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"who","type":"address"},{"internalType":"address","name":"where","type":"address"},{"internalType":"bytes4","name":"what","type":"bytes4"},{"internalType":"uint256[]","name":"how","type":"uint256[]"}],"name":"isAuthorized","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"who","type":"address"},{"internalType":"address","name":"where","type":"address"},{"internalType":"bytes4","name":"what","type":"bytes4"}],"name":"unauthorize","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
608060405234801561001057600080fd5b5061001961001e565b6100dd565b600054610100900460ff161561008a5760405162461bcd60e51b815260206004820152602760248201527f496e697469616c697a61626c653a20636f6e747261637420697320696e697469604482015266616c697a696e6760c81b606482015260840160405180910390fd5b60005460ff908116146100db576000805460ff191660ff9081179091556040519081527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b565b611d01806100ec6000396000f3fe608060405234801561001057600080fd5b50600436106100c95760003560e01c8063840510cc11610081578063ca7c51d01161005b578063ca7c51d014610217578063e8a67dad1461022a578063fd1ccc9b1461027257600080fd5b8063840510cc146101a4578063a224cee7146101e4578063b091986d146101f757600080fd5b8063261a48af116100b2578063261a48af1461017c5780632852289514610191578063405d30af146101a457600080fd5b80630eb39344146100ce57806315771845146100f4575b600080fd5b6100e16100dc3660046113a6565b610285565b6040519081526020015b60405180910390f35b61016c610102366004611409565b73ffffffffffffffffffffffffffffffffffffffff808416600090815260336020908152604080832093861683529281528282207fffffffff00000000000000000000000000000000000000000000000000000000851683526001019052205460ff169392505050565b60405190151581526020016100eb565b61018f61018a366004611409565b6102bf565b005b61016c61019f36600461153a565b61031b565b6101bf73ffffffffffffffffffffffffffffffffffffffff81565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100eb565b61018f6101f2366004611602565b6103c9565b61020a610205366004611409565b61069c565b6040516100eb919061169a565b61018f610225366004611862565b610789565b61016c6102383660046113a6565b73ffffffffffffffffffffffffffffffffffffffff9182166000908152603360209081526040808320939094168252919091522054151590565b61018f610280366004611ac9565b610886565b73ffffffffffffffffffffffffffffffffffffffff8083166000908152603360209081526040808320938516835292905220545b92915050565b6102c76108e4565b60006102d4848484610957565b9050610301337f261a48af0000000000000000000000000000000000000000000000000000000083610a15565b61030c848484610a64565b5061031660018055565b505050565b600061032985858585610bd6565b15610336575060016103c1565b61035673ffffffffffffffffffffffffffffffffffffffff858585610bd6565b15610363575060016103c1565b6103838573ffffffffffffffffffffffffffffffffffffffff8585610bd6565b15610390575060016103c1565b6103b073ffffffffffffffffffffffffffffffffffffffff808585610bd6565b156103bd575060016103c1565b5060005b949350505050565b600054610100900460ff16158080156103e95750600054600160ff909116105b806104035750303b158015610403575060005460ff166001145b610494576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084015b60405180910390fd5b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117905580156104f257600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b6104fa610cdd565b60005b82518110156106345761059583828151811061051b5761051b611b38565b6020908102919091010151307ffd1ccc9b00000000000000000000000000000000000000000000000000000000600060405190808252806020026020018201604052801561058f57816020015b60408051808201909152600080825260208201528152602001906001900390816105685790505b50610d7e565b6106228382815181106105aa576105aa611b38565b6020908102919091010151307f261a48af00000000000000000000000000000000000000000000000000000000600060405190808252806020026020018201604052801561058f5781602001604080518082019091526000808252602082015281526020019060019003908161056857905050610d7e565b8061062c81611b96565b9150506104fd565b50801561069857600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b5050565b73ffffffffffffffffffffffffffffffffffffffff808416600090815260336020908152604080832093861683529281528282207fffffffff00000000000000000000000000000000000000000000000000000000851683526001908101825283832001805484518184028101840190955280855260609493919290919084015b8282101561077c576000848152602090819020604080518082019091529084015460ff8116825261010090047effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff168183015282526001909201910161071d565b5050505090509392505050565b60005b81518110156106985760008282815181106107a9576107a9611b38565b6020026020010151905060005b816020015151811015610814576000826020015182815181106107db576107db611b38565b602002602001015190506108018160000151846000015183602001518460400151610886565b508061080c81611b96565b9150506107b6565b5060005b8160400151518110156108715760008260400151828151811061083d5761083d611b38565b6020026020010151905061085e8160000151846000015183602001516102bf565b508061086981611b96565b915050610818565b5050808061087e90611b96565b91505061078c565b61088e6108e4565b600061089b858585610957565b90506108c8337ffd1ccc9b0000000000000000000000000000000000000000000000000000000083610a15565b6108d485858585610d7e565b506108de60018055565b50505050565b600260015403610950576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015260640161048b565b6002600155565b604080516003808252608082019092526060916020820183803683370190505090508373ffffffffffffffffffffffffffffffffffffffff16816000815181106109a3576109a3611b38565b6020026020010181815250508273ffffffffffffffffffffffffffffffffffffffff16816001815181106109d9576109d9611b38565b6020026020010181815250508160e01c63ffffffff1681600281518110610a0257610a02611b38565b6020026020010181815250509392505050565b6000610a238430858561031b565b9050806108de57833084846040517f61174e8800000000000000000000000000000000000000000000000000000000815260040161048b9493929190611bce565b73ffffffffffffffffffffffffffffffffffffffff808416600090815260336020908152604080832093861683529281528282207fffffffff000000000000000000000000000000000000000000000000000000008516835260018101909152919020805460ff1615610ae5578154826000610adf83611c67565b91905055505b7fffffffff000000000000000000000000000000000000000000000000000000008316600090815260018084016020526040822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001681559190610b4d90830182611343565b5050827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168473ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff167fa8095e01dcc1c206b8b64f0bcaf4fee219b0ee0bd623ea32f9876e19600cdb6360405160405180910390a45050505050565b60018055565b73ffffffffffffffffffffffffffffffffffffffff808516600090815260336020908152604080832093871683529281528282207fffffffff00000000000000000000000000000000000000000000000000000000861683526001019052908120805460ff168015610cd35750610cd381600101805480602002602001604051908101604052809291908181526020016000905b82821015610cc9576000848152602090819020604080518082019091529084015460ff8116825261010090047effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1681830152825260019092019101610c6a565b5050505084610f4a565b9695505050505050565b600054610100900460ff16610d74576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e67000000000000000000000000000000000000000000606482015260840161048b565b610d7c611010565b565b73ffffffffffffffffffffffffffffffffffffffff808516600090815260336020908152604080832093871683529281528282207fffffffff000000000000000000000000000000000000000000000000000000008616835260018101909152919020805460ff16610dfe578154826000610df883611b96565b91905055505b80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660019081178255610e369082016000611343565b60005b8351811015610ebc5781600101848281518110610e5857610e58611b38565b6020908102919091018101518254600181018455600093845292829020815191909201517effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff166101000260ff9091161791015580610eb481611b96565b915050610e39565b50837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167fa4e3ad0d161589a3d7d368c479c5c4bd9d753ea8f4865b26801b7e9823235ff586604051610f3a919061169a565b60405180910390a4505050505050565b6000805b8351811015611006576000848281518110610f6b57610f6b611b38565b60200260200101519050835182108015610fa55750610fa381858481518110610f9657610f96611b38565b60200260200101516110a7565b155b80610fe3575083518210158015610fe357506000815160ff166006811115610fcf57610fcf611c9c565b6006811115610fe057610fe0611c9c565b14155b15610ff3576000925050506102b9565b5080610ffe81611b96565b915050610f4e565b5060019392505050565b600054610100900460ff16610bd0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e67000000000000000000000000000000000000000000606482015260840161048b565b600080835160ff1660068111156110c0576110c0611c9c565b60068111156110d1576110d1611c9c565b036110de575060016102b9565b6001835160ff1660068111156110f6576110f6611c9c565b600681111561110757611107611c9c565b0361113a575060208201517effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1681146102b9565b6002835160ff16600681111561115257611152611c9c565b600681111561116357611163611c9c565b03611197575060208201517effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff168114156102b9565b6003835160ff1660068111156111af576111af611c9c565b60068111156111c0576111c0611c9c565b036111f3575060208201517effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1681116102b9565b6004835160ff16600681111561120b5761120b611c9c565b600681111561121c5761121c611c9c565b0361124f575060208201517effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1681106102b9565b6005835160ff16600681111561126757611267611c9c565b600681111561127857611278611c9c565b036112ac575060208201517effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff168110156102b9565b6006835160ff1660068111156112c4576112c4611c9c565b60068111156112d5576112d5611c9c565b03611309575060208201517effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff168111156102b9565b82516040517f69f2cbf500000000000000000000000000000000000000000000000000000000815260ff909116600482015260240161048b565b50805460008255906000526020600020908101906113619190611364565b50565b5b808211156113795760008155600101611365565b5090565b803573ffffffffffffffffffffffffffffffffffffffff811681146113a157600080fd5b919050565b600080604083850312156113b957600080fd5b6113c28361137d565b91506113d06020840161137d565b90509250929050565b80357fffffffff00000000000000000000000000000000000000000000000000000000811681146113a157600080fd5b60008060006060848603121561141e57600080fd5b6114278461137d565b92506114356020850161137d565b9150611443604085016113d9565b90509250925092565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040805190810167ffffffffffffffff8111828210171561149e5761149e61144c565b60405290565b6040516060810167ffffffffffffffff8111828210171561149e5761149e61144c565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff8111828210171561150e5761150e61144c565b604052919050565b600067ffffffffffffffff8211156115305761153061144c565b5060051b60200190565b6000806000806080858703121561155057600080fd5b6115598561137d565b9350602061156881870161137d565b9350611576604087016113d9565b9250606086013567ffffffffffffffff81111561159257600080fd5b8601601f810188136115a357600080fd5b80356115b66115b182611516565b6114c7565b81815260059190911b8201830190838101908a8311156115d557600080fd5b928401925b828410156115f3578335825292840192908401906115da565b979a9699509497505050505050565b6000602080838503121561161557600080fd5b823567ffffffffffffffff81111561162c57600080fd5b8301601f8101851361163d57600080fd5b803561164b6115b182611516565b81815260059190911b8201830190838101908783111561166a57600080fd5b928401925b8284101561168f576116808461137d565b8252928401929084019061166f565b979650505050505050565b602080825282518282018190526000919060409081850190868401855b82811015611700578151805160ff1685528601517effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff168685015292840192908501906001016116b7565b5091979650505050505050565b600082601f83011261171e57600080fd5b8135602061172e6115b183611516565b82815260069290921b8401810191818101908684111561174d57600080fd5b8286015b848110156117ca576040818903121561176a5760008081fd5b61177261147b565b813560ff811681146117845760008081fd5b8152818501357effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff811681146117b85760008081fd5b81860152835291830191604001611751565b509695505050505050565b600082601f8301126117e657600080fd5b813560206117f66115b183611516565b82815260069290921b8401810191818101908684111561181557600080fd5b8286015b848110156117ca57604081890312156118325760008081fd5b61183a61147b565b6118438261137d565b81526118508583016113d9565b81860152835291830191604001611819565b60006020828403121561187457600080fd5b67ffffffffffffffff8235111561188a57600080fd5b8135820183601f82011261189d57600080fd5b6118aa6115b18235611516565b81358082526020808301929160051b8401018610156118c857600080fd5b602083015b6020843560051b850101811015611abf5767ffffffffffffffff813511156118f457600080fd5b8035840160607fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0828a0301121561192a57600080fd5b6119326114a4565b61193e6020830161137d565b815267ffffffffffffffff6040830135111561195957600080fd5b6040820135820189603f82011261196f57600080fd5b61197f6115b16020830135611516565b602082810135808352908201919060051b83016040018c10156119a157600080fd5b604083015b6040602085013560051b850101811015611a775767ffffffffffffffff813511156119d057600080fd5b60607fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0823586018f03011215611a0557600080fd5b611a0d6114a4565b611a1c6040833587010161137d565b8152611a2d606083358701016113d9565b602082015267ffffffffffffffff60808335870101351115611a4e57600080fd5b611a648e8335870160808101350160400161170d565b60408201528352602092830192016119a6565b506020840152505067ffffffffffffffff60608301351115611a9857600080fd5b611aab89602060608501358501016117d5565b6040820152845250602092830192016118cd565b5095945050505050565b60008060008060808587031215611adf57600080fd5b611ae88561137d565b9350611af66020860161137d565b9250611b04604086016113d9565b9150606085013567ffffffffffffffff811115611b2057600080fd5b611b2c8782880161170d565b91505092959194509250565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203611bc757611bc7611b67565b5060010190565b60006080820173ffffffffffffffffffffffffffffffffffffffff80881684526020818816818601527fffffffff000000000000000000000000000000000000000000000000000000008716604086015260806060860152829150855180845260a086019250818701935060005b81811015611c5857845184529382019392820192600101611c3c565b50919998505050505050505050565b600081611c7657611c76611b67565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fdfea264697066735822122010f73222ea0d815cb6e46c1aaef2b993a8da022a3742cc1de1bffc7ef5b3390964736f6c63430008110033
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106100c95760003560e01c8063840510cc11610081578063ca7c51d01161005b578063ca7c51d014610217578063e8a67dad1461022a578063fd1ccc9b1461027257600080fd5b8063840510cc146101a4578063a224cee7146101e4578063b091986d146101f757600080fd5b8063261a48af116100b2578063261a48af1461017c5780632852289514610191578063405d30af146101a457600080fd5b80630eb39344146100ce57806315771845146100f4575b600080fd5b6100e16100dc3660046113a6565b610285565b6040519081526020015b60405180910390f35b61016c610102366004611409565b73ffffffffffffffffffffffffffffffffffffffff808416600090815260336020908152604080832093861683529281528282207fffffffff00000000000000000000000000000000000000000000000000000000851683526001019052205460ff169392505050565b60405190151581526020016100eb565b61018f61018a366004611409565b6102bf565b005b61016c61019f36600461153a565b61031b565b6101bf73ffffffffffffffffffffffffffffffffffffffff81565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100eb565b61018f6101f2366004611602565b6103c9565b61020a610205366004611409565b61069c565b6040516100eb919061169a565b61018f610225366004611862565b610789565b61016c6102383660046113a6565b73ffffffffffffffffffffffffffffffffffffffff9182166000908152603360209081526040808320939094168252919091522054151590565b61018f610280366004611ac9565b610886565b73ffffffffffffffffffffffffffffffffffffffff8083166000908152603360209081526040808320938516835292905220545b92915050565b6102c76108e4565b60006102d4848484610957565b9050610301337f261a48af0000000000000000000000000000000000000000000000000000000083610a15565b61030c848484610a64565b5061031660018055565b505050565b600061032985858585610bd6565b15610336575060016103c1565b61035673ffffffffffffffffffffffffffffffffffffffff858585610bd6565b15610363575060016103c1565b6103838573ffffffffffffffffffffffffffffffffffffffff8585610bd6565b15610390575060016103c1565b6103b073ffffffffffffffffffffffffffffffffffffffff808585610bd6565b156103bd575060016103c1565b5060005b949350505050565b600054610100900460ff16158080156103e95750600054600160ff909116105b806104035750303b158015610403575060005460ff166001145b610494576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084015b60405180910390fd5b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117905580156104f257600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b6104fa610cdd565b60005b82518110156106345761059583828151811061051b5761051b611b38565b6020908102919091010151307ffd1ccc9b00000000000000000000000000000000000000000000000000000000600060405190808252806020026020018201604052801561058f57816020015b60408051808201909152600080825260208201528152602001906001900390816105685790505b50610d7e565b6106228382815181106105aa576105aa611b38565b6020908102919091010151307f261a48af00000000000000000000000000000000000000000000000000000000600060405190808252806020026020018201604052801561058f5781602001604080518082019091526000808252602082015281526020019060019003908161056857905050610d7e565b8061062c81611b96565b9150506104fd565b50801561069857600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b5050565b73ffffffffffffffffffffffffffffffffffffffff808416600090815260336020908152604080832093861683529281528282207fffffffff00000000000000000000000000000000000000000000000000000000851683526001908101825283832001805484518184028101840190955280855260609493919290919084015b8282101561077c576000848152602090819020604080518082019091529084015460ff8116825261010090047effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff168183015282526001909201910161071d565b5050505090509392505050565b60005b81518110156106985760008282815181106107a9576107a9611b38565b6020026020010151905060005b816020015151811015610814576000826020015182815181106107db576107db611b38565b602002602001015190506108018160000151846000015183602001518460400151610886565b508061080c81611b96565b9150506107b6565b5060005b8160400151518110156108715760008260400151828151811061083d5761083d611b38565b6020026020010151905061085e8160000151846000015183602001516102bf565b508061086981611b96565b915050610818565b5050808061087e90611b96565b91505061078c565b61088e6108e4565b600061089b858585610957565b90506108c8337ffd1ccc9b0000000000000000000000000000000000000000000000000000000083610a15565b6108d485858585610d7e565b506108de60018055565b50505050565b600260015403610950576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015260640161048b565b6002600155565b604080516003808252608082019092526060916020820183803683370190505090508373ffffffffffffffffffffffffffffffffffffffff16816000815181106109a3576109a3611b38565b6020026020010181815250508273ffffffffffffffffffffffffffffffffffffffff16816001815181106109d9576109d9611b38565b6020026020010181815250508160e01c63ffffffff1681600281518110610a0257610a02611b38565b6020026020010181815250509392505050565b6000610a238430858561031b565b9050806108de57833084846040517f61174e8800000000000000000000000000000000000000000000000000000000815260040161048b9493929190611bce565b73ffffffffffffffffffffffffffffffffffffffff808416600090815260336020908152604080832093861683529281528282207fffffffff000000000000000000000000000000000000000000000000000000008516835260018101909152919020805460ff1615610ae5578154826000610adf83611c67565b91905055505b7fffffffff000000000000000000000000000000000000000000000000000000008316600090815260018084016020526040822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001681559190610b4d90830182611343565b5050827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168473ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff167fa8095e01dcc1c206b8b64f0bcaf4fee219b0ee0bd623ea32f9876e19600cdb6360405160405180910390a45050505050565b60018055565b73ffffffffffffffffffffffffffffffffffffffff808516600090815260336020908152604080832093871683529281528282207fffffffff00000000000000000000000000000000000000000000000000000000861683526001019052908120805460ff168015610cd35750610cd381600101805480602002602001604051908101604052809291908181526020016000905b82821015610cc9576000848152602090819020604080518082019091529084015460ff8116825261010090047effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1681830152825260019092019101610c6a565b5050505084610f4a565b9695505050505050565b600054610100900460ff16610d74576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e67000000000000000000000000000000000000000000606482015260840161048b565b610d7c611010565b565b73ffffffffffffffffffffffffffffffffffffffff808516600090815260336020908152604080832093871683529281528282207fffffffff000000000000000000000000000000000000000000000000000000008616835260018101909152919020805460ff16610dfe578154826000610df883611b96565b91905055505b80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660019081178255610e369082016000611343565b60005b8351811015610ebc5781600101848281518110610e5857610e58611b38565b6020908102919091018101518254600181018455600093845292829020815191909201517effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff166101000260ff9091161791015580610eb481611b96565b915050610e39565b50837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19168573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167fa4e3ad0d161589a3d7d368c479c5c4bd9d753ea8f4865b26801b7e9823235ff586604051610f3a919061169a565b60405180910390a4505050505050565b6000805b8351811015611006576000848281518110610f6b57610f6b611b38565b60200260200101519050835182108015610fa55750610fa381858481518110610f9657610f96611b38565b60200260200101516110a7565b155b80610fe3575083518210158015610fe357506000815160ff166006811115610fcf57610fcf611c9c565b6006811115610fe057610fe0611c9c565b14155b15610ff3576000925050506102b9565b5080610ffe81611b96565b915050610f4e565b5060019392505050565b600054610100900460ff16610bd0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201527f6e697469616c697a696e67000000000000000000000000000000000000000000606482015260840161048b565b600080835160ff1660068111156110c0576110c0611c9c565b60068111156110d1576110d1611c9c565b036110de575060016102b9565b6001835160ff1660068111156110f6576110f6611c9c565b600681111561110757611107611c9c565b0361113a575060208201517effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1681146102b9565b6002835160ff16600681111561115257611152611c9c565b600681111561116357611163611c9c565b03611197575060208201517effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff168114156102b9565b6003835160ff1660068111156111af576111af611c9c565b60068111156111c0576111c0611c9c565b036111f3575060208201517effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1681116102b9565b6004835160ff16600681111561120b5761120b611c9c565b600681111561121c5761121c611c9c565b0361124f575060208201517effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1681106102b9565b6005835160ff16600681111561126757611267611c9c565b600681111561127857611278611c9c565b036112ac575060208201517effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff168110156102b9565b6006835160ff1660068111156112c4576112c4611c9c565b60068111156112d5576112d5611c9c565b03611309575060208201517effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff168111156102b9565b82516040517f69f2cbf500000000000000000000000000000000000000000000000000000000815260ff909116600482015260240161048b565b50805460008255906000526020600020908101906113619190611364565b50565b5b808211156113795760008155600101611365565b5090565b803573ffffffffffffffffffffffffffffffffffffffff811681146113a157600080fd5b919050565b600080604083850312156113b957600080fd5b6113c28361137d565b91506113d06020840161137d565b90509250929050565b80357fffffffff00000000000000000000000000000000000000000000000000000000811681146113a157600080fd5b60008060006060848603121561141e57600080fd5b6114278461137d565b92506114356020850161137d565b9150611443604085016113d9565b90509250925092565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040805190810167ffffffffffffffff8111828210171561149e5761149e61144c565b60405290565b6040516060810167ffffffffffffffff8111828210171561149e5761149e61144c565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff8111828210171561150e5761150e61144c565b604052919050565b600067ffffffffffffffff8211156115305761153061144c565b5060051b60200190565b6000806000806080858703121561155057600080fd5b6115598561137d565b9350602061156881870161137d565b9350611576604087016113d9565b9250606086013567ffffffffffffffff81111561159257600080fd5b8601601f810188136115a357600080fd5b80356115b66115b182611516565b6114c7565b81815260059190911b8201830190838101908a8311156115d557600080fd5b928401925b828410156115f3578335825292840192908401906115da565b979a9699509497505050505050565b6000602080838503121561161557600080fd5b823567ffffffffffffffff81111561162c57600080fd5b8301601f8101851361163d57600080fd5b803561164b6115b182611516565b81815260059190911b8201830190838101908783111561166a57600080fd5b928401925b8284101561168f576116808461137d565b8252928401929084019061166f565b979650505050505050565b602080825282518282018190526000919060409081850190868401855b82811015611700578151805160ff1685528601517effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff168685015292840192908501906001016116b7565b5091979650505050505050565b600082601f83011261171e57600080fd5b8135602061172e6115b183611516565b82815260069290921b8401810191818101908684111561174d57600080fd5b8286015b848110156117ca576040818903121561176a5760008081fd5b61177261147b565b813560ff811681146117845760008081fd5b8152818501357effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff811681146117b85760008081fd5b81860152835291830191604001611751565b509695505050505050565b600082601f8301126117e657600080fd5b813560206117f66115b183611516565b82815260069290921b8401810191818101908684111561181557600080fd5b8286015b848110156117ca57604081890312156118325760008081fd5b61183a61147b565b6118438261137d565b81526118508583016113d9565b81860152835291830191604001611819565b60006020828403121561187457600080fd5b67ffffffffffffffff8235111561188a57600080fd5b8135820183601f82011261189d57600080fd5b6118aa6115b18235611516565b81358082526020808301929160051b8401018610156118c857600080fd5b602083015b6020843560051b850101811015611abf5767ffffffffffffffff813511156118f457600080fd5b8035840160607fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0828a0301121561192a57600080fd5b6119326114a4565b61193e6020830161137d565b815267ffffffffffffffff6040830135111561195957600080fd5b6040820135820189603f82011261196f57600080fd5b61197f6115b16020830135611516565b602082810135808352908201919060051b83016040018c10156119a157600080fd5b604083015b6040602085013560051b850101811015611a775767ffffffffffffffff813511156119d057600080fd5b60607fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0823586018f03011215611a0557600080fd5b611a0d6114a4565b611a1c6040833587010161137d565b8152611a2d606083358701016113d9565b602082015267ffffffffffffffff60808335870101351115611a4e57600080fd5b611a648e8335870160808101350160400161170d565b60408201528352602092830192016119a6565b506020840152505067ffffffffffffffff60608301351115611a9857600080fd5b611aab89602060608501358501016117d5565b6040820152845250602092830192016118cd565b5095945050505050565b60008060008060808587031215611adf57600080fd5b611ae88561137d565b9350611af66020860161137d565b9250611b04604086016113d9565b9150606085013567ffffffffffffffff811115611b2057600080fd5b611b2c8782880161170d565b91505092959194509250565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203611bc757611bc7611b67565b5060010190565b60006080820173ffffffffffffffffffffffffffffffffffffffff80881684526020818816818601527fffffffff000000000000000000000000000000000000000000000000000000008716604086015260806060860152829150855180845260a086019250818701935060005b81811015611c5857845184529382019392820192600101611c3c565b50919998505050505050505050565b600081611c7657611c76611b67565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fdfea264697066735822122010f73222ea0d815cb6e46c1aaef2b993a8da022a3742cc1de1bffc7ef5b3390964736f6c63430008110033
Loading...
Loading
Loading...
Loading
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.