Source Code
Overview
ETH Balance
0 ETH
ETH Value
$0.00| Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
|---|---|---|---|---|---|---|---|---|---|
Latest 1 internal transaction
Advanced mode:
| Parent Transaction Hash | Block | From | To | |||
|---|---|---|---|---|---|---|
| 17417926 | 14 days ago | Contract Creation | 0 ETH |
Cross-Chain Transactions
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 Source Code Verified (Exact Match)
Contract Name:
DAO
Compiler Version
v0.8.28+commit.7893614a
Optimization Enabled:
Yes with 200 runs
Other Settings:
cancun EvmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: AGPL-3.0-or-later
pragma solidity ^0.8.8;
import {ERC165StorageUpgradeable} from "@openzeppelin/contracts-upgradeable/utils/introspection/ERC165StorageUpgradeable.sol";
import {Initializable} from "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";
import {UUPSUpgradeable} from "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol";
import {SafeERC20Upgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC20/utils/SafeERC20Upgradeable.sol";
import {IERC20Upgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol";
import {IERC721ReceiverUpgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC721/IERC721ReceiverUpgradeable.sol";
import {IERC1155Upgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC1155/IERC1155Upgradeable.sol";
import {IERC1155ReceiverUpgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC1155/IERC1155ReceiverUpgradeable.sol";
import {AddressUpgradeable} from "@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol";
import {IERC1271} from "@openzeppelin/contracts/interfaces/IERC1271.sol";
import {IProtocolVersion} from "@aragon/osx-commons-contracts/src/utils/versioning/IProtocolVersion.sol";
import {ProtocolVersion} from "@aragon/osx-commons-contracts/src/utils/versioning/ProtocolVersion.sol";
import {VersionComparisonLib} from "@aragon/osx-commons-contracts/src/utils/versioning/VersionComparisonLib.sol";
import {hasBit, flipBit} from "@aragon/osx-commons-contracts/src/utils/math/BitMap.sol";
import {Action} from "@aragon/osx-commons-contracts/src/executors/Executor.sol";
import {IExecutor} from "@aragon/osx-commons-contracts/src/executors/IExecutor.sol";
import {IDAO} from "@aragon/osx-commons-contracts/src/dao/IDAO.sol";
import {PermissionManager} from "../permission/PermissionManager.sol";
import {CallbackHandler} from "../utils/CallbackHandler.sol";
import {IEIP4824} from "./IEIP4824.sol";
/// @title DAO
/// @author Aragon X - 2021-2024
/// @notice This contract is the entry point to the Aragon DAO framework and provides our users a simple and easy to use public interface.
/// @dev Public API of the Aragon DAO framework.
/// @custom:security-contact [email protected]
contract DAO is
IEIP4824,
Initializable,
IERC1271,
ERC165StorageUpgradeable,
IDAO,
IExecutor,
UUPSUpgradeable,
ProtocolVersion,
PermissionManager,
CallbackHandler
{
using SafeERC20Upgradeable for IERC20Upgradeable;
using AddressUpgradeable for address;
using VersionComparisonLib for uint8[3];
/// @notice The ID of the permission required to call the `execute` function.
bytes32 public constant EXECUTE_PERMISSION_ID = keccak256("EXECUTE_PERMISSION");
/// @notice The ID of the permission required to call the `_authorizeUpgrade` function.
bytes32 public constant UPGRADE_DAO_PERMISSION_ID = keccak256("UPGRADE_DAO_PERMISSION");
/// @notice The ID of the permission required to call the `setMetadata` function.
bytes32 public constant SET_METADATA_PERMISSION_ID = keccak256("SET_METADATA_PERMISSION");
/// @notice The ID of the permission required to call the `setTrustedForwarder` function.
bytes32 public constant SET_TRUSTED_FORWARDER_PERMISSION_ID =
keccak256("SET_TRUSTED_FORWARDER_PERMISSION");
/// @notice The ID of the permission required to call the `registerStandardCallback` function.
bytes32 public constant REGISTER_STANDARD_CALLBACK_PERMISSION_ID =
keccak256("REGISTER_STANDARD_CALLBACK_PERMISSION");
/// @notice The ID of the permission required to validate [ERC-1271](https://eips.ethereum.org/EIPS/eip-1271) signatures.
bytes32 public constant VALIDATE_SIGNATURE_PERMISSION_ID =
keccak256("VALIDATE_SIGNATURE_PERMISSION");
/// @notice The internal constant storing the maximal action array length.
uint256 internal constant MAX_ACTIONS = 256;
/// @notice The first out of two values to which the `_reentrancyStatus` state variable (used by the `nonReentrant` modifier) can be set indicating that a function was not entered.
uint256 private constant _NOT_ENTERED = 1;
/// @notice The second out of two values to which the `_reentrancyStatus` state variable (used by the `nonReentrant` modifier) can be set indicating that a function was entered.
uint256 private constant _ENTERED = 2;
/// @notice Removed variable that is left here to maintain the storage layout.
/// @dev Introduced in v1.0.0. Removed in v1.4.0.
/// @custom:oz-renamed-from signatureValidator
address private __removed0;
/// @notice The address of the trusted forwarder verifying meta transactions.
/// @dev Added in v1.0.0.
address private trustedForwarder;
/// @notice The [EIP-4824](https://eips.ethereum.org/EIPS/eip-4824) DAO URI.
/// @dev Added in v1.0.0.
string private _daoURI;
/// @notice The state variable for the reentrancy guard of the `execute` function.
/// @dev Added in v1.3.0. The variable can be of value `_NOT_ENTERED = 1` or `_ENTERED = 2` in usage and is initialized with `_NOT_ENTERED`.
uint256 private _reentrancyStatus;
/// @notice Thrown if a call is reentrant.
error ReentrantCall();
/// @notice Thrown if the action array length is larger than `MAX_ACTIONS`.
error TooManyActions();
/// @notice Thrown if action execution has failed.
/// @param index The index of the action in the action array that failed.
error ActionFailed(uint256 index);
/// @notice Thrown if an action has insufficient gas left.
error InsufficientGas();
/// @notice Thrown if the deposit amount is zero.
error ZeroAmount();
/// @notice Thrown if there is a mismatch between the expected and actually deposited amount of native tokens.
/// @param expected The expected native token amount.
/// @param actual The actual native token amount deposited.
error NativeTokenDepositAmountMismatch(uint256 expected, uint256 actual);
/// @notice Thrown if an upgrade is not supported from a specific protocol version .
error ProtocolVersionUpgradeNotSupported(uint8[3] protocolVersion);
/// @notice Thrown when a function is removed but left to not corrupt the interface ID.
error FunctionRemoved();
/// @notice Thrown when initialize is called after it has already been executed.
error AlreadyInitialized();
/// @notice Emitted when a new DAO URI is set.
/// @param daoURI The new URI.
event NewURI(string daoURI);
/// @notice A modifier to protect a function from calling itself, directly or indirectly (reentrancy).
/// @dev Currently, this modifier is only applied to the `execute()` function. If this is used multiple times, private `_beforeNonReentrant()` and `_afterNonReentrant()` functions should be created to prevent code duplication.
modifier nonReentrant() {
if (_reentrancyStatus == _ENTERED) {
revert ReentrantCall();
}
_reentrancyStatus = _ENTERED;
_;
_reentrancyStatus = _NOT_ENTERED;
}
/// @notice This ensures that the initialize function cannot be called during the upgrade process.
modifier onlyCallAtInitialization() {
if (_getInitializedVersion() != 0) {
revert AlreadyInitialized();
}
_;
}
/// @notice Disables the initializers on the implementation contract to prevent it from being left uninitialized.
/// @custom:oz-upgrades-unsafe-allow constructor
constructor() {
_disableInitializers();
}
/// @notice Initializes the DAO by
/// - setting the reentrancy status variable to `_NOT_ENTERED`
/// - registering the [ERC-165](https://eips.ethereum.org/EIPS/eip-165) interface ID
/// - setting the trusted forwarder for meta transactions
/// - giving the `ROOT_PERMISSION_ID` permission to the initial owner (that should be revoked and transferred to the DAO after setup).
/// @dev This method is required to support [ERC-1822](https://eips.ethereum.org/EIPS/eip-1822).
/// @param _metadata IPFS hash that points to all the metadata (logo, description, tags, etc.) of a DAO.
/// @param _initialOwner The initial owner of the DAO having the `ROOT_PERMISSION_ID` permission.
/// @param _trustedForwarder The trusted forwarder responsible for verifying meta transactions.
/// @param daoURI_ The DAO URI required to support [ERC-4824](https://eips.ethereum.org/EIPS/eip-4824).
function initialize(
bytes calldata _metadata,
address _initialOwner,
address _trustedForwarder,
string calldata daoURI_
) external onlyCallAtInitialization reinitializer(3) {
_reentrancyStatus = _NOT_ENTERED; // added in v1.3.0
// In addition to the current interfaceId, also support previous version of the interfaceId.
_registerInterface(type(IDAO).interfaceId ^ IExecutor.execute.selector);
_registerInterface(type(IDAO).interfaceId);
_registerInterface(type(IExecutor).interfaceId);
_registerInterface(type(IERC1271).interfaceId);
_registerInterface(type(IEIP4824).interfaceId);
_registerInterface(type(IProtocolVersion).interfaceId); // added in v1.3.0
_registerTokenInterfaces();
_setMetadata(_metadata);
_setTrustedForwarder(_trustedForwarder);
_setDaoURI(daoURI_);
__PermissionManager_init(_initialOwner);
}
/// @notice Initializes the DAO after an upgrade from a previous protocol version.
/// @param _previousProtocolVersion The semantic protocol version number of the previous DAO implementation contract this upgrade is transitioning from.
/// @param _initData The initialization data to be passed to via `upgradeToAndCall` (see [ERC-1967](https://docs.openzeppelin.com/contracts/4.x/api/proxy#ERC1967Upgrade)).
function initializeFrom(
uint8[3] calldata _previousProtocolVersion,
bytes calldata _initData
) external reinitializer(3) {
_initData; // Silences the unused function parameter warning.
// Check that the contract is not upgrading from a different major release.
if (_previousProtocolVersion[0] != 1) {
revert ProtocolVersionUpgradeNotSupported(_previousProtocolVersion);
}
// Initialize `_reentrancyStatus` that was added in v1.3.0.
// Register Interface `ProtocolVersion` that was added in v1.3.0.
if (_previousProtocolVersion.lt([1, 3, 0])) {
_reentrancyStatus = _NOT_ENTERED;
_registerInterface(type(IProtocolVersion).interfaceId);
}
// Revoke the `SET_SIGNATURE_VALIDATOR_PERMISSION` that was deprecated in v1.4.0.
if (_previousProtocolVersion.lt([1, 4, 0])) {
_revoke({
_where: address(this),
_who: address(this),
_permissionId: keccak256("SET_SIGNATURE_VALIDATOR_PERMISSION")
});
_registerInterface(type(IDAO).interfaceId);
_registerInterface(type(IExecutor).interfaceId);
}
}
/// @inheritdoc PermissionManager
function isPermissionRestrictedForAnyAddr(
bytes32 _permissionId
) internal pure override returns (bool) {
return
_permissionId == EXECUTE_PERMISSION_ID ||
_permissionId == UPGRADE_DAO_PERMISSION_ID ||
_permissionId == SET_METADATA_PERMISSION_ID ||
_permissionId == SET_TRUSTED_FORWARDER_PERMISSION_ID ||
_permissionId == REGISTER_STANDARD_CALLBACK_PERMISSION_ID;
}
/// @notice Internal method authorizing the upgrade of the contract via the [upgradeability mechanism for UUPS proxies](https://docs.openzeppelin.com/contracts/4.x/api/proxy#UUPSUpgradeable) (see [ERC-1822](https://eips.ethereum.org/EIPS/eip-1822)).
/// @dev The caller must have the `UPGRADE_DAO_PERMISSION_ID` permission.
function _authorizeUpgrade(address) internal virtual override auth(UPGRADE_DAO_PERMISSION_ID) {}
/// @inheritdoc IDAO
function setTrustedForwarder(
address _newTrustedForwarder
) external override auth(SET_TRUSTED_FORWARDER_PERMISSION_ID) {
_setTrustedForwarder(_newTrustedForwarder);
}
/// @inheritdoc IDAO
function getTrustedForwarder() external view virtual override returns (address) {
return trustedForwarder;
}
/// @inheritdoc IDAO
function hasPermission(
address _where,
address _who,
bytes32 _permissionId,
bytes memory _data
) external view override returns (bool) {
return isGranted({_where: _where, _who: _who, _permissionId: _permissionId, _data: _data});
}
/// @inheritdoc IDAO
function setMetadata(
bytes calldata _metadata
) external override auth(SET_METADATA_PERMISSION_ID) {
_setMetadata(_metadata);
}
/// @inheritdoc IExecutor
function execute(
bytes32 _callId,
Action[] calldata _actions,
uint256 _allowFailureMap
)
external
override
nonReentrant
auth(EXECUTE_PERMISSION_ID)
returns (bytes[] memory execResults, uint256 failureMap)
{
// Check that the action array length is within bounds.
if (_actions.length > MAX_ACTIONS) {
revert TooManyActions();
}
execResults = new bytes[](_actions.length);
uint256 gasBefore;
uint256 gasAfter;
for (uint256 i = 0; i < _actions.length; ) {
gasBefore = gasleft();
(bool success, bytes memory result) = _actions[i].to.call{value: _actions[i].value}(
_actions[i].data
);
gasAfter = gasleft();
// Check if failure is allowed
if (!hasBit(_allowFailureMap, uint8(i))) {
// Check if the call failed.
if (!success) {
revert ActionFailed(i);
}
} else {
// Check if the call failed.
if (!success) {
// Make sure that the action call did not fail because 63/64 of `gasleft()` was insufficient to execute the external call `.to.call` (see [ERC-150](https://eips.ethereum.org/EIPS/eip-150)).
// In specific scenarios, i.e. proposal execution where the last action in the action array is allowed to fail, the account calling `execute` could force-fail this action by setting a gas limit
// where 63/64 is insufficient causing the `.to.call` to fail, but where the remaining 1/64 gas are sufficient to successfully finish the `execute` call.
if (gasAfter < gasBefore / 64) {
revert InsufficientGas();
}
// Store that this action failed.
failureMap = flipBit(failureMap, uint8(i));
}
}
execResults[i] = result;
unchecked {
++i;
}
}
emit Executed({
actor: msg.sender,
callId: _callId,
actions: _actions,
allowFailureMap: _allowFailureMap,
failureMap: failureMap,
execResults: execResults
});
}
/// @inheritdoc IDAO
function deposit(
address _token,
uint256 _amount,
string calldata _reference
) external payable override {
if (_amount == 0) revert ZeroAmount();
if (_token == address(0)) {
if (msg.value != _amount)
revert NativeTokenDepositAmountMismatch({expected: _amount, actual: msg.value});
} else {
if (msg.value != 0)
revert NativeTokenDepositAmountMismatch({expected: 0, actual: msg.value});
IERC20Upgradeable(_token).safeTransferFrom(msg.sender, address(this), _amount);
}
emit Deposited(msg.sender, _token, _amount, _reference);
}
/// @inheritdoc IDAO
function setSignatureValidator(address) external pure override {
revert FunctionRemoved();
}
/// @inheritdoc IDAO
/// @dev Relays the validation logic determining who is allowed to sign on behalf of the DAO to its permission manager.
/// Caller specific bypassing can be set direct granting (i.e., `grant({_where: dao, _who: specificErc1271Caller, _permissionId: VALIDATE_SIGNATURE_PERMISSION_ID})`).
/// Caller specific signature validation logic can be set by granting with a `PermissionCondition` (i.e., `grantWithCondition({_where: dao, _who: specificErc1271Caller, _permissionId: VALIDATE_SIGNATURE_PERMISSION_ID, _condition: yourConditionImplementation})`)
/// Generic signature validation logic can be set for all calling contracts by granting with a `PermissionCondition` to `PermissionManager.ANY_ADDR()` (i.e., `grantWithCondition({_where: dao, _who: PermissionManager.ANY_ADDR(), _permissionId: VALIDATE_SIGNATURE_PERMISSION_ID, _condition: yourConditionImplementation})`).
function isValidSignature(
bytes32 _hash,
bytes memory _signature
) external view override(IDAO, IERC1271) returns (bytes4) {
if (
isGranted({
_where: address(this),
_who: msg.sender,
_permissionId: VALIDATE_SIGNATURE_PERMISSION_ID,
_data: abi.encode(_hash, _signature)
})
) {
return 0x1626ba7e; // `type(IERC1271).interfaceId` = bytes4(keccak256("isValidSignature(bytes32,bytes)")`
}
return 0xffffffff; // `bytes4(uint32(type(uint32).max-1))`
}
/// @notice Emits the `NativeTokenDeposited` event to track native token deposits that weren't made via the deposit method.
/// @dev This call is bound by the gas limitations for `send`/`transfer` calls introduced by [ERC-2929](https://eips.ethereum.org/EIPS/eip-2929).
/// Gas cost increases in future hard forks might break this function. As an alternative, [ERC-2930](https://eips.ethereum.org/EIPS/eip-2930)-type transactions using access lists can be employed.
receive() external payable {
emit NativeTokenDeposited(msg.sender, msg.value);
}
/// @notice Fallback to handle future versions of the [ERC-165](https://eips.ethereum.org/EIPS/eip-165) standard.
/// @param _input An alias being equivalent to `msg.data`. This feature of the fallback function was introduced with the [solidity compiler version 0.7.6](https://github.com/ethereum/solidity/releases/tag/v0.7.6)
/// @return The magic number registered for the function selector triggering the fallback.
fallback(bytes calldata _input) external returns (bytes memory) {
bytes4 magicNumber = _handleCallback(msg.sig, _input);
return abi.encode(magicNumber);
}
/// @notice Emits the MetadataSet event if new metadata is set.
/// @param _metadata Hash of the IPFS metadata object.
function _setMetadata(bytes calldata _metadata) internal {
emit MetadataSet(_metadata);
}
/// @notice Sets the trusted forwarder on the DAO and emits the associated event.
/// @param _trustedForwarder The trusted forwarder address.
function _setTrustedForwarder(address _trustedForwarder) internal {
trustedForwarder = _trustedForwarder;
emit TrustedForwarderSet(_trustedForwarder);
}
/// @notice Registers the [ERC-721](https://eips.ethereum.org/EIPS/eip-721) and [ERC-1155](https://eips.ethereum.org/EIPS/eip-1155) interfaces and callbacks.
function _registerTokenInterfaces() private {
_registerInterface(type(IERC721ReceiverUpgradeable).interfaceId);
_registerInterface(type(IERC1155ReceiverUpgradeable).interfaceId);
_registerCallback(
IERC721ReceiverUpgradeable.onERC721Received.selector,
IERC721ReceiverUpgradeable.onERC721Received.selector
);
_registerCallback(
IERC1155ReceiverUpgradeable.onERC1155Received.selector,
IERC1155ReceiverUpgradeable.onERC1155Received.selector
);
_registerCallback(
IERC1155ReceiverUpgradeable.onERC1155BatchReceived.selector,
IERC1155ReceiverUpgradeable.onERC1155BatchReceived.selector
);
}
/// @inheritdoc IDAO
function registerStandardCallback(
bytes4 _interfaceId,
bytes4 _callbackSelector,
bytes4 _magicNumber
) external override auth(REGISTER_STANDARD_CALLBACK_PERMISSION_ID) {
_registerInterface(_interfaceId);
_registerCallback(_callbackSelector, _magicNumber);
emit StandardCallbackRegistered(_interfaceId, _callbackSelector, _magicNumber);
}
/// @inheritdoc IEIP4824
function daoURI() external view returns (string memory) {
return _daoURI;
}
/// @notice Updates the set DAO URI to a new value.
/// @param newDaoURI The new DAO URI to be set.
function setDaoURI(string calldata newDaoURI) external auth(SET_METADATA_PERMISSION_ID) {
_setDaoURI(newDaoURI);
}
/// @notice Sets the new [ERC-4824](https://eips.ethereum.org/EIPS/eip-4824) DAO URI and emits the associated event.
/// @param daoURI_ The new DAO URI.
function _setDaoURI(string calldata daoURI_) internal {
_daoURI = daoURI_;
emit NewURI(daoURI_);
}
/// @notice 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 [OpenZeppelin's guide about storage gaps](https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps)).
uint256[46] private __gap;
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165Storage.sol)
pragma solidity ^0.8.0;
import "./ERC165Upgradeable.sol";
import {Initializable} from "../../proxy/utils/Initializable.sol";
/**
* @dev Storage based implementation of the {IERC165} interface.
*
* Contracts may inherit from this and call {_registerInterface} to declare
* their support of an interface.
*/
abstract contract ERC165StorageUpgradeable is Initializable, ERC165Upgradeable {
/**
* @dev Mapping of interface ids to whether or not it's supported.
*/
mapping(bytes4 => bool) private _supportedInterfaces;
function __ERC165Storage_init() internal onlyInitializing {
}
function __ERC165Storage_init_unchained() internal onlyInitializing {
}
/**
* @dev See {IERC165-supportsInterface}.
*/
function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
return super.supportsInterface(interfaceId) || _supportedInterfaces[interfaceId];
}
/**
* @dev Registers the contract as an implementer of the interface defined by
* `interfaceId`. Support of the actual ERC165 interface is automatic and
* registering its interface id is not required.
*
* See {IERC165-supportsInterface}.
*
* Requirements:
*
* - `interfaceId` cannot be the ERC165 invalid interface (`0xffffffff`).
*/
function _registerInterface(bytes4 interfaceId) internal virtual {
require(interfaceId != 0xffffffff, "ERC165: invalid interface id");
_supportedInterfaces[interfaceId] = true;
}
/**
* @dev This empty reserved space is put in place to allow future versions to add new
* variables without shifting down storage in the inheritance chain.
* See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps
*/
uint256[49] private __gap;
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (proxy/utils/Initializable.sol)
pragma solidity ^0.8.2;
import "../../utils/AddressUpgradeable.sol";
/**
* @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed
* behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an
* external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer
* function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.
*
* The initialization functions use a version number. Once a version number is used, it is consumed and cannot be
* reused. This mechanism prevents re-execution of each "step" but allows the creation of new initialization steps in
* case an upgrade adds a module that needs to be initialized.
*
* For example:
*
* [.hljs-theme-light.nopadding]
* ```solidity
* contract MyToken is ERC20Upgradeable {
* function initialize() initializer public {
* __ERC20_init("MyToken", "MTK");
* }
* }
*
* contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {
* function initializeV2() reinitializer(2) public {
* __ERC20Permit_init("MyToken");
* }
* }
* ```
*
* TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as
* possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.
*
* CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure
* that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.
*
* [CAUTION]
* ====
* Avoid leaving a contract uninitialized.
*
* An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation
* contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke
* the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:
*
* [.hljs-theme-light.nopadding]
* ```
* /// @custom:oz-upgrades-unsafe-allow constructor
* constructor() {
* _disableInitializers();
* }
* ```
* ====
*/
abstract contract Initializable {
/**
* @dev Indicates that the contract has been initialized.
* @custom:oz-retyped-from bool
*/
uint8 private _initialized;
/**
* @dev Indicates that the contract is in the process of being initialized.
*/
bool private _initializing;
/**
* @dev Triggered when the contract has been initialized or reinitialized.
*/
event Initialized(uint8 version);
/**
* @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,
* `onlyInitializing` functions can be used to initialize parent contracts.
*
* Similar to `reinitializer(1)`, except that functions marked with `initializer` can be nested in the context of a
* constructor.
*
* Emits an {Initialized} event.
*/
modifier initializer() {
bool isTopLevelCall = !_initializing;
require(
(isTopLevelCall && _initialized < 1) || (!AddressUpgradeable.isContract(address(this)) && _initialized == 1),
"Initializable: contract is already initialized"
);
_initialized = 1;
if (isTopLevelCall) {
_initializing = true;
}
_;
if (isTopLevelCall) {
_initializing = false;
emit Initialized(1);
}
}
/**
* @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the
* contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be
* used to initialize parent contracts.
*
* A reinitializer may be used after the original initialization step. This is essential to configure modules that
* are added through upgrades and that require initialization.
*
* When `version` is 1, this modifier is similar to `initializer`, except that functions marked with `reinitializer`
* cannot be nested. If one is invoked in the context of another, execution will revert.
*
* Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in
* a contract, executing them in the right order is up to the developer or operator.
*
* WARNING: setting the version to 255 will prevent any future reinitialization.
*
* Emits an {Initialized} event.
*/
modifier reinitializer(uint8 version) {
require(!_initializing && _initialized < version, "Initializable: contract is already initialized");
_initialized = version;
_initializing = true;
_;
_initializing = false;
emit Initialized(version);
}
/**
* @dev Modifier to protect an initialization function so that it can only be invoked by functions with the
* {initializer} and {reinitializer} modifiers, directly or indirectly.
*/
modifier onlyInitializing() {
require(_initializing, "Initializable: contract is not initializing");
_;
}
/**
* @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.
* Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized
* to any version. It is recommended to use this to lock implementation contracts that are designed to be called
* through proxies.
*
* Emits an {Initialized} event the first time it is successfully executed.
*/
function _disableInitializers() internal virtual {
require(!_initializing, "Initializable: contract is initializing");
if (_initialized != type(uint8).max) {
_initialized = type(uint8).max;
emit Initialized(type(uint8).max);
}
}
/**
* @dev Returns the highest version that has been initialized. See {reinitializer}.
*/
function _getInitializedVersion() internal view returns (uint8) {
return _initialized;
}
/**
* @dev Returns `true` if the contract is currently initializing. See {onlyInitializing}.
*/
function _isInitializing() internal view returns (bool) {
return _initializing;
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (proxy/utils/UUPSUpgradeable.sol)
pragma solidity ^0.8.0;
import "../../interfaces/draft-IERC1822Upgradeable.sol";
import "../ERC1967/ERC1967UpgradeUpgradeable.sol";
import {Initializable} from "./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 {
/// @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");
_;
}
function __UUPSUpgradeable_init() internal onlyInitializing {
}
function __UUPSUpgradeable_init_unchained() internal onlyInitializing {
}
/**
* @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.3) (token/ERC20/utils/SafeERC20.sol)
pragma solidity ^0.8.0;
import "../IERC20Upgradeable.sol";
import "../extensions/IERC20PermitUpgradeable.sol";
import "../../../utils/AddressUpgradeable.sol";
/**
* @title SafeERC20
* @dev Wrappers around ERC20 operations that throw on failure (when the token
* contract returns false). Tokens that return no value (and instead revert or
* throw on failure) are also supported, non-reverting calls are assumed to be
* successful.
* To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,
* which allows you to call the safe operations as `token.safeTransfer(...)`, etc.
*/
library SafeERC20Upgradeable {
using AddressUpgradeable for address;
/**
* @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value,
* non-reverting calls are assumed to be successful.
*/
function safeTransfer(IERC20Upgradeable token, address to, uint256 value) internal {
_callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));
}
/**
* @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the
* calling contract. If `token` returns no value, non-reverting calls are assumed to be successful.
*/
function safeTransferFrom(IERC20Upgradeable token, address from, address to, uint256 value) internal {
_callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));
}
/**
* @dev Deprecated. This function has issues similar to the ones found in
* {IERC20-approve}, and its usage is discouraged.
*
* Whenever possible, use {safeIncreaseAllowance} and
* {safeDecreaseAllowance} instead.
*/
function safeApprove(IERC20Upgradeable token, address spender, uint256 value) internal {
// safeApprove should only be called when setting an initial allowance,
// or when resetting it to zero. To increase and decrease it, use
// 'safeIncreaseAllowance' and 'safeDecreaseAllowance'
require(
(value == 0) || (token.allowance(address(this), spender) == 0),
"SafeERC20: approve from non-zero to non-zero allowance"
);
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));
}
/**
* @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value,
* non-reverting calls are assumed to be successful.
*/
function safeIncreaseAllowance(IERC20Upgradeable token, address spender, uint256 value) internal {
uint256 oldAllowance = token.allowance(address(this), spender);
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance + value));
}
/**
* @dev Decrease the calling contract's allowance toward `spender` by `value`. If `token` returns no value,
* non-reverting calls are assumed to be successful.
*/
function safeDecreaseAllowance(IERC20Upgradeable token, address spender, uint256 value) internal {
unchecked {
uint256 oldAllowance = token.allowance(address(this), spender);
require(oldAllowance >= value, "SafeERC20: decreased allowance below zero");
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance - value));
}
}
/**
* @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value,
* non-reverting calls are assumed to be successful. Meant to be used with tokens that require the approval
* to be set to zero before setting it to a non-zero value, such as USDT.
*/
function forceApprove(IERC20Upgradeable token, address spender, uint256 value) internal {
bytes memory approvalCall = abi.encodeWithSelector(token.approve.selector, spender, value);
if (!_callOptionalReturnBool(token, approvalCall)) {
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, 0));
_callOptionalReturn(token, approvalCall);
}
}
/**
* @dev Use a ERC-2612 signature to set the `owner` approval toward `spender` on `token`.
* Revert on invalid signature.
*/
function safePermit(
IERC20PermitUpgradeable token,
address owner,
address spender,
uint256 value,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) internal {
uint256 nonceBefore = token.nonces(owner);
token.permit(owner, spender, value, deadline, v, r, s);
uint256 nonceAfter = token.nonces(owner);
require(nonceAfter == nonceBefore + 1, "SafeERC20: permit did not succeed");
}
/**
* @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement
* on the return value: the return value is optional (but if data is returned, it must not be false).
* @param token The token targeted by the call.
* @param data The call data (encoded using abi.encode or one of its variants).
*/
function _callOptionalReturn(IERC20Upgradeable token, bytes memory data) private {
// We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since
// we're implementing it ourselves. We use {Address-functionCall} to perform this call, which verifies that
// the target address contains contract code and also asserts for success in the low-level call.
bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed");
require(returndata.length == 0 || abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed");
}
/**
* @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement
* on the return value: the return value is optional (but if data is returned, it must not be false).
* @param token The token targeted by the call.
* @param data The call data (encoded using abi.encode or one of its variants).
*
* This is a variant of {_callOptionalReturn} that silents catches all reverts and returns a bool instead.
*/
function _callOptionalReturnBool(IERC20Upgradeable token, bytes memory data) private returns (bool) {
// We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since
// we're implementing it ourselves. We cannot use {Address-functionCall} here since this should return false
// and not revert is the subcall reverts.
(bool success, bytes memory returndata) = address(token).call(data);
return
success && (returndata.length == 0 || abi.decode(returndata, (bool))) && AddressUpgradeable.isContract(address(token));
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/IERC20.sol)
pragma solidity ^0.8.0;
/**
* @dev Interface of the ERC20 standard as defined in the EIP.
*/
interface IERC20Upgradeable {
/**
* @dev Emitted when `value` tokens are moved from one account (`from`) to
* another (`to`).
*
* Note that `value` may be zero.
*/
event Transfer(address indexed from, address indexed to, uint256 value);
/**
* @dev Emitted when the allowance of a `spender` for an `owner` is set by
* a call to {approve}. `value` is the new allowance.
*/
event Approval(address indexed owner, address indexed spender, uint256 value);
/**
* @dev Returns the amount of tokens in existence.
*/
function totalSupply() external view returns (uint256);
/**
* @dev Returns the amount of tokens owned by `account`.
*/
function balanceOf(address account) external view returns (uint256);
/**
* @dev Moves `amount` tokens from the caller's account to `to`.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transfer(address to, uint256 amount) external returns (bool);
/**
* @dev Returns the remaining number of tokens that `spender` will be
* allowed to spend on behalf of `owner` through {transferFrom}. This is
* zero by default.
*
* This value changes when {approve} or {transferFrom} are called.
*/
function allowance(address owner, address spender) external view returns (uint256);
/**
* @dev Sets `amount` as the allowance of `spender` over the caller's tokens.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* IMPORTANT: Beware that changing an allowance with this method brings the risk
* that someone may use both the old and the new allowance by unfortunate
* transaction ordering. One possible solution to mitigate this race
* condition is to first reduce the spender's allowance to 0 and set the
* desired value afterwards:
* https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
*
* Emits an {Approval} event.
*/
function approve(address spender, uint256 amount) external returns (bool);
/**
* @dev Moves `amount` tokens from `from` to `to` using the
* allowance mechanism. `amount` is then deducted from the caller's
* allowance.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transferFrom(address from, address to, uint256 amount) external returns (bool);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol)
pragma solidity ^0.8.0;
/**
* @title ERC721 token receiver interface
* @dev Interface for any contract that wants to support safeTransfers
* from ERC721 asset contracts.
*/
interface IERC721ReceiverUpgradeable {
/**
* @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}
* by `operator` from `from`, this function is called.
*
* It must return its Solidity selector to confirm the token transfer.
* If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted.
*
* The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`.
*/
function onERC721Received(
address operator,
address from,
uint256 tokenId,
bytes calldata data
) external returns (bytes4);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC1155/IERC1155.sol)
pragma solidity ^0.8.0;
import "../../utils/introspection/IERC165Upgradeable.sol";
/**
* @dev Required interface of an ERC1155 compliant contract, as defined in the
* https://eips.ethereum.org/EIPS/eip-1155[EIP].
*
* _Available since v3.1._
*/
interface IERC1155Upgradeable is IERC165Upgradeable {
/**
* @dev Emitted when `value` tokens of token type `id` are transferred from `from` to `to` by `operator`.
*/
event TransferSingle(address indexed operator, address indexed from, address indexed to, uint256 id, uint256 value);
/**
* @dev Equivalent to multiple {TransferSingle} events, where `operator`, `from` and `to` are the same for all
* transfers.
*/
event TransferBatch(
address indexed operator,
address indexed from,
address indexed to,
uint256[] ids,
uint256[] values
);
/**
* @dev Emitted when `account` grants or revokes permission to `operator` to transfer their tokens, according to
* `approved`.
*/
event ApprovalForAll(address indexed account, address indexed operator, bool approved);
/**
* @dev Emitted when the URI for token type `id` changes to `value`, if it is a non-programmatic URI.
*
* If an {URI} event was emitted for `id`, the standard
* https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[guarantees] that `value` will equal the value
* returned by {IERC1155MetadataURI-uri}.
*/
event URI(string value, uint256 indexed id);
/**
* @dev Returns the amount of tokens of token type `id` owned by `account`.
*
* Requirements:
*
* - `account` cannot be the zero address.
*/
function balanceOf(address account, uint256 id) external view returns (uint256);
/**
* @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {balanceOf}.
*
* Requirements:
*
* - `accounts` and `ids` must have the same length.
*/
function balanceOfBatch(
address[] calldata accounts,
uint256[] calldata ids
) external view returns (uint256[] memory);
/**
* @dev Grants or revokes permission to `operator` to transfer the caller's tokens, according to `approved`,
*
* Emits an {ApprovalForAll} event.
*
* Requirements:
*
* - `operator` cannot be the caller.
*/
function setApprovalForAll(address operator, bool approved) external;
/**
* @dev Returns true if `operator` is approved to transfer ``account``'s tokens.
*
* See {setApprovalForAll}.
*/
function isApprovedForAll(address account, address operator) external view returns (bool);
/**
* @dev Transfers `amount` tokens of token type `id` from `from` to `to`.
*
* Emits a {TransferSingle} event.
*
* Requirements:
*
* - `to` cannot be the zero address.
* - If the caller is not `from`, it must have been approved to spend ``from``'s tokens via {setApprovalForAll}.
* - `from` must have a balance of tokens of type `id` of at least `amount`.
* - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the
* acceptance magic value.
*/
function safeTransferFrom(address from, address to, uint256 id, uint256 amount, bytes calldata data) external;
/**
* @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {safeTransferFrom}.
*
* Emits a {TransferBatch} event.
*
* Requirements:
*
* - `ids` and `amounts` must have the same length.
* - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the
* acceptance magic value.
*/
function safeBatchTransferFrom(
address from,
address to,
uint256[] calldata ids,
uint256[] calldata amounts,
bytes calldata data
) external;
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC1155/IERC1155Receiver.sol)
pragma solidity ^0.8.0;
import "../../utils/introspection/IERC165Upgradeable.sol";
/**
* @dev _Available since v3.1._
*/
interface IERC1155ReceiverUpgradeable is IERC165Upgradeable {
/**
* @dev Handles the receipt of a single ERC1155 token type. This function is
* called at the end of a `safeTransferFrom` after the balance has been updated.
*
* NOTE: To accept the transfer, this must return
* `bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)"))`
* (i.e. 0xf23a6e61, or its own function selector).
*
* @param operator The address which initiated the transfer (i.e. msg.sender)
* @param from The address which previously owned the token
* @param id The ID of the token being transferred
* @param value The amount of tokens being transferred
* @param data Additional data with no specified format
* @return `bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)"))` if transfer is allowed
*/
function onERC1155Received(
address operator,
address from,
uint256 id,
uint256 value,
bytes calldata data
) external returns (bytes4);
/**
* @dev Handles the receipt of a multiple ERC1155 token types. This function
* is called at the end of a `safeBatchTransferFrom` after the balances have
* been updated.
*
* NOTE: To accept the transfer(s), this must return
* `bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)"))`
* (i.e. 0xbc197c81, or its own function selector).
*
* @param operator The address which initiated the batch transfer (i.e. msg.sender)
* @param from The address which previously owned the token
* @param ids An array containing ids of each token being transferred (order and length must match values array)
* @param values An array containing amounts of each token being transferred (order and length must match ids array)
* @param data Additional data with no specified format
* @return `bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)"))` if transfer is allowed
*/
function onERC1155BatchReceived(
address operator,
address from,
uint256[] calldata ids,
uint256[] calldata values,
bytes calldata data
) external returns (bytes4);
}// 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 (interfaces/IERC1271.sol)
pragma solidity ^0.8.0;
/**
* @dev Interface of the ERC1271 standard signature validation method for
* contracts as defined in https://eips.ethereum.org/EIPS/eip-1271[ERC-1271].
*
* _Available since v4.1._
*/
interface IERC1271 {
/**
* @dev Should return whether the signature provided is valid for the provided data
* @param hash Hash of the data to be signed
* @param signature Signature byte array associated with _data
*/
function isValidSignature(bytes32 hash, bytes memory signature) external view returns (bytes4 magicValue);
}// SPDX-License-Identifier: AGPL-3.0-or-later pragma solidity ^0.8.8; /// @title IProtocolVersion /// @author Aragon X - 2022-2023 /// @notice An interface defining the semantic Aragon OSx protocol version number. /// @custom:security-contact [email protected] interface IProtocolVersion { /// @notice Returns the semantic Aragon OSx protocol version number that the implementing contract is associated with. /// @return _version Returns the semantic Aragon OSx protocol version number. /// @dev This version number is not to be confused with the `release` and `build` numbers found in the `Version.Tag` struct inside the `PluginRepo` contract being used to version plugin setup and associated plugin implementation contracts. function protocolVersion() external view returns (uint8[3] memory _version); }
// SPDX-License-Identifier: AGPL-3.0-or-later
pragma solidity ^0.8.8;
import {IProtocolVersion} from "./IProtocolVersion.sol";
/// @title ProtocolVersion
/// @author Aragon X - 2023
/// @notice An abstract, stateless, non-upgradeable contract providing the current Aragon OSx protocol version number.
/// @dev Do not add any new variables to this contract that would shift down storage in the inheritance chain.
/// @custom:security-contact [email protected]
abstract contract ProtocolVersion is IProtocolVersion {
// IMPORTANT: Do not add any storage variable, see the above notice.
/// @inheritdoc IProtocolVersion
function protocolVersion() public pure returns (uint8[3] memory) {
return [1, 4, 0];
}
}// SPDX-License-Identifier: AGPL-3.0-or-later pragma solidity ^0.8.8; /// @title VersionComparisonLib /// @author Aragon X - 2023 /// @notice A library containing methods for [semantic version number](https://semver.org/spec/v2.0.0.html) comparison. /// @custom:security-contact [email protected] library VersionComparisonLib { /// @notice Equality comparator for two semantic version numbers. /// @param lhs The left-hand side semantic version number. /// @param rhs The right-hand side semantic version number. /// @return Whether the two numbers are equal or not. function eq(uint8[3] memory lhs, uint8[3] memory rhs) internal pure returns (bool) { if (lhs[0] != rhs[0]) return false; if (lhs[1] != rhs[1]) return false; if (lhs[2] != rhs[2]) return false; return true; } /// @notice Inequality comparator for two semantic version numbers. /// @param lhs The left-hand side semantic version number. /// @param rhs The right-hand side semantic version number. /// @return Whether the two numbers are inequal or not. function neq(uint8[3] memory lhs, uint8[3] memory rhs) internal pure returns (bool) { if (lhs[0] != rhs[0]) return true; if (lhs[1] != rhs[1]) return true; if (lhs[2] != rhs[2]) return true; return false; } /// @notice Less than comparator for two semantic version numbers. /// @param lhs The left-hand side semantic version number. /// @param rhs The right-hand side semantic version number. /// @return Whether the first number is less than the second number or not. function lt(uint8[3] memory lhs, uint8[3] memory rhs) internal pure returns (bool) { if (lhs[0] < rhs[0]) return true; if (lhs[0] > rhs[0]) return false; if (lhs[1] < rhs[1]) return true; if (lhs[1] > rhs[1]) return false; if (lhs[2] < rhs[2]) return true; return false; } /// @notice Less than or equal to comparator for two semantic version numbers. /// @param lhs The left-hand side semantic version number. /// @param rhs The right-hand side semantic version number. /// @return Whether the first number is less than or equal to the second number or not. function lte(uint8[3] memory lhs, uint8[3] memory rhs) internal pure returns (bool) { if (lhs[0] < rhs[0]) return true; if (lhs[0] > rhs[0]) return false; if (lhs[1] < rhs[1]) return true; if (lhs[1] > rhs[1]) return false; if (lhs[2] <= rhs[2]) return true; return false; } /// @notice Greater than comparator for two semantic version numbers. /// @param lhs The left-hand side semantic version number. /// @param rhs The right-hand side semantic version number. /// @return Whether the first number is greater than the second number or not. function gt(uint8[3] memory lhs, uint8[3] memory rhs) internal pure returns (bool) { if (lhs[0] > rhs[0]) return true; if (lhs[0] < rhs[0]) return false; if (lhs[1] > rhs[1]) return true; if (lhs[1] < rhs[1]) return false; if (lhs[2] > rhs[2]) return true; return false; } /// @notice Greater than or equal to comparator for two semantic version numbers. /// @param lhs The left-hand side semantic version number. /// @param rhs The right-hand side semantic version number. /// @return Whether the first number is greater than or equal to the second number or not. function gte(uint8[3] memory lhs, uint8[3] memory rhs) internal pure returns (bool) { if (lhs[0] > rhs[0]) return true; if (lhs[0] < rhs[0]) return false; if (lhs[1] > rhs[1]) return true; if (lhs[1] < rhs[1]) return false; if (lhs[2] >= rhs[2]) return true; return false; } }
// SPDX-License-Identifier: AGPL-3.0-or-later pragma solidity ^0.8.8; /// @param bitmap The `uint256` representation of bits. /// @param index The index number to check whether 1 or 0 is set. /// @return Returns `true` if the bit is set at `index` on `bitmap`. /// @custom:security-contact [email protected] function hasBit(uint256 bitmap, uint8 index) pure returns (bool) { uint256 bitValue = bitmap & (1 << index); return bitValue > 0; } /// @param bitmap The `uint256` representation of bits. /// @param index The index number to set the bit. /// @return Returns a new number in which the bit is set at `index`. /// @custom:security-contact [email protected] function flipBit(uint256 bitmap, uint8 index) pure returns (uint256) { return bitmap ^ (1 << index); }
// SPDX-License-Identifier: AGPL-3.0-or-later
pragma solidity ^0.8.8;
import {ERC165} from "@openzeppelin/contracts/utils/introspection/ERC165.sol";
import {IExecutor, Action} from "./IExecutor.sol";
import {flipBit, hasBit} from "../utils/math/BitMap.sol";
/// @title IDAO
/// @author Aragon X - 2024
/// @notice Simple Executor that loops through the actions and executes them.
/// @dev This doesn't use any type of permission for execution and can be called by anyone.
/// Most useful use-case is to deploy it as non-upgradeable and call from another contract via delegatecall.
/// If used with delegatecall, DO NOT add state variables in sequential slots, otherwise this will overwrite
/// the storage of the calling contract.
/// @custom:security-contact [email protected]
contract Executor is IExecutor, ERC165 {
/// @notice The internal constant storing the maximal action array length.
uint256 internal constant MAX_ACTIONS = 256;
// keccak256("osx-commons.storage.Executor")
bytes32 private constant REENTRANCY_GUARD_STORAGE_LOCATION =
0x4d6542319dfb3f7c8adbb488d7b4d7cf849381f14faf4b64de3ac05d08c0bdec;
/// @notice The first out of two values to which the `_reentrancyStatus` state variable (used by the `nonReentrant` modifier) can be set indicating that a function was not entered.
uint256 private constant _NOT_ENTERED = 1;
/// @notice The second out of two values to which the `_reentrancyStatus` state variable (used by the `nonReentrant` modifier) can be set indicating that a function was entered.
uint256 private constant _ENTERED = 2;
/// @notice Thrown if the action array length is larger than `MAX_ACTIONS`.
error TooManyActions();
/// @notice Thrown if an action has insufficient gas left.
error InsufficientGas();
/// @notice Thrown if action execution has failed.
/// @param index The index of the action in the action array that failed.
error ActionFailed(uint256 index);
/// @notice Thrown if a call is reentrant.
error ReentrantCall();
/// @notice Initializes the contract with a non-entered reentrancy status.
/// @dev Sets the reentrancy guard status to `_NOT_ENTERED` to prevent reentrant calls from the start.
constructor() {
_storeReentrancyStatus(_NOT_ENTERED);
}
/// @notice Prevents reentrant calls to a function.
/// @dev This modifier checks the reentrancy status before function execution. If already entered, it reverts with
/// `ReentrantCall()`. Sets the status to `_ENTERED` during execution and resets it to `_NOT_ENTERED` afterward.
modifier nonReentrant() {
if (_getReentrancyStatus() == _ENTERED) {
revert ReentrantCall();
}
_storeReentrancyStatus(_ENTERED);
_;
_storeReentrancyStatus(_NOT_ENTERED);
}
/// @notice Checks if this or the parent contract supports an interface by its ID.
/// @param _interfaceId The ID of the interface.
/// @return Returns `true` if the interface is supported.
function supportsInterface(bytes4 _interfaceId) public view virtual override returns (bool) {
return _interfaceId == type(IExecutor).interfaceId || super.supportsInterface(_interfaceId);
}
/// @inheritdoc IExecutor
function execute(
bytes32 _callId,
Action[] memory _actions,
uint256 _allowFailureMap
)
public
virtual
override
nonReentrant
returns (bytes[] memory execResults, uint256 failureMap)
{
// Check that the action array length is within bounds.
if (_actions.length > MAX_ACTIONS) {
revert TooManyActions();
}
execResults = new bytes[](_actions.length);
uint256 gasBefore;
uint256 gasAfter;
for (uint256 i = 0; i < _actions.length; ) {
gasBefore = gasleft();
(bool success, bytes memory data) = _actions[i].to.call{value: _actions[i].value}(
_actions[i].data
);
gasAfter = gasleft();
// Check if failure is allowed
if (!success) {
if (!hasBit(_allowFailureMap, uint8(i))) {
revert ActionFailed(i);
}
// Make sure that the action call did not fail because 63/64 of `gasleft()` was insufficient to execute the external call `.to.call` (see [ERC-150](https://eips.ethereum.org/EIPS/eip-150)).
// In specific scenarios, i.e. proposal execution where the last action in the action array is allowed to fail, the account calling `execute` could force-fail this action by setting a gas limit
// where 63/64 is insufficient causing the `.to.call` to fail, but where the remaining 1/64 gas are sufficient to successfully finish the `execute` call.
if (gasAfter < gasBefore / 64) {
revert InsufficientGas();
}
// Store that this action failed.
failureMap = flipBit(failureMap, uint8(i));
}
execResults[i] = data;
unchecked {
++i;
}
}
emit Executed({
actor: msg.sender,
callId: _callId,
actions: _actions,
allowFailureMap: _allowFailureMap,
failureMap: failureMap,
execResults: execResults
});
}
/// @notice Gets the current reentrancy status.
/// @return status This returns the current reentrancy status.
function _getReentrancyStatus() private view returns (uint256 status) {
// solhint-disable-next-line no-inline-assembly
assembly {
status := sload(REENTRANCY_GUARD_STORAGE_LOCATION)
}
}
/// @notice Stores the reentrancy status at a specific storage slot.
/// @param _status The reentrancy status to be stored, typically `_ENTERED` or `_NOT_ENTERED`.
/// @dev Uses inline assembly to store the `_status` value at `REENTRANCY_GUARD_STORAGE_LOCATION` to manage
/// reentrancy status efficiently.
function _storeReentrancyStatus(uint256 _status) private {
// solhint-disable-next-line no-inline-assembly
assembly {
sstore(REENTRANCY_GUARD_STORAGE_LOCATION, _status)
}
}
}// SPDX-License-Identifier: AGPL-3.0-or-later
pragma solidity ^0.8.8;
/// @notice The action struct to be consumed by the DAO's `execute` function resulting in an external call.
/// @param to The address to call.
/// @param value The native token value to be sent with the call.
/// @param data The bytes-encoded function selector and calldata for the call.
struct Action {
address to;
uint256 value;
bytes data;
}
/// @title IExecutor
/// @author Aragon X - 2024
/// @notice The interface required for Executors within the Aragon App DAO framework.
/// @custom:security-contact [email protected]
interface IExecutor {
/// @notice Emitted when a proposal is executed.
/// @dev The value of `callId` is defined by the component/contract calling the execute function.
/// A `Plugin` implementation can use it, for example, as a nonce.
/// @param actor The address of the caller.
/// @param callId The ID of the call.
/// @param actions The array of actions executed.
/// @param allowFailureMap The allow failure map encoding which actions are allowed to fail.
/// @param failureMap The failure map encoding which actions have failed.
/// @param execResults The array with the results of the executed actions.
event Executed(
address indexed actor,
bytes32 callId,
Action[] actions,
uint256 allowFailureMap,
uint256 failureMap,
bytes[] execResults
);
/// @notice Executes a list of actions. If a zero allow-failure map is provided, a failing action reverts the entire execution. If a non-zero allow-failure map is provided, allowed actions can fail without the entire call being reverted.
/// @param _callId The ID of the call. The definition of the value of `callId` is up to the calling contract and can be used, e.g., as a nonce.
/// @param _actions The array of actions.
/// @param _allowFailureMap A bitmap allowing execution to succeed, even if individual actions might revert. If the bit at index `i` is 1, the execution succeeds even if the `i`th action reverts. A failure map value of 0 requires every action to not revert.
/// @return The array of results obtained from the executed actions in `bytes`.
/// @return The resulting failure map containing the actions have actually failed.
function execute(
bytes32 _callId,
Action[] memory _actions,
uint256 _allowFailureMap
) external returns (bytes[] memory, uint256);
}// SPDX-License-Identifier: AGPL-3.0-or-later pragma solidity ^0.8.8; /// @title IDAO /// @author Aragon X - 2022-2024 /// @notice The interface required for DAOs within the Aragon App DAO framework. /// @custom:security-contact [email protected] interface IDAO { /// @notice Checks if an address has permission on a contract via a permission identifier and considers if `ANY_ADDRESS` was used in the granting process. /// @param _where The address of the contract. /// @param _who The address of a EOA or contract to give the permissions. /// @param _permissionId The permission identifier. /// @param _data The optional data passed to the `PermissionCondition` registered. /// @return Returns true if the address has permission, false if not. function hasPermission( address _where, address _who, bytes32 _permissionId, bytes memory _data ) external view returns (bool); /// @notice Updates the DAO metadata (e.g., an IPFS hash). /// @param _metadata The IPFS hash of the new metadata object. function setMetadata(bytes calldata _metadata) external; /// @notice Emitted when the DAO metadata is updated. /// @param metadata The IPFS hash of the new metadata object. event MetadataSet(bytes metadata); /// @notice Emitted when a standard callback is registered. /// @param interfaceId The ID of the interface. /// @param callbackSelector The selector of the callback function. /// @param magicNumber The magic number to be registered for the callback function selector. event StandardCallbackRegistered( bytes4 interfaceId, bytes4 callbackSelector, bytes4 magicNumber ); /// @notice Deposits (native) tokens to the DAO contract with a reference string. /// @param _token The address of the token or address(0) in case of the native token. /// @param _amount The amount of tokens to deposit. /// @param _reference The reference describing the deposit reason. function deposit(address _token, uint256 _amount, string calldata _reference) external payable; /// @notice Emitted when a token deposit has been made to the DAO. /// @param sender The address of the sender. /// @param token The address of the deposited token. /// @param amount The amount of tokens deposited. /// @param _reference The reference describing the deposit reason. event Deposited( address indexed sender, address indexed token, uint256 amount, string _reference ); /// @notice Emitted when a native token deposit has been made to the DAO. /// @dev This event is intended to be emitted in the `receive` function and is therefore bound by the gas limitations for `send`/`transfer` calls introduced by [ERC-2929](https://eips.ethereum.org/EIPS/eip-2929). /// @param sender The address of the sender. /// @param amount The amount of native tokens deposited. event NativeTokenDeposited(address sender, uint256 amount); /// @notice Setter for the trusted forwarder verifying the meta transaction. /// @param _trustedForwarder The trusted forwarder address. function setTrustedForwarder(address _trustedForwarder) external; /// @notice Getter for the trusted forwarder verifying the meta transaction. /// @return The trusted forwarder address. function getTrustedForwarder() external view returns (address); /// @notice Emitted when a new TrustedForwarder is set on the DAO. /// @param forwarder the new forwarder address. event TrustedForwarderSet(address forwarder); /// @notice Checks whether a signature is valid for a provided hash according to [ERC-1271](https://eips.ethereum.org/EIPS/eip-1271). /// @param _hash The hash of the data to be signed. /// @param _signature The signature byte array associated with `_hash`. /// @return Returns the `bytes4` magic value `0x1626ba7e` if the signature is valid and `0xffffffff` if not. function isValidSignature(bytes32 _hash, bytes memory _signature) external returns (bytes4); /// @notice Registers an ERC standard having a callback by registering its [ERC-165](https://eips.ethereum.org/EIPS/eip-165) interface ID and callback function signature. /// @param _interfaceId The ID of the interface. /// @param _callbackSelector The selector of the callback function. /// @param _magicNumber The magic number to be registered for the function signature. function registerStandardCallback( bytes4 _interfaceId, bytes4 _callbackSelector, bytes4 _magicNumber ) external; /// @notice Removed function being left here to not corrupt the IDAO interface ID. Any call will revert. /// @dev Introduced in v1.0.0. Removed in v1.4.0. function setSignatureValidator(address) external; }
// SPDX-License-Identifier: AGPL-3.0-or-later
pragma solidity ^0.8.8;
import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";
import "@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol";
import {IPermissionCondition} from "@aragon/osx-commons-contracts/src/permission/condition/IPermissionCondition.sol";
import {PermissionCondition} from "@aragon/osx-commons-contracts/src/permission/condition/PermissionCondition.sol";
import {PermissionLib} from "@aragon/osx-commons-contracts/src/permission/PermissionLib.sol";
/// @title PermissionManager
/// @author Aragon X - 2021-2023
/// @notice The abstract permission manager used in a DAO, its associated plugins, and other framework-related components.
/// @custom:security-contact [email protected]
abstract contract PermissionManager is Initializable {
using AddressUpgradeable for address;
/// @notice The ID of the permission required to call the `grant`, `grantWithCondition`, `revoke`, and `bulk` function.
bytes32 public constant ROOT_PERMISSION_ID = keccak256("ROOT_PERMISSION");
/// @notice A special address encoding permissions that are valid for any address `who` or `where`.
address internal constant ANY_ADDR = address(type(uint160).max);
/// @notice A special address encoding if a permissions is not set and therefore not allowed.
address internal constant UNSET_FLAG = address(0);
/// @notice A special address encoding if a permission is allowed.
address internal constant ALLOW_FLAG = address(2);
/// @notice A mapping storing permissions as hashes (i.e., `permissionHash(where, who, permissionId)`) and their status encoded by an address (unset, allowed, or redirecting to a `PermissionCondition`).
mapping(bytes32 => address) internal permissionsHashed;
/// @notice Thrown if a call is unauthorized.
/// @param where The context in which the authorization reverted.
/// @param who The address (EOA or contract) missing the permission.
/// @param permissionId The permission identifier.
error Unauthorized(address where, address who, bytes32 permissionId);
/// @notice Thrown if a permission has been already granted with a different condition.
/// @dev This makes sure that condition on the same permission can not be overwriten by a different condition.
/// @param where The address of the target contract to grant `_who` permission to.
/// @param who The address (EOA or contract) to which the permission has already been granted.
/// @param permissionId The permission identifier.
/// @param currentCondition The current condition set for permissionId.
/// @param newCondition The new condition it tries to set for permissionId.
error PermissionAlreadyGrantedForDifferentCondition(
address where,
address who,
bytes32 permissionId,
address currentCondition,
address newCondition
);
/// @notice Thrown if a condition address is not a contract.
/// @param condition The address that is not a contract.
error ConditionNotAContract(IPermissionCondition condition);
/// @notice Thrown if a condition contract does not support the `IPermissionCondition` interface.
/// @param condition The address that is not a contract.
error ConditionInterfaceNotSupported(IPermissionCondition condition);
/// @notice Thrown for `ROOT_PERMISSION_ID` or `EXECUTE_PERMISSION_ID` permission grants where `who` or `where` is `ANY_ADDR`.
error PermissionsForAnyAddressDisallowed();
/// @notice Thrown for permission grants where `who` and `where` are both `ANY_ADDR`.
error AnyAddressDisallowedForWhoAndWhere();
/// @notice Thrown if `Operation.GrantWithCondition` is requested as an operation but the method does not support it.
error GrantWithConditionNotSupported();
/// @notice Emitted when a permission `permission` is granted in the context `here` to the address `_who` for the contract `_where`.
/// @param permissionId The permission identifier.
/// @param here The address of the context in which the permission is granted.
/// @param where The address of the target contract for which `_who` receives permission.
/// @param who The address (EOA or contract) receiving the permission.
/// @param condition The address `ALLOW_FLAG` for regular permissions or, alternatively, the `IPermissionCondition` contract implementation to be used.
event Granted(
bytes32 indexed permissionId,
address indexed here,
address where,
address indexed who,
address condition
);
/// @notice Emitted when a permission `permission` is revoked in the context `here` from the address `_who` for the contract `_where`.
/// @param permissionId The permission identifier.
/// @param here The address of the context in which the permission is revoked.
/// @param where The address of the target contract for which `_who` loses permission.
/// @param who The address (EOA or contract) losing the permission.
event Revoked(
bytes32 indexed permissionId,
address indexed here,
address where,
address indexed who
);
/// @notice A modifier to make functions on inheriting contracts authorized. Permissions to call the function are checked through this permission manager.
/// @param _permissionId The permission identifier required to call the method this modifier is applied to.
modifier auth(bytes32 _permissionId) {
_auth(_permissionId);
_;
}
/// @notice Initialization method to set the initial owner of the permission manager.
/// @dev The initial owner is granted the `ROOT_PERMISSION_ID` permission.
/// @param _initialOwner The initial owner of the permission manager.
function __PermissionManager_init(address _initialOwner) internal onlyInitializing {
_initializePermissionManager({_initialOwner: _initialOwner});
}
/// @notice Grants permission to an address to call methods in a contract guarded by an auth modifier with the specified permission identifier.
/// @dev Requires the `ROOT_PERMISSION_ID` permission.
/// @param _where The address of the target contract for which `_who` receives permission.
/// @param _who The address (EOA or contract) receiving the permission.
/// @param _permissionId The permission identifier.
/// @dev Note, that granting permissions with `_who` or `_where` equal to `ANY_ADDR` does not replace other permissions with specific `_who` and `_where` addresses that exist in parallel.
function grant(
address _where,
address _who,
bytes32 _permissionId
) external virtual auth(ROOT_PERMISSION_ID) {
_grant({_where: _where, _who: _who, _permissionId: _permissionId});
}
/// @notice Grants permission to an address to call methods in a target contract guarded by an auth modifier with the specified permission identifier if the referenced condition permits it.
/// @dev Requires the `ROOT_PERMISSION_ID` permission
/// @param _where The address of the target contract for which `_who` receives permission.
/// @param _who The address (EOA or contract) receiving the permission.
/// @param _permissionId The permission identifier.
/// @param _condition The `PermissionCondition` that will be asked for authorization on calls connected to the specified permission identifier.
/// @dev Note, that granting permissions with `_who` or `_where` equal to `ANY_ADDR` does not replace other permissions with specific `_who` and `_where` addresses that exist in parallel.
function grantWithCondition(
address _where,
address _who,
bytes32 _permissionId,
IPermissionCondition _condition
) external virtual auth(ROOT_PERMISSION_ID) {
_grantWithCondition({
_where: _where,
_who: _who,
_permissionId: _permissionId,
_condition: _condition
});
}
/// @notice Revokes permission from an address to call methods in a target contract guarded by an auth modifier with the specified permission identifier.
/// @dev Requires the `ROOT_PERMISSION_ID` permission.
/// @param _where The address of the target contract for which `_who` loses permission.
/// @param _who The address (EOA or contract) losing the permission.
/// @param _permissionId The permission identifier.
/// @dev Note, that revoking permissions with `_who` or `_where` equal to `ANY_ADDR` does not revoke other permissions with specific `_who` and `_where` addresses that exist in parallel.
function revoke(
address _where,
address _who,
bytes32 _permissionId
) external virtual auth(ROOT_PERMISSION_ID) {
_revoke({_where: _where, _who: _who, _permissionId: _permissionId});
}
/// @notice Applies an array of permission operations on a single target contracts `_where`.
/// @param _where The address of the single target contract.
/// @param items The array of single-targeted permission operations to apply.
function applySingleTargetPermissions(
address _where,
PermissionLib.SingleTargetPermission[] calldata items
) external virtual auth(ROOT_PERMISSION_ID) {
for (uint256 i; i < items.length; ) {
PermissionLib.SingleTargetPermission memory item = items[i];
if (item.operation == PermissionLib.Operation.Grant) {
_grant({_where: _where, _who: item.who, _permissionId: item.permissionId});
} else if (item.operation == PermissionLib.Operation.Revoke) {
_revoke({_where: _where, _who: item.who, _permissionId: item.permissionId});
} else if (item.operation == PermissionLib.Operation.GrantWithCondition) {
revert GrantWithConditionNotSupported();
}
unchecked {
++i;
}
}
}
/// @notice Applies an array of permission operations on multiple target contracts `items[i].where`.
/// @param _items The array of multi-targeted permission operations to apply.
function applyMultiTargetPermissions(
PermissionLib.MultiTargetPermission[] calldata _items
) external virtual auth(ROOT_PERMISSION_ID) {
for (uint256 i; i < _items.length; ) {
PermissionLib.MultiTargetPermission memory item = _items[i];
if (item.operation == PermissionLib.Operation.Grant) {
// Ensure a non-zero condition isn't passed, as `_grant` can't handle conditions.
// This avoids the false impression that a conditional grant occurred,
// since the transaction would still succeed without conditions.
if (item.condition != address(0)) {
revert GrantWithConditionNotSupported();
}
_grant({_where: item.where, _who: item.who, _permissionId: item.permissionId});
} else if (item.operation == PermissionLib.Operation.Revoke) {
_revoke({_where: item.where, _who: item.who, _permissionId: item.permissionId});
} else if (item.operation == PermissionLib.Operation.GrantWithCondition) {
_grantWithCondition({
_where: item.where,
_who: item.who,
_permissionId: item.permissionId,
_condition: IPermissionCondition(item.condition)
});
}
unchecked {
++i;
}
}
}
/// @notice Checks if the caller address has permission on the target contract via a permission identifier and relays the answer to a condition contract if this was declared during the granting process.
/// @param _where The address of the target contract for which `_who` receives permission.
/// @param _who The address (EOA or contract) for which the permission is checked.
/// @param _permissionId The permission identifier.
/// @param _data Optional data to be passed to the set `PermissionCondition`.
/// @return Returns true if `_who` has the permissions on the target contract via the specified permission identifier.
function isGranted(
address _where,
address _who,
bytes32 _permissionId,
bytes memory _data
) public view virtual returns (bool) {
// Specific caller (`_who`) and target (`_where`) permission check
{
// This permission may have been granted directly via the `grant` function or with a condition via the `grantWithCondition` function.
address specificCallerTargetPermission = permissionsHashed[
permissionHash({_where: _where, _who: _who, _permissionId: _permissionId})
];
// If the permission was granted directly, return `true`.
if (specificCallerTargetPermission == ALLOW_FLAG) return true;
// If the permission was granted with a condition, check the condition and return the result.
if (specificCallerTargetPermission != UNSET_FLAG) {
return
_checkCondition({
_condition: specificCallerTargetPermission,
_where: _where,
_who: _who,
_permissionId: _permissionId,
_data: _data
});
}
// If this permission is not set, continue.
}
// Generic caller (`_who: ANY_ADDR`)
{
address genericCallerPermission = permissionsHashed[
permissionHash({_where: _where, _who: ANY_ADDR, _permissionId: _permissionId})
];
// If the permission was granted directly to (`_who: ANY_ADDR`), return `true`.
if (genericCallerPermission == ALLOW_FLAG) return true;
// If the permission was granted with a condition, check the condition and return the result.
if (genericCallerPermission != UNSET_FLAG) {
return
_checkCondition({
_condition: genericCallerPermission,
_where: _where,
_who: _who,
_permissionId: _permissionId,
_data: _data
});
}
// If this permission is not set, continue.
}
// Generic target (`_where: ANY_ADDR`) condition check
{
// This permission can only be granted in conjunction with a condition via the `grantWithCondition` function.
address genericTargetPermission = permissionsHashed[
permissionHash({_where: ANY_ADDR, _who: _who, _permissionId: _permissionId})
];
// If the permission was granted with a condition, check the condition and return the result.
if (genericTargetPermission != UNSET_FLAG) {
return
_checkCondition({
_condition: genericTargetPermission,
_where: _where,
_who: _who,
_permissionId: _permissionId,
_data: _data
});
}
// If this permission is not set, continue.
}
// No specific or generic permission applies to the `_who`, `_where`, `_permissionId`, so we return `false`.
return false;
}
/// @notice Relays the question if caller address has permission on target contract via a permission identifier to a condition contract.
/// @notice Checks a condition contract by doing an external call via try/catch.
/// @param _condition The condition contract that is called.
/// @param _where The address of the target contract for which `_who` receives permission.
/// @param _who The address (EOA or contract) owning the permission.
/// @param _permissionId The permission identifier.
/// @param _data Optional data to be passed to a referenced `PermissionCondition`.
/// @return Returns `true` if a caller (`_who`) has the permissions on the contract (`_where`) via the specified permission identifier.
/// @dev If the external call fails, we return `false`.
function _checkCondition(
address _condition,
address _where,
address _who,
bytes32 _permissionId,
bytes memory _data
) internal view virtual returns (bool) {
// Try-catch to skip failures
try
IPermissionCondition(_condition).isGranted({
_where: _where,
_who: _who,
_permissionId: _permissionId,
_data: _data
})
returns (bool result) {
if (result) {
return true;
}
} catch {}
return false;
}
/// @notice Grants the `ROOT_PERMISSION_ID` permission to the initial owner during initialization of the permission manager.
/// @param _initialOwner The initial owner of the permission manager.
function _initializePermissionManager(address _initialOwner) internal {
_grant({_where: address(this), _who: _initialOwner, _permissionId: ROOT_PERMISSION_ID});
}
/// @notice This method is used in the external `grant` method of the permission manager.
/// @param _where The address of the target contract for which `_who` receives permission.
/// @param _who The address (EOA or contract) owning the permission.
/// @param _permissionId The permission identifier.
/// @dev Note, that granting permissions with `_who` or `_where` equal to `ANY_ADDR` does not replace other permissions with specific `_who` and `_where` addresses that exist in parallel.
function _grant(address _where, address _who, bytes32 _permissionId) internal virtual {
if (_where == ANY_ADDR) {
revert PermissionsForAnyAddressDisallowed();
}
if (_who == ANY_ADDR) {
if (
_permissionId == ROOT_PERMISSION_ID ||
isPermissionRestrictedForAnyAddr(_permissionId)
) {
revert PermissionsForAnyAddressDisallowed();
}
}
bytes32 permHash = permissionHash({
_where: _where,
_who: _who,
_permissionId: _permissionId
});
address currentFlag = permissionsHashed[permHash];
// Means permHash is not currently set.
if (currentFlag == UNSET_FLAG) {
permissionsHashed[permHash] = ALLOW_FLAG;
emit Granted({
permissionId: _permissionId,
here: msg.sender,
where: _where,
who: _who,
condition: ALLOW_FLAG
});
}
}
/// @notice This method is used in the external `grantWithCondition` method of the permission manager.
/// @param _where The address of the target contract for which `_who` receives permission.
/// @param _who The address (EOA or contract) owning the permission.
/// @param _permissionId The permission identifier.
/// @param _condition An address either resolving to a `PermissionCondition` contract address or being the `ALLOW_FLAG` address (`address(2)`).
/// @dev Note, that granting permissions with `_who` or `_where` equal to `ANY_ADDR` does not replace other permissions with specific `_who` and `_where` addresses that exist in parallel.
function _grantWithCondition(
address _where,
address _who,
bytes32 _permissionId,
IPermissionCondition _condition
) internal virtual {
address conditionAddr = address(_condition);
if (!conditionAddr.isContract()) {
revert ConditionNotAContract(_condition);
}
if (
!PermissionCondition(conditionAddr).supportsInterface(
type(IPermissionCondition).interfaceId
)
) {
revert ConditionInterfaceNotSupported(_condition);
}
if (_where == ANY_ADDR && _who == ANY_ADDR) {
revert AnyAddressDisallowedForWhoAndWhere();
}
if (_where == ANY_ADDR || _who == ANY_ADDR) {
if (
_permissionId == ROOT_PERMISSION_ID ||
isPermissionRestrictedForAnyAddr(_permissionId)
) {
revert PermissionsForAnyAddressDisallowed();
}
}
bytes32 permHash = permissionHash({
_where: _where,
_who: _who,
_permissionId: _permissionId
});
address currentCondition = permissionsHashed[permHash];
// Means permHash is not currently set.
if (currentCondition == UNSET_FLAG) {
permissionsHashed[permHash] = conditionAddr;
emit Granted({
permissionId: _permissionId,
here: msg.sender,
where: _where,
who: _who,
condition: conditionAddr
});
} else if (currentCondition != conditionAddr) {
// Revert if `permHash` is already granted, but uses a different condition.
// If we don't revert, we either should:
// - allow overriding the condition on the same permission
// which could be confusing whoever granted the same permission first
// - or do nothing and succeed silently which could be confusing for the caller.
revert PermissionAlreadyGrantedForDifferentCondition({
where: _where,
who: _who,
permissionId: _permissionId,
currentCondition: currentCondition,
newCondition: conditionAddr
});
}
}
/// @notice This method is used in the public `revoke` method of the permission manager.
/// @param _where The address of the target contract for which `_who` receives permission.
/// @param _who The address (EOA or contract) owning the permission.
/// @param _permissionId The permission identifier.
/// @dev Note, that revoking permissions with `_who` or `_where` equal to `ANY_ADDR` does not revoke other permissions with specific `_who` and `_where` addresses that might have been granted in parallel.
function _revoke(address _where, address _who, bytes32 _permissionId) internal virtual {
bytes32 permHash = permissionHash({
_where: _where,
_who: _who,
_permissionId: _permissionId
});
if (permissionsHashed[permHash] != UNSET_FLAG) {
permissionsHashed[permHash] = UNSET_FLAG;
emit Revoked({permissionId: _permissionId, here: msg.sender, where: _where, who: _who});
}
}
/// @notice A private function to be used to check permissions on the permission manager contract (`address(this)`) itself.
/// @param _permissionId The permission identifier required to call the method this modifier is applied to.
function _auth(bytes32 _permissionId) internal view virtual {
if (!isGranted(address(this), msg.sender, _permissionId, msg.data)) {
revert Unauthorized({
where: address(this),
who: msg.sender,
permissionId: _permissionId
});
}
}
/// @notice Generates the hash for the `permissionsHashed` mapping obtained from the word "PERMISSION", the contract address, the address owning the permission, and the permission identifier.
/// @param _where The address of the target contract for which `_who` receives permission.
/// @param _who The address (EOA or contract) owning the permission.
/// @param _permissionId The permission identifier.
/// @return The permission hash.
function permissionHash(
address _where,
address _who,
bytes32 _permissionId
) internal pure virtual returns (bytes32) {
return keccak256(abi.encodePacked("PERMISSION", _who, _where, _permissionId));
}
/// @notice Decides if the granting permissionId is restricted when `_who == ANY_ADDR` or `_where == ANY_ADDR`.
/// @param _permissionId The permission identifier.
/// @return Whether or not the permission is restricted.
/// @dev By default, every permission is unrestricted and it is the derived contract's responsibility to override it. Note, that the `ROOT_PERMISSION_ID` is included and not required to be set it again.
function isPermissionRestrictedForAnyAddr(
bytes32 _permissionId
) internal view virtual returns (bool) {
(_permissionId); // silence the warning.
return false;
}
/// @notice 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 [OpenZeppelin's guide about storage gaps](https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps)).
uint256[49] private __gap;
}// SPDX-License-Identifier: AGPL-3.0-or-later pragma solidity ^0.8.8; /// @title CallbackHandler /// @author Aragon X - 2022-2023 /// @notice This contract handles callbacks by registering a magic number together with the callback function's selector. It provides the `_handleCallback` function that inheriting contracts have to call inside their `fallback()` function (`_handleCallback(msg.callbackSelector, msg.data)`). This allows to adaptively register ERC standards (e.g., [ERC-721](https://eips.ethereum.org/EIPS/eip-721), [ERC-1115](https://eips.ethereum.org/EIPS/eip-1155), or future versions of [ERC-165](https://eips.ethereum.org/EIPS/eip-165)) and returning the required magic numbers for the associated callback functions for the inheriting contract so that it doesn't need to be upgraded. /// @dev This callback handling functionality is intended to be used by executor contracts (i.e., `DAO.sol`). /// @custom:security-contact [email protected] abstract contract CallbackHandler { /// @notice A mapping between callback function selectors and magic return numbers. mapping(bytes4 => bytes4) internal callbackMagicNumbers; /// @notice The magic number refering to unregistered callbacks. bytes4 internal constant UNREGISTERED_CALLBACK = bytes4(0); /// @notice Thrown if the callback function is not registered. /// @param callbackSelector The selector of the callback function. /// @param magicNumber The magic number to be registered for the callback function selector. error UnknownCallback(bytes4 callbackSelector, bytes4 magicNumber); /// @notice Emitted when `_handleCallback` is called. /// @param sender Who called the callback. /// @param sig The function signature. /// @param data The calldata. event CallbackReceived(address sender, bytes4 indexed sig, bytes data); /// @notice Handles callbacks to adaptively support ERC standards. /// @dev This function is supposed to be called via `_handleCallback(msg.sig, msg.data)` in the `fallback()` function of the inheriting contract. /// @param _callbackSelector The function selector of the callback function. /// @param _data The calldata. /// @return The magic number registered for the function selector triggering the fallback. function _handleCallback( bytes4 _callbackSelector, bytes memory _data ) internal virtual returns (bytes4) { bytes4 magicNumber = callbackMagicNumbers[_callbackSelector]; if (magicNumber == UNREGISTERED_CALLBACK) { revert UnknownCallback({callbackSelector: _callbackSelector, magicNumber: magicNumber}); } emit CallbackReceived({sender: msg.sender, sig: _callbackSelector, data: _data}); return magicNumber; } /// @notice Registers a magic number for a callback function selector. /// @param _callbackSelector The selector of the callback function. /// @param _magicNumber The magic number to be registered for the callback function selector. function _registerCallback(bytes4 _callbackSelector, bytes4 _magicNumber) internal virtual { callbackMagicNumbers[_callbackSelector] = _magicNumber; } /// @notice 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 [OpenZeppelin's guide about storage gaps](https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps)). uint256[49] private __gap; }
// SPDX-License-Identifier: AGPL-3.0-or-later pragma solidity ^0.8.8; /// @title EIP-4824 Common Interfaces for DAOs /// @dev See https://eips.ethereum.org/EIPS/eip-4824 /// @author Aragon X - 2021-2023 /// @custom:security-contact [email protected] interface IEIP4824 { /// @notice A distinct Uniform Resource Identifier (URI) pointing to a JSON object following the "EIP-4824 DAO JSON-LD Schema". This JSON file splits into four URIs: membersURI, proposalsURI, activityLogURI, and governanceURI. The membersURI should point to a JSON file that conforms to the "EIP-4824 Members JSON-LD Schema". The proposalsURI should point to a JSON file that conforms to the "EIP-4824 Proposals JSON-LD Schema". The activityLogURI should point to a JSON file that conforms to the "EIP-4824 Activity Log JSON-LD Schema". The governanceURI should point to a flatfile, normatively a .md file. Each of the JSON files named above can be statically hosted or dynamically-generated. /// @return _daoURI The DAO URI. function daoURI() external view returns (string memory _daoURI); }
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)
pragma solidity ^0.8.0;
import "./IERC165Upgradeable.sol";
import {Initializable} from "../../proxy/utils/Initializable.sol";
/**
* @dev Implementation of the {IERC165} interface.
*
* Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check
* for the additional interface id that will be supported. For example:
*
* ```solidity
* function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
* return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);
* }
* ```
*
* Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.
*/
abstract contract ERC165Upgradeable is Initializable, IERC165Upgradeable {
function __ERC165_init() internal onlyInitializing {
}
function __ERC165_init_unchained() internal onlyInitializing {
}
/**
* @dev See {IERC165-supportsInterface}.
*/
function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
return interfaceId == type(IERC165Upgradeable).interfaceId;
}
/**
* @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.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) (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 {Initializable} from "../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 {
// 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;
function __ERC1967Upgrade_init() internal onlyInitializing {
}
function __ERC1967Upgrade_init_unchained() internal onlyInitializing {
}
/**
* @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.4) (token/ERC20/extensions/IERC20Permit.sol)
pragma solidity ^0.8.0;
/**
* @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in
* https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].
*
* Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by
* presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't
* need to send a transaction, and thus is not required to hold Ether at all.
*
* ==== Security Considerations
*
* There are two important considerations concerning the use of `permit`. The first is that a valid permit signature
* expresses an allowance, and it should not be assumed to convey additional meaning. In particular, it should not be
* considered as an intention to spend the allowance in any specific way. The second is that because permits have
* built-in replay protection and can be submitted by anyone, they can be frontrun. A protocol that uses permits should
* take this into consideration and allow a `permit` call to fail. Combining these two aspects, a pattern that may be
* generally recommended is:
*
* ```solidity
* function doThingWithPermit(..., uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s) public {
* try token.permit(msg.sender, address(this), value, deadline, v, r, s) {} catch {}
* doThing(..., value);
* }
*
* function doThing(..., uint256 value) public {
* token.safeTransferFrom(msg.sender, address(this), value);
* ...
* }
* ```
*
* Observe that: 1) `msg.sender` is used as the owner, leaving no ambiguity as to the signer intent, and 2) the use of
* `try/catch` allows the permit to fail and makes the code tolerant to frontrunning. (See also
* {SafeERC20-safeTransferFrom}).
*
* Additionally, note that smart contract wallets (such as Argent or Safe) are not able to produce permit signatures, so
* contracts should have entry points that don't rely on permit.
*/
interface IERC20PermitUpgradeable {
/**
* @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,
* given ``owner``'s signed approval.
*
* IMPORTANT: The same issues {IERC20-approve} has related to transaction
* ordering also apply here.
*
* Emits an {Approval} event.
*
* Requirements:
*
* - `spender` cannot be the zero address.
* - `deadline` must be a timestamp in the future.
* - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`
* over the EIP712-formatted function arguments.
* - the signature must use ``owner``'s current nonce (see {nonces}).
*
* For more information on the signature format, see the
* https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP
* section].
*
* CAUTION: See Security Considerations above.
*/
function permit(
address owner,
address spender,
uint256 value,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) external;
/**
* @dev Returns the current nonce for `owner`. This value must be
* included whenever a signature is generated for {permit}.
*
* Every successful call to {permit} increases ``owner``'s nonce by one. This
* prevents a signature from being used multiple times.
*/
function nonces(address owner) external view returns (uint256);
/**
* @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.
*/
// solhint-disable-next-line func-name-mixedcase
function DOMAIN_SEPARATOR() external view returns (bytes32);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)
pragma solidity ^0.8.0;
/**
* @dev Interface of the ERC165 standard, as defined in the
* https://eips.ethereum.org/EIPS/eip-165[EIP].
*
* Implementers can declare support of contract interfaces, which can then be
* queried by others ({ERC165Checker}).
*
* For an implementation, see {ERC165}.
*/
interface IERC165Upgradeable {
/**
* @dev Returns true if this contract implements the interface defined by
* `interfaceId`. See the corresponding
* https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]
* to learn more about how these ids are created.
*
* This function call must use less than 30 000 gas.
*/
function supportsInterface(bytes4 interfaceId) external view returns (bool);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)
pragma solidity ^0.8.0;
import "./IERC165.sol";
/**
* @dev Implementation of the {IERC165} interface.
*
* Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check
* for the additional interface id that will be supported. For example:
*
* ```solidity
* function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
* return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);
* }
* ```
*
* Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.
*/
abstract contract ERC165 is IERC165 {
/**
* @dev See {IERC165-supportsInterface}.
*/
function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
return interfaceId == type(IERC165).interfaceId;
}
}// SPDX-License-Identifier: AGPL-3.0-or-later pragma solidity ^0.8.8; /// @title IPermissionCondition /// @author Aragon X - 2021-2023 /// @notice An interface to be implemented to support custom permission logic. /// @dev To attach a condition to a permission, the `grantWithCondition` function must be used and refer to the implementing contract's address with the `condition` argument. /// @custom:security-contact [email protected] interface IPermissionCondition { /// @notice Checks if a call is permitted. /// @param _where The address of the target contract. /// @param _who The address (EOA or contract) for which the permissions are checked. /// @param _permissionId The permission identifier. /// @param _data Optional data passed to the `PermissionCondition` implementation. /// @return isPermitted Returns true if the call is permitted. function isGranted( address _where, address _who, bytes32 _permissionId, bytes calldata _data ) external view returns (bool isPermitted); }
// SPDX-License-Identifier: AGPL-3.0-or-later
pragma solidity ^0.8.8;
import {ERC165} from "@openzeppelin/contracts/utils/introspection/ERC165.sol";
import {IProtocolVersion} from "../../utils/versioning/IProtocolVersion.sol";
import {ProtocolVersion} from "../../utils/versioning/ProtocolVersion.sol";
import {IPermissionCondition} from "./IPermissionCondition.sol";
/// @title PermissionCondition
/// @author Aragon X - 2023
/// @notice An abstract contract for non-upgradeable contracts instantiated via the `new` keyword to inherit from to support customary permissions depending on arbitrary on-chain state.
/// @custom:security-contact [email protected]
abstract contract PermissionCondition is ERC165, IPermissionCondition, ProtocolVersion {
/// @notice Checks if an interface is supported by this or its parent contract.
/// @param _interfaceId The ID of the interface.
/// @return Returns `true` if the interface is supported.
function supportsInterface(bytes4 _interfaceId) public view virtual override returns (bool) {
return
_interfaceId == type(IPermissionCondition).interfaceId ||
_interfaceId == type(IProtocolVersion).interfaceId ||
super.supportsInterface(_interfaceId);
}
}// SPDX-License-Identifier: AGPL-3.0-or-later pragma solidity ^0.8.8; /// @title PermissionLib /// @author Aragon X - 2021-2023 /// @notice A library containing objects for permission processing. /// @custom:security-contact [email protected] library PermissionLib { /// @notice A constant expressing that no condition is applied to a permission. address public constant NO_CONDITION = address(0); /// @notice The types of permission operations available in the `PermissionManager`. /// @param Grant The grant operation setting a permission without a condition. /// @param Revoke The revoke operation removing a permission (that was granted with or without a condition). /// @param GrantWithCondition The grant operation setting a permission with a condition. enum Operation { Grant, Revoke, GrantWithCondition } /// @notice A struct containing the information for a permission to be applied on a single target contract without a condition. /// @param operation The permission operation type. /// @param who The address (EOA or contract) receiving the permission. /// @param permissionId The permission identifier. struct SingleTargetPermission { Operation operation; address who; bytes32 permissionId; } /// @notice A struct containing the information for a permission to be applied on multiple target contracts, optionally, with a condition. /// @param operation The permission operation type. /// @param where The address of the target contract for which `who` receives permission. /// @param who The address (EOA or contract) receiving the permission. /// @param condition The `PermissionCondition` that will be asked for authorization on calls connected to the specified permission identifier. /// @param permissionId The permission identifier. struct MultiTargetPermission { Operation operation; address where; address who; address condition; bytes32 permissionId; } }
// 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) (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 (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 v4.4.1 (utils/introspection/IERC165.sol)
pragma solidity ^0.8.0;
/**
* @dev Interface of the ERC165 standard, as defined in the
* https://eips.ethereum.org/EIPS/eip-165[EIP].
*
* Implementers can declare support of contract interfaces, which can then be
* queried by others ({ERC165Checker}).
*
* For an implementation, see {ERC165}.
*/
interface IERC165 {
/**
* @dev Returns true if this contract implements the interface defined by
* `interfaceId`. See the corresponding
* https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]
* to learn more about how these ids are created.
*
* This function call must use less than 30 000 gas.
*/
function supportsInterface(bytes4 interfaceId) external view returns (bool);
}{
"remappings": [
"@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/",
"@openzeppelin/contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/contracts/",
"@aragon/osx/=lib/osx/packages/contracts/src/",
"@aragon/osx-commons-contracts/=lib/osx-commons/contracts/",
"@aragon/admin-plugin/=lib/admin-plugin/packages/contracts/src/",
"@aragon/multisig-plugin/=lib/multisig-plugin/packages/contracts/src/",
"@aragon/token-voting-plugin/=lib/token-voting-plugin/src/",
"@aragon/staged-proposal-processor-plugin/=lib/staged-proposal-processor-plugin/src/",
"@ensdomains/ens-contracts/=lib/ens-contracts/",
"@ensdomains/buffer/=lib/buffer/",
"forge-std/=lib/forge-std/src/",
"@openzeppelin/openzeppelin-foundry-upgrades/=lib/staged-proposal-processor-plugin/node_modules/@openzeppelin/openzeppelin-foundry-upgrades/src/",
"admin-plugin/=lib/admin-plugin/",
"buffer/=lib/buffer/contracts/",
"ds-test/=lib/openzeppelin-contracts-upgradeable/lib/forge-std/lib/ds-test/src/",
"ens-contracts/=lib/ens-contracts/contracts/",
"erc4626-tests/=lib/openzeppelin-contracts-upgradeable/lib/erc4626-tests/",
"multisig-plugin/=lib/multisig-plugin/",
"openzeppelin-contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/",
"openzeppelin-contracts/=lib/openzeppelin-contracts/",
"openzeppelin/=lib/openzeppelin-contracts-upgradeable/contracts/",
"osx-commons/=lib/osx-commons/",
"osx/=lib/osx/",
"plugin-version-1.3/=lib/token-voting-plugin/lib/plugin-version-1.3/packages/contracts/src/",
"solidity-stringutils/=lib/staged-proposal-processor-plugin/node_modules/solidity-stringutils/",
"staged-proposal-processor-plugin/=lib/staged-proposal-processor-plugin/src/",
"token-voting-plugin/=lib/token-voting-plugin/src/"
],
"optimizer": {
"enabled": true,
"runs": 200
},
"metadata": {
"useLiteralContent": false,
"bytecodeHash": "ipfs",
"appendCBOR": true
},
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"devdoc",
"userdoc",
"metadata",
"abi"
]
}
},
"evmVersion": "cancun",
"viaIR": true
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"uint256","name":"index","type":"uint256"}],"name":"ActionFailed","type":"error"},{"inputs":[],"name":"AlreadyInitialized","type":"error"},{"inputs":[],"name":"AnyAddressDisallowedForWhoAndWhere","type":"error"},{"inputs":[{"internalType":"contract IPermissionCondition","name":"condition","type":"address"}],"name":"ConditionInterfaceNotSupported","type":"error"},{"inputs":[{"internalType":"contract IPermissionCondition","name":"condition","type":"address"}],"name":"ConditionNotAContract","type":"error"},{"inputs":[],"name":"FunctionRemoved","type":"error"},{"inputs":[],"name":"GrantWithConditionNotSupported","type":"error"},{"inputs":[],"name":"InsufficientGas","type":"error"},{"inputs":[{"internalType":"uint256","name":"expected","type":"uint256"},{"internalType":"uint256","name":"actual","type":"uint256"}],"name":"NativeTokenDepositAmountMismatch","type":"error"},{"inputs":[{"internalType":"address","name":"where","type":"address"},{"internalType":"address","name":"who","type":"address"},{"internalType":"bytes32","name":"permissionId","type":"bytes32"},{"internalType":"address","name":"currentCondition","type":"address"},{"internalType":"address","name":"newCondition","type":"address"}],"name":"PermissionAlreadyGrantedForDifferentCondition","type":"error"},{"inputs":[],"name":"PermissionsForAnyAddressDisallowed","type":"error"},{"inputs":[{"internalType":"uint8[3]","name":"protocolVersion","type":"uint8[3]"}],"name":"ProtocolVersionUpgradeNotSupported","type":"error"},{"inputs":[],"name":"ReentrantCall","type":"error"},{"inputs":[],"name":"TooManyActions","type":"error"},{"inputs":[{"internalType":"address","name":"where","type":"address"},{"internalType":"address","name":"who","type":"address"},{"internalType":"bytes32","name":"permissionId","type":"bytes32"}],"name":"Unauthorized","type":"error"},{"inputs":[{"internalType":"bytes4","name":"callbackSelector","type":"bytes4"},{"internalType":"bytes4","name":"magicNumber","type":"bytes4"}],"name":"UnknownCallback","type":"error"},{"inputs":[],"name":"ZeroAmount","type":"error"},{"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":"address","name":"sender","type":"address"},{"indexed":true,"internalType":"bytes4","name":"sig","type":"bytes4"},{"indexed":false,"internalType":"bytes","name":"data","type":"bytes"}],"name":"CallbackReceived","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":true,"internalType":"address","name":"token","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"string","name":"_reference","type":"string"}],"name":"Deposited","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"actor","type":"address"},{"indexed":false,"internalType":"bytes32","name":"callId","type":"bytes32"},{"components":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"indexed":false,"internalType":"struct Action[]","name":"actions","type":"tuple[]"},{"indexed":false,"internalType":"uint256","name":"allowFailureMap","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"failureMap","type":"uint256"},{"indexed":false,"internalType":"bytes[]","name":"execResults","type":"bytes[]"}],"name":"Executed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"permissionId","type":"bytes32"},{"indexed":true,"internalType":"address","name":"here","type":"address"},{"indexed":false,"internalType":"address","name":"where","type":"address"},{"indexed":true,"internalType":"address","name":"who","type":"address"},{"indexed":false,"internalType":"address","name":"condition","type":"address"}],"name":"Granted","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint8","name":"version","type":"uint8"}],"name":"Initialized","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes","name":"metadata","type":"bytes"}],"name":"MetadataSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"sender","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"NativeTokenDeposited","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"daoURI","type":"string"}],"name":"NewURI","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"permissionId","type":"bytes32"},{"indexed":true,"internalType":"address","name":"here","type":"address"},{"indexed":false,"internalType":"address","name":"where","type":"address"},{"indexed":true,"internalType":"address","name":"who","type":"address"}],"name":"Revoked","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes4","name":"interfaceId","type":"bytes4"},{"indexed":false,"internalType":"bytes4","name":"callbackSelector","type":"bytes4"},{"indexed":false,"internalType":"bytes4","name":"magicNumber","type":"bytes4"}],"name":"StandardCallbackRegistered","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"forwarder","type":"address"}],"name":"TrustedForwarderSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"implementation","type":"address"}],"name":"Upgraded","type":"event"},{"stateMutability":"nonpayable","type":"fallback"},{"inputs":[],"name":"EXECUTE_PERMISSION_ID","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"REGISTER_STANDARD_CALLBACK_PERMISSION_ID","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ROOT_PERMISSION_ID","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"SET_METADATA_PERMISSION_ID","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"SET_TRUSTED_FORWARDER_PERMISSION_ID","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"UPGRADE_DAO_PERMISSION_ID","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"VALIDATE_SIGNATURE_PERMISSION_ID","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"enum PermissionLib.Operation","name":"operation","type":"uint8"},{"internalType":"address","name":"where","type":"address"},{"internalType":"address","name":"who","type":"address"},{"internalType":"address","name":"condition","type":"address"},{"internalType":"bytes32","name":"permissionId","type":"bytes32"}],"internalType":"struct PermissionLib.MultiTargetPermission[]","name":"_items","type":"tuple[]"}],"name":"applyMultiTargetPermissions","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_where","type":"address"},{"components":[{"internalType":"enum PermissionLib.Operation","name":"operation","type":"uint8"},{"internalType":"address","name":"who","type":"address"},{"internalType":"bytes32","name":"permissionId","type":"bytes32"}],"internalType":"struct PermissionLib.SingleTargetPermission[]","name":"items","type":"tuple[]"}],"name":"applySingleTargetPermissions","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"daoURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_token","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"string","name":"_reference","type":"string"}],"name":"deposit","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_callId","type":"bytes32"},{"components":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"internalType":"struct Action[]","name":"_actions","type":"tuple[]"},{"internalType":"uint256","name":"_allowFailureMap","type":"uint256"}],"name":"execute","outputs":[{"internalType":"bytes[]","name":"execResults","type":"bytes[]"},{"internalType":"uint256","name":"failureMap","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"getTrustedForwarder","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_where","type":"address"},{"internalType":"address","name":"_who","type":"address"},{"internalType":"bytes32","name":"_permissionId","type":"bytes32"}],"name":"grant","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_where","type":"address"},{"internalType":"address","name":"_who","type":"address"},{"internalType":"bytes32","name":"_permissionId","type":"bytes32"},{"internalType":"contract IPermissionCondition","name":"_condition","type":"address"}],"name":"grantWithCondition","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_where","type":"address"},{"internalType":"address","name":"_who","type":"address"},{"internalType":"bytes32","name":"_permissionId","type":"bytes32"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"hasPermission","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes","name":"_metadata","type":"bytes"},{"internalType":"address","name":"_initialOwner","type":"address"},{"internalType":"address","name":"_trustedForwarder","type":"address"},{"internalType":"string","name":"daoURI_","type":"string"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint8[3]","name":"_previousProtocolVersion","type":"uint8[3]"},{"internalType":"bytes","name":"_initData","type":"bytes"}],"name":"initializeFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_where","type":"address"},{"internalType":"address","name":"_who","type":"address"},{"internalType":"bytes32","name":"_permissionId","type":"bytes32"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"isGranted","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_hash","type":"bytes32"},{"internalType":"bytes","name":"_signature","type":"bytes"}],"name":"isValidSignature","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"protocolVersion","outputs":[{"internalType":"uint8[3]","name":"","type":"uint8[3]"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"proxiableUUID","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes4","name":"_interfaceId","type":"bytes4"},{"internalType":"bytes4","name":"_callbackSelector","type":"bytes4"},{"internalType":"bytes4","name":"_magicNumber","type":"bytes4"}],"name":"registerStandardCallback","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_where","type":"address"},{"internalType":"address","name":"_who","type":"address"},{"internalType":"bytes32","name":"_permissionId","type":"bytes32"}],"name":"revoke","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"newDaoURI","type":"string"}],"name":"setDaoURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes","name":"_metadata","type":"bytes"}],"name":"setMetadata","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"setSignatureValidator","outputs":[],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"_newTrustedForwarder","type":"address"}],"name":"setTrustedForwarder","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"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"},{"stateMutability":"payable","type":"receive"}]Contract Creation Code
60a080604052346100da57306080525f549060ff8260081c16610088575060ff8082160361004e575b60405161312890816100df82396080518181816112770152818161135f01526119070152f35b60ff90811916175f557f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498602060405160ff8152a15f610028565b62461bcd60e51b815260206004820152602760248201527f496e697469616c697a61626c653a20636f6e747261637420697320696e697469604482015266616c697a696e6760c81b6064820152608490fd5b5f80fdfe608080604052600436101561011a575b5036156100e957346100e5575f356001600160e01b03191661003036611efa565b9061003e6040519283611ed9565b368252365f60208401375f60203684010152805f5260fb60205263ffffffff60e01b60405f205460e01b169182156100cf576100af7f4792cb6e46e49876374bea490ba23274bacea6b84c216a64f47abab54027589b9160405191829133835260406020840152604083019061200c565b0390a260405160208101918252602081526100cb604082611ed9565b5190f35b50634aa318c360e01b5f5260045260245260445ffd5b5f80fd5b7f62c2c8e34665db7c56b2cabd7f5fb9702ccd352ffa8150147e450797e9f8e8f360408051338152346020820152a1005b5f3560e01c90816301ffc9a714611e25575080630729d05414611dfe57806309e56b1414611dd75780631080f99b14611d9b5780631626ba7e14611d4b57806322844d0414611c1757806324b4d73f14611bf05780632675fdd01461027b57806326875b1f14611bc95780632ae9c60014611b5c5780633659cfe6146118e95780633e2ab0d9146118c057806342d8e99e146115e85780634ec7ac23146115c15780634f1ef2861461132757806352d1902d146112655780637034731b14611194578063829331a11461116d578063bfe07da614610f5e578063c4a5014514610de8578063c71bf32414610a45578063c9dbc2a4146109fa578063ce1b815f146109d1578063d68bad2c146109b2578063d96054c414610993578063da74222814610904578063e306bee7146108dd578063e978afe5146106f8578063eafb8b06146102c3578063ee57e36f146102805763fdef91061461027b575f61000f565b611f9b565b346100e55760203660031901126100e5576004356001600160401b0381116100e5576102b36102c1913690600401611e91565b906102bc612517565b612ddc565b005b346100e55760803660031901126100e5576004356001600160401b0381116100e5576102f3903690600401611e91565b906102fc611f71565b916044356001600160a01b03811681036100e5576064356001600160401b0381116100e55761032f903690600401611e91565b9290915f5460ff811692836106ea57610574966101038361036561056f9760ff61056a9760081c161590816106df575b5061237d565b61ffff1916175f90815560016101308190557f2dd0f5ec3fbf050b78ec4c3d6ba16f3115022f2844d2f03cc58cdaa4402c8e88805460ff1990811683179091557ffefb654910b912e24b178f0bc09b5fe5971ae8a0dce588dc9321dc79fad35e8180548216831790557f1aa0fa3ce14642b336ea63139f6c7f2303168ba0a6471e1bd553e6490f77493980548216831790557f3244762813c531f1490b38900bb8750f879055d333cb43ca28d6f1c14282f61280548216831790557fb675f6d058fef1af3db0f797cfc9e0732d03c4eba47cb39683ecca426f80946280548216831790557f0694e0bc0f5c2fec9e5fab675807d55c7e41563f8b82e3f5f24d0d62385ebbe180548216831790557fb58f686c68cd9dfbabb72688d100a65fa0fad5014bad246510fefb74d36ce41380548216831790557ecbad7156f80fe4adddb2ec8acf4741a6e01e259e59bc61305a9e0cf72a3d9e8054909116909117905560fb6020527f5a08f87af82de422c581ce019b2e54a9c17372e9cba575ae0470ba2482d63686805463ffffffff1990811663150b7a02179091557fe1cfe341950d56d8854f782066100d5ae1d5930cdb4949b973e554a343efc6c38054821663f23a6e6117905563bc197c8160e01b9091527f08ba3617671847c1c169da222a5bc01cfdefcc3c4f1e5525214a474479c89123805490911663bc197c81179055612ddc565b612d8f565b612664565b60ff5f5460081c161561068657306001600160a01b0314610677576001600160a01b0381811691908214610677575f5160206130735f395f51905f526105ba9130612a1e565b5f81815260c960205260409020546001600160a01b03161561060d575b61ff00195f54165f557f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498602060405160038152a1005b5f90815260c9602090815260409182902080546001600160a01b031916600290811790915582513081529182015233915f5160206130735f395f51905f52917f0f579ad49235a8c1fd9041427e7067b1eb10926bbed380bf6fabc73e0e8076449190a480806105d7565b6324159e5b60e01b5f5260045ffd5b60405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b6064820152608490fd5b60039150108d61035f565b62dc149f60e41b5f5260045ffd5b346100e55760203660031901126100e5576004356001600160401b0381116100e557366023820112156100e5578060040135906001600160401b0382116100e55736602460a08402830101116100e557610750612586565b5f5b828110156102c15760a0810282019060a060231983360301126100e55760405160a081018181106001600160401b038211176108c95760405260248301359060038210156100e5578181526107a960448501611f87565b91602082019283526107bd60648601611f87565b91604081019283526107d160848701611f87565b916060820192835260a4608083019701358752155f1461082e5750516001600160a01b031661081f57905190519251600193610819926001600160a01b039182169116612887565b01610752565b63d4d3bef760e01b5f5260045ffd5b809392935160038110156108b5576001036108685750505190519251600193610863926001600160a01b0391821691166127f8565b610819565b929192519460038610156108b55760026001961461088a575b50505050610819565b92519151925190516108ac9360a087901b879003918216939082169116612b9e565b84808080610881565b634e487b7160e01b5f52602160045260245ffd5b634e487b7160e01b5f52604160045260245ffd5b346100e5575f3660031901126100e55760206040515f516020612ff35f395f51905f528152f35b346100e55760203660031901126100e55761091d611f5b565b61095d61092936611efa565b6109366040519182611ed9565b368152365f60208301375f602036830101525f5160206130135f395f51905f52333061220c565b1561096b576102c190612d8f565b631e09743f60e01b5f5230600452336024525f5160206130135f395f51905f5260445260645ffd5b346100e5576102c16109a436612088565b916109ad612586565b6127f8565b346100e5576102c16109c336612088565b916109cc612586565b612887565b346100e5575f3660031901126100e55761012e546040516001600160a01b039091168152602090f35b346100e55760803660031901126100e557610a13611f5b565b610a1b611f71565b90606435906001600160a01b03821682036100e5576102c192610a3c612586565b60443591612b9e565b346100e55760603660031901126100e5576024356001600160401b0381116100e557366023820112156100e55780600401356001600160401b0381116100e55760248201908060051b36602482860101116100e55760443560026101305414610dd957600261013055610aee610aba36611efa565b610ac76040519182611ed9565b368152365f60208301375f602036830101525f5160206130b35f395f51905f52333061220c565b15610db1575f926101008111610da257610b0a81969596612487565b94610b186040519687611ed9565b818652601f19610b2783612487565b015f5b818110610d8f5750505f5b828110610c7b575090604051938160a08601600435875260a060208801525260c08086019186010197925f90608219813603015b848310610bdf57610bd58a8a8d7fd4e57c2049f004fb297ef78591cd409503ceb6b2c722d7ffed032fc99e5f3b588c8c6040820152836060820152808303608082015280610bb8339487612030565b0390a2600161013055604051928392604084526040840190612030565b9060208301520390f35b90919293949960bf198882030185528a35828112156100e55783016001600160a01b03610c0e60248301611f87565b1682526044810135602083015260648101359060421936829003018212156100e5576024910101602081359101906001600160401b0381116100e55780360382136100e557610c6d602092839260608681604060019901520191612467565b9c0196950193019190610b69565b5a610c8782858b61249e565b356001600160a01b03811681036100e5576020610ca584878d61249e565b013590610cb384878d61249e565b604081013590601e19813603018212156100e55701908135916001600160401b0383116100e5576020019180360383136100e5575f938493826040519384928337810185815203925af1610d056124d4565b915a600160ff86161b91888316610d525750505015610d3f57906001915b610d2d828a612503565b52610d388189612503565b5001610b35565b5063a6a7dbbd60e01b5f5260045260245ffd5b90919215610d67575b50505090600191610d23565b6006999493991c11610d80579091189560018a80610d5b565b6307099c5360e21b5f5260045ffd5b60606020828a0181019190915201610b2a565b6308e3b1eb60e11b5f5260045ffd5b631e09743f60e01b5f5230600452336024525f5160206130b35f395f51905f5260445260645ffd5b6306fda65d60e31b5f5260045ffd5b346100e55760603660031901126100e557610e01611e7a565b6024359063ffffffff60e01b82168092036100e557604435906001600160e01b03198216908183036100e557610e6d610e3936611efa565b610e466040519182611ed9565b368152365f60208301375f602036830101525f516020612fd35f395f51905f52333061220c565b15610f36576001600160e01b031990811691908214610ef1577ffc72fd547553f7a663e0048e590afc9c47b56a4242e960f31cf4c62e23d308b993606093835f52603360205260405f20600160ff19825416179055815f5260fb60205260405f209060e01c63ffffffff1982541617905560405192835260208301526040820152a1005b60405162461bcd60e51b815260206004820152601c60248201527f4552433136353a20696e76616c696420696e74657266616365206964000000006044820152606490fd5b631e09743f60e01b5f5230600452336024525f516020612fd35f395f51905f5260445260645ffd5b60603660031901126100e557610f72611f5b565b602435906044356001600160401b0381116100e557610f95903690600401611e91565b91831561115e576001600160a01b0316928361100f57803403610ff957907f2bc500cf071be2d1c1458ed6ff484cd4db4345ada8943dee7ff29e7af3558f76915b610ff460405192839283526040602084015233956040840191612467565b0390a3005b6301abd56160e41b5f526004523460245260445ffd5b90346111475761109a6040515f80602083016323b872dd60e01b81523360248501523060448501528660648501526064845261104c608485611ed9565b6040519361105b604086611ed9565b602085527f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c656460208601525190828a5af16110936124d4565b9087612f35565b805190811591821561112d575b5050156110d5577f2bc500cf071be2d1c1458ed6ff484cd4db4345ada8943dee7ff29e7af3558f7691610fd6565b60405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152608490fd5b6111409250602080918301019101612a73565b85806110a7565b6301abd56160e41b5f525f6004523460245260445ffd5b631f2a200560e01b5f5260045ffd5b346100e5575f3660031901126100e55760206040515f5160206130135f395f51905f528152f35b346100e5575f3660031901126100e5576040515f61012f546111b58161242f565b808452906001811690811561124157506001146111f5575b6111f1836111dd81850382611ed9565b60405191829160208352602083019061200c565b0390f35b91905061012f5f525f5160206130535f395f51905f52915f905b808210611227575090915081016020016111dd6111cd565b91926001816020925483858801015201910190929161120f565b60ff191660208086019190915291151560051b840190910191506111dd90506111cd565b346100e5575f3660031901126100e5577f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031630036112bc5760206040515f5160206130335f395f51905f528152f35b60405162461bcd60e51b815260206004820152603860248201527f555550535570677261646561626c653a206d757374206e6f742062652063616c60448201527f6c6564207468726f7567682064656c656761746563616c6c00000000000000006064820152608490fd5b60403660031901126100e55761133b611f5b565b6024356001600160401b0381116100e55761135a903690600401611f15565b6113b17f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316611393308214156122bb565b5f5160206130335f395f51905f52546001600160a01b03161461231c565b6113b96125f5565b7f4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd91435460ff16156113ed57506102c190612e9e565b6040516352d1902d60e01b81526001600160a01b03831690602081600481855afa5f918161158d575b506114775760405162461bcd60e51b815260206004820152602e60248201527f45524331393637557067726164653a206e657720696d706c656d656e7461746960448201526d6f6e206973206e6f74205555505360901b6064820152608490fd5b5f5160206130335f395f51905f52036115365761149383612e9e565b7fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b5f80a280511580159061152e575b6114c857005b6102c1915f80604051936114dd606086611ed9565b602785527f416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c6020860152660819985a5b195960ca1b6040860152602081519101845af46115286124d4565b91612f35565b5060016114c2565b60405162461bcd60e51b815260206004820152602960248201527f45524331393637557067726164653a20756e737570706f727465642070726f786044820152681a58589b195555525160ba1b6064820152608490fd5b9091506020813d6020116115b9575b816115a960209383611ed9565b810103126100e557519085611416565b3d915061159c565b346100e5575f3660031901126100e55760206040515f5160206130935f395f51905f528152f35b346100e55760803660031901126100e557366064116100e5576064356001600160401b0381116100e557611620903690600401611e91565b50506101035f5460ff8160081c1615806118b3575b61163e9061237d565b61ffff1916175f5560043560ff81168091036100e5576001036118725761168a611667366123ee565b6040519061167482611ebe565b60018252600360208301525f6040830152612b35565b61182b575b6116be61169b366123ee565b604051906116a882611ebe565b60018252600460208301525f6040830152612b35565b6116f85761ff00195f54165f557f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498602060405160038152a1005b6117237f0dcbfb19b09fb8ff4e9af583d4b8e9c8127cc1b26529b4d96dd3b7e7780883723030612a1e565b5f81815260c960205260409020546001600160a01b03166117bb575b50632a4f53ad60e11b5f5260336020527ffefb654910b912e24b178f0bc09b5fe5971ae8a0dce588dc9321dc79fad35e81805460ff191660011790556331c6fcc960e21b5f5260336020527f1aa0fa3ce14642b336ea63139f6c7f2303168ba0a6471e1bd553e6490f774939805460ff191660011790556105d7565b5f5260c960205260405f206001600160601b0360a01b815416905560405130815230907f0dcbfb19b09fb8ff4e9af583d4b8e9c8127cc1b26529b4d96dd3b7e7780883727f3ca48185ec3f6e47e24db18b13f1c65b1ce05da1659f9c1c4fe717dda5f6752460203393a48061173f565b6001610130819055621574e360e91b5f5260336020527f0694e0bc0f5c2fec9e5fab675807d55c7e41563f8b82e3f5f24d0d62385ebbe1805460ff1916909117905561168f565b6040516384833d6760e01b815260045f8183015b6003821061189357606484fd5b60208060019260ff6118a4876123e0565b16815201930191019091611886565b50600360ff821610611635565b346100e55760203660031901126100e5576118d9611f5b565b5063b2728e9960e01b5f5260045ffd5b346100e55760203660031901126100e557611902611f5b565b61193b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316611393308214156122bb565b6119436125f5565b6040519060206119538184611ed9565b5f8352808301601f1982013682377f4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd91435460ff16156119975750506102c19150612e9e565b6040516352d1902d60e01b81529192916001600160a01b038316908481600481855afa5f9181611b2d575b50611a235760405162461bcd60e51b815260048101869052602e60248201527f45524331393637557067726164653a206e657720696d706c656d656e7461746960448201526d6f6e206973206e6f74205555505360901b6064820152608490fd5b5f5160206130335f395f51905f5203611ad657611a3f83612e9e565b7fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b5f80a2835115801590611acf575b611a7457005b5f80916102c1957f416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c60405196611aab606089611ed9565b60278852870152660819985a5b195960ca1b60408701525190845af46115286124d4565b505f611a6e565b60405162461bcd60e51b815260048101859052602960248201527f45524331393637557067726164653a20756e737570706f727465642070726f786044820152681a58589b195555525160ba1b6064820152608490fd5b9091508581813d8311611b55575b611b458183611ed9565b810103126100e5575190876119c2565b503d611b3b565b346100e5575f3660031901126100e5576060604051611b7b8282611ed9565b369037604051611b8a81611ebe565b60018152600460208201525f604082015260405190815f905b60038210611bb057606084f35b60208060019260ff865116815201930191019091611ba3565b346100e5575f3660031901126100e55760206040515f516020612fd35f395f51905f528152f35b346100e5575f3660031901126100e55760206040515f5160206130d35f395f51905f528152f35b346100e55760403660031901126100e557611c30611f5b565b602435906001600160401b0382116100e557366023830112156100e5578160040135916001600160401b0383116100e55736602460608502830101116100e557611c78612586565b5f5b838110156102c157606081028201606060231982360301126100e557604051611ca281611ebe565b60248201359060038210156100e557818152611cc060448401611f87565b91602082019283526064604083019401358452155f14611cfc575051905160019291611cf691906001600160a01b031686612887565b01611c7a565b805160038110156108b557600103611d2f575051905160019291611d2a91906001600160a01b0316866127f8565b611cf6565b9150505160038110156108b55760021461081f57600190611cf6565b346100e55760403660031901126100e5576024356001600160401b0381116100e557611d88611d806020923690600401611f15565b6004356120c2565b6040516001600160e01b03199091168152f35b346100e55760203660031901126100e5576004356001600160401b0381116100e557611dce6102c1913690600401611e91565b9061056f612517565b346100e5575f3660031901126100e55760206040515f5160206130735f395f51905f528152f35b346100e5575f3660031901126100e55760206040515f5160206130b35f395f51905f528152f35b346100e55760203660031901126100e5576020906001600160e01b0319611e4a611e7a565b166301ffc9a760e01b8114908115611e64575b5015158152f35b90505f526033825260ff60405f20541683611e5d565b600435906001600160e01b0319821682036100e557565b9181601f840112156100e5578235916001600160401b0383116100e557602083818601950101116100e557565b606081019081106001600160401b038211176108c957604052565b90601f801991011681019081106001600160401b038211176108c957604052565b6001600160401b0381116108c957601f01601f191660200190565b81601f820112156100e557803590611f2c82611efa565b92611f3a6040519485611ed9565b828452602083830101116100e557815f926020809301838601378301015290565b600435906001600160a01b03821682036100e557565b602435906001600160a01b03821682036100e557565b35906001600160a01b03821682036100e557565b346100e55760803660031901126100e5576004356001600160a01b03811681036100e557602435906001600160a01b03821682036100e557606435906044356001600160401b0383116100e557602093611ffc612002943690600401611f15565b9261220c565b6040519015158152f35b805180835260209291819084018484015e5f828201840152601f01601f1916010190565b9080602083519182815201916020808360051b8301019401925f915b83831061205b57505050505090565b9091929394602080612079600193601f19868203018752895161200c565b9701930193019193929061204c565b60609060031901126100e5576004356001600160a01b03811681036100e557906024356001600160a01b03811681036100e5579060443590565b906120f66120fd926120e86040519384926020840152604080840152606083019061200c565b03601f198101835282611ed9565b3330612118565b61210d576001600160e01b031990565b630b135d3f60e11b90565b91906121325f5160206130935f395f51905f528285612a1e565b5f90815260c960205260409020546001600160a01b03166002811461220357806121ea575061216e5f5160206130935f395f51905f528461297a565b5f90815260c960205260409020546001600160a01b03166002811461220357806121ea57506121aa5f5160206130935f395f51905f52826129cf565b5f90815260c960205260409020546001600160a01b031690816121cf57505050505f90565b6121e7935f5160206130935f395f51905f5292612a8b565b90565b906121e7935f5160206130935f395f51905f5292612a8b565b50505050600190565b92919061221a828286612a1e565b5f90815260c960205260409020546001600160a01b0316600281146122b157806122a75750612249828561297a565b5f90815260c960205260409020546001600160a01b0316600281146122b157806122a7575061227882826129cf565b5f90815260c960205260409020546001600160a01b0316938461229e5750505050505f90565b6121e794612a8b565b936121e794612a8b565b5050505050600190565b156122c257565b60405162461bcd60e51b815260206004820152602c60248201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060448201526b19195b1959d85d1958d85b1b60a21b6064820152608490fd5b1561232357565b60405162461bcd60e51b815260206004820152602c60248201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060448201526b6163746976652070726f787960a01b6064820152608490fd5b1561238457565b60405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b6064820152608490fd5b359060ff821682036100e557565b90604051916123fe606084611ed9565b82906064116100e5576004905b60648210612417575050565b60208091612424846123e0565b81520191019061240b565b90600182811c9216801561245d575b602083101461244957565b634e487b7160e01b5f52602260045260245ffd5b91607f169161243e565b908060209392818452848401375f828201840152601f01601f1916010190565b6001600160401b0381116108c95760051b60200190565b91908110156124c05760051b81013590605e19813603018212156100e5570190565b634e487b7160e01b5f52603260045260245ffd5b3d156124fe573d906124e582611efa565b916124f36040519384611ed9565b82523d5f602084013e565b606090565b80518210156124c05760209160051b010190565b61255761252336611efa565b6125306040519182611ed9565b368152365f60208301375f602036830101525f516020612ff35f395f51905f52333061220c565b1561255e57565b631e09743f60e01b5f5230600452336024525f516020612ff35f395f51905f5260445260645ffd5b6125c661259236611efa565b61259f6040519182611ed9565b368152365f60208301375f602036830101525f5160206130735f395f51905f52333061220c565b156125cd57565b631e09743f60e01b5f5230600452336024525f5160206130735f395f51905f5260445260645ffd5b61263561260136611efa565b61260e6040519182611ed9565b368152365f60208301375f602036830101525f5160206130d35f395f51905f52333061220c565b1561263c57565b631e09743f60e01b5f5230600452336024525f5160206130d35f395f51905f5260445260645ffd5b9190916001600160401b0383116108c95761268161012f5461242f565b601f811161278f575b505f92601f81116001146126ff57807fe9b617ecb5f63f6a9ccd8d4d5fa0d7b2ef9b17ce3f48e6b135808d6a40e6774293945f916126f4575b508160011b905f198360031b1c19161761012f555b6126ef604051928392602084526020840191612467565b0390a1565b90508201355f6126c3565b601f1981169361012f5f525f5160206130535f395f51905f52905f5b8681106127775750827fe9b617ecb5f63f6a9ccd8d4d5fa0d7b2ef9b17ce3f48e6b135808d6a40e6774295961061275e575b5050600181811b0161012f556126d8565b8301355f19600384901b60f8161c191690555f8061274d565b9091602060018192858801358155019301910161271b565b61012f5f52601f840160051c5f5160206130535f395f51905f520190602085106127e3575b601f0160051c5f5160206130535f395f51905f5201905b8181106127d8575061268a565b5f81556001016127cb565b5f5160206130535f395f51905f5291506127b4565b90612804838284612a1e565b5f81815260c960205260409020546001600160a01b0316612826575b50505050565b5f5260c960205260405f206001600160601b0360a01b81541690556040519160018060a01b0316825260018060a01b0316917f3ca48185ec3f6e47e24db18b13f1c65b1ce05da1659f9c1c4fe717dda5f6752460203393a45f808080612820565b90916001600160a01b0380831614610677576001600160a01b0383811693908290851461294b575b6128b99184612a1e565b5f81815260c960205260409020546001600160a01b0316156128db5750505050565b5f5260c960205260405f2060026001600160601b0360a01b8254161790557f0f579ad49235a8c1fd9041427e7067b1eb10926bbed380bf6fabc73e0e8076446040518061293f3395826020600291939293604081019460018060a01b031681520152565b0390a45f808080612820565b5f5160206130735f395f51905f5214801561296b575b61067757816128af565b5061297582612e15565b612961565b90604051906020820192692822a926a4a9a9a4a7a760b11b84526001600160601b0319602a8401526001600160601b03199060601b16603e8301526052820152605281526129c9607282611ed9565b51902090565b90604051906020820192692822a926a4a9a9a4a7a760b11b84526001600160601b03199060601b16602a8301526001600160601b0319603e8301526052820152605281526129c9607282611ed9565b9091604051916020830193692822a926a4a9a9a4a7a760b11b85526001600160601b03199060601b16602a8401526001600160601b03199060601b16603e8301526052820152605281526129c9607282611ed9565b908160209103126100e5575180151581036100e55790565b6040516302675fdd60e41b81526001600160a01b03928316600482015292909116602483015260448201929092526080606482015291602091839182908190612ad890608483019061200c565b03916001600160a01b03165afa5f9181612b04575b50612af757505f90565b612aff575f90565b600190565b612b2791925060203d602011612b2e575b612b1f8183611ed9565b810190612a73565b905f612aed565b503d612b15565b60ff81511660ff83511611612b975760ff81511660ff83511610612b91576020810160ff81511690602084019160ff835116116122035760ff8091511691511610612b9157604060ff8181930151169201511611612aff575f90565b50505f90565b5050600190565b91926001600160a01b0316803b15612d7d576040516301ffc9a760e01b81526302675fdd60e41b6004820152602081602481855afa908115612d72575f91612d53575b5015612d41576001600160a01b03838116939084148080612d2f575b612d2057838187929015612d0e575b612cdd575b612c1a92612a1e565b5f81815260c960205260409020546001600160a01b031680612c9057505f5260c960205260405f20816001600160601b0360a01b825416179055604051928352602083015260018060a01b0316917f0f579ad49235a8c1fd9041427e7067b1eb10926bbed380bf6fabc73e0e80764460403393a4565b92905081839592949503612ca5575050505050565b6040516305cc3c4f60e11b815260048101959095526001600160a01b0316602485015260448401526064830152608482015260a49150fd5b505f5160206130735f395f51905f52148015612cff575b610677578483612c11565b50612d0985612e15565b612cf4565b506001600160a01b0381811614612c0c565b6385f1ba9960e01b5f5260045ffd5b506001600160a01b0384811614612bfd565b636dd8243160e11b5f5260045260245ffd5b612d6c915060203d602011612b2e57612b1f8183611ed9565b5f612be1565b6040513d5f823e3d90fd5b63241acd7b60e11b5f5260045260245ffd5b61012e80546001600160a01b0319166001600160a01b0390921691821790556040519081527fd91237492a9e30cd2faf361fc103998a382ff0ec2b1b07dc1cbebb76ae2f1ea290602090a1565b7fbb39ebb37e60fb5d606ffdb749d2336e56b88e6c88c4bd6513b308f643186eed916126ef604051928392602084526020840191612467565b5f5160206130b35f395f51905f528114908115612e87575b8115612e70575b8115612e59575b8115612e45575090565b5f516020612fd35f395f51905f5291501490565b5f5160206130135f395f51905f5281149150612e3b565b5f516020612ff35f395f51905f5281149150612e34565b5f5160206130d35f395f51905f5281149150612e2d565b803b15612eda5760018060a01b03166001600160601b0360a01b5f5160206130335f395f51905f525416175f5160206130335f395f51905f5255565b60405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b6064820152608490fd5b91929015612f975750815115612f49575090565b3b15612f525790565b60405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606490fd5b825190915015612faa5750805190602001fd5b60405162461bcd60e51b815260206004820152908190612fce90602483019061200c565b0390fdfefaf505be9907aa6951c2ebe5b0312f4980e14f21912ed355372103cc8bd683bc4707e94b25cfce1a7c363508fbb838c35864388ad77284b248282b9746982b9b06d294bc8cbad2e393408b20dd019a772661f60b8d633e56761157cb1ec85f8c360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc232da9e50dad2971456a78fb5cd6ff6b75019984d6e918139ce990999420f979815fe80e4b37c8582a3b773d1d7071f983eacfd56b5965db654f3087c25ada33968c17ebf04aa1b7544168e69314cdab6b69ba813bb6080d49c0c40a65560f58bf04b4486c9663d805744005c3da000eda93de6e3308a4a7a812eb565327b78d1f53edd44352e5d15bad2b29233baa93bcd595e09457780bc7c5445bbbe751cca264697066735822122050945f41411a4d93a28a9bef887ccfbdbb13e26262c8a0cf64b6a8b44ad73e8f64736f6c634300081c0033
Deployed Bytecode
0x608080604052600436101561011a575b5036156100e957346100e5575f356001600160e01b03191661003036611efa565b9061003e6040519283611ed9565b368252365f60208401375f60203684010152805f5260fb60205263ffffffff60e01b60405f205460e01b169182156100cf576100af7f4792cb6e46e49876374bea490ba23274bacea6b84c216a64f47abab54027589b9160405191829133835260406020840152604083019061200c565b0390a260405160208101918252602081526100cb604082611ed9565b5190f35b50634aa318c360e01b5f5260045260245260445ffd5b5f80fd5b7f62c2c8e34665db7c56b2cabd7f5fb9702ccd352ffa8150147e450797e9f8e8f360408051338152346020820152a1005b5f3560e01c90816301ffc9a714611e25575080630729d05414611dfe57806309e56b1414611dd75780631080f99b14611d9b5780631626ba7e14611d4b57806322844d0414611c1757806324b4d73f14611bf05780632675fdd01461027b57806326875b1f14611bc95780632ae9c60014611b5c5780633659cfe6146118e95780633e2ab0d9146118c057806342d8e99e146115e85780634ec7ac23146115c15780634f1ef2861461132757806352d1902d146112655780637034731b14611194578063829331a11461116d578063bfe07da614610f5e578063c4a5014514610de8578063c71bf32414610a45578063c9dbc2a4146109fa578063ce1b815f146109d1578063d68bad2c146109b2578063d96054c414610993578063da74222814610904578063e306bee7146108dd578063e978afe5146106f8578063eafb8b06146102c3578063ee57e36f146102805763fdef91061461027b575f61000f565b611f9b565b346100e55760203660031901126100e5576004356001600160401b0381116100e5576102b36102c1913690600401611e91565b906102bc612517565b612ddc565b005b346100e55760803660031901126100e5576004356001600160401b0381116100e5576102f3903690600401611e91565b906102fc611f71565b916044356001600160a01b03811681036100e5576064356001600160401b0381116100e55761032f903690600401611e91565b9290915f5460ff811692836106ea57610574966101038361036561056f9760ff61056a9760081c161590816106df575b5061237d565b61ffff1916175f90815560016101308190557f2dd0f5ec3fbf050b78ec4c3d6ba16f3115022f2844d2f03cc58cdaa4402c8e88805460ff1990811683179091557ffefb654910b912e24b178f0bc09b5fe5971ae8a0dce588dc9321dc79fad35e8180548216831790557f1aa0fa3ce14642b336ea63139f6c7f2303168ba0a6471e1bd553e6490f77493980548216831790557f3244762813c531f1490b38900bb8750f879055d333cb43ca28d6f1c14282f61280548216831790557fb675f6d058fef1af3db0f797cfc9e0732d03c4eba47cb39683ecca426f80946280548216831790557f0694e0bc0f5c2fec9e5fab675807d55c7e41563f8b82e3f5f24d0d62385ebbe180548216831790557fb58f686c68cd9dfbabb72688d100a65fa0fad5014bad246510fefb74d36ce41380548216831790557ecbad7156f80fe4adddb2ec8acf4741a6e01e259e59bc61305a9e0cf72a3d9e8054909116909117905560fb6020527f5a08f87af82de422c581ce019b2e54a9c17372e9cba575ae0470ba2482d63686805463ffffffff1990811663150b7a02179091557fe1cfe341950d56d8854f782066100d5ae1d5930cdb4949b973e554a343efc6c38054821663f23a6e6117905563bc197c8160e01b9091527f08ba3617671847c1c169da222a5bc01cfdefcc3c4f1e5525214a474479c89123805490911663bc197c81179055612ddc565b612d8f565b612664565b60ff5f5460081c161561068657306001600160a01b0314610677576001600160a01b0381811691908214610677575f5160206130735f395f51905f526105ba9130612a1e565b5f81815260c960205260409020546001600160a01b03161561060d575b61ff00195f54165f557f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498602060405160038152a1005b5f90815260c9602090815260409182902080546001600160a01b031916600290811790915582513081529182015233915f5160206130735f395f51905f52917f0f579ad49235a8c1fd9041427e7067b1eb10926bbed380bf6fabc73e0e8076449190a480806105d7565b6324159e5b60e01b5f5260045ffd5b60405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b6064820152608490fd5b60039150108d61035f565b62dc149f60e41b5f5260045ffd5b346100e55760203660031901126100e5576004356001600160401b0381116100e557366023820112156100e5578060040135906001600160401b0382116100e55736602460a08402830101116100e557610750612586565b5f5b828110156102c15760a0810282019060a060231983360301126100e55760405160a081018181106001600160401b038211176108c95760405260248301359060038210156100e5578181526107a960448501611f87565b91602082019283526107bd60648601611f87565b91604081019283526107d160848701611f87565b916060820192835260a4608083019701358752155f1461082e5750516001600160a01b031661081f57905190519251600193610819926001600160a01b039182169116612887565b01610752565b63d4d3bef760e01b5f5260045ffd5b809392935160038110156108b5576001036108685750505190519251600193610863926001600160a01b0391821691166127f8565b610819565b929192519460038610156108b55760026001961461088a575b50505050610819565b92519151925190516108ac9360a087901b879003918216939082169116612b9e565b84808080610881565b634e487b7160e01b5f52602160045260245ffd5b634e487b7160e01b5f52604160045260245ffd5b346100e5575f3660031901126100e55760206040515f516020612ff35f395f51905f528152f35b346100e55760203660031901126100e55761091d611f5b565b61095d61092936611efa565b6109366040519182611ed9565b368152365f60208301375f602036830101525f5160206130135f395f51905f52333061220c565b1561096b576102c190612d8f565b631e09743f60e01b5f5230600452336024525f5160206130135f395f51905f5260445260645ffd5b346100e5576102c16109a436612088565b916109ad612586565b6127f8565b346100e5576102c16109c336612088565b916109cc612586565b612887565b346100e5575f3660031901126100e55761012e546040516001600160a01b039091168152602090f35b346100e55760803660031901126100e557610a13611f5b565b610a1b611f71565b90606435906001600160a01b03821682036100e5576102c192610a3c612586565b60443591612b9e565b346100e55760603660031901126100e5576024356001600160401b0381116100e557366023820112156100e55780600401356001600160401b0381116100e55760248201908060051b36602482860101116100e55760443560026101305414610dd957600261013055610aee610aba36611efa565b610ac76040519182611ed9565b368152365f60208301375f602036830101525f5160206130b35f395f51905f52333061220c565b15610db1575f926101008111610da257610b0a81969596612487565b94610b186040519687611ed9565b818652601f19610b2783612487565b015f5b818110610d8f5750505f5b828110610c7b575090604051938160a08601600435875260a060208801525260c08086019186010197925f90608219813603015b848310610bdf57610bd58a8a8d7fd4e57c2049f004fb297ef78591cd409503ceb6b2c722d7ffed032fc99e5f3b588c8c6040820152836060820152808303608082015280610bb8339487612030565b0390a2600161013055604051928392604084526040840190612030565b9060208301520390f35b90919293949960bf198882030185528a35828112156100e55783016001600160a01b03610c0e60248301611f87565b1682526044810135602083015260648101359060421936829003018212156100e5576024910101602081359101906001600160401b0381116100e55780360382136100e557610c6d602092839260608681604060019901520191612467565b9c0196950193019190610b69565b5a610c8782858b61249e565b356001600160a01b03811681036100e5576020610ca584878d61249e565b013590610cb384878d61249e565b604081013590601e19813603018212156100e55701908135916001600160401b0383116100e5576020019180360383136100e5575f938493826040519384928337810185815203925af1610d056124d4565b915a600160ff86161b91888316610d525750505015610d3f57906001915b610d2d828a612503565b52610d388189612503565b5001610b35565b5063a6a7dbbd60e01b5f5260045260245ffd5b90919215610d67575b50505090600191610d23565b6006999493991c11610d80579091189560018a80610d5b565b6307099c5360e21b5f5260045ffd5b60606020828a0181019190915201610b2a565b6308e3b1eb60e11b5f5260045ffd5b631e09743f60e01b5f5230600452336024525f5160206130b35f395f51905f5260445260645ffd5b6306fda65d60e31b5f5260045ffd5b346100e55760603660031901126100e557610e01611e7a565b6024359063ffffffff60e01b82168092036100e557604435906001600160e01b03198216908183036100e557610e6d610e3936611efa565b610e466040519182611ed9565b368152365f60208301375f602036830101525f516020612fd35f395f51905f52333061220c565b15610f36576001600160e01b031990811691908214610ef1577ffc72fd547553f7a663e0048e590afc9c47b56a4242e960f31cf4c62e23d308b993606093835f52603360205260405f20600160ff19825416179055815f5260fb60205260405f209060e01c63ffffffff1982541617905560405192835260208301526040820152a1005b60405162461bcd60e51b815260206004820152601c60248201527f4552433136353a20696e76616c696420696e74657266616365206964000000006044820152606490fd5b631e09743f60e01b5f5230600452336024525f516020612fd35f395f51905f5260445260645ffd5b60603660031901126100e557610f72611f5b565b602435906044356001600160401b0381116100e557610f95903690600401611e91565b91831561115e576001600160a01b0316928361100f57803403610ff957907f2bc500cf071be2d1c1458ed6ff484cd4db4345ada8943dee7ff29e7af3558f76915b610ff460405192839283526040602084015233956040840191612467565b0390a3005b6301abd56160e41b5f526004523460245260445ffd5b90346111475761109a6040515f80602083016323b872dd60e01b81523360248501523060448501528660648501526064845261104c608485611ed9565b6040519361105b604086611ed9565b602085527f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c656460208601525190828a5af16110936124d4565b9087612f35565b805190811591821561112d575b5050156110d5577f2bc500cf071be2d1c1458ed6ff484cd4db4345ada8943dee7ff29e7af3558f7691610fd6565b60405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152608490fd5b6111409250602080918301019101612a73565b85806110a7565b6301abd56160e41b5f525f6004523460245260445ffd5b631f2a200560e01b5f5260045ffd5b346100e5575f3660031901126100e55760206040515f5160206130135f395f51905f528152f35b346100e5575f3660031901126100e5576040515f61012f546111b58161242f565b808452906001811690811561124157506001146111f5575b6111f1836111dd81850382611ed9565b60405191829160208352602083019061200c565b0390f35b91905061012f5f525f5160206130535f395f51905f52915f905b808210611227575090915081016020016111dd6111cd565b91926001816020925483858801015201910190929161120f565b60ff191660208086019190915291151560051b840190910191506111dd90506111cd565b346100e5575f3660031901126100e5577f0000000000000000000000008e241da6591d07a9f2480117b5d94de4a63c4b3f6001600160a01b031630036112bc5760206040515f5160206130335f395f51905f528152f35b60405162461bcd60e51b815260206004820152603860248201527f555550535570677261646561626c653a206d757374206e6f742062652063616c60448201527f6c6564207468726f7567682064656c656761746563616c6c00000000000000006064820152608490fd5b60403660031901126100e55761133b611f5b565b6024356001600160401b0381116100e55761135a903690600401611f15565b6113b17f0000000000000000000000008e241da6591d07a9f2480117b5d94de4a63c4b3f6001600160a01b0316611393308214156122bb565b5f5160206130335f395f51905f52546001600160a01b03161461231c565b6113b96125f5565b7f4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd91435460ff16156113ed57506102c190612e9e565b6040516352d1902d60e01b81526001600160a01b03831690602081600481855afa5f918161158d575b506114775760405162461bcd60e51b815260206004820152602e60248201527f45524331393637557067726164653a206e657720696d706c656d656e7461746960448201526d6f6e206973206e6f74205555505360901b6064820152608490fd5b5f5160206130335f395f51905f52036115365761149383612e9e565b7fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b5f80a280511580159061152e575b6114c857005b6102c1915f80604051936114dd606086611ed9565b602785527f416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c6020860152660819985a5b195960ca1b6040860152602081519101845af46115286124d4565b91612f35565b5060016114c2565b60405162461bcd60e51b815260206004820152602960248201527f45524331393637557067726164653a20756e737570706f727465642070726f786044820152681a58589b195555525160ba1b6064820152608490fd5b9091506020813d6020116115b9575b816115a960209383611ed9565b810103126100e557519085611416565b3d915061159c565b346100e5575f3660031901126100e55760206040515f5160206130935f395f51905f528152f35b346100e55760803660031901126100e557366064116100e5576064356001600160401b0381116100e557611620903690600401611e91565b50506101035f5460ff8160081c1615806118b3575b61163e9061237d565b61ffff1916175f5560043560ff81168091036100e5576001036118725761168a611667366123ee565b6040519061167482611ebe565b60018252600360208301525f6040830152612b35565b61182b575b6116be61169b366123ee565b604051906116a882611ebe565b60018252600460208301525f6040830152612b35565b6116f85761ff00195f54165f557f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498602060405160038152a1005b6117237f0dcbfb19b09fb8ff4e9af583d4b8e9c8127cc1b26529b4d96dd3b7e7780883723030612a1e565b5f81815260c960205260409020546001600160a01b03166117bb575b50632a4f53ad60e11b5f5260336020527ffefb654910b912e24b178f0bc09b5fe5971ae8a0dce588dc9321dc79fad35e81805460ff191660011790556331c6fcc960e21b5f5260336020527f1aa0fa3ce14642b336ea63139f6c7f2303168ba0a6471e1bd553e6490f774939805460ff191660011790556105d7565b5f5260c960205260405f206001600160601b0360a01b815416905560405130815230907f0dcbfb19b09fb8ff4e9af583d4b8e9c8127cc1b26529b4d96dd3b7e7780883727f3ca48185ec3f6e47e24db18b13f1c65b1ce05da1659f9c1c4fe717dda5f6752460203393a48061173f565b6001610130819055621574e360e91b5f5260336020527f0694e0bc0f5c2fec9e5fab675807d55c7e41563f8b82e3f5f24d0d62385ebbe1805460ff1916909117905561168f565b6040516384833d6760e01b815260045f8183015b6003821061189357606484fd5b60208060019260ff6118a4876123e0565b16815201930191019091611886565b50600360ff821610611635565b346100e55760203660031901126100e5576118d9611f5b565b5063b2728e9960e01b5f5260045ffd5b346100e55760203660031901126100e557611902611f5b565b61193b7f0000000000000000000000008e241da6591d07a9f2480117b5d94de4a63c4b3f6001600160a01b0316611393308214156122bb565b6119436125f5565b6040519060206119538184611ed9565b5f8352808301601f1982013682377f4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd91435460ff16156119975750506102c19150612e9e565b6040516352d1902d60e01b81529192916001600160a01b038316908481600481855afa5f9181611b2d575b50611a235760405162461bcd60e51b815260048101869052602e60248201527f45524331393637557067726164653a206e657720696d706c656d656e7461746960448201526d6f6e206973206e6f74205555505360901b6064820152608490fd5b5f5160206130335f395f51905f5203611ad657611a3f83612e9e565b7fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b5f80a2835115801590611acf575b611a7457005b5f80916102c1957f416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c60405196611aab606089611ed9565b60278852870152660819985a5b195960ca1b60408701525190845af46115286124d4565b505f611a6e565b60405162461bcd60e51b815260048101859052602960248201527f45524331393637557067726164653a20756e737570706f727465642070726f786044820152681a58589b195555525160ba1b6064820152608490fd5b9091508581813d8311611b55575b611b458183611ed9565b810103126100e5575190876119c2565b503d611b3b565b346100e5575f3660031901126100e5576060604051611b7b8282611ed9565b369037604051611b8a81611ebe565b60018152600460208201525f604082015260405190815f905b60038210611bb057606084f35b60208060019260ff865116815201930191019091611ba3565b346100e5575f3660031901126100e55760206040515f516020612fd35f395f51905f528152f35b346100e5575f3660031901126100e55760206040515f5160206130d35f395f51905f528152f35b346100e55760403660031901126100e557611c30611f5b565b602435906001600160401b0382116100e557366023830112156100e5578160040135916001600160401b0383116100e55736602460608502830101116100e557611c78612586565b5f5b838110156102c157606081028201606060231982360301126100e557604051611ca281611ebe565b60248201359060038210156100e557818152611cc060448401611f87565b91602082019283526064604083019401358452155f14611cfc575051905160019291611cf691906001600160a01b031686612887565b01611c7a565b805160038110156108b557600103611d2f575051905160019291611d2a91906001600160a01b0316866127f8565b611cf6565b9150505160038110156108b55760021461081f57600190611cf6565b346100e55760403660031901126100e5576024356001600160401b0381116100e557611d88611d806020923690600401611f15565b6004356120c2565b6040516001600160e01b03199091168152f35b346100e55760203660031901126100e5576004356001600160401b0381116100e557611dce6102c1913690600401611e91565b9061056f612517565b346100e5575f3660031901126100e55760206040515f5160206130735f395f51905f528152f35b346100e5575f3660031901126100e55760206040515f5160206130b35f395f51905f528152f35b346100e55760203660031901126100e5576020906001600160e01b0319611e4a611e7a565b166301ffc9a760e01b8114908115611e64575b5015158152f35b90505f526033825260ff60405f20541683611e5d565b600435906001600160e01b0319821682036100e557565b9181601f840112156100e5578235916001600160401b0383116100e557602083818601950101116100e557565b606081019081106001600160401b038211176108c957604052565b90601f801991011681019081106001600160401b038211176108c957604052565b6001600160401b0381116108c957601f01601f191660200190565b81601f820112156100e557803590611f2c82611efa565b92611f3a6040519485611ed9565b828452602083830101116100e557815f926020809301838601378301015290565b600435906001600160a01b03821682036100e557565b602435906001600160a01b03821682036100e557565b35906001600160a01b03821682036100e557565b346100e55760803660031901126100e5576004356001600160a01b03811681036100e557602435906001600160a01b03821682036100e557606435906044356001600160401b0383116100e557602093611ffc612002943690600401611f15565b9261220c565b6040519015158152f35b805180835260209291819084018484015e5f828201840152601f01601f1916010190565b9080602083519182815201916020808360051b8301019401925f915b83831061205b57505050505090565b9091929394602080612079600193601f19868203018752895161200c565b9701930193019193929061204c565b60609060031901126100e5576004356001600160a01b03811681036100e557906024356001600160a01b03811681036100e5579060443590565b906120f66120fd926120e86040519384926020840152604080840152606083019061200c565b03601f198101835282611ed9565b3330612118565b61210d576001600160e01b031990565b630b135d3f60e11b90565b91906121325f5160206130935f395f51905f528285612a1e565b5f90815260c960205260409020546001600160a01b03166002811461220357806121ea575061216e5f5160206130935f395f51905f528461297a565b5f90815260c960205260409020546001600160a01b03166002811461220357806121ea57506121aa5f5160206130935f395f51905f52826129cf565b5f90815260c960205260409020546001600160a01b031690816121cf57505050505f90565b6121e7935f5160206130935f395f51905f5292612a8b565b90565b906121e7935f5160206130935f395f51905f5292612a8b565b50505050600190565b92919061221a828286612a1e565b5f90815260c960205260409020546001600160a01b0316600281146122b157806122a75750612249828561297a565b5f90815260c960205260409020546001600160a01b0316600281146122b157806122a7575061227882826129cf565b5f90815260c960205260409020546001600160a01b0316938461229e5750505050505f90565b6121e794612a8b565b936121e794612a8b565b5050505050600190565b156122c257565b60405162461bcd60e51b815260206004820152602c60248201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060448201526b19195b1959d85d1958d85b1b60a21b6064820152608490fd5b1561232357565b60405162461bcd60e51b815260206004820152602c60248201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060448201526b6163746976652070726f787960a01b6064820152608490fd5b1561238457565b60405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b6064820152608490fd5b359060ff821682036100e557565b90604051916123fe606084611ed9565b82906064116100e5576004905b60648210612417575050565b60208091612424846123e0565b81520191019061240b565b90600182811c9216801561245d575b602083101461244957565b634e487b7160e01b5f52602260045260245ffd5b91607f169161243e565b908060209392818452848401375f828201840152601f01601f1916010190565b6001600160401b0381116108c95760051b60200190565b91908110156124c05760051b81013590605e19813603018212156100e5570190565b634e487b7160e01b5f52603260045260245ffd5b3d156124fe573d906124e582611efa565b916124f36040519384611ed9565b82523d5f602084013e565b606090565b80518210156124c05760209160051b010190565b61255761252336611efa565b6125306040519182611ed9565b368152365f60208301375f602036830101525f516020612ff35f395f51905f52333061220c565b1561255e57565b631e09743f60e01b5f5230600452336024525f516020612ff35f395f51905f5260445260645ffd5b6125c661259236611efa565b61259f6040519182611ed9565b368152365f60208301375f602036830101525f5160206130735f395f51905f52333061220c565b156125cd57565b631e09743f60e01b5f5230600452336024525f5160206130735f395f51905f5260445260645ffd5b61263561260136611efa565b61260e6040519182611ed9565b368152365f60208301375f602036830101525f5160206130d35f395f51905f52333061220c565b1561263c57565b631e09743f60e01b5f5230600452336024525f5160206130d35f395f51905f5260445260645ffd5b9190916001600160401b0383116108c95761268161012f5461242f565b601f811161278f575b505f92601f81116001146126ff57807fe9b617ecb5f63f6a9ccd8d4d5fa0d7b2ef9b17ce3f48e6b135808d6a40e6774293945f916126f4575b508160011b905f198360031b1c19161761012f555b6126ef604051928392602084526020840191612467565b0390a1565b90508201355f6126c3565b601f1981169361012f5f525f5160206130535f395f51905f52905f5b8681106127775750827fe9b617ecb5f63f6a9ccd8d4d5fa0d7b2ef9b17ce3f48e6b135808d6a40e6774295961061275e575b5050600181811b0161012f556126d8565b8301355f19600384901b60f8161c191690555f8061274d565b9091602060018192858801358155019301910161271b565b61012f5f52601f840160051c5f5160206130535f395f51905f520190602085106127e3575b601f0160051c5f5160206130535f395f51905f5201905b8181106127d8575061268a565b5f81556001016127cb565b5f5160206130535f395f51905f5291506127b4565b90612804838284612a1e565b5f81815260c960205260409020546001600160a01b0316612826575b50505050565b5f5260c960205260405f206001600160601b0360a01b81541690556040519160018060a01b0316825260018060a01b0316917f3ca48185ec3f6e47e24db18b13f1c65b1ce05da1659f9c1c4fe717dda5f6752460203393a45f808080612820565b90916001600160a01b0380831614610677576001600160a01b0383811693908290851461294b575b6128b99184612a1e565b5f81815260c960205260409020546001600160a01b0316156128db5750505050565b5f5260c960205260405f2060026001600160601b0360a01b8254161790557f0f579ad49235a8c1fd9041427e7067b1eb10926bbed380bf6fabc73e0e8076446040518061293f3395826020600291939293604081019460018060a01b031681520152565b0390a45f808080612820565b5f5160206130735f395f51905f5214801561296b575b61067757816128af565b5061297582612e15565b612961565b90604051906020820192692822a926a4a9a9a4a7a760b11b84526001600160601b0319602a8401526001600160601b03199060601b16603e8301526052820152605281526129c9607282611ed9565b51902090565b90604051906020820192692822a926a4a9a9a4a7a760b11b84526001600160601b03199060601b16602a8301526001600160601b0319603e8301526052820152605281526129c9607282611ed9565b9091604051916020830193692822a926a4a9a9a4a7a760b11b85526001600160601b03199060601b16602a8401526001600160601b03199060601b16603e8301526052820152605281526129c9607282611ed9565b908160209103126100e5575180151581036100e55790565b6040516302675fdd60e41b81526001600160a01b03928316600482015292909116602483015260448201929092526080606482015291602091839182908190612ad890608483019061200c565b03916001600160a01b03165afa5f9181612b04575b50612af757505f90565b612aff575f90565b600190565b612b2791925060203d602011612b2e575b612b1f8183611ed9565b810190612a73565b905f612aed565b503d612b15565b60ff81511660ff83511611612b975760ff81511660ff83511610612b91576020810160ff81511690602084019160ff835116116122035760ff8091511691511610612b9157604060ff8181930151169201511611612aff575f90565b50505f90565b5050600190565b91926001600160a01b0316803b15612d7d576040516301ffc9a760e01b81526302675fdd60e41b6004820152602081602481855afa908115612d72575f91612d53575b5015612d41576001600160a01b03838116939084148080612d2f575b612d2057838187929015612d0e575b612cdd575b612c1a92612a1e565b5f81815260c960205260409020546001600160a01b031680612c9057505f5260c960205260405f20816001600160601b0360a01b825416179055604051928352602083015260018060a01b0316917f0f579ad49235a8c1fd9041427e7067b1eb10926bbed380bf6fabc73e0e80764460403393a4565b92905081839592949503612ca5575050505050565b6040516305cc3c4f60e11b815260048101959095526001600160a01b0316602485015260448401526064830152608482015260a49150fd5b505f5160206130735f395f51905f52148015612cff575b610677578483612c11565b50612d0985612e15565b612cf4565b506001600160a01b0381811614612c0c565b6385f1ba9960e01b5f5260045ffd5b506001600160a01b0384811614612bfd565b636dd8243160e11b5f5260045260245ffd5b612d6c915060203d602011612b2e57612b1f8183611ed9565b5f612be1565b6040513d5f823e3d90fd5b63241acd7b60e11b5f5260045260245ffd5b61012e80546001600160a01b0319166001600160a01b0390921691821790556040519081527fd91237492a9e30cd2faf361fc103998a382ff0ec2b1b07dc1cbebb76ae2f1ea290602090a1565b7fbb39ebb37e60fb5d606ffdb749d2336e56b88e6c88c4bd6513b308f643186eed916126ef604051928392602084526020840191612467565b5f5160206130b35f395f51905f528114908115612e87575b8115612e70575b8115612e59575b8115612e45575090565b5f516020612fd35f395f51905f5291501490565b5f5160206130135f395f51905f5281149150612e3b565b5f516020612ff35f395f51905f5281149150612e34565b5f5160206130d35f395f51905f5281149150612e2d565b803b15612eda5760018060a01b03166001600160601b0360a01b5f5160206130335f395f51905f525416175f5160206130335f395f51905f5255565b60405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b6064820152608490fd5b91929015612f975750815115612f49575090565b3b15612f525790565b60405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606490fd5b825190915015612faa5750805190602001fd5b60405162461bcd60e51b815260206004820152908190612fce90602483019061200c565b0390fdfefaf505be9907aa6951c2ebe5b0312f4980e14f21912ed355372103cc8bd683bc4707e94b25cfce1a7c363508fbb838c35864388ad77284b248282b9746982b9b06d294bc8cbad2e393408b20dd019a772661f60b8d633e56761157cb1ec85f8c360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc232da9e50dad2971456a78fb5cd6ff6b75019984d6e918139ce990999420f979815fe80e4b37c8582a3b773d1d7071f983eacfd56b5965db654f3087c25ada33968c17ebf04aa1b7544168e69314cdab6b69ba813bb6080d49c0c40a65560f58bf04b4486c9663d805744005c3da000eda93de6e3308a4a7a812eb565327b78d1f53edd44352e5d15bad2b29233baa93bcd595e09457780bc7c5445bbbe751cca264697066735822122050945f41411a4d93a28a9bef887ccfbdbb13e26262c8a0cf64b6a8b44ad73e8f64736f6c634300081c0033
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 34 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|
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.