Source Code
Overview
ETH Balance
0 ETH
ETH Value
$0.00| Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
|---|---|---|---|---|---|---|---|---|---|
Advanced mode: Intended for advanced users or developers and will display all Internal Transactions including zero value transfers.
Latest 25 internal transactions (View All)
Advanced mode:
| Parent Transaction Hash | Block | From | To | ||||
|---|---|---|---|---|---|---|---|
| 17862036 | 10 days ago | 0 ETH | |||||
| 17862036 | 10 days ago | 0 ETH | |||||
| 17862036 | 10 days ago | Contract Creation | 0 ETH | ||||
| 17862036 | 10 days ago | Contract Creation | 0 ETH | ||||
| 17862036 | 10 days ago | 0 ETH | |||||
| 17492968 | 14 days ago | 0 ETH | |||||
| 17492968 | 14 days ago | 0 ETH | |||||
| 17492968 | 14 days ago | Contract Creation | 0 ETH | ||||
| 17492968 | 14 days ago | Contract Creation | 0 ETH | ||||
| 17492968 | 14 days ago | 0 ETH | |||||
| 17492835 | 14 days ago | 0 ETH | |||||
| 17492835 | 14 days ago | 0 ETH | |||||
| 17492835 | 14 days ago | Contract Creation | 0 ETH | ||||
| 17492835 | 14 days ago | Contract Creation | 0 ETH | ||||
| 17492835 | 14 days ago | 0 ETH | |||||
| 17492332 | 14 days ago | 0 ETH | |||||
| 17492332 | 14 days ago | 0 ETH | |||||
| 17492332 | 14 days ago | Contract Creation | 0 ETH | ||||
| 17492332 | 14 days ago | Contract Creation | 0 ETH | ||||
| 17492332 | 14 days ago | 0 ETH | |||||
| 17417926 | 15 days ago | 0 ETH | |||||
| 17417926 | 15 days ago | 0 ETH | |||||
| 17417926 | 15 days ago | Contract Creation | 0 ETH | ||||
| 17417926 | 15 days ago | Contract Creation | 0 ETH | ||||
| 17417926 | 15 days ago | 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:
MultisigSetup
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;
/* solhint-disable max-line-length */
import {PermissionLib} from "@aragon/osx-commons-contracts/src/permission/PermissionLib.sol";
import {IPluginSetup} from "@aragon/osx-commons-contracts/src/plugin/setup/IPluginSetup.sol";
import {PluginUpgradeableSetup} from "@aragon/osx-commons-contracts/src/plugin/setup/PluginUpgradeableSetup.sol";
import {IPlugin} from "@aragon/osx-commons-contracts/src/plugin/IPlugin.sol";
import {ProxyLib} from "@aragon/osx-commons-contracts/src/utils/deployment/ProxyLib.sol";
import {IDAO} from "@aragon/osx-commons-contracts/src/dao/IDAO.sol";
import {ListedCheckCondition} from "./ListedCheckCondition.sol";
import {Multisig} from "./Multisig.sol";
/* solhint-enable max-line-length */
/// @title MultisigSetup
/// @author Aragon X - 2022-2024
/// @notice The setup contract of the `Multisig` plugin.
/// @dev v1.3 (Release 1, Build 3)
/// @custom:security-contact [email protected]
contract MultisigSetup is PluginUpgradeableSetup {
using ProxyLib for address;
/// @notice The ID of the permission required to call the `execute` function on a DAO.
bytes32 private constant EXECUTE_PERMISSION_ID = keccak256("EXECUTE_PERMISSION");
/// @notice The ID of the permission required to call the `upgradeToAndCall` function.
bytes32 private constant UPGRADE_PLUGIN_PERMISSION_ID = keccak256("UPGRADE_PLUGIN_PERMISSION");
/// @notice The ID of the permission required to call the `setTargetConfig` function.
bytes32 private constant SET_TARGET_CONFIG_PERMISSION_ID =
keccak256("SET_TARGET_CONFIG_PERMISSION");
/// @notice The ID of the permission required to call the `setMetadata` function on a DAO.
bytes32 private constant SET_METADATA_PERMISSION_ID = keccak256("SET_METADATA_PERMISSION");
/// @notice The ID of the permission required to call the `updateMultisigSettings` function.
bytes32 private constant UPDATE_MULTISIG_SETTINGS_PERMISSION_ID =
keccak256("UPDATE_MULTISIG_SETTINGS_PERMISSION");
/// @notice A special address encoding permissions that are valid for any address `who` or `where`.
address private constant ANY_ADDR = address(type(uint160).max);
/// @notice The contract constructor, that deploys the `Multisig` plugin logic contract.
constructor() PluginUpgradeableSetup(address(new Multisig())) {}
/// @inheritdoc IPluginSetup
function prepareInstallation(
address _dao,
bytes calldata _data
) external returns (address plugin, PreparedSetupData memory preparedSetupData) {
// Decode `_data` to extract the params needed for deploying and initializing `Multisig` plugin.
(
address[] memory members,
Multisig.MultisigSettings memory multisigSettings,
IPlugin.TargetConfig memory targetConfig,
bytes memory pluginMetadata
) = abi.decode(_data, (address[], Multisig.MultisigSettings, IPlugin.TargetConfig, bytes));
// Deploy and initialize the plugin UUPS proxy.
plugin = IMPLEMENTATION.deployUUPSProxy(
abi.encodeCall(
Multisig.initialize,
(IDAO(_dao), members, multisigSettings, targetConfig, pluginMetadata)
)
);
// Deploy a ListedCheckCondition contract.
address listedCheckCondition = address(new ListedCheckCondition(plugin));
// Prepare permissions
PermissionLib.MultiTargetPermission[]
memory permissions = new PermissionLib.MultiTargetPermission[](6);
// Set permissions to be granted.
// Grant the list of permissions of the plugin to the DAO.
permissions[0] = PermissionLib.MultiTargetPermission({
operation: PermissionLib.Operation.Grant,
where: plugin,
who: _dao,
condition: PermissionLib.NO_CONDITION,
permissionId: UPDATE_MULTISIG_SETTINGS_PERMISSION_ID
});
permissions[1] = PermissionLib.MultiTargetPermission({
operation: PermissionLib.Operation.Grant,
where: _dao,
who: plugin,
condition: PermissionLib.NO_CONDITION,
permissionId: EXECUTE_PERMISSION_ID
});
permissions[2] = PermissionLib.MultiTargetPermission({
operation: PermissionLib.Operation.GrantWithCondition,
where: plugin,
who: ANY_ADDR,
condition: listedCheckCondition,
permissionId: Multisig(IMPLEMENTATION).CREATE_PROPOSAL_PERMISSION_ID()
});
permissions[3] = PermissionLib.MultiTargetPermission({
operation: PermissionLib.Operation.Grant,
where: plugin,
who: _dao,
condition: PermissionLib.NO_CONDITION,
permissionId: SET_TARGET_CONFIG_PERMISSION_ID
});
permissions[4] = PermissionLib.MultiTargetPermission({
operation: PermissionLib.Operation.Grant,
where: plugin,
who: _dao,
condition: PermissionLib.NO_CONDITION,
permissionId: SET_METADATA_PERMISSION_ID
});
permissions[5] = PermissionLib.MultiTargetPermission({
operation: PermissionLib.Operation.Grant,
where: plugin,
who: ANY_ADDR,
condition: PermissionLib.NO_CONDITION,
permissionId: Multisig(IMPLEMENTATION).EXECUTE_PROPOSAL_PERMISSION_ID()
});
preparedSetupData.permissions = permissions;
preparedSetupData.helpers = new address[](1);
preparedSetupData.helpers[0] = listedCheckCondition;
}
/// @inheritdoc IPluginSetup
/// @dev Revoke the upgrade plugin permission to the DAO for all builds prior the current one (3).
function prepareUpdate(
address _dao,
uint16 _fromBuild,
SetupPayload calldata _payload
)
external
override
returns (bytes memory initData, PreparedSetupData memory preparedSetupData)
{
if (_fromBuild < 3) {
address listedCheckCondition = address(new ListedCheckCondition(_payload.plugin));
PermissionLib.MultiTargetPermission[]
memory permissions = new PermissionLib.MultiTargetPermission[](5);
permissions[0] = PermissionLib.MultiTargetPermission({
operation: PermissionLib.Operation.Revoke,
where: _payload.plugin,
who: _dao,
condition: PermissionLib.NO_CONDITION,
permissionId: UPGRADE_PLUGIN_PERMISSION_ID
});
permissions[1] = PermissionLib.MultiTargetPermission({
operation: PermissionLib.Operation.GrantWithCondition,
where: _payload.plugin,
who: ANY_ADDR,
condition: listedCheckCondition,
permissionId: Multisig(IMPLEMENTATION).CREATE_PROPOSAL_PERMISSION_ID()
});
permissions[2] = PermissionLib.MultiTargetPermission({
operation: PermissionLib.Operation.Grant,
where: _payload.plugin,
who: _dao,
condition: PermissionLib.NO_CONDITION,
permissionId: SET_TARGET_CONFIG_PERMISSION_ID
});
permissions[3] = PermissionLib.MultiTargetPermission({
operation: PermissionLib.Operation.Grant,
where: _payload.plugin,
who: _dao,
condition: PermissionLib.NO_CONDITION,
permissionId: SET_METADATA_PERMISSION_ID
});
permissions[4] = PermissionLib.MultiTargetPermission({
operation: PermissionLib.Operation.Grant,
where: _payload.plugin,
who: ANY_ADDR,
condition: PermissionLib.NO_CONDITION,
permissionId: Multisig(IMPLEMENTATION).EXECUTE_PROPOSAL_PERMISSION_ID()
});
preparedSetupData.permissions = permissions;
preparedSetupData.helpers = new address[](1);
preparedSetupData.helpers[0] = listedCheckCondition;
initData = abi.encodeCall(Multisig.initializeFrom, (_fromBuild, _payload.data));
}
}
/// @inheritdoc IPluginSetup
function prepareUninstallation(
address _dao,
SetupPayload calldata _payload
) external view returns (PermissionLib.MultiTargetPermission[] memory permissions) {
// Prepare permissions
permissions = new PermissionLib.MultiTargetPermission[](6);
// Set permissions to be Revoked.
permissions[0] = PermissionLib.MultiTargetPermission({
operation: PermissionLib.Operation.Revoke,
where: _payload.plugin,
who: _dao,
condition: PermissionLib.NO_CONDITION,
permissionId: UPDATE_MULTISIG_SETTINGS_PERMISSION_ID
});
permissions[1] = PermissionLib.MultiTargetPermission({
operation: PermissionLib.Operation.Revoke,
where: _dao,
who: _payload.plugin,
condition: PermissionLib.NO_CONDITION,
permissionId: EXECUTE_PERMISSION_ID
});
permissions[2] = PermissionLib.MultiTargetPermission({
operation: PermissionLib.Operation.Revoke,
where: _payload.plugin,
who: _dao,
condition: PermissionLib.NO_CONDITION,
permissionId: SET_TARGET_CONFIG_PERMISSION_ID
});
permissions[3] = PermissionLib.MultiTargetPermission({
operation: PermissionLib.Operation.Revoke,
where: _payload.plugin,
who: _dao,
condition: PermissionLib.NO_CONDITION,
permissionId: SET_METADATA_PERMISSION_ID
});
permissions[4] = PermissionLib.MultiTargetPermission({
operation: PermissionLib.Operation.Revoke,
where: _payload.plugin,
who: ANY_ADDR,
condition: PermissionLib.NO_CONDITION,
permissionId: Multisig(IMPLEMENTATION).CREATE_PROPOSAL_PERMISSION_ID()
});
permissions[5] = PermissionLib.MultiTargetPermission({
operation: PermissionLib.Operation.Revoke,
where: _payload.plugin,
who: ANY_ADDR,
condition: PermissionLib.NO_CONDITION,
permissionId: Multisig(IMPLEMENTATION).EXECUTE_PROPOSAL_PERMISSION_ID()
});
}
}// 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: AGPL-3.0-or-later
pragma solidity ^0.8.8;
import {PermissionLib} from "../../permission/PermissionLib.sol";
// solhint-disable-next-line no-unused-import
import {IDAO} from "../../dao/IDAO.sol";
/// @title IPluginSetup
/// @author Aragon X - 2022-2023
/// @notice The interface required for a plugin setup contract to be consumed by the `PluginSetupProcessor` for plugin installations, updates, and uninstallations.
/// @custom:security-contact [email protected]
interface IPluginSetup {
/// @notice The data associated with a prepared setup.
/// @param helpers The address array of helpers (contracts or EOAs) associated with this plugin version after the installation or update.
/// @param permissions The array of multi-targeted permission operations to be applied by the `PluginSetupProcessor` to the installing or updating DAO.
struct PreparedSetupData {
address[] helpers;
PermissionLib.MultiTargetPermission[] permissions;
}
/// @notice The payload for plugin updates and uninstallations containing the existing contracts as well as optional data to be consumed by the plugin setup.
/// @param plugin The address of the `Plugin`.
/// @param currentHelpers The address array of all current helpers (contracts or EOAs) associated with the plugin to update from.
/// @param data The bytes-encoded data containing the input parameters for the preparation of update/uninstall as specified in the corresponding ABI on the version's metadata.
struct SetupPayload {
address plugin;
address[] currentHelpers;
bytes data;
}
/// @notice Prepares the installation of a plugin.
/// @param _dao The address of the installing DAO.
/// @param _data The bytes-encoded data containing the input parameters for the installation as specified in the plugin's build metadata JSON file.
/// @return plugin The address of the `Plugin` contract being prepared for installation.
/// @return preparedSetupData The deployed plugin's relevant data which consists of helpers and permissions.
function prepareInstallation(
address _dao,
bytes calldata _data
) external returns (address plugin, PreparedSetupData memory preparedSetupData);
/// @notice Prepares the update of a plugin.
/// @param _dao The address of the updating DAO.
/// @param _fromBuild The build number of the plugin to update from.
/// @param _payload The relevant data necessary for the `prepareUpdate`. See above.
/// @return initData The initialization data to be passed to upgradeable contracts when the update is applied in the `PluginSetupProcessor`.
/// @return preparedSetupData The deployed plugin's relevant data which consists of helpers and permissions.
function prepareUpdate(
address _dao,
uint16 _fromBuild,
SetupPayload calldata _payload
) external returns (bytes memory initData, PreparedSetupData memory preparedSetupData);
/// @notice Prepares the uninstallation of a plugin.
/// @param _dao The address of the uninstalling DAO.
/// @param _payload The relevant data necessary for the `prepareUninstallation`. See above.
/// @return permissions The array of multi-targeted permission operations to be applied by the `PluginSetupProcessor` to the uninstalling DAO.
function prepareUninstallation(
address _dao,
SetupPayload calldata _payload
) external returns (PermissionLib.MultiTargetPermission[] memory permissions);
/// @notice Returns the plugin implementation address.
/// @return The address of the plugin implementation contract.
/// @dev The implementation can be instantiated via the `new` keyword, cloned via the minimal proxy pattern (see [ERC-1167](https://eips.ethereum.org/EIPS/eip-1167)), or proxied via the UUPS proxy pattern (see [ERC-1822](https://eips.ethereum.org/EIPS/eip-1822)).
function implementation() external view returns (address);
}// 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 {IPluginSetup} from "./IPluginSetup.sol";
/// @title PluginUpgradeableSetup
/// @author Aragon X - 2022-2024
/// @notice An abstract contract to inherit from to implement the plugin setup for upgradeable plugins, i.e, `PluginUUPSUpgradeable` being deployed via the UUPS pattern (see [ERC-1822](https://eips.ethereum.org/EIPS/eip-1822) and [ERC-1967](https://eips.ethereum.org/EIPS/eip-1967)).
/// @custom:security-contact [email protected]
abstract contract PluginUpgradeableSetup is ERC165, IPluginSetup, ProtocolVersion {
/// @notice The address of the plugin implementation contract for initial block explorer verification
/// and to create [ERC-1967](https://eips.ethereum.org/EIPS/eip-1967) UUPS proxies from.
address internal immutable IMPLEMENTATION;
/// @notice Thrown when an update path is not available, for example, if this is the initial build.
/// @param fromBuild The build number to update from.
/// @param thisBuild The build number of this setup to update to.
error InvalidUpdatePath(uint16 fromBuild, uint16 thisBuild);
/// @notice The contract constructor, that setting the plugin implementation contract.
/// @param _implementation The address of the plugin implementation contract.
constructor(address _implementation) {
IMPLEMENTATION = _implementation;
}
/// @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(IPluginSetup).interfaceId ||
_interfaceId == type(IProtocolVersion).interfaceId ||
super.supportsInterface(_interfaceId);
}
/// @inheritdoc IPluginSetup
function implementation() public view returns (address) {
return IMPLEMENTATION;
}
}// SPDX-License-Identifier: AGPL-3.0-or-later pragma solidity ^0.8.8; /// @title IPlugin /// @author Aragon X - 2022-2024 /// @notice An interface defining the traits of a plugin. /// @custom:security-contact [email protected] interface IPlugin { /// @notice Types of plugin implementations available within OSx. enum PluginType { UUPS, Cloneable, Constructable } /// @notice Specifies the type of operation to perform. enum Operation { Call, DelegateCall } /// @notice Configuration for the target contract that the plugin will interact with, including the address and operation type. /// @dev By default, the plugin typically targets the associated DAO and performs a `Call` operation. However, this /// configuration allows the plugin to specify a custom executor and select either `Call` or `DelegateCall` based on /// the desired execution context. /// @param target The address of the target contract, typically the associated DAO but configurable to a custom executor. /// @param operation The type of operation (`Call` or `DelegateCall`) to execute on the target, as defined by `Operation`. struct TargetConfig { address target; Operation operation; } /// @notice Returns the plugin's type function pluginType() external view returns (PluginType); }
// SPDX-License-Identifier: AGPL-3.0-or-later
pragma solidity ^0.8.8;
import {ERC1967Proxy} from "@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol";
import {Clones} from "@openzeppelin/contracts/proxy/Clones.sol";
import {Address} from "@openzeppelin/contracts/utils/Address.sol";
/// @title ProxyLib
/// @author Aragon X - 2024
/// @notice A library containing methods for the deployment of proxies via the UUPS pattern (see [ERC-1822](https://eips.ethereum.org/EIPS/eip-1822)) and minimal proxy pattern (see [ERC-1167](https://eips.ethereum.org/EIPS/eip-1167)).
/// @custom:security-contact [email protected]
library ProxyLib {
using Address for address;
using Clones for address;
/// @notice Creates an [ERC-1967](https://eips.ethereum.org/EIPS/eip-1967) UUPS proxy contract pointing to a logic contract and allows to immediately initialize it.
/// @param _logic The logic contract the proxy is pointing to.
/// @param _initCalldata The initialization data for this contract.
/// @return uupsProxy The address of the UUPS proxy contract created.
/// @dev If `_initCalldata` is non-empty, it is used in a delegate call to the `_logic` contract. This will typically be an encoded function call initializing the storage of the proxy (see [OpenZeppelin ERC1967Proxy-constructor](https://docs.openzeppelin.com/contracts/4.x/api/proxy#ERC1967Proxy-constructor-address-bytes-)).
function deployUUPSProxy(
address _logic,
bytes memory _initCalldata
) internal returns (address uupsProxy) {
uupsProxy = address(new ERC1967Proxy({_logic: _logic, _data: _initCalldata}));
}
/// @notice Creates an [ERC-1167](https://eips.ethereum.org/EIPS/eip-1167) minimal proxy contract, also known as clones, pointing to a logic contract and allows to immediately initialize it.
/// @param _logic The logic contract the proxy is pointing to.
/// @param _initCalldata The initialization data for this contract.
/// @return minimalProxy The address of the minimal proxy contract created.
/// @dev If `_initCalldata` is non-empty, it is used in a call to the clone contract. This will typically be an encoded function call initializing the storage of the contract.
function deployMinimalProxy(
address _logic,
bytes memory _initCalldata
) internal returns (address minimalProxy) {
minimalProxy = _logic.clone();
if (_initCalldata.length > 0) {
minimalProxy.functionCall({data: _initCalldata});
}
}
}// 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 {Multisig} from "./Multisig.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";
/// @title ListedCheckCondition
/// @author Aragon X - 2024
/// @notice A condition contract that checks if an address is listed as a member in the associated Multisig contract.
/// @custom:security-contact [email protected]
contract ListedCheckCondition is PermissionCondition {
/// @notice The immutable address of the Multisig plugin used for fetching plugin settings.
Multisig private immutable MULTISIG;
/// @notice Initializes the condition with the address of the Multisig plugin.
/// @param _multisig The address of the Multisig plugin that stores listing and other configuration settings.
constructor(address _multisig) {
MULTISIG = Multisig(_multisig);
}
/// @inheritdoc IPermissionCondition
function isGranted(
address _where,
address _who,
bytes32 _permissionId,
bytes calldata _data
) public view override returns (bool) {
(_where, _data, _permissionId);
(bool onlyListed, ) = MULTISIG.multisigSettings();
if (onlyListed && !MULTISIG.isListed(_who)) {
return false;
}
return true;
}
}// SPDX-License-Identifier: AGPL-3.0-or-later
pragma solidity ^0.8.8;
/* solhint-disable max-line-length */
import {SafeCastUpgradeable} from "@openzeppelin/contracts-upgradeable/utils/math/SafeCastUpgradeable.sol";
import {IMembership} from "@aragon/osx-commons-contracts/src/plugin/extensions/membership/IMembership.sol";
import {Addresslist} from "@aragon/osx-commons-contracts/src/plugin/extensions/governance/Addresslist.sol";
import {ProposalUpgradeable} from "@aragon/osx-commons-contracts/src/plugin/extensions/proposal/ProposalUpgradeable.sol";
import {PluginUUPSUpgradeable} from "@aragon/osx-commons-contracts/src/plugin/PluginUUPSUpgradeable.sol";
import {IProposal} from "@aragon/osx-commons-contracts/src/plugin/extensions/proposal/IProposal.sol";
import {IDAO} from "@aragon/osx-commons-contracts/src/dao/IDAO.sol";
import {Action} from "@aragon/osx-commons-contracts/src/executors/IExecutor.sol";
import {MetadataExtensionUpgradeable} from "@aragon/osx-commons-contracts/src/utils/metadata/MetadataExtensionUpgradeable.sol";
import {IMultisig} from "./IMultisig.sol";
/* solhint-enable max-line-length */
/// @title Multisig
/// @author Aragon X - 2022-2024
/// @notice The on-chain multisig governance plugin in which a proposal passes if X out of Y approvals are met.
/// @dev v1.3 (Release 1, Build 3). For each upgrade, if the reinitialization step is required,
/// increment the version numbers in the modifier for both the initialize and initializeFrom functions.
/// @custom:security-contact [email protected]
contract Multisig is
IMultisig,
IMembership,
MetadataExtensionUpgradeable,
PluginUUPSUpgradeable,
ProposalUpgradeable,
Addresslist
{
using SafeCastUpgradeable for uint256;
/// @notice A container for proposal-related information.
/// @param executed Whether the proposal is executed or not.
/// @param approvals The number of approvals casted.
/// @param parameters The proposal-specific approve settings at the time of the proposal creation.
/// @param approvers The approves casted by the approvers.
/// @param actions The actions to be executed when the proposal passes.
/// @param allowFailureMap A bitmap allowing the proposal to succeed, even if individual actions might revert.
/// If the bit at index `i` is 1, the proposal succeeds even if the `i`th action reverts.
/// A failure map value of 0 requires every action to not revert.
/// @param targetConfig Configuration for the execution target, specifying the target address and operation type
/// (either `Call` or `DelegateCall`). Defined by `TargetConfig` in the `IPlugin` interface,
/// part of the `osx-commons-contracts` package, added in build 3.
struct Proposal {
bool executed;
uint16 approvals;
ProposalParameters parameters;
mapping(address => bool) approvers;
Action[] actions;
uint256 allowFailureMap;
TargetConfig targetConfig; // added in build 3.
}
/// @notice A container for the proposal parameters.
/// @param minApprovals The number of approvals required.
/// @param snapshotBlock The number of the block prior to the proposal creation.
/// @param startDate The timestamp when the proposal starts.
/// @param endDate The timestamp when the proposal expires.
struct ProposalParameters {
uint16 minApprovals;
uint64 snapshotBlock;
uint64 startDate;
uint64 endDate;
}
/// @notice A container for the plugin settings.
/// @param onlyListed Whether only listed addresses can create a proposal or not.
/// @param minApprovals The minimal number of approvals required for a proposal to pass.
struct MultisigSettings {
bool onlyListed;
uint16 minApprovals;
}
/// @notice The [ERC-165](https://eips.ethereum.org/EIPS/eip-165) interface ID of the contract.
bytes4 internal constant MULTISIG_INTERFACE_ID =
this.updateMultisigSettings.selector ^
bytes4(
keccak256(
"createProposal(bytes,(address,uint256,bytes)[],uint256,bool,bool,uint64,uint64)"
)
) ^
this.getProposal.selector;
/// @notice The ID of the permission required to call the
/// `addAddresses`, `removeAddresses` and `updateMultisigSettings` functions.
bytes32 public constant UPDATE_MULTISIG_SETTINGS_PERMISSION_ID =
keccak256("UPDATE_MULTISIG_SETTINGS_PERMISSION");
/// @notice The ID of the permission required to call the `createProposal` function.
bytes32 public constant CREATE_PROPOSAL_PERMISSION_ID = keccak256("CREATE_PROPOSAL_PERMISSION");
/// @notice The ID of the permission required to call the `execute` function.
bytes32 public constant EXECUTE_PROPOSAL_PERMISSION_ID =
keccak256("EXECUTE_PROPOSAL_PERMISSION");
/// @notice A mapping between proposal IDs and proposal information.
// solhint-disable-next-line named-parameters-mapping
mapping(uint256 => Proposal) internal proposals;
/// @notice The current plugin settings.
MultisigSettings public multisigSettings;
/// @notice Keeps track at which block number the multisig settings have been changed the last time.
/// @dev This variable prevents a proposal from being created in the same block in which the multisig
/// settings change.
uint64 public lastMultisigSettingsChange;
/// @notice Thrown when a sender is not allowed to create a proposal.
/// @param sender The sender address.
error ProposalCreationForbidden(address sender);
/// @notice Thrown when a proposal doesn't exist.
/// @param proposalId The ID of the proposal which doesn't exist.
error NonexistentProposal(uint256 proposalId);
/// @notice Thrown if an approver is not allowed to cast an approve. This can be because the proposal
/// - is not open,
/// - was executed, or
/// - the approver is not on the address list
/// @param proposalId The ID of the proposal.
/// @param sender The address of the sender.
error ApprovalCastForbidden(uint256 proposalId, address sender);
/// @notice Thrown if the proposal execution is forbidden.
/// @param proposalId The ID of the proposal.
error ProposalExecutionForbidden(uint256 proposalId);
/// @notice Thrown if the minimal approvals value is out of bounds (less than 1 or greater than the number of
/// members in the address list).
/// @param limit The maximal value.
/// @param actual The actual value.
error MinApprovalsOutOfBounds(uint16 limit, uint16 actual);
/// @notice Thrown if the address list length is out of bounds.
/// @param limit The limit value.
/// @param actual The actual value.
error AddresslistLengthOutOfBounds(uint16 limit, uint256 actual);
/// @notice Thrown if the proposal with the same id already exists.
/// @param proposalId The id of the proposal.
error ProposalAlreadyExists(uint256 proposalId);
/// @notice Thrown if a date is out of bounds.
/// @param limit The limit value.
/// @param actual The actual value.
error DateOutOfBounds(uint64 limit, uint64 actual);
/// @notice Emitted when a proposal is approve by an approver.
/// @param proposalId The ID of the proposal.
/// @param approver The approver casting the approve.
event Approved(uint256 indexed proposalId, address indexed approver);
/// @notice Emitted when the plugin settings are set.
/// @param onlyListed Whether only listed addresses can create a proposal.
/// @param minApprovals The minimum amount of approvals needed to pass a proposal.
event MultisigSettingsUpdated(bool onlyListed, uint16 indexed minApprovals);
/// @notice Initializes Release 1, Build 3.
/// @dev This method is required to support [ERC-1822](https://eips.ethereum.org/EIPS/eip-1822).
/// @param _dao The IDAO interface of the associated DAO.
/// @param _members The addresses of the initial members to be added.
/// @param _multisigSettings The multisig settings.
/// @param _targetConfig Configuration for the execution target, specifying the target address and
/// operation type(either `Call` or `DelegateCall`). Defined by `TargetConfig` in the `IPlugin`
/// interface of `osx-commons-contracts` package, added in build 3.
/// @param _pluginMetadata The plugin specific information encoded in bytes.
/// This can also be an ipfs cid encoded in bytes.
function initialize(
IDAO _dao,
address[] calldata _members,
MultisigSettings calldata _multisigSettings,
TargetConfig calldata _targetConfig,
bytes calldata _pluginMetadata
) external onlyCallAtInitialization reinitializer(2) {
__PluginUUPSUpgradeable_init(_dao);
if (_members.length > type(uint16).max) {
revert AddresslistLengthOutOfBounds({limit: type(uint16).max, actual: _members.length});
}
_addAddresses(_members);
emit MembersAdded({members: _members});
_updateMultisigSettings(_multisigSettings);
_setMetadata(_pluginMetadata);
_setTargetConfig(_targetConfig);
}
/// @notice Reinitializes the Multisig after an upgrade from a previous build version. For each
/// reinitialization step, use the `_fromBuild` version to decide which internal functions to call
/// for reinitialization.
/// @dev WARNING: The contract should only be upgradeable through PSP to ensure that _fromBuild is not
/// incorrectly passed, and that the appropriate permissions for the upgrade are properly configured.
/// @param _fromBuild The build version number of the previous 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(uint16 _fromBuild, bytes calldata _initData) external reinitializer(2) {
if (_fromBuild < 3) {
(TargetConfig memory targetConfig, bytes memory pluginMetadata) = abi.decode(
_initData,
(TargetConfig, bytes)
);
_setTargetConfig(targetConfig);
_setMetadata(pluginMetadata);
}
}
/// @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(MetadataExtensionUpgradeable, PluginUUPSUpgradeable, ProposalUpgradeable)
returns (bool)
{
return
_interfaceId == MULTISIG_INTERFACE_ID ||
_interfaceId == type(IMultisig).interfaceId ||
_interfaceId == type(Addresslist).interfaceId ||
_interfaceId == type(IMembership).interfaceId ||
super.supportsInterface(_interfaceId);
}
/// @inheritdoc IMultisig
/// @dev Requires the `UPDATE_MULTISIG_SETTINGS_PERMISSION_ID` permission.
function addAddresses(
address[] calldata _members
) external auth(UPDATE_MULTISIG_SETTINGS_PERMISSION_ID) {
uint256 newAddresslistLength = addresslistLength() + _members.length;
// Check if the new address list length would be greater than `type(uint16).max`, the maximal number of
// approvals.
if (newAddresslistLength > type(uint16).max) {
revert AddresslistLengthOutOfBounds({
limit: type(uint16).max,
actual: newAddresslistLength
});
}
_addAddresses(_members);
emit MembersAdded({members: _members});
}
/// @inheritdoc IMultisig
/// @dev Requires the `UPDATE_MULTISIG_SETTINGS_PERMISSION_ID` permission.
function removeAddresses(
address[] calldata _members
) external auth(UPDATE_MULTISIG_SETTINGS_PERMISSION_ID) {
uint16 newAddresslistLength = uint16(addresslistLength() - _members.length);
// Check if the new address list length would become less than the current minimum number of approvals required.
if (newAddresslistLength < multisigSettings.minApprovals) {
revert MinApprovalsOutOfBounds({
limit: newAddresslistLength,
actual: multisigSettings.minApprovals
});
}
_removeAddresses(_members);
emit MembersRemoved({members: _members});
}
/// @notice Updates the plugin settings.
/// @dev Requires the `UPDATE_MULTISIG_SETTINGS_PERMISSION_ID` permission.
/// @param _multisigSettings The new settings.
function updateMultisigSettings(
MultisigSettings calldata _multisigSettings
) external auth(UPDATE_MULTISIG_SETTINGS_PERMISSION_ID) {
_updateMultisigSettings(_multisigSettings);
}
/// @notice Creates a new multisig proposal.
/// @dev Requires the `CREATE_PROPOSAL_PERMISSION_ID` permission.
/// @param _metadata The metadata of the proposal.
/// @param _actions The actions that will be executed after the proposal passes.
/// @param _allowFailureMap A bitmap allowing the proposal to succeed, even if individual actions might revert.
/// If the bit at index `i` is 1, the proposal succeeds even if the `i`th action reverts.
/// A failure map value of 0 requires every action to not revert.
/// @param _approveProposal If `true`, the sender will approve the proposal.
/// @param _tryExecution If `true`, execution is tried after the vote cast. The call does not revert if
/// execution is not possible.
/// @param _startDate The start date of the proposal.
/// @param _endDate The end date of the proposal.
/// @return proposalId The ID of the proposal.
// solhint-disable-next-line code-complexity
function createProposal(
bytes calldata _metadata,
Action[] calldata _actions,
uint256 _allowFailureMap,
bool _approveProposal,
bool _tryExecution,
uint64 _startDate,
uint64 _endDate
) public auth(CREATE_PROPOSAL_PERMISSION_ID) returns (uint256 proposalId) {
uint64 snapshotBlock;
unchecked {
// The snapshot block must be mined already to protect the transaction against backrunning transactions
// causing census changes.
snapshotBlock = block.number.toUint64() - 1;
}
// Revert if the settings have been changed in the same block as this proposal should be created in.
// This prevents a malicious party from voting with previous addresses and the new settings.
if (lastMultisigSettingsChange > snapshotBlock) {
revert ProposalCreationForbidden(_msgSender());
}
if (_startDate == 0) {
_startDate = block.timestamp.toUint64();
} else if (_startDate < block.timestamp.toUint64()) {
revert DateOutOfBounds({limit: block.timestamp.toUint64(), actual: _startDate});
}
if (_endDate < _startDate) {
revert DateOutOfBounds({limit: _startDate, actual: _endDate});
}
proposalId = _createProposalId(keccak256(abi.encode(_actions, _metadata)));
// Create the proposal
Proposal storage proposal_ = proposals[proposalId];
// Revert if a proposal with the given `proposalId` already exists.
if (_proposalExists(proposalId)) {
revert ProposalAlreadyExists(proposalId);
}
proposal_.parameters.snapshotBlock = snapshotBlock;
proposal_.parameters.startDate = _startDate;
proposal_.parameters.endDate = _endDate;
proposal_.parameters.minApprovals = multisigSettings.minApprovals;
proposal_.targetConfig = getTargetConfig();
// Reduce costs
if (_allowFailureMap != 0) {
proposal_.allowFailureMap = _allowFailureMap;
}
for (uint256 i; i < _actions.length; ) {
proposal_.actions.push(_actions[i]);
unchecked {
++i;
}
}
if (_approveProposal) {
approve(proposalId, _tryExecution);
}
_emitProposalCreatedEvent(
_actions,
_metadata,
_allowFailureMap,
_startDate,
_endDate,
proposalId
);
}
/// @inheritdoc IProposal
/// @dev Calls a public function that requires the `CREATE_PROPOSAL_PERMISSION_ID` permission.
function createProposal(
bytes calldata _metadata,
Action[] calldata _actions,
uint64 _startDate,
uint64 _endDate,
bytes memory _data
) external override returns (uint256 proposalId) {
// Custom parameters
uint256 _allowFailureMap;
bool _approveProposal;
bool _tryExecution;
if (_data.length != 0) {
(_allowFailureMap, _approveProposal, _tryExecution) = abi.decode(
_data,
(uint256, bool, bool)
);
}
// Calls a public function for permission check.
proposalId = createProposal(
_metadata,
_actions,
_allowFailureMap,
_approveProposal,
_tryExecution,
_startDate,
_endDate
);
}
/// @inheritdoc IProposal
function customProposalParamsABI() external pure override returns (string memory) {
return "(uint256 allowFailureMap, bool approveProposal, bool tryExecution)";
}
/// @inheritdoc IMultisig
/// @dev If `_tryExecution` is `true`, the function attempts execution after recording the approval.
/// Execution will only proceed if the proposal is no longer open, the minimum approval requirements are met,
/// and the caller has been granted execution permission. If execution conditions are not met,
/// the function does not revert.
function approve(uint256 _proposalId, bool _tryExecution) public {
address approver = _msgSender();
if (!_canApprove(_proposalId, approver)) {
revert ApprovalCastForbidden(_proposalId, approver);
}
Proposal storage proposal_ = proposals[_proposalId];
// As the list can never become more than type(uint16).max (due to `addAddresses` check)
// It's safe to use unchecked as it would never overflow.
unchecked {
proposal_.approvals += 1;
}
proposal_.approvers[approver] = true;
emit Approved({proposalId: _proposalId, approver: approver});
if (!_tryExecution) {
return;
}
if (
_canExecute(_proposalId) &&
dao().hasPermission(address(this), approver, EXECUTE_PROPOSAL_PERMISSION_ID, msg.data)
) {
_execute(_proposalId);
}
}
/// @inheritdoc IMultisig
/// @dev Reverts if the proposal with the given `_proposalId` does not exist.
function canApprove(uint256 _proposalId, address _account) external view returns (bool) {
if (!_proposalExists(_proposalId)) {
revert NonexistentProposal(_proposalId);
}
return _canApprove(_proposalId, _account);
}
/// @inheritdoc IMultisig
/// @dev Reverts if the proposal with the given `_proposalId` does not exist.
function canExecute(
uint256 _proposalId
) external view virtual override(IMultisig, IProposal) returns (bool) {
if (!_proposalExists(_proposalId)) {
revert NonexistentProposal(_proposalId);
}
return _canExecute(_proposalId);
}
/// @inheritdoc IProposal
function hasSucceeded(uint256 _proposalId) external view virtual override returns (bool) {
if (!_proposalExists(_proposalId)) {
revert NonexistentProposal(_proposalId);
}
Proposal storage proposal_ = proposals[_proposalId];
return proposal_.approvals >= proposal_.parameters.minApprovals;
}
/// @notice Returns all information for a proposal by its ID.
/// @param _proposalId The ID of the proposal.
/// @return executed Whether the proposal is executed or not.
/// @return approvals The number of approvals casted.
/// @return parameters The parameters of the proposal.
/// @return actions The actions to be executed to the `target` contract address.
/// @return allowFailureMap A bitmap allowing the proposal to succeed, even if individual actions might revert.
/// If the bit at index `i` is 1, the proposal succeeds even if the `i`th action reverts.
/// A failure map value of 0 requires every action to not revert.
/// @return targetConfig Execution configuration, applied to the proposal when it was created. Added in build 3.
function getProposal(
uint256 _proposalId
)
public
view
returns (
bool executed,
uint16 approvals,
ProposalParameters memory parameters,
Action[] memory actions,
uint256 allowFailureMap,
TargetConfig memory targetConfig
)
{
Proposal storage proposal_ = proposals[_proposalId];
executed = proposal_.executed;
approvals = proposal_.approvals;
parameters = proposal_.parameters;
actions = proposal_.actions;
allowFailureMap = proposal_.allowFailureMap;
targetConfig = proposal_.targetConfig;
}
/// @inheritdoc IMultisig
/// @dev May return false if the `_proposalId` or `_account` do not exist,
/// as the function does not verify their existence.
function hasApproved(uint256 _proposalId, address _account) public view returns (bool) {
return proposals[_proposalId].approvers[_account];
}
/// @inheritdoc IMultisig
/// @dev Requires the `EXECUTE_PROPOSAL_PERMISSION_ID` permission.
/// @dev Reverts if the proposal is still open or if the minimum approval threshold has not been met.
function execute(
uint256 _proposalId
) public override(IMultisig, IProposal) auth(EXECUTE_PROPOSAL_PERMISSION_ID) {
if (!_canExecute(_proposalId)) {
revert ProposalExecutionForbidden(_proposalId);
}
_execute(_proposalId);
}
/// @inheritdoc IMembership
function isMember(address _account) external view returns (bool) {
return isListed(_account);
}
/// @notice Internal function to execute a proposal.
/// @dev It assumes the queried proposal exists.
/// @param _proposalId The ID of the proposal.
function _execute(uint256 _proposalId) internal {
Proposal storage proposal_ = proposals[_proposalId];
proposal_.executed = true;
_execute(
proposal_.targetConfig.target,
bytes32(_proposalId),
proposal_.actions,
proposal_.allowFailureMap,
proposal_.targetConfig.operation
);
emit ProposalExecuted(_proposalId);
}
/// @notice Checks if proposal exists or not.
/// @dev A proposal is considered to exist if its `snapshotBlock` in `parameters` is non-zero.
/// @param _proposalId The ID of the proposal.
/// @return Returns `true` if proposal exists, otherwise false.
function _proposalExists(uint256 _proposalId) private view returns (bool) {
return proposals[_proposalId].parameters.snapshotBlock != 0;
}
/// @notice Internal function to check if an account can approve.
/// @dev It assumes the queried proposal exists.
/// @param _proposalId The ID of the proposal.
/// @param _account The account to check.
/// @return Returns `true` if the given account can approve on a certain proposal and `false` otherwise.
function _canApprove(uint256 _proposalId, address _account) internal view returns (bool) {
Proposal storage proposal_ = proposals[_proposalId];
if (!_isProposalOpen(proposal_)) {
// The proposal was executed already
return false;
}
if (!isListedAtBlock(_account, proposal_.parameters.snapshotBlock)) {
// The approver has no voting power.
return false;
}
if (proposal_.approvers[_account]) {
// The approver has already approved
return false;
}
return true;
}
/// @notice Internal function to check if a proposal can be executed.
/// @dev It assumes the queried proposal exists.
/// @param _proposalId The ID of the proposal.
/// @return Returns `true` if the proposal can be executed and `false` otherwise.
function _canExecute(uint256 _proposalId) internal view returns (bool) {
Proposal storage proposal_ = proposals[_proposalId];
// Verify that the proposal has not been executed or expired.
if (!_isProposalOpen(proposal_)) {
return false;
}
return proposal_.approvals >= proposal_.parameters.minApprovals;
}
/// @notice Internal function to check if a proposal is still open.
/// @param proposal_ The proposal struct.
/// @return True if the proposal is open, false otherwise.
function _isProposalOpen(Proposal storage proposal_) internal view returns (bool) {
uint64 currentTimestamp64 = block.timestamp.toUint64();
return
!proposal_.executed &&
proposal_.parameters.startDate <= currentTimestamp64 &&
proposal_.parameters.endDate >= currentTimestamp64;
}
/// @notice Internal function to update the plugin settings.
/// @param _multisigSettings The new settings.
function _updateMultisigSettings(MultisigSettings calldata _multisigSettings) internal {
uint16 addresslistLength_ = uint16(addresslistLength());
if (_multisigSettings.minApprovals > addresslistLength_) {
revert MinApprovalsOutOfBounds({
limit: addresslistLength_,
actual: _multisigSettings.minApprovals
});
}
if (_multisigSettings.minApprovals < 1) {
revert MinApprovalsOutOfBounds({limit: 1, actual: _multisigSettings.minApprovals});
}
multisigSettings = _multisigSettings;
lastMultisigSettingsChange = block.number.toUint64();
emit MultisigSettingsUpdated({
onlyListed: _multisigSettings.onlyListed,
minApprovals: _multisigSettings.minApprovals
});
}
/// @dev Helper function to avoid stack too deep.
function _emitProposalCreatedEvent(
Action[] memory _actions,
bytes memory _metadata,
uint256 _allowFailureMap,
uint64 _startDate,
uint64 _endDate,
uint256 _proposalId
) private {
emit ProposalCreated(
_proposalId,
_msgSender(),
_startDate,
_endDate,
_metadata,
_actions,
_allowFailureMap
);
}
/// @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.
/// https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps
uint256[47] private __gap;
}// 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 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: MIT
// OpenZeppelin Contracts (last updated v4.7.0) (proxy/ERC1967/ERC1967Proxy.sol)
pragma solidity ^0.8.0;
import "../Proxy.sol";
import "./ERC1967Upgrade.sol";
/**
* @dev This contract implements an upgradeable proxy. It is upgradeable because calls are delegated to an
* implementation address that can be changed. This address is stored in storage in the location specified by
* https://eips.ethereum.org/EIPS/eip-1967[EIP1967], so that it doesn't conflict with the storage layout of the
* implementation behind the proxy.
*/
contract ERC1967Proxy is Proxy, ERC1967Upgrade {
/**
* @dev Initializes the upgradeable proxy with an initial implementation specified by `_logic`.
*
* If `_data` is nonempty, it's used as data in a delegate call to `_logic`. This will typically be an encoded
* function call, and allows initializing the storage of the proxy like a Solidity constructor.
*/
constructor(address _logic, bytes memory _data) payable {
_upgradeToAndCall(_logic, _data, false);
}
/**
* @dev Returns the current implementation address.
*/
function _implementation() internal view virtual override returns (address impl) {
return ERC1967Upgrade._getImplementation();
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (proxy/Clones.sol)
pragma solidity ^0.8.0;
/**
* @dev https://eips.ethereum.org/EIPS/eip-1167[EIP 1167] is a standard for
* deploying minimal proxy contracts, also known as "clones".
*
* > To simply and cheaply clone contract functionality in an immutable way, this standard specifies
* > a minimal bytecode implementation that delegates all calls to a known, fixed address.
*
* The library includes functions to deploy a proxy using either `create` (traditional deployment) or `create2`
* (salted deterministic deployment). It also includes functions to predict the addresses of clones deployed using the
* deterministic method.
*
* _Available since v3.4._
*/
library Clones {
/**
* @dev Deploys and returns the address of a clone that mimics the behaviour of `implementation`.
*
* This function uses the create opcode, which should never revert.
*/
function clone(address implementation) internal returns (address instance) {
/// @solidity memory-safe-assembly
assembly {
// Cleans the upper 96 bits of the `implementation` word, then packs the first 3 bytes
// of the `implementation` address with the bytecode before the address.
mstore(0x00, or(shr(0xe8, shl(0x60, implementation)), 0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000))
// Packs the remaining 17 bytes of `implementation` with the bytecode after the address.
mstore(0x20, or(shl(0x78, implementation), 0x5af43d82803e903d91602b57fd5bf3))
instance := create(0, 0x09, 0x37)
}
require(instance != address(0), "ERC1167: create failed");
}
/**
* @dev Deploys and returns the address of a clone that mimics the behaviour of `implementation`.
*
* This function uses the create2 opcode and a `salt` to deterministically deploy
* the clone. Using the same `implementation` and `salt` multiple time will revert, since
* the clones cannot be deployed twice at the same address.
*/
function cloneDeterministic(address implementation, bytes32 salt) internal returns (address instance) {
/// @solidity memory-safe-assembly
assembly {
// Cleans the upper 96 bits of the `implementation` word, then packs the first 3 bytes
// of the `implementation` address with the bytecode before the address.
mstore(0x00, or(shr(0xe8, shl(0x60, implementation)), 0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000))
// Packs the remaining 17 bytes of `implementation` with the bytecode after the address.
mstore(0x20, or(shl(0x78, implementation), 0x5af43d82803e903d91602b57fd5bf3))
instance := create2(0, 0x09, 0x37, salt)
}
require(instance != address(0), "ERC1167: create2 failed");
}
/**
* @dev Computes the address of a clone deployed using {Clones-cloneDeterministic}.
*/
function predictDeterministicAddress(
address implementation,
bytes32 salt,
address deployer
) internal pure returns (address predicted) {
/// @solidity memory-safe-assembly
assembly {
let ptr := mload(0x40)
mstore(add(ptr, 0x38), deployer)
mstore(add(ptr, 0x24), 0x5af43d82803e903d91602b57fd5bf3ff)
mstore(add(ptr, 0x14), implementation)
mstore(ptr, 0x3d602d80600a3d3981f3363d3d373d3d3d363d73)
mstore(add(ptr, 0x58), salt)
mstore(add(ptr, 0x78), keccak256(add(ptr, 0x0c), 0x37))
predicted := keccak256(add(ptr, 0x43), 0x55)
}
}
/**
* @dev Computes the address of a clone deployed using {Clones-cloneDeterministic}.
*/
function predictDeterministicAddress(
address implementation,
bytes32 salt
) internal view returns (address predicted) {
return predictDeterministicAddress(implementation, salt, address(this));
}
}// 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 Address {
/**
* @dev Returns true if `account` is a contract.
*
* [IMPORTANT]
* ====
* It is unsafe to assume that an address for which this function returns
* false is an externally-owned account (EOA) and not a contract.
*
* Among others, `isContract` will return false for the following
* types of addresses:
*
* - an externally-owned account
* - a contract in construction
* - an address where a contract will be created
* - an address where a contract lived, but was destroyed
*
* 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: 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: MIT
// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SafeCast.sol)
// This file was procedurally generated from scripts/generate/templates/SafeCast.js.
pragma solidity ^0.8.0;
/**
* @dev Wrappers over Solidity's uintXX/intXX casting operators with added overflow
* checks.
*
* Downcasting from uint256/int256 in Solidity does not revert on overflow. This can
* easily result in undesired exploitation or bugs, since developers usually
* assume that overflows raise errors. `SafeCast` restores this intuition by
* reverting the transaction when such an operation overflows.
*
* Using this library instead of the unchecked operations eliminates an entire
* class of bugs, so it's recommended to use it always.
*
* Can be combined with {SafeMath} and {SignedSafeMath} to extend it to smaller types, by performing
* all math on `uint256` and `int256` and then downcasting.
*/
library SafeCastUpgradeable {
/**
* @dev Returns the downcasted uint248 from uint256, reverting on
* overflow (when the input is greater than largest uint248).
*
* Counterpart to Solidity's `uint248` operator.
*
* Requirements:
*
* - input must fit into 248 bits
*
* _Available since v4.7._
*/
function toUint248(uint256 value) internal pure returns (uint248) {
require(value <= type(uint248).max, "SafeCast: value doesn't fit in 248 bits");
return uint248(value);
}
/**
* @dev Returns the downcasted uint240 from uint256, reverting on
* overflow (when the input is greater than largest uint240).
*
* Counterpart to Solidity's `uint240` operator.
*
* Requirements:
*
* - input must fit into 240 bits
*
* _Available since v4.7._
*/
function toUint240(uint256 value) internal pure returns (uint240) {
require(value <= type(uint240).max, "SafeCast: value doesn't fit in 240 bits");
return uint240(value);
}
/**
* @dev Returns the downcasted uint232 from uint256, reverting on
* overflow (when the input is greater than largest uint232).
*
* Counterpart to Solidity's `uint232` operator.
*
* Requirements:
*
* - input must fit into 232 bits
*
* _Available since v4.7._
*/
function toUint232(uint256 value) internal pure returns (uint232) {
require(value <= type(uint232).max, "SafeCast: value doesn't fit in 232 bits");
return uint232(value);
}
/**
* @dev Returns the downcasted uint224 from uint256, reverting on
* overflow (when the input is greater than largest uint224).
*
* Counterpart to Solidity's `uint224` operator.
*
* Requirements:
*
* - input must fit into 224 bits
*
* _Available since v4.2._
*/
function toUint224(uint256 value) internal pure returns (uint224) {
require(value <= type(uint224).max, "SafeCast: value doesn't fit in 224 bits");
return uint224(value);
}
/**
* @dev Returns the downcasted uint216 from uint256, reverting on
* overflow (when the input is greater than largest uint216).
*
* Counterpart to Solidity's `uint216` operator.
*
* Requirements:
*
* - input must fit into 216 bits
*
* _Available since v4.7._
*/
function toUint216(uint256 value) internal pure returns (uint216) {
require(value <= type(uint216).max, "SafeCast: value doesn't fit in 216 bits");
return uint216(value);
}
/**
* @dev Returns the downcasted uint208 from uint256, reverting on
* overflow (when the input is greater than largest uint208).
*
* Counterpart to Solidity's `uint208` operator.
*
* Requirements:
*
* - input must fit into 208 bits
*
* _Available since v4.7._
*/
function toUint208(uint256 value) internal pure returns (uint208) {
require(value <= type(uint208).max, "SafeCast: value doesn't fit in 208 bits");
return uint208(value);
}
/**
* @dev Returns the downcasted uint200 from uint256, reverting on
* overflow (when the input is greater than largest uint200).
*
* Counterpart to Solidity's `uint200` operator.
*
* Requirements:
*
* - input must fit into 200 bits
*
* _Available since v4.7._
*/
function toUint200(uint256 value) internal pure returns (uint200) {
require(value <= type(uint200).max, "SafeCast: value doesn't fit in 200 bits");
return uint200(value);
}
/**
* @dev Returns the downcasted uint192 from uint256, reverting on
* overflow (when the input is greater than largest uint192).
*
* Counterpart to Solidity's `uint192` operator.
*
* Requirements:
*
* - input must fit into 192 bits
*
* _Available since v4.7._
*/
function toUint192(uint256 value) internal pure returns (uint192) {
require(value <= type(uint192).max, "SafeCast: value doesn't fit in 192 bits");
return uint192(value);
}
/**
* @dev Returns the downcasted uint184 from uint256, reverting on
* overflow (when the input is greater than largest uint184).
*
* Counterpart to Solidity's `uint184` operator.
*
* Requirements:
*
* - input must fit into 184 bits
*
* _Available since v4.7._
*/
function toUint184(uint256 value) internal pure returns (uint184) {
require(value <= type(uint184).max, "SafeCast: value doesn't fit in 184 bits");
return uint184(value);
}
/**
* @dev Returns the downcasted uint176 from uint256, reverting on
* overflow (when the input is greater than largest uint176).
*
* Counterpart to Solidity's `uint176` operator.
*
* Requirements:
*
* - input must fit into 176 bits
*
* _Available since v4.7._
*/
function toUint176(uint256 value) internal pure returns (uint176) {
require(value <= type(uint176).max, "SafeCast: value doesn't fit in 176 bits");
return uint176(value);
}
/**
* @dev Returns the downcasted uint168 from uint256, reverting on
* overflow (when the input is greater than largest uint168).
*
* Counterpart to Solidity's `uint168` operator.
*
* Requirements:
*
* - input must fit into 168 bits
*
* _Available since v4.7._
*/
function toUint168(uint256 value) internal pure returns (uint168) {
require(value <= type(uint168).max, "SafeCast: value doesn't fit in 168 bits");
return uint168(value);
}
/**
* @dev Returns the downcasted uint160 from uint256, reverting on
* overflow (when the input is greater than largest uint160).
*
* Counterpart to Solidity's `uint160` operator.
*
* Requirements:
*
* - input must fit into 160 bits
*
* _Available since v4.7._
*/
function toUint160(uint256 value) internal pure returns (uint160) {
require(value <= type(uint160).max, "SafeCast: value doesn't fit in 160 bits");
return uint160(value);
}
/**
* @dev Returns the downcasted uint152 from uint256, reverting on
* overflow (when the input is greater than largest uint152).
*
* Counterpart to Solidity's `uint152` operator.
*
* Requirements:
*
* - input must fit into 152 bits
*
* _Available since v4.7._
*/
function toUint152(uint256 value) internal pure returns (uint152) {
require(value <= type(uint152).max, "SafeCast: value doesn't fit in 152 bits");
return uint152(value);
}
/**
* @dev Returns the downcasted uint144 from uint256, reverting on
* overflow (when the input is greater than largest uint144).
*
* Counterpart to Solidity's `uint144` operator.
*
* Requirements:
*
* - input must fit into 144 bits
*
* _Available since v4.7._
*/
function toUint144(uint256 value) internal pure returns (uint144) {
require(value <= type(uint144).max, "SafeCast: value doesn't fit in 144 bits");
return uint144(value);
}
/**
* @dev Returns the downcasted uint136 from uint256, reverting on
* overflow (when the input is greater than largest uint136).
*
* Counterpart to Solidity's `uint136` operator.
*
* Requirements:
*
* - input must fit into 136 bits
*
* _Available since v4.7._
*/
function toUint136(uint256 value) internal pure returns (uint136) {
require(value <= type(uint136).max, "SafeCast: value doesn't fit in 136 bits");
return uint136(value);
}
/**
* @dev Returns the downcasted uint128 from uint256, reverting on
* overflow (when the input is greater than largest uint128).
*
* Counterpart to Solidity's `uint128` operator.
*
* Requirements:
*
* - input must fit into 128 bits
*
* _Available since v2.5._
*/
function toUint128(uint256 value) internal pure returns (uint128) {
require(value <= type(uint128).max, "SafeCast: value doesn't fit in 128 bits");
return uint128(value);
}
/**
* @dev Returns the downcasted uint120 from uint256, reverting on
* overflow (when the input is greater than largest uint120).
*
* Counterpart to Solidity's `uint120` operator.
*
* Requirements:
*
* - input must fit into 120 bits
*
* _Available since v4.7._
*/
function toUint120(uint256 value) internal pure returns (uint120) {
require(value <= type(uint120).max, "SafeCast: value doesn't fit in 120 bits");
return uint120(value);
}
/**
* @dev Returns the downcasted uint112 from uint256, reverting on
* overflow (when the input is greater than largest uint112).
*
* Counterpart to Solidity's `uint112` operator.
*
* Requirements:
*
* - input must fit into 112 bits
*
* _Available since v4.7._
*/
function toUint112(uint256 value) internal pure returns (uint112) {
require(value <= type(uint112).max, "SafeCast: value doesn't fit in 112 bits");
return uint112(value);
}
/**
* @dev Returns the downcasted uint104 from uint256, reverting on
* overflow (when the input is greater than largest uint104).
*
* Counterpart to Solidity's `uint104` operator.
*
* Requirements:
*
* - input must fit into 104 bits
*
* _Available since v4.7._
*/
function toUint104(uint256 value) internal pure returns (uint104) {
require(value <= type(uint104).max, "SafeCast: value doesn't fit in 104 bits");
return uint104(value);
}
/**
* @dev Returns the downcasted uint96 from uint256, reverting on
* overflow (when the input is greater than largest uint96).
*
* Counterpart to Solidity's `uint96` operator.
*
* Requirements:
*
* - input must fit into 96 bits
*
* _Available since v4.2._
*/
function toUint96(uint256 value) internal pure returns (uint96) {
require(value <= type(uint96).max, "SafeCast: value doesn't fit in 96 bits");
return uint96(value);
}
/**
* @dev Returns the downcasted uint88 from uint256, reverting on
* overflow (when the input is greater than largest uint88).
*
* Counterpart to Solidity's `uint88` operator.
*
* Requirements:
*
* - input must fit into 88 bits
*
* _Available since v4.7._
*/
function toUint88(uint256 value) internal pure returns (uint88) {
require(value <= type(uint88).max, "SafeCast: value doesn't fit in 88 bits");
return uint88(value);
}
/**
* @dev Returns the downcasted uint80 from uint256, reverting on
* overflow (when the input is greater than largest uint80).
*
* Counterpart to Solidity's `uint80` operator.
*
* Requirements:
*
* - input must fit into 80 bits
*
* _Available since v4.7._
*/
function toUint80(uint256 value) internal pure returns (uint80) {
require(value <= type(uint80).max, "SafeCast: value doesn't fit in 80 bits");
return uint80(value);
}
/**
* @dev Returns the downcasted uint72 from uint256, reverting on
* overflow (when the input is greater than largest uint72).
*
* Counterpart to Solidity's `uint72` operator.
*
* Requirements:
*
* - input must fit into 72 bits
*
* _Available since v4.7._
*/
function toUint72(uint256 value) internal pure returns (uint72) {
require(value <= type(uint72).max, "SafeCast: value doesn't fit in 72 bits");
return uint72(value);
}
/**
* @dev Returns the downcasted uint64 from uint256, reverting on
* overflow (when the input is greater than largest uint64).
*
* Counterpart to Solidity's `uint64` operator.
*
* Requirements:
*
* - input must fit into 64 bits
*
* _Available since v2.5._
*/
function toUint64(uint256 value) internal pure returns (uint64) {
require(value <= type(uint64).max, "SafeCast: value doesn't fit in 64 bits");
return uint64(value);
}
/**
* @dev Returns the downcasted uint56 from uint256, reverting on
* overflow (when the input is greater than largest uint56).
*
* Counterpart to Solidity's `uint56` operator.
*
* Requirements:
*
* - input must fit into 56 bits
*
* _Available since v4.7._
*/
function toUint56(uint256 value) internal pure returns (uint56) {
require(value <= type(uint56).max, "SafeCast: value doesn't fit in 56 bits");
return uint56(value);
}
/**
* @dev Returns the downcasted uint48 from uint256, reverting on
* overflow (when the input is greater than largest uint48).
*
* Counterpart to Solidity's `uint48` operator.
*
* Requirements:
*
* - input must fit into 48 bits
*
* _Available since v4.7._
*/
function toUint48(uint256 value) internal pure returns (uint48) {
require(value <= type(uint48).max, "SafeCast: value doesn't fit in 48 bits");
return uint48(value);
}
/**
* @dev Returns the downcasted uint40 from uint256, reverting on
* overflow (when the input is greater than largest uint40).
*
* Counterpart to Solidity's `uint40` operator.
*
* Requirements:
*
* - input must fit into 40 bits
*
* _Available since v4.7._
*/
function toUint40(uint256 value) internal pure returns (uint40) {
require(value <= type(uint40).max, "SafeCast: value doesn't fit in 40 bits");
return uint40(value);
}
/**
* @dev Returns the downcasted uint32 from uint256, reverting on
* overflow (when the input is greater than largest uint32).
*
* Counterpart to Solidity's `uint32` operator.
*
* Requirements:
*
* - input must fit into 32 bits
*
* _Available since v2.5._
*/
function toUint32(uint256 value) internal pure returns (uint32) {
require(value <= type(uint32).max, "SafeCast: value doesn't fit in 32 bits");
return uint32(value);
}
/**
* @dev Returns the downcasted uint24 from uint256, reverting on
* overflow (when the input is greater than largest uint24).
*
* Counterpart to Solidity's `uint24` operator.
*
* Requirements:
*
* - input must fit into 24 bits
*
* _Available since v4.7._
*/
function toUint24(uint256 value) internal pure returns (uint24) {
require(value <= type(uint24).max, "SafeCast: value doesn't fit in 24 bits");
return uint24(value);
}
/**
* @dev Returns the downcasted uint16 from uint256, reverting on
* overflow (when the input is greater than largest uint16).
*
* Counterpart to Solidity's `uint16` operator.
*
* Requirements:
*
* - input must fit into 16 bits
*
* _Available since v2.5._
*/
function toUint16(uint256 value) internal pure returns (uint16) {
require(value <= type(uint16).max, "SafeCast: value doesn't fit in 16 bits");
return uint16(value);
}
/**
* @dev Returns the downcasted uint8 from uint256, reverting on
* overflow (when the input is greater than largest uint8).
*
* Counterpart to Solidity's `uint8` operator.
*
* Requirements:
*
* - input must fit into 8 bits
*
* _Available since v2.5._
*/
function toUint8(uint256 value) internal pure returns (uint8) {
require(value <= type(uint8).max, "SafeCast: value doesn't fit in 8 bits");
return uint8(value);
}
/**
* @dev Converts a signed int256 into an unsigned uint256.
*
* Requirements:
*
* - input must be greater than or equal to 0.
*
* _Available since v3.0._
*/
function toUint256(int256 value) internal pure returns (uint256) {
require(value >= 0, "SafeCast: value must be positive");
return uint256(value);
}
/**
* @dev Returns the downcasted int248 from int256, reverting on
* overflow (when the input is less than smallest int248 or
* greater than largest int248).
*
* Counterpart to Solidity's `int248` operator.
*
* Requirements:
*
* - input must fit into 248 bits
*
* _Available since v4.7._
*/
function toInt248(int256 value) internal pure returns (int248 downcasted) {
downcasted = int248(value);
require(downcasted == value, "SafeCast: value doesn't fit in 248 bits");
}
/**
* @dev Returns the downcasted int240 from int256, reverting on
* overflow (when the input is less than smallest int240 or
* greater than largest int240).
*
* Counterpart to Solidity's `int240` operator.
*
* Requirements:
*
* - input must fit into 240 bits
*
* _Available since v4.7._
*/
function toInt240(int256 value) internal pure returns (int240 downcasted) {
downcasted = int240(value);
require(downcasted == value, "SafeCast: value doesn't fit in 240 bits");
}
/**
* @dev Returns the downcasted int232 from int256, reverting on
* overflow (when the input is less than smallest int232 or
* greater than largest int232).
*
* Counterpart to Solidity's `int232` operator.
*
* Requirements:
*
* - input must fit into 232 bits
*
* _Available since v4.7._
*/
function toInt232(int256 value) internal pure returns (int232 downcasted) {
downcasted = int232(value);
require(downcasted == value, "SafeCast: value doesn't fit in 232 bits");
}
/**
* @dev Returns the downcasted int224 from int256, reverting on
* overflow (when the input is less than smallest int224 or
* greater than largest int224).
*
* Counterpart to Solidity's `int224` operator.
*
* Requirements:
*
* - input must fit into 224 bits
*
* _Available since v4.7._
*/
function toInt224(int256 value) internal pure returns (int224 downcasted) {
downcasted = int224(value);
require(downcasted == value, "SafeCast: value doesn't fit in 224 bits");
}
/**
* @dev Returns the downcasted int216 from int256, reverting on
* overflow (when the input is less than smallest int216 or
* greater than largest int216).
*
* Counterpart to Solidity's `int216` operator.
*
* Requirements:
*
* - input must fit into 216 bits
*
* _Available since v4.7._
*/
function toInt216(int256 value) internal pure returns (int216 downcasted) {
downcasted = int216(value);
require(downcasted == value, "SafeCast: value doesn't fit in 216 bits");
}
/**
* @dev Returns the downcasted int208 from int256, reverting on
* overflow (when the input is less than smallest int208 or
* greater than largest int208).
*
* Counterpart to Solidity's `int208` operator.
*
* Requirements:
*
* - input must fit into 208 bits
*
* _Available since v4.7._
*/
function toInt208(int256 value) internal pure returns (int208 downcasted) {
downcasted = int208(value);
require(downcasted == value, "SafeCast: value doesn't fit in 208 bits");
}
/**
* @dev Returns the downcasted int200 from int256, reverting on
* overflow (when the input is less than smallest int200 or
* greater than largest int200).
*
* Counterpart to Solidity's `int200` operator.
*
* Requirements:
*
* - input must fit into 200 bits
*
* _Available since v4.7._
*/
function toInt200(int256 value) internal pure returns (int200 downcasted) {
downcasted = int200(value);
require(downcasted == value, "SafeCast: value doesn't fit in 200 bits");
}
/**
* @dev Returns the downcasted int192 from int256, reverting on
* overflow (when the input is less than smallest int192 or
* greater than largest int192).
*
* Counterpart to Solidity's `int192` operator.
*
* Requirements:
*
* - input must fit into 192 bits
*
* _Available since v4.7._
*/
function toInt192(int256 value) internal pure returns (int192 downcasted) {
downcasted = int192(value);
require(downcasted == value, "SafeCast: value doesn't fit in 192 bits");
}
/**
* @dev Returns the downcasted int184 from int256, reverting on
* overflow (when the input is less than smallest int184 or
* greater than largest int184).
*
* Counterpart to Solidity's `int184` operator.
*
* Requirements:
*
* - input must fit into 184 bits
*
* _Available since v4.7._
*/
function toInt184(int256 value) internal pure returns (int184 downcasted) {
downcasted = int184(value);
require(downcasted == value, "SafeCast: value doesn't fit in 184 bits");
}
/**
* @dev Returns the downcasted int176 from int256, reverting on
* overflow (when the input is less than smallest int176 or
* greater than largest int176).
*
* Counterpart to Solidity's `int176` operator.
*
* Requirements:
*
* - input must fit into 176 bits
*
* _Available since v4.7._
*/
function toInt176(int256 value) internal pure returns (int176 downcasted) {
downcasted = int176(value);
require(downcasted == value, "SafeCast: value doesn't fit in 176 bits");
}
/**
* @dev Returns the downcasted int168 from int256, reverting on
* overflow (when the input is less than smallest int168 or
* greater than largest int168).
*
* Counterpart to Solidity's `int168` operator.
*
* Requirements:
*
* - input must fit into 168 bits
*
* _Available since v4.7._
*/
function toInt168(int256 value) internal pure returns (int168 downcasted) {
downcasted = int168(value);
require(downcasted == value, "SafeCast: value doesn't fit in 168 bits");
}
/**
* @dev Returns the downcasted int160 from int256, reverting on
* overflow (when the input is less than smallest int160 or
* greater than largest int160).
*
* Counterpart to Solidity's `int160` operator.
*
* Requirements:
*
* - input must fit into 160 bits
*
* _Available since v4.7._
*/
function toInt160(int256 value) internal pure returns (int160 downcasted) {
downcasted = int160(value);
require(downcasted == value, "SafeCast: value doesn't fit in 160 bits");
}
/**
* @dev Returns the downcasted int152 from int256, reverting on
* overflow (when the input is less than smallest int152 or
* greater than largest int152).
*
* Counterpart to Solidity's `int152` operator.
*
* Requirements:
*
* - input must fit into 152 bits
*
* _Available since v4.7._
*/
function toInt152(int256 value) internal pure returns (int152 downcasted) {
downcasted = int152(value);
require(downcasted == value, "SafeCast: value doesn't fit in 152 bits");
}
/**
* @dev Returns the downcasted int144 from int256, reverting on
* overflow (when the input is less than smallest int144 or
* greater than largest int144).
*
* Counterpart to Solidity's `int144` operator.
*
* Requirements:
*
* - input must fit into 144 bits
*
* _Available since v4.7._
*/
function toInt144(int256 value) internal pure returns (int144 downcasted) {
downcasted = int144(value);
require(downcasted == value, "SafeCast: value doesn't fit in 144 bits");
}
/**
* @dev Returns the downcasted int136 from int256, reverting on
* overflow (when the input is less than smallest int136 or
* greater than largest int136).
*
* Counterpart to Solidity's `int136` operator.
*
* Requirements:
*
* - input must fit into 136 bits
*
* _Available since v4.7._
*/
function toInt136(int256 value) internal pure returns (int136 downcasted) {
downcasted = int136(value);
require(downcasted == value, "SafeCast: value doesn't fit in 136 bits");
}
/**
* @dev Returns the downcasted int128 from int256, reverting on
* overflow (when the input is less than smallest int128 or
* greater than largest int128).
*
* Counterpart to Solidity's `int128` operator.
*
* Requirements:
*
* - input must fit into 128 bits
*
* _Available since v3.1._
*/
function toInt128(int256 value) internal pure returns (int128 downcasted) {
downcasted = int128(value);
require(downcasted == value, "SafeCast: value doesn't fit in 128 bits");
}
/**
* @dev Returns the downcasted int120 from int256, reverting on
* overflow (when the input is less than smallest int120 or
* greater than largest int120).
*
* Counterpart to Solidity's `int120` operator.
*
* Requirements:
*
* - input must fit into 120 bits
*
* _Available since v4.7._
*/
function toInt120(int256 value) internal pure returns (int120 downcasted) {
downcasted = int120(value);
require(downcasted == value, "SafeCast: value doesn't fit in 120 bits");
}
/**
* @dev Returns the downcasted int112 from int256, reverting on
* overflow (when the input is less than smallest int112 or
* greater than largest int112).
*
* Counterpart to Solidity's `int112` operator.
*
* Requirements:
*
* - input must fit into 112 bits
*
* _Available since v4.7._
*/
function toInt112(int256 value) internal pure returns (int112 downcasted) {
downcasted = int112(value);
require(downcasted == value, "SafeCast: value doesn't fit in 112 bits");
}
/**
* @dev Returns the downcasted int104 from int256, reverting on
* overflow (when the input is less than smallest int104 or
* greater than largest int104).
*
* Counterpart to Solidity's `int104` operator.
*
* Requirements:
*
* - input must fit into 104 bits
*
* _Available since v4.7._
*/
function toInt104(int256 value) internal pure returns (int104 downcasted) {
downcasted = int104(value);
require(downcasted == value, "SafeCast: value doesn't fit in 104 bits");
}
/**
* @dev Returns the downcasted int96 from int256, reverting on
* overflow (when the input is less than smallest int96 or
* greater than largest int96).
*
* Counterpart to Solidity's `int96` operator.
*
* Requirements:
*
* - input must fit into 96 bits
*
* _Available since v4.7._
*/
function toInt96(int256 value) internal pure returns (int96 downcasted) {
downcasted = int96(value);
require(downcasted == value, "SafeCast: value doesn't fit in 96 bits");
}
/**
* @dev Returns the downcasted int88 from int256, reverting on
* overflow (when the input is less than smallest int88 or
* greater than largest int88).
*
* Counterpart to Solidity's `int88` operator.
*
* Requirements:
*
* - input must fit into 88 bits
*
* _Available since v4.7._
*/
function toInt88(int256 value) internal pure returns (int88 downcasted) {
downcasted = int88(value);
require(downcasted == value, "SafeCast: value doesn't fit in 88 bits");
}
/**
* @dev Returns the downcasted int80 from int256, reverting on
* overflow (when the input is less than smallest int80 or
* greater than largest int80).
*
* Counterpart to Solidity's `int80` operator.
*
* Requirements:
*
* - input must fit into 80 bits
*
* _Available since v4.7._
*/
function toInt80(int256 value) internal pure returns (int80 downcasted) {
downcasted = int80(value);
require(downcasted == value, "SafeCast: value doesn't fit in 80 bits");
}
/**
* @dev Returns the downcasted int72 from int256, reverting on
* overflow (when the input is less than smallest int72 or
* greater than largest int72).
*
* Counterpart to Solidity's `int72` operator.
*
* Requirements:
*
* - input must fit into 72 bits
*
* _Available since v4.7._
*/
function toInt72(int256 value) internal pure returns (int72 downcasted) {
downcasted = int72(value);
require(downcasted == value, "SafeCast: value doesn't fit in 72 bits");
}
/**
* @dev Returns the downcasted int64 from int256, reverting on
* overflow (when the input is less than smallest int64 or
* greater than largest int64).
*
* Counterpart to Solidity's `int64` operator.
*
* Requirements:
*
* - input must fit into 64 bits
*
* _Available since v3.1._
*/
function toInt64(int256 value) internal pure returns (int64 downcasted) {
downcasted = int64(value);
require(downcasted == value, "SafeCast: value doesn't fit in 64 bits");
}
/**
* @dev Returns the downcasted int56 from int256, reverting on
* overflow (when the input is less than smallest int56 or
* greater than largest int56).
*
* Counterpart to Solidity's `int56` operator.
*
* Requirements:
*
* - input must fit into 56 bits
*
* _Available since v4.7._
*/
function toInt56(int256 value) internal pure returns (int56 downcasted) {
downcasted = int56(value);
require(downcasted == value, "SafeCast: value doesn't fit in 56 bits");
}
/**
* @dev Returns the downcasted int48 from int256, reverting on
* overflow (when the input is less than smallest int48 or
* greater than largest int48).
*
* Counterpart to Solidity's `int48` operator.
*
* Requirements:
*
* - input must fit into 48 bits
*
* _Available since v4.7._
*/
function toInt48(int256 value) internal pure returns (int48 downcasted) {
downcasted = int48(value);
require(downcasted == value, "SafeCast: value doesn't fit in 48 bits");
}
/**
* @dev Returns the downcasted int40 from int256, reverting on
* overflow (when the input is less than smallest int40 or
* greater than largest int40).
*
* Counterpart to Solidity's `int40` operator.
*
* Requirements:
*
* - input must fit into 40 bits
*
* _Available since v4.7._
*/
function toInt40(int256 value) internal pure returns (int40 downcasted) {
downcasted = int40(value);
require(downcasted == value, "SafeCast: value doesn't fit in 40 bits");
}
/**
* @dev Returns the downcasted int32 from int256, reverting on
* overflow (when the input is less than smallest int32 or
* greater than largest int32).
*
* Counterpart to Solidity's `int32` operator.
*
* Requirements:
*
* - input must fit into 32 bits
*
* _Available since v3.1._
*/
function toInt32(int256 value) internal pure returns (int32 downcasted) {
downcasted = int32(value);
require(downcasted == value, "SafeCast: value doesn't fit in 32 bits");
}
/**
* @dev Returns the downcasted int24 from int256, reverting on
* overflow (when the input is less than smallest int24 or
* greater than largest int24).
*
* Counterpart to Solidity's `int24` operator.
*
* Requirements:
*
* - input must fit into 24 bits
*
* _Available since v4.7._
*/
function toInt24(int256 value) internal pure returns (int24 downcasted) {
downcasted = int24(value);
require(downcasted == value, "SafeCast: value doesn't fit in 24 bits");
}
/**
* @dev Returns the downcasted int16 from int256, reverting on
* overflow (when the input is less than smallest int16 or
* greater than largest int16).
*
* Counterpart to Solidity's `int16` operator.
*
* Requirements:
*
* - input must fit into 16 bits
*
* _Available since v3.1._
*/
function toInt16(int256 value) internal pure returns (int16 downcasted) {
downcasted = int16(value);
require(downcasted == value, "SafeCast: value doesn't fit in 16 bits");
}
/**
* @dev Returns the downcasted int8 from int256, reverting on
* overflow (when the input is less than smallest int8 or
* greater than largest int8).
*
* Counterpart to Solidity's `int8` operator.
*
* Requirements:
*
* - input must fit into 8 bits
*
* _Available since v3.1._
*/
function toInt8(int256 value) internal pure returns (int8 downcasted) {
downcasted = int8(value);
require(downcasted == value, "SafeCast: value doesn't fit in 8 bits");
}
/**
* @dev Converts an unsigned uint256 into a signed int256.
*
* Requirements:
*
* - input must be less than or equal to maxInt256.
*
* _Available since v3.0._
*/
function toInt256(uint256 value) internal pure returns (int256) {
// Note: Unsafe cast below is okay because `type(int256).max` is guaranteed to be positive
require(value <= uint256(type(int256).max), "SafeCast: value doesn't fit in an int256");
return int256(value);
}
}// SPDX-License-Identifier: AGPL-3.0-or-later pragma solidity ^0.8.8; /// @title IMembership /// @author Aragon X - 2022-2023 /// @notice An interface to be implemented by DAO plugins that define membership. /// @custom:security-contact [email protected] interface IMembership { /// @notice Emitted when members are added to the DAO plugin. /// @param members The list of new members being added. event MembersAdded(address[] members); /// @notice Emitted when members are removed from the DAO plugin. /// @param members The list of existing members being removed. event MembersRemoved(address[] members); /// @notice Emitted to announce the membership being defined by a contract. /// @param definingContract The contract defining the membership. event MembershipContractAnnounced(address indexed definingContract); /// @notice Checks if an account is a member of the DAO. /// @param _account The address of the account to be checked. /// @return Whether the account is a member or not. /// @dev This function must be implemented in the plugin contract that introduces the members to the DAO. function isMember(address _account) external view returns (bool); }
// SPDX-License-Identifier: AGPL-3.0-or-later
pragma solidity ^0.8.8;
import {CheckpointsUpgradeable} from "@openzeppelin/contracts-upgradeable/utils/CheckpointsUpgradeable.sol";
import {_uncheckedAdd, _uncheckedSub} from "../../../utils/math/UncheckedMath.sol";
/// @title Addresslist
/// @author Aragon X - 2021-2023
/// @notice The majority voting implementation using a list of member addresses.
/// @dev This contract inherits from `MajorityVotingBase` and implements the `IMajorityVoting` interface.
/// @custom:security-contact [email protected]
abstract contract Addresslist {
using CheckpointsUpgradeable for CheckpointsUpgradeable.History;
/// @notice The mapping containing the checkpointed history of the address list.
// solhint-disable-next-line named-parameters-mapping
mapping(address => CheckpointsUpgradeable.History) private _addresslistCheckpoints;
/// @notice The checkpointed history of the length of the address list.
CheckpointsUpgradeable.History private _addresslistLengthCheckpoints;
/// @notice Thrown when the address list update is invalid, which can be caused by the addition of an existing member or removal of a non-existing member.
/// @param member The array of member addresses to be added or removed.
error InvalidAddresslistUpdate(address member);
/// @notice Checks if an account is on the address list at a specific block number.
/// @param _account The account address being checked.
/// @param _blockNumber The block number.
/// @return Whether the account is listed at the specified block number.
function isListedAtBlock(
address _account,
uint256 _blockNumber
) public view virtual returns (bool) {
return _addresslistCheckpoints[_account].getAtBlock(_blockNumber) == 1;
}
/// @notice Checks if an account is currently on the address list.
/// @param _account The account address being checked.
/// @return Whether the account is currently listed.
function isListed(address _account) public view virtual returns (bool) {
return _addresslistCheckpoints[_account].latest() == 1;
}
/// @notice Returns the length of the address list at a specific block number.
/// @param _blockNumber The specific block to get the count from. If `0`, then the latest checkpoint value is returned.
/// @return The address list length at the specified block number.
function addresslistLengthAtBlock(uint256 _blockNumber) public view virtual returns (uint256) {
return _addresslistLengthCheckpoints.getAtBlock(_blockNumber);
}
/// @notice Returns the current length of the address list.
/// @return The current address list length.
function addresslistLength() public view virtual returns (uint256) {
return _addresslistLengthCheckpoints.latest();
}
/// @notice Internal function to add new addresses to the address list.
/// @param _newAddresses The new addresses to be added.
function _addAddresses(address[] calldata _newAddresses) internal virtual {
for (uint256 i; i < _newAddresses.length; ) {
if (isListed(_newAddresses[i])) {
revert InvalidAddresslistUpdate(_newAddresses[i]);
}
// Mark the address as listed
_addresslistCheckpoints[_newAddresses[i]].push(1);
unchecked {
++i;
}
}
_addresslistLengthCheckpoints.push(_uncheckedAdd, _newAddresses.length);
}
/// @notice Internal function to remove existing addresses from the address list.
/// @param _exitingAddresses The existing addresses to be removed.
function _removeAddresses(address[] calldata _exitingAddresses) internal virtual {
for (uint256 i; i < _exitingAddresses.length; ) {
if (!isListed(_exitingAddresses[i])) {
revert InvalidAddresslistUpdate(_exitingAddresses[i]);
}
// Mark the address as not listed
_addresslistCheckpoints[_exitingAddresses[i]].push(0);
unchecked {
++i;
}
}
_addresslistLengthCheckpoints.push(_uncheckedSub, _exitingAddresses.length);
}
/// @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.
/// https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps
uint256[48] private __gap;
}// SPDX-License-Identifier: AGPL-3.0-or-later
pragma solidity ^0.8.8;
import {CountersUpgradeable} from "@openzeppelin/contracts-upgradeable/utils/CountersUpgradeable.sol";
import {ERC165Upgradeable} from "@openzeppelin/contracts-upgradeable/utils/introspection/ERC165Upgradeable.sol";
import {IProposal} from "./IProposal.sol";
/// @title ProposalUpgradeable
/// @author Aragon X - 2022-2024
/// @notice An abstract contract containing the traits and internal functionality to create and execute proposals
/// that can be inherited by upgradeable DAO plugins.
/// @custom:security-contact [email protected]
abstract contract ProposalUpgradeable is IProposal, ERC165Upgradeable {
using CountersUpgradeable for CountersUpgradeable.Counter;
error FunctionDeprecated();
/// @notice The incremental ID for proposals and executions.
CountersUpgradeable.Counter private proposalCounter;
/// @inheritdoc IProposal
function proposalCount() public view virtual override returns (uint256) {
revert FunctionDeprecated();
}
/// @notice Creates a proposal Id.
/// @dev Uses block number and chain id to ensure more probability of uniqueness.
/// @param _salt The extra salt to help with uniqueness.
/// @return The id of the proposal.
function _createProposalId(bytes32 _salt) internal view virtual returns (uint256) {
return uint256(keccak256(abi.encode(block.chainid, block.number, address(this), _salt)));
}
/// @notice Checks if this or the parent contract supports an interface by its ID.
/// @dev In addition to the current interfaceId, also support previous version of the interfaceId
/// that did not include the following functions:
/// `createProposal`, `hasSucceeded`, `execute`, `canExecute`, `customProposalParamsABI`.
/// @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(IProposal).interfaceId ^
IProposal.createProposal.selector ^
IProposal.hasSucceeded.selector ^
IProposal.execute.selector ^
IProposal.canExecute.selector ^
IProposal.customProposalParamsABI.selector ||
_interfaceId == type(IProposal).interfaceId ||
super.supportsInterface(_interfaceId);
}
/// @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;
import {UUPSUpgradeable} from "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol";
import {IERC1822ProxiableUpgradeable} from "@openzeppelin/contracts-upgradeable/interfaces/draft-IERC1822Upgradeable.sol";
import {ERC165Upgradeable} from "@openzeppelin/contracts-upgradeable/utils/introspection/ERC165Upgradeable.sol";
import {ERC165CheckerUpgradeable} from "@openzeppelin/contracts-upgradeable/utils/introspection/ERC165CheckerUpgradeable.sol";
import {IProtocolVersion} from "../utils/versioning/IProtocolVersion.sol";
import {ProtocolVersion} from "../utils/versioning/ProtocolVersion.sol";
import {DaoAuthorizableUpgradeable} from "../permission/auth/DaoAuthorizableUpgradeable.sol";
import {IPlugin} from "./IPlugin.sol";
import {IDAO} from "../dao/IDAO.sol";
import {IExecutor, Action} from "../executors/IExecutor.sol";
/// @title PluginUUPSUpgradeable
/// @author Aragon X - 2022-2024
/// @notice An abstract, upgradeable contract to inherit from when creating a plugin being deployed via the UUPS pattern (see [ERC-1822](https://eips.ethereum.org/EIPS/eip-1822)).
/// @custom:security-contact [email protected]
abstract contract PluginUUPSUpgradeable is
IPlugin,
ERC165Upgradeable,
UUPSUpgradeable,
DaoAuthorizableUpgradeable,
ProtocolVersion
{
using ERC165CheckerUpgradeable for address;
// NOTE: When adding new state variables to the contract, the size of `_gap` has to be adapted below as well.
/// @notice Stores the current target configuration, defining the target contract and operation type for a plugin.
TargetConfig private currentTargetConfig;
/// @notice Thrown when target is of type 'IDAO', but operation is `delegateCall`.
/// @param targetConfig The target config to update it to.
error InvalidTargetConfig(TargetConfig targetConfig);
/// @notice Thrown when `delegatecall` fails.
error DelegateCallFailed();
/// @notice Thrown when initialize is called after it has already been executed.
error AlreadyInitialized();
/// @notice Emitted each time the TargetConfig is set.
event TargetSet(TargetConfig newTargetConfig);
/// @notice The ID of the permission required to call the `setTargetConfig` function.
bytes32 public constant SET_TARGET_CONFIG_PERMISSION_ID =
keccak256("SET_TARGET_CONFIG_PERMISSION");
/// @notice The ID of the permission required to call the `_authorizeUpgrade` function.
bytes32 public constant UPGRADE_PLUGIN_PERMISSION_ID = keccak256("UPGRADE_PLUGIN_PERMISSION");
/// @notice Disables the initializers on the implementation contract to prevent it from being left uninitialized.
/// @custom:oz-upgrades-unsafe-allow constructor
constructor() {
_disableInitializers();
}
/// @notice This ensures that the initialize function cannot be called during the upgrade process.
modifier onlyCallAtInitialization() {
if (_getInitializedVersion() != 0) {
revert AlreadyInitialized();
}
_;
}
/// @inheritdoc IPlugin
function pluginType() public pure override returns (PluginType) {
return PluginType.UUPS;
}
/// @notice Returns the currently set target contract.
/// @return TargetConfig The currently set target.
function getCurrentTargetConfig() public view virtual returns (TargetConfig memory) {
return currentTargetConfig;
}
/// @notice A convenient function to get current target config only if its target is not address(0), otherwise dao().
/// @return TargetConfig The current target config if its target is not address(0), otherwise returns dao()."
function getTargetConfig() public view virtual returns (TargetConfig memory) {
TargetConfig memory targetConfig = currentTargetConfig;
if (targetConfig.target == address(0)) {
targetConfig = TargetConfig({target: address(dao()), operation: Operation.Call});
}
return targetConfig;
}
/// @notice Initializes the plugin by storing the associated DAO.
/// @param _dao The DAO contract.
// solhint-disable-next-line func-name-mixedcase
function __PluginUUPSUpgradeable_init(IDAO _dao) internal virtual onlyInitializing {
__DaoAuthorizableUpgradeable_init(_dao);
}
/// @dev Sets the target to a new target (`newTarget`).
/// The caller must have the `SET_TARGET_CONFIG_PERMISSION_ID` permission.
/// @param _targetConfig The target Config containing the address and operation type.
function setTargetConfig(
TargetConfig calldata _targetConfig
) public auth(SET_TARGET_CONFIG_PERMISSION_ID) {
_setTargetConfig(_targetConfig);
}
/// @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(IPlugin).interfaceId ||
_interfaceId == type(IProtocolVersion).interfaceId ||
_interfaceId == type(IERC1822ProxiableUpgradeable).interfaceId ||
_interfaceId ==
this.setTargetConfig.selector ^
this.getTargetConfig.selector ^
this.getCurrentTargetConfig.selector ||
super.supportsInterface(_interfaceId);
}
/// @notice Returns the address of the implementation contract in the [proxy storage slot](https://eips.ethereum.org/EIPS/eip-1967) slot the [UUPS proxy](https://eips.ethereum.org/EIPS/eip-1822) is pointing to.
/// @return The address of the implementation contract.
function implementation() public view returns (address) {
return _getImplementation();
}
/// @notice Sets the target to a new target (`newTarget`).
/// @param _targetConfig The target Config containing the address and operation type.
function _setTargetConfig(TargetConfig memory _targetConfig) internal virtual {
// safety check to avoid setting dao as `target` with `delegatecall` operation
// as this would not work and cause the plugin to be bricked.
if (
_targetConfig.target.supportsInterface(type(IDAO).interfaceId) &&
_targetConfig.operation == Operation.DelegateCall
) {
revert InvalidTargetConfig(_targetConfig);
}
currentTargetConfig = _targetConfig;
emit TargetSet(_targetConfig);
}
/// @notice Forwards the actions to the currently set `target` for the execution.
/// @dev If target is not set, passes actions to the dao.
/// @param _callId Identifier for this execution.
/// @param _actions actions that will be eventually called.
/// @param _allowFailureMap Bitmap-encoded number.
/// @return execResults address of the implementation contract.
/// @return failureMap address of the implementation contract.
function _execute(
bytes32 _callId,
Action[] memory _actions,
uint256 _allowFailureMap
) internal virtual returns (bytes[] memory execResults, uint256 failureMap) {
TargetConfig memory targetConfig = getTargetConfig();
return
_execute(
targetConfig.target,
_callId,
_actions,
_allowFailureMap,
targetConfig.operation
);
}
/// @notice Forwards the actions to the `target` for the execution.
/// @param _target The address of the target contract.
/// @param _callId Identifier for this execution.
/// @param _actions actions that will be eventually called.
/// @param _allowFailureMap A bitmap allowing the 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.
/// @param _op The type of operation (`Call` or `DelegateCall`) to be used for the execution.
/// @return execResults address of the implementation contract.
/// @return failureMap address of the implementation contract.
function _execute(
address _target,
bytes32 _callId,
Action[] memory _actions,
uint256 _allowFailureMap,
Operation _op
) internal virtual returns (bytes[] memory execResults, uint256 failureMap) {
if (_op == Operation.DelegateCall) {
bool success;
bytes memory data;
// solhint-disable-next-line avoid-low-level-calls
(success, data) = _target.delegatecall(
abi.encodeCall(IExecutor.execute, (_callId, _actions, _allowFailureMap))
);
if (!success) {
if (data.length > 0) {
// solhint-disable-next-line no-inline-assembly
assembly {
let returndata_size := mload(data)
revert(add(32, data), returndata_size)
}
} else {
revert DelegateCallFailed();
}
}
(execResults, failureMap) = abi.decode(data, (bytes[], uint256));
} else {
(execResults, failureMap) = IExecutor(_target).execute(
_callId,
_actions,
_allowFailureMap
);
}
}
/// @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_PLUGIN_PERMISSION_ID` permission.
function _authorizeUpgrade(
address
)
internal
virtual
override
auth(UPGRADE_PLUGIN_PERMISSION_ID)
// solhint-disable-next-line no-empty-blocks
{
}
/// @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;
import {Action} from "../../../executors/IExecutor.sol";
/// @title IProposal
/// @author Aragon X - 2022-2024
/// @notice An interface to be implemented by DAO plugins that create and execute proposals.
/// @custom:security-contact [email protected]
interface IProposal {
/// @notice Emitted when a proposal is created.
/// @param proposalId The ID of the proposal.
/// @param creator The creator of the proposal.
/// @param startDate The start date of the proposal in seconds.
/// @param endDate The end date of the proposal in seconds.
/// @param metadata The metadata of the proposal.
/// @param actions The actions that will be executed if the proposal passes.
/// @param allowFailureMap A bitmap allowing the proposal to succeed, even if individual actions might revert.
/// If the bit at index `i` is 1, the proposal succeeds even if the `i`th action reverts.
/// A failure map value of 0 requires every action to not revert.
event ProposalCreated(
uint256 indexed proposalId,
address indexed creator,
uint64 startDate,
uint64 endDate,
bytes metadata,
Action[] actions,
uint256 allowFailureMap
);
/// @notice Emitted when a proposal is executed.
/// @param proposalId The ID of the proposal.
event ProposalExecuted(uint256 indexed proposalId);
/// @notice Creates a new proposal.
/// @param _metadata The metadata of the proposal.
/// @param _actions The actions that will be executed after the proposal passes.
/// @param _startDate The start date of the proposal.
/// @param _endDate The end date of the proposal.
/// @param _data The additional abi-encoded data to include more necessary fields.
/// @return proposalId The id of the proposal.
function createProposal(
bytes memory _metadata,
Action[] memory _actions,
uint64 _startDate,
uint64 _endDate,
bytes memory _data
) external returns (uint256 proposalId);
/// @notice Whether proposal succeeded or not.
/// @dev Note that this must not include time window checks and only make a decision based on the thresholds.
/// @param _proposalId The id of the proposal.
/// @return Returns if proposal has been succeeded or not without including time window checks.
function hasSucceeded(uint256 _proposalId) external view returns (bool);
/// @notice Executes a proposal.
/// @param _proposalId The ID of the proposal to be executed.
function execute(uint256 _proposalId) external;
/// @notice Checks if a proposal can be executed.
/// @param _proposalId The ID of the proposal to be checked.
/// @return True if the proposal can be executed, false otherwise.
function canExecute(uint256 _proposalId) external view returns (bool);
/// @notice The human-readable abi format for extra params included in `data` of `createProposal`.
/// @dev Used for UI to easily detect what extra params the contract expects.
/// @return ABI of params in `data` of `createProposal`.
function customProposalParamsABI() external view returns (string memory);
/// @notice Returns the proposal count which determines the next proposal ID.
/// @dev This function is deprecated but remains in the interface for backward compatibility.
/// It now reverts to prevent ambiguity.
/// @return The proposal count.
function proposalCount() external view returns (uint256);
}// 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;
import {ERC165Upgradeable} from "@openzeppelin/contracts-upgradeable/utils/introspection/ERC165Upgradeable.sol";
import {DaoAuthorizableUpgradeable} from "../../permission/auth/DaoAuthorizableUpgradeable.sol";
/// @title MetadataExtensionUpgradeable
/// @author Aragon X - 2024
/// @notice An abstract, upgradeable contract for managing and retrieving metadata associated with a plugin.
/// @dev Due to the requirements that already existing upgradeable plugins need to start inheritting from this,
/// we're required to use hardcoded/specific slots for storage instead of sequential slots with gaps.
/// @custom:security-contact [email protected]
abstract contract MetadataExtensionUpgradeable is ERC165Upgradeable, DaoAuthorizableUpgradeable {
/// @notice The ID of the permission required to call the `setMetadata` function.
bytes32 public constant SET_METADATA_PERMISSION_ID = keccak256("SET_METADATA_PERMISSION");
// keccak256(abi.encode(uint256(keccak256("osx-commons.storage.MetadataExtension")) - 1)) & ~bytes32(uint256(0xff))
// solhint-disable-next-line const-name-snakecase
bytes32 private constant MetadataExtensionStorageLocation =
0x47ff9796f72d439c6e5c30a24b9fad985a00c85a9f2258074c400a94f8746b00;
/// @notice Emitted when metadata is updated.
event MetadataSet(bytes metadata);
struct MetadataExtensionStorage {
bytes metadata;
}
function _getMetadataExtensionStorage()
private
pure
returns (MetadataExtensionStorage storage $)
{
// solhint-disable-next-line no-inline-assembly
assembly {
$.slot := MetadataExtensionStorageLocation
}
}
/// @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 == this.setMetadata.selector ^ this.getMetadata.selector ||
super.supportsInterface(_interfaceId);
}
/// @notice Allows to update only the metadata.
/// @param _metadata The utf8 bytes of a content addressing cid that stores plugin's information.
function setMetadata(bytes calldata _metadata) public virtual auth(SET_METADATA_PERMISSION_ID) {
_setMetadata(_metadata);
}
/// @notice Returns the metadata currently applied.
/// @return The The utf8 bytes of a content addressing cid.
function getMetadata() public view returns (bytes memory) {
MetadataExtensionStorage storage $ = _getMetadataExtensionStorage();
return $.metadata;
}
/// @notice Internal function to update metadata.
/// @param _metadata The utf8 bytes of a content addressing cid that stores contract's information.
function _setMetadata(bytes memory _metadata) internal virtual {
MetadataExtensionStorage storage $ = _getMetadataExtensionStorage();
$.metadata = _metadata;
emit MetadataSet(_metadata);
}
}// SPDX-License-Identifier: AGPL-3.0-or-later pragma solidity ^0.8.8; /// @title IMultisig /// @author Aragon X - 2022-2024 /// @notice An interface for an on-chain multisig governance plugin in which a proposal passes /// if X out of Y approvals are met. /// @custom:security-contact [email protected] interface IMultisig { /// @notice Adds new members to the address list. Previously, it checks if the new address /// list length would be greater than `type(uint16).max`, the maximal number of approvals. /// @param _members The addresses of the members to be added. function addAddresses(address[] calldata _members) external; /// @notice Removes existing members from the address list. Previously, it checks if the /// new address list length is at least as long as the minimum approvals parameter requires. /// Note that `minApprovals` is must be at least 1 so the address list cannot become empty. /// @param _members The addresses of the members to be removed. function removeAddresses(address[] calldata _members) external; /// @notice Records an approval for a proposal and, if specified, attempts execution if certain conditions are met. /// @param _proposalId The ID of the proposal to approve. /// @param _tryExecution If `true`, attempts execution of the proposal after approval, without reverting on failure. function approve(uint256 _proposalId, bool _tryExecution) external; /// @notice Checks if an account is eligible to participate in a proposal vote. /// Confirms that the proposal is open, the account is listed as a member, /// and the account has not previously voted or approved this proposal. /// @param _proposalId The ID of the proposal. /// @param _account The address of the account to check. /// @return True if the account is eligible to vote. function canApprove(uint256 _proposalId, address _account) external view returns (bool); /// @notice Checks if a proposal can be executed. /// @param _proposalId The ID of the proposal to be checked. /// @return True if the proposal can be executed, false otherwise. function canExecute(uint256 _proposalId) external view returns (bool); /// @notice Returns whether the account has approved the proposal. /// @param _proposalId The ID of the proposal. /// @param _account The account address to be checked. /// @return The vote option cast by a voter for a certain proposal. function hasApproved(uint256 _proposalId, address _account) external view returns (bool); /// @notice Executes a proposal if all execution conditions are met. /// @param _proposalId The ID of the proposal to be executed. function execute(uint256 _proposalId) external; }
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)
pragma solidity ^0.8.0;
/**
* @dev Interface of the ERC165 standard, as defined in the
* https://eips.ethereum.org/EIPS/eip-165[EIP].
*
* Implementers can declare support of contract interfaces, which can then be
* queried by others ({ERC165Checker}).
*
* For an implementation, see {ERC165}.
*/
interface IERC165 {
/**
* @dev Returns true if this contract implements the interface defined by
* `interfaceId`. See the corresponding
* https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]
* to learn more about how these ids are created.
*
* This function call must use less than 30 000 gas.
*/
function supportsInterface(bytes4 interfaceId) external view returns (bool);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.6.0) (proxy/Proxy.sol)
pragma solidity ^0.8.0;
/**
* @dev This abstract contract provides a fallback function that delegates all calls to another contract using the EVM
* instruction `delegatecall`. We refer to the second contract as the _implementation_ behind the proxy, and it has to
* be specified by overriding the virtual {_implementation} function.
*
* Additionally, delegation to the implementation can be triggered manually through the {_fallback} function, or to a
* different contract through the {_delegate} function.
*
* The success and return data of the delegated call will be returned back to the caller of the proxy.
*/
abstract contract Proxy {
/**
* @dev Delegates the current call to `implementation`.
*
* This function does not return to its internal call site, it will return directly to the external caller.
*/
function _delegate(address implementation) internal virtual {
assembly {
// Copy msg.data. We take full control of memory in this inline assembly
// block because it will not return to Solidity code. We overwrite the
// Solidity scratch pad at memory position 0.
calldatacopy(0, 0, calldatasize())
// Call the implementation.
// out and outsize are 0 because we don't know the size yet.
let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0)
// Copy the returned data.
returndatacopy(0, 0, returndatasize())
switch result
// delegatecall returns 0 on error.
case 0 {
revert(0, returndatasize())
}
default {
return(0, returndatasize())
}
}
}
/**
* @dev This is a virtual function that should be overridden so it returns the address to which the fallback function
* and {_fallback} should delegate.
*/
function _implementation() internal view virtual returns (address);
/**
* @dev Delegates the current call to the address returned by `_implementation()`.
*
* This function does not return to its internal call site, it will return directly to the external caller.
*/
function _fallback() internal virtual {
_beforeFallback();
_delegate(_implementation());
}
/**
* @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if no other
* function in the contract matches the call data.
*/
fallback() external payable virtual {
_fallback();
}
/**
* @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if call data
* is empty.
*/
receive() external payable virtual {
_fallback();
}
/**
* @dev Hook that is called before falling back to the implementation. Can happen as part of a manual `_fallback`
* call, or as part of the Solidity `fallback` or `receive` functions.
*
* If overridden should call `super._beforeFallback()`.
*/
function _beforeFallback() internal virtual {}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (proxy/ERC1967/ERC1967Upgrade.sol)
pragma solidity ^0.8.2;
import "../beacon/IBeacon.sol";
import "../../interfaces/IERC1967.sol";
import "../../interfaces/draft-IERC1822.sol";
import "../../utils/Address.sol";
import "../../utils/StorageSlot.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 ERC1967Upgrade is IERC1967 {
// This is the keccak-256 hash of "eip1967.proxy.rollback" subtracted by 1
bytes32 private constant _ROLLBACK_SLOT = 0x4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd9143;
/**
* @dev Storage slot with the address of the current implementation.
* This is the keccak-256 hash of "eip1967.proxy.implementation" subtracted by 1, and is
* validated in the constructor.
*/
bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;
/**
* @dev Returns the current implementation address.
*/
function _getImplementation() internal view returns (address) {
return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;
}
/**
* @dev Stores a new address in the EIP1967 implementation slot.
*/
function _setImplementation(address newImplementation) private {
require(Address.isContract(newImplementation), "ERC1967: new implementation is not a contract");
StorageSlot.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) {
Address.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 (StorageSlot.getBooleanSlot(_ROLLBACK_SLOT).value) {
_setImplementation(newImplementation);
} else {
try IERC1822Proxiable(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 StorageSlot.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");
StorageSlot.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 StorageSlot.getAddressSlot(_BEACON_SLOT).value;
}
/**
* @dev Stores a new beacon in the EIP1967 beacon slot.
*/
function _setBeacon(address newBeacon) private {
require(Address.isContract(newBeacon), "ERC1967: new beacon is not a contract");
require(
Address.isContract(IBeacon(newBeacon).implementation()),
"ERC1967: beacon implementation is not a contract"
);
StorageSlot.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) {
Address.functionDelegateCall(IBeacon(newBeacon).implementation(), data);
}
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (utils/Checkpoints.sol)
// This file was procedurally generated from scripts/generate/templates/Checkpoints.js.
pragma solidity ^0.8.0;
import "./math/MathUpgradeable.sol";
import "./math/SafeCastUpgradeable.sol";
/**
* @dev This library defines the `History` struct, for checkpointing values as they change at different points in
* time, and later looking up past values by block number. See {Votes} as an example.
*
* To create a history of checkpoints define a variable type `Checkpoints.History` in your contract, and store a new
* checkpoint for the current transaction block using the {push} function.
*
* _Available since v4.5._
*/
library CheckpointsUpgradeable {
struct History {
Checkpoint[] _checkpoints;
}
struct Checkpoint {
uint32 _blockNumber;
uint224 _value;
}
/**
* @dev Returns the value at a given block number. If a checkpoint is not available at that block, the closest one
* before it is returned, or zero otherwise. Because the number returned corresponds to that at the end of the
* block, the requested block number must be in the past, excluding the current block.
*/
function getAtBlock(History storage self, uint256 blockNumber) internal view returns (uint256) {
require(blockNumber < block.number, "Checkpoints: block not yet mined");
uint32 key = SafeCastUpgradeable.toUint32(blockNumber);
uint256 len = self._checkpoints.length;
uint256 pos = _upperBinaryLookup(self._checkpoints, key, 0, len);
return pos == 0 ? 0 : _unsafeAccess(self._checkpoints, pos - 1)._value;
}
/**
* @dev Returns the value at a given block number. If a checkpoint is not available at that block, the closest one
* before it is returned, or zero otherwise. Similar to {upperLookup} but optimized for the case when the searched
* checkpoint is probably "recent", defined as being among the last sqrt(N) checkpoints where N is the number of
* checkpoints.
*/
function getAtProbablyRecentBlock(History storage self, uint256 blockNumber) internal view returns (uint256) {
require(blockNumber < block.number, "Checkpoints: block not yet mined");
uint32 key = SafeCastUpgradeable.toUint32(blockNumber);
uint256 len = self._checkpoints.length;
uint256 low = 0;
uint256 high = len;
if (len > 5) {
uint256 mid = len - MathUpgradeable.sqrt(len);
if (key < _unsafeAccess(self._checkpoints, mid)._blockNumber) {
high = mid;
} else {
low = mid + 1;
}
}
uint256 pos = _upperBinaryLookup(self._checkpoints, key, low, high);
return pos == 0 ? 0 : _unsafeAccess(self._checkpoints, pos - 1)._value;
}
/**
* @dev Pushes a value onto a History so that it is stored as the checkpoint for the current block.
*
* Returns previous value and new value.
*/
function push(History storage self, uint256 value) internal returns (uint256, uint256) {
return _insert(self._checkpoints, SafeCastUpgradeable.toUint32(block.number), SafeCastUpgradeable.toUint224(value));
}
/**
* @dev Pushes a value onto a History, by updating the latest value using binary operation `op`. The new value will
* be set to `op(latest, delta)`.
*
* Returns previous value and new value.
*/
function push(
History storage self,
function(uint256, uint256) view returns (uint256) op,
uint256 delta
) internal returns (uint256, uint256) {
return push(self, op(latest(self), delta));
}
/**
* @dev Returns the value in the most recent checkpoint, or zero if there are no checkpoints.
*/
function latest(History storage self) internal view returns (uint224) {
uint256 pos = self._checkpoints.length;
return pos == 0 ? 0 : _unsafeAccess(self._checkpoints, pos - 1)._value;
}
/**
* @dev Returns whether there is a checkpoint in the structure (i.e. it is not empty), and if so the key and value
* in the most recent checkpoint.
*/
function latestCheckpoint(
History storage self
) internal view returns (bool exists, uint32 _blockNumber, uint224 _value) {
uint256 pos = self._checkpoints.length;
if (pos == 0) {
return (false, 0, 0);
} else {
Checkpoint memory ckpt = _unsafeAccess(self._checkpoints, pos - 1);
return (true, ckpt._blockNumber, ckpt._value);
}
}
/**
* @dev Returns the number of checkpoint.
*/
function length(History storage self) internal view returns (uint256) {
return self._checkpoints.length;
}
/**
* @dev Pushes a (`key`, `value`) pair into an ordered list of checkpoints, either by inserting a new checkpoint,
* or by updating the last one.
*/
function _insert(Checkpoint[] storage self, uint32 key, uint224 value) private returns (uint224, uint224) {
uint256 pos = self.length;
if (pos > 0) {
// Copying to memory is important here.
Checkpoint memory last = _unsafeAccess(self, pos - 1);
// Checkpoint keys must be non-decreasing.
require(last._blockNumber <= key, "Checkpoint: decreasing keys");
// Update or push new checkpoint
if (last._blockNumber == key) {
_unsafeAccess(self, pos - 1)._value = value;
} else {
self.push(Checkpoint({_blockNumber: key, _value: value}));
}
return (last._value, value);
} else {
self.push(Checkpoint({_blockNumber: key, _value: value}));
return (0, value);
}
}
/**
* @dev Return the index of the last (most recent) checkpoint with key lower or equal than the search key, or `high` if there is none.
* `low` and `high` define a section where to do the search, with inclusive `low` and exclusive `high`.
*
* WARNING: `high` should not be greater than the array's length.
*/
function _upperBinaryLookup(
Checkpoint[] storage self,
uint32 key,
uint256 low,
uint256 high
) private view returns (uint256) {
while (low < high) {
uint256 mid = MathUpgradeable.average(low, high);
if (_unsafeAccess(self, mid)._blockNumber > key) {
high = mid;
} else {
low = mid + 1;
}
}
return high;
}
/**
* @dev Return the index of the first (oldest) checkpoint with key is greater or equal than the search key, or `high` if there is none.
* `low` and `high` define a section where to do the search, with inclusive `low` and exclusive `high`.
*
* WARNING: `high` should not be greater than the array's length.
*/
function _lowerBinaryLookup(
Checkpoint[] storage self,
uint32 key,
uint256 low,
uint256 high
) private view returns (uint256) {
while (low < high) {
uint256 mid = MathUpgradeable.average(low, high);
if (_unsafeAccess(self, mid)._blockNumber < key) {
low = mid + 1;
} else {
high = mid;
}
}
return high;
}
/**
* @dev Access an element of the array without performing bounds check. The position is assumed to be within bounds.
*/
function _unsafeAccess(Checkpoint[] storage self, uint256 pos) private pure returns (Checkpoint storage result) {
assembly {
mstore(0, self.slot)
result.slot := add(keccak256(0, 0x20), pos)
}
}
struct Trace224 {
Checkpoint224[] _checkpoints;
}
struct Checkpoint224 {
uint32 _key;
uint224 _value;
}
/**
* @dev Pushes a (`key`, `value`) pair into a Trace224 so that it is stored as the checkpoint.
*
* Returns previous value and new value.
*/
function push(Trace224 storage self, uint32 key, uint224 value) internal returns (uint224, uint224) {
return _insert(self._checkpoints, key, value);
}
/**
* @dev Returns the value in the first (oldest) checkpoint with key greater or equal than the search key, or zero if there is none.
*/
function lowerLookup(Trace224 storage self, uint32 key) internal view returns (uint224) {
uint256 len = self._checkpoints.length;
uint256 pos = _lowerBinaryLookup(self._checkpoints, key, 0, len);
return pos == len ? 0 : _unsafeAccess(self._checkpoints, pos)._value;
}
/**
* @dev Returns the value in the last (most recent) checkpoint with key lower or equal than the search key, or zero if there is none.
*/
function upperLookup(Trace224 storage self, uint32 key) internal view returns (uint224) {
uint256 len = self._checkpoints.length;
uint256 pos = _upperBinaryLookup(self._checkpoints, key, 0, len);
return pos == 0 ? 0 : _unsafeAccess(self._checkpoints, pos - 1)._value;
}
/**
* @dev Returns the value in the last (most recent) checkpoint with key lower or equal than the search key, or zero if there is none.
*
* NOTE: This is a variant of {upperLookup} that is optimised to find "recent" checkpoint (checkpoints with high keys).
*/
function upperLookupRecent(Trace224 storage self, uint32 key) internal view returns (uint224) {
uint256 len = self._checkpoints.length;
uint256 low = 0;
uint256 high = len;
if (len > 5) {
uint256 mid = len - MathUpgradeable.sqrt(len);
if (key < _unsafeAccess(self._checkpoints, mid)._key) {
high = mid;
} else {
low = mid + 1;
}
}
uint256 pos = _upperBinaryLookup(self._checkpoints, key, low, high);
return pos == 0 ? 0 : _unsafeAccess(self._checkpoints, pos - 1)._value;
}
/**
* @dev Returns the value in the most recent checkpoint, or zero if there are no checkpoints.
*/
function latest(Trace224 storage self) internal view returns (uint224) {
uint256 pos = self._checkpoints.length;
return pos == 0 ? 0 : _unsafeAccess(self._checkpoints, pos - 1)._value;
}
/**
* @dev Returns whether there is a checkpoint in the structure (i.e. it is not empty), and if so the key and value
* in the most recent checkpoint.
*/
function latestCheckpoint(Trace224 storage self) internal view returns (bool exists, uint32 _key, uint224 _value) {
uint256 pos = self._checkpoints.length;
if (pos == 0) {
return (false, 0, 0);
} else {
Checkpoint224 memory ckpt = _unsafeAccess(self._checkpoints, pos - 1);
return (true, ckpt._key, ckpt._value);
}
}
/**
* @dev Returns the number of checkpoint.
*/
function length(Trace224 storage self) internal view returns (uint256) {
return self._checkpoints.length;
}
/**
* @dev Pushes a (`key`, `value`) pair into an ordered list of checkpoints, either by inserting a new checkpoint,
* or by updating the last one.
*/
function _insert(Checkpoint224[] storage self, uint32 key, uint224 value) private returns (uint224, uint224) {
uint256 pos = self.length;
if (pos > 0) {
// Copying to memory is important here.
Checkpoint224 memory last = _unsafeAccess(self, pos - 1);
// Checkpoint keys must be non-decreasing.
require(last._key <= key, "Checkpoint: decreasing keys");
// Update or push new checkpoint
if (last._key == key) {
_unsafeAccess(self, pos - 1)._value = value;
} else {
self.push(Checkpoint224({_key: key, _value: value}));
}
return (last._value, value);
} else {
self.push(Checkpoint224({_key: key, _value: value}));
return (0, value);
}
}
/**
* @dev Return the index of the last (most recent) checkpoint with key lower or equal than the search key, or `high` if there is none.
* `low` and `high` define a section where to do the search, with inclusive `low` and exclusive `high`.
*
* WARNING: `high` should not be greater than the array's length.
*/
function _upperBinaryLookup(
Checkpoint224[] storage self,
uint32 key,
uint256 low,
uint256 high
) private view returns (uint256) {
while (low < high) {
uint256 mid = MathUpgradeable.average(low, high);
if (_unsafeAccess(self, mid)._key > key) {
high = mid;
} else {
low = mid + 1;
}
}
return high;
}
/**
* @dev Return the index of the first (oldest) checkpoint with key is greater or equal than the search key, or `high` if there is none.
* `low` and `high` define a section where to do the search, with inclusive `low` and exclusive `high`.
*
* WARNING: `high` should not be greater than the array's length.
*/
function _lowerBinaryLookup(
Checkpoint224[] storage self,
uint32 key,
uint256 low,
uint256 high
) private view returns (uint256) {
while (low < high) {
uint256 mid = MathUpgradeable.average(low, high);
if (_unsafeAccess(self, mid)._key < key) {
low = mid + 1;
} else {
high = mid;
}
}
return high;
}
/**
* @dev Access an element of the array without performing bounds check. The position is assumed to be within bounds.
*/
function _unsafeAccess(
Checkpoint224[] storage self,
uint256 pos
) private pure returns (Checkpoint224 storage result) {
assembly {
mstore(0, self.slot)
result.slot := add(keccak256(0, 0x20), pos)
}
}
struct Trace160 {
Checkpoint160[] _checkpoints;
}
struct Checkpoint160 {
uint96 _key;
uint160 _value;
}
/**
* @dev Pushes a (`key`, `value`) pair into a Trace160 so that it is stored as the checkpoint.
*
* Returns previous value and new value.
*/
function push(Trace160 storage self, uint96 key, uint160 value) internal returns (uint160, uint160) {
return _insert(self._checkpoints, key, value);
}
/**
* @dev Returns the value in the first (oldest) checkpoint with key greater or equal than the search key, or zero if there is none.
*/
function lowerLookup(Trace160 storage self, uint96 key) internal view returns (uint160) {
uint256 len = self._checkpoints.length;
uint256 pos = _lowerBinaryLookup(self._checkpoints, key, 0, len);
return pos == len ? 0 : _unsafeAccess(self._checkpoints, pos)._value;
}
/**
* @dev Returns the value in the last (most recent) checkpoint with key lower or equal than the search key, or zero if there is none.
*/
function upperLookup(Trace160 storage self, uint96 key) internal view returns (uint160) {
uint256 len = self._checkpoints.length;
uint256 pos = _upperBinaryLookup(self._checkpoints, key, 0, len);
return pos == 0 ? 0 : _unsafeAccess(self._checkpoints, pos - 1)._value;
}
/**
* @dev Returns the value in the last (most recent) checkpoint with key lower or equal than the search key, or zero if there is none.
*
* NOTE: This is a variant of {upperLookup} that is optimised to find "recent" checkpoint (checkpoints with high keys).
*/
function upperLookupRecent(Trace160 storage self, uint96 key) internal view returns (uint160) {
uint256 len = self._checkpoints.length;
uint256 low = 0;
uint256 high = len;
if (len > 5) {
uint256 mid = len - MathUpgradeable.sqrt(len);
if (key < _unsafeAccess(self._checkpoints, mid)._key) {
high = mid;
} else {
low = mid + 1;
}
}
uint256 pos = _upperBinaryLookup(self._checkpoints, key, low, high);
return pos == 0 ? 0 : _unsafeAccess(self._checkpoints, pos - 1)._value;
}
/**
* @dev Returns the value in the most recent checkpoint, or zero if there are no checkpoints.
*/
function latest(Trace160 storage self) internal view returns (uint160) {
uint256 pos = self._checkpoints.length;
return pos == 0 ? 0 : _unsafeAccess(self._checkpoints, pos - 1)._value;
}
/**
* @dev Returns whether there is a checkpoint in the structure (i.e. it is not empty), and if so the key and value
* in the most recent checkpoint.
*/
function latestCheckpoint(Trace160 storage self) internal view returns (bool exists, uint96 _key, uint160 _value) {
uint256 pos = self._checkpoints.length;
if (pos == 0) {
return (false, 0, 0);
} else {
Checkpoint160 memory ckpt = _unsafeAccess(self._checkpoints, pos - 1);
return (true, ckpt._key, ckpt._value);
}
}
/**
* @dev Returns the number of checkpoint.
*/
function length(Trace160 storage self) internal view returns (uint256) {
return self._checkpoints.length;
}
/**
* @dev Pushes a (`key`, `value`) pair into an ordered list of checkpoints, either by inserting a new checkpoint,
* or by updating the last one.
*/
function _insert(Checkpoint160[] storage self, uint96 key, uint160 value) private returns (uint160, uint160) {
uint256 pos = self.length;
if (pos > 0) {
// Copying to memory is important here.
Checkpoint160 memory last = _unsafeAccess(self, pos - 1);
// Checkpoint keys must be non-decreasing.
require(last._key <= key, "Checkpoint: decreasing keys");
// Update or push new checkpoint
if (last._key == key) {
_unsafeAccess(self, pos - 1)._value = value;
} else {
self.push(Checkpoint160({_key: key, _value: value}));
}
return (last._value, value);
} else {
self.push(Checkpoint160({_key: key, _value: value}));
return (0, value);
}
}
/**
* @dev Return the index of the last (most recent) checkpoint with key lower or equal than the search key, or `high` if there is none.
* `low` and `high` define a section where to do the search, with inclusive `low` and exclusive `high`.
*
* WARNING: `high` should not be greater than the array's length.
*/
function _upperBinaryLookup(
Checkpoint160[] storage self,
uint96 key,
uint256 low,
uint256 high
) private view returns (uint256) {
while (low < high) {
uint256 mid = MathUpgradeable.average(low, high);
if (_unsafeAccess(self, mid)._key > key) {
high = mid;
} else {
low = mid + 1;
}
}
return high;
}
/**
* @dev Return the index of the first (oldest) checkpoint with key is greater or equal than the search key, or `high` if there is none.
* `low` and `high` define a section where to do the search, with inclusive `low` and exclusive `high`.
*
* WARNING: `high` should not be greater than the array's length.
*/
function _lowerBinaryLookup(
Checkpoint160[] storage self,
uint96 key,
uint256 low,
uint256 high
) private view returns (uint256) {
while (low < high) {
uint256 mid = MathUpgradeable.average(low, high);
if (_unsafeAccess(self, mid)._key < key) {
low = mid + 1;
} else {
high = mid;
}
}
return high;
}
/**
* @dev Access an element of the array without performing bounds check. The position is assumed to be within bounds.
*/
function _unsafeAccess(
Checkpoint160[] storage self,
uint256 pos
) private pure returns (Checkpoint160 storage result) {
assembly {
mstore(0, self.slot)
result.slot := add(keccak256(0, 0x20), pos)
}
}
}// SPDX-License-Identifier: AGPL-3.0-or-later pragma solidity ^0.8.8; /// @notice Adds two unsigned integers without checking the result for overflow errors (using safe math). /// @param a The first summand. /// @param b The second summand. /// @return The sum. /// @custom:security-contact [email protected] function _uncheckedAdd(uint256 a, uint256 b) pure returns (uint256) { unchecked { return a + b; } } /// @notice Subtracts two unsigned integers without checking the result for overflow errors (using safe math). /// @param a The minuend. /// @param b The subtrahend. /// @return The difference. /// @custom:security-contact [email protected] function _uncheckedSub(uint256 a, uint256 b) pure returns (uint256) { unchecked { return a - b; } }
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/Counters.sol)
pragma solidity ^0.8.0;
/**
* @title Counters
* @author Matt Condon (@shrugs)
* @dev Provides counters that can only be incremented, decremented or reset. This can be used e.g. to track the number
* of elements in a mapping, issuing ERC721 ids, or counting request ids.
*
* Include with `using Counters for Counters.Counter;`
*/
library CountersUpgradeable {
struct Counter {
// This variable should never be directly accessed by users of the library: interactions must be restricted to
// the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add
// this feature: see https://github.com/ethereum/solidity/issues/4637
uint256 _value; // default: 0
}
function current(Counter storage counter) internal view returns (uint256) {
return counter._value;
}
function increment(Counter storage counter) internal {
unchecked {
counter._value += 1;
}
}
function decrement(Counter storage counter) internal {
uint256 value = counter._value;
require(value > 0, "Counter: decrement overflow");
unchecked {
counter._value = value - 1;
}
}
function reset(Counter storage counter) internal {
counter._value = 0;
}
}// 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.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.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) (utils/introspection/ERC165Checker.sol)
pragma solidity ^0.8.0;
import "./IERC165Upgradeable.sol";
/**
* @dev Library used to query support of an interface declared via {IERC165}.
*
* Note that these functions return the actual result of the query: they do not
* `revert` if an interface is not supported. It is up to the caller to decide
* what to do in these cases.
*/
library ERC165CheckerUpgradeable {
// As per the EIP-165 spec, no interface should ever match 0xffffffff
bytes4 private constant _INTERFACE_ID_INVALID = 0xffffffff;
/**
* @dev Returns true if `account` supports the {IERC165} interface.
*/
function supportsERC165(address account) internal view returns (bool) {
// Any contract that implements ERC165 must explicitly indicate support of
// InterfaceId_ERC165 and explicitly indicate non-support of InterfaceId_Invalid
return
supportsERC165InterfaceUnchecked(account, type(IERC165Upgradeable).interfaceId) &&
!supportsERC165InterfaceUnchecked(account, _INTERFACE_ID_INVALID);
}
/**
* @dev Returns true if `account` supports the interface defined by
* `interfaceId`. Support for {IERC165} itself is queried automatically.
*
* See {IERC165-supportsInterface}.
*/
function supportsInterface(address account, bytes4 interfaceId) internal view returns (bool) {
// query support of both ERC165 as per the spec and support of _interfaceId
return supportsERC165(account) && supportsERC165InterfaceUnchecked(account, interfaceId);
}
/**
* @dev Returns a boolean array where each value corresponds to the
* interfaces passed in and whether they're supported or not. This allows
* you to batch check interfaces for a contract where your expectation
* is that some interfaces may not be supported.
*
* See {IERC165-supportsInterface}.
*
* _Available since v3.4._
*/
function getSupportedInterfaces(
address account,
bytes4[] memory interfaceIds
) internal view returns (bool[] memory) {
// an array of booleans corresponding to interfaceIds and whether they're supported or not
bool[] memory interfaceIdsSupported = new bool[](interfaceIds.length);
// query support of ERC165 itself
if (supportsERC165(account)) {
// query support of each interface in interfaceIds
for (uint256 i = 0; i < interfaceIds.length; i++) {
interfaceIdsSupported[i] = supportsERC165InterfaceUnchecked(account, interfaceIds[i]);
}
}
return interfaceIdsSupported;
}
/**
* @dev Returns true if `account` supports all the interfaces defined in
* `interfaceIds`. Support for {IERC165} itself is queried automatically.
*
* Batch-querying can lead to gas savings by skipping repeated checks for
* {IERC165} support.
*
* See {IERC165-supportsInterface}.
*/
function supportsAllInterfaces(address account, bytes4[] memory interfaceIds) internal view returns (bool) {
// query support of ERC165 itself
if (!supportsERC165(account)) {
return false;
}
// query support of each interface in interfaceIds
for (uint256 i = 0; i < interfaceIds.length; i++) {
if (!supportsERC165InterfaceUnchecked(account, interfaceIds[i])) {
return false;
}
}
// all interfaces supported
return true;
}
/**
* @notice Query if a contract implements an interface, does not check ERC165 support
* @param account The address of the contract to query for support of an interface
* @param interfaceId The interface identifier, as specified in ERC-165
* @return true if the contract at account indicates support of the interface with
* identifier interfaceId, false otherwise
* @dev Assumes that account contains a contract that supports ERC165, otherwise
* the behavior of this method is undefined. This precondition can be checked
* with {supportsERC165}.
*
* Some precompiled contracts will falsely indicate support for a given interface, so caution
* should be exercised when using this function.
*
* Interface identification is specified in ERC-165.
*/
function supportsERC165InterfaceUnchecked(address account, bytes4 interfaceId) internal view returns (bool) {
// prepare call
bytes memory encodedParams = abi.encodeWithSelector(IERC165Upgradeable.supportsInterface.selector, interfaceId);
// perform static call
bool success;
uint256 returnSize;
uint256 returnValue;
assembly {
success := staticcall(30000, account, add(encodedParams, 0x20), mload(encodedParams), 0x00, 0x20)
returnSize := returndatasize()
returnValue := mload(0x00)
}
return success && returnSize >= 0x20 && returnValue > 0;
}
}// SPDX-License-Identifier: AGPL-3.0-or-later
pragma solidity ^0.8.8;
import {ContextUpgradeable} from "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol";
import {IDAO} from "../../dao/IDAO.sol";
import {_auth} from "./auth.sol";
/// @title DaoAuthorizableUpgradeable
/// @author Aragon X - 2022-2023
/// @notice An abstract contract providing a meta-transaction compatible modifier for upgradeable or cloneable contracts to authorize function calls through an associated DAO.
/// @dev Make sure to call `__DaoAuthorizableUpgradeable_init` during initialization of the inheriting contract.
/// @custom:security-contact [email protected]
abstract contract DaoAuthorizableUpgradeable is ContextUpgradeable {
/// @notice The associated DAO managing the permissions of inheriting contracts.
IDAO private dao_;
/// @notice Initializes the contract by setting the associated DAO.
/// @param _dao The associated DAO address.
// solhint-disable-next-line func-name-mixedcase
function __DaoAuthorizableUpgradeable_init(IDAO _dao) internal onlyInitializing {
dao_ = _dao;
}
/// @notice Returns the DAO contract.
/// @return The DAO contract.
function dao() public view returns (IDAO) {
return dao_;
}
/// @notice A modifier to make functions on inheriting contracts authorized. Permissions to call the function are checked through the associated DAO's permission manager.
/// @param _permissionId The permission identifier required to call the method this modifier is applied to.
modifier auth(bytes32 _permissionId) {
_auth(dao_, address(this), _msgSender(), _permissionId, _msgData());
_;
}
/// @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: 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 IBeacon {
/**
* @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 IERC1967 {
/**
* @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.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 IERC1822Proxiable {
/**
* @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) (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 StorageSlot {
struct AddressSlot {
address value;
}
struct BooleanSlot {
bool value;
}
struct Bytes32Slot {
bytes32 value;
}
struct Uint256Slot {
uint256 value;
}
struct StringSlot {
string value;
}
struct BytesSlot {
bytes value;
}
/**
* @dev Returns an `AddressSlot` with member `value` located at `slot`.
*/
function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) {
/// @solidity memory-safe-assembly
assembly {
r.slot := slot
}
}
/**
* @dev Returns an `BooleanSlot` with member `value` located at `slot`.
*/
function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) {
/// @solidity memory-safe-assembly
assembly {
r.slot := slot
}
}
/**
* @dev Returns an `Bytes32Slot` with member `value` located at `slot`.
*/
function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) {
/// @solidity memory-safe-assembly
assembly {
r.slot := slot
}
}
/**
* @dev Returns an `Uint256Slot` with member `value` located at `slot`.
*/
function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) {
/// @solidity memory-safe-assembly
assembly {
r.slot := slot
}
}
/**
* @dev Returns an `StringSlot` with member `value` located at `slot`.
*/
function getStringSlot(bytes32 slot) internal pure returns (StringSlot storage r) {
/// @solidity memory-safe-assembly
assembly {
r.slot := slot
}
}
/**
* @dev Returns an `StringSlot` representation of the string storage pointer `store`.
*/
function getStringSlot(string storage store) internal pure returns (StringSlot storage r) {
/// @solidity memory-safe-assembly
assembly {
r.slot := store.slot
}
}
/**
* @dev Returns an `BytesSlot` with member `value` located at `slot`.
*/
function getBytesSlot(bytes32 slot) internal pure returns (BytesSlot storage r) {
/// @solidity memory-safe-assembly
assembly {
r.slot := slot
}
}
/**
* @dev Returns an `BytesSlot` representation of the bytes storage pointer `store`.
*/
function getBytesSlot(bytes storage store) internal pure returns (BytesSlot storage r) {
/// @solidity memory-safe-assembly
assembly {
r.slot := store.slot
}
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (utils/math/Math.sol)
pragma solidity ^0.8.0;
/**
* @dev Standard math utilities missing in the Solidity language.
*/
library MathUpgradeable {
enum Rounding {
Down, // Toward negative infinity
Up, // Toward infinity
Zero // Toward zero
}
/**
* @dev Returns the largest of two numbers.
*/
function max(uint256 a, uint256 b) internal pure returns (uint256) {
return a > b ? a : b;
}
/**
* @dev Returns the smallest of two numbers.
*/
function min(uint256 a, uint256 b) internal pure returns (uint256) {
return a < b ? a : b;
}
/**
* @dev Returns the average of two numbers. The result is rounded towards
* zero.
*/
function average(uint256 a, uint256 b) internal pure returns (uint256) {
// (a + b) / 2 can overflow.
return (a & b) + (a ^ b) / 2;
}
/**
* @dev Returns the ceiling of the division of two numbers.
*
* This differs from standard division with `/` in that it rounds up instead
* of rounding down.
*/
function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {
// (a + b - 1) / b can overflow on addition, so we distribute.
return a == 0 ? 0 : (a - 1) / b + 1;
}
/**
* @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0
* @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv)
* with further edits by Uniswap Labs also under MIT license.
*/
function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) {
unchecked {
// 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use
// use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256
// variables such that product = prod1 * 2^256 + prod0.
uint256 prod0; // Least significant 256 bits of the product
uint256 prod1; // Most significant 256 bits of the product
assembly {
let mm := mulmod(x, y, not(0))
prod0 := mul(x, y)
prod1 := sub(sub(mm, prod0), lt(mm, prod0))
}
// Handle non-overflow cases, 256 by 256 division.
if (prod1 == 0) {
// Solidity will revert if denominator == 0, unlike the div opcode on its own.
// The surrounding unchecked block does not change this fact.
// See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic.
return prod0 / denominator;
}
// Make sure the result is less than 2^256. Also prevents denominator == 0.
require(denominator > prod1, "Math: mulDiv overflow");
///////////////////////////////////////////////
// 512 by 256 division.
///////////////////////////////////////////////
// Make division exact by subtracting the remainder from [prod1 prod0].
uint256 remainder;
assembly {
// Compute remainder using mulmod.
remainder := mulmod(x, y, denominator)
// Subtract 256 bit number from 512 bit number.
prod1 := sub(prod1, gt(remainder, prod0))
prod0 := sub(prod0, remainder)
}
// Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1.
// See https://cs.stackexchange.com/q/138556/92363.
// Does not overflow because the denominator cannot be zero at this stage in the function.
uint256 twos = denominator & (~denominator + 1);
assembly {
// Divide denominator by twos.
denominator := div(denominator, twos)
// Divide [prod1 prod0] by twos.
prod0 := div(prod0, twos)
// Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.
twos := add(div(sub(0, twos), twos), 1)
}
// Shift in bits from prod1 into prod0.
prod0 |= prod1 * twos;
// Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such
// that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for
// four bits. That is, denominator * inv = 1 mod 2^4.
uint256 inverse = (3 * denominator) ^ 2;
// Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works
// in modular arithmetic, doubling the correct bits in each step.
inverse *= 2 - denominator * inverse; // inverse mod 2^8
inverse *= 2 - denominator * inverse; // inverse mod 2^16
inverse *= 2 - denominator * inverse; // inverse mod 2^32
inverse *= 2 - denominator * inverse; // inverse mod 2^64
inverse *= 2 - denominator * inverse; // inverse mod 2^128
inverse *= 2 - denominator * inverse; // inverse mod 2^256
// Because the division is now exact we can divide by multiplying with the modular inverse of denominator.
// This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is
// less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1
// is no longer required.
result = prod0 * inverse;
return result;
}
}
/**
* @notice Calculates x * y / denominator with full precision, following the selected rounding direction.
*/
function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) {
uint256 result = mulDiv(x, y, denominator);
if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {
result += 1;
}
return result;
}
/**
* @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down.
*
* Inspired by Henry S. Warren, Jr.'s "Hacker's Delight" (Chapter 11).
*/
function sqrt(uint256 a) internal pure returns (uint256) {
if (a == 0) {
return 0;
}
// For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.
//
// We know that the "msb" (most significant bit) of our target number `a` is a power of 2 such that we have
// `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`.
//
// This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)`
// → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))`
// → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)`
//
// Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit.
uint256 result = 1 << (log2(a) >> 1);
// At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,
// since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at
// every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision
// into the expected uint128 result.
unchecked {
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
return min(result, a / result);
}
}
/**
* @notice Calculates sqrt(a), following the selected rounding direction.
*/
function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {
unchecked {
uint256 result = sqrt(a);
return result + (rounding == Rounding.Up && result * result < a ? 1 : 0);
}
}
/**
* @dev Return the log in base 2, rounded down, of a positive value.
* Returns 0 if given 0.
*/
function log2(uint256 value) internal pure returns (uint256) {
uint256 result = 0;
unchecked {
if (value >> 128 > 0) {
value >>= 128;
result += 128;
}
if (value >> 64 > 0) {
value >>= 64;
result += 64;
}
if (value >> 32 > 0) {
value >>= 32;
result += 32;
}
if (value >> 16 > 0) {
value >>= 16;
result += 16;
}
if (value >> 8 > 0) {
value >>= 8;
result += 8;
}
if (value >> 4 > 0) {
value >>= 4;
result += 4;
}
if (value >> 2 > 0) {
value >>= 2;
result += 2;
}
if (value >> 1 > 0) {
result += 1;
}
}
return result;
}
/**
* @dev Return the log in base 2, following the selected rounding direction, of a positive value.
* Returns 0 if given 0.
*/
function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {
unchecked {
uint256 result = log2(value);
return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0);
}
}
/**
* @dev Return the log in base 10, rounded down, of a positive value.
* Returns 0 if given 0.
*/
function log10(uint256 value) internal pure returns (uint256) {
uint256 result = 0;
unchecked {
if (value >= 10 ** 64) {
value /= 10 ** 64;
result += 64;
}
if (value >= 10 ** 32) {
value /= 10 ** 32;
result += 32;
}
if (value >= 10 ** 16) {
value /= 10 ** 16;
result += 16;
}
if (value >= 10 ** 8) {
value /= 10 ** 8;
result += 8;
}
if (value >= 10 ** 4) {
value /= 10 ** 4;
result += 4;
}
if (value >= 10 ** 2) {
value /= 10 ** 2;
result += 2;
}
if (value >= 10 ** 1) {
result += 1;
}
}
return result;
}
/**
* @dev Return the log in base 10, following the selected rounding direction, of a positive value.
* Returns 0 if given 0.
*/
function log10(uint256 value, Rounding rounding) internal pure returns (uint256) {
unchecked {
uint256 result = log10(value);
return result + (rounding == Rounding.Up && 10 ** result < value ? 1 : 0);
}
}
/**
* @dev Return the log in base 256, rounded down, of a positive value.
* Returns 0 if given 0.
*
* Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string.
*/
function log256(uint256 value) internal pure returns (uint256) {
uint256 result = 0;
unchecked {
if (value >> 128 > 0) {
value >>= 128;
result += 16;
}
if (value >> 64 > 0) {
value >>= 64;
result += 8;
}
if (value >> 32 > 0) {
value >>= 32;
result += 4;
}
if (value >> 16 > 0) {
value >>= 16;
result += 2;
}
if (value >> 8 > 0) {
result += 1;
}
}
return result;
}
/**
* @dev Return the log in base 256, following the selected rounding direction, of a positive value.
* Returns 0 if given 0.
*/
function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {
unchecked {
uint256 result = log256(value);
return result + (rounding == Rounding.Up && 1 << (result << 3) < value ? 1 : 0);
}
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts 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 (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/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) (utils/Context.sol)
pragma solidity ^0.8.0;
import {Initializable} from "../proxy/utils/Initializable.sol";
/**
* @dev Provides information about the current execution context, including the
* sender of the transaction and its data. While these are generally available
* via msg.sender and msg.data, they should not be accessed in such a direct
* manner, since when dealing with meta-transactions the account sending and
* paying for execution may not be the actual sender (as far as an application
* is concerned).
*
* This contract is only required for intermediate, library-like contracts.
*/
abstract contract ContextUpgradeable is Initializable {
function __Context_init() internal onlyInitializing {
}
function __Context_init_unchained() internal onlyInitializing {
}
function _msgSender() internal view virtual returns (address) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes calldata) {
return msg.data;
}
function _contextSuffixLength() internal view virtual returns (uint256) {
return 0;
}
/**
* @dev This empty reserved space is put in place to allow future versions to add new
* variables without shifting down storage in the inheritance chain.
* See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps
*/
uint256[50] private __gap;
}// SPDX-License-Identifier: AGPL-3.0-or-later
pragma solidity ^0.8.8;
import {IDAO} from "../../dao/IDAO.sol";
/// @title DAO Authorization Utilities
/// @author Aragon X - 2022-2024
/// @notice Provides utility functions for verifying if a caller has specific permissions in an associated DAO.
/// @custom:security-contact [email protected]
/// @notice Thrown if a call is unauthorized in the associated DAO.
/// @param dao The associated DAO.
/// @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 DaoUnauthorized(address dao, address where, address who, bytes32 permissionId);
/// @notice A free function checking if a caller is granted permissions on a target contract via a permission identifier that redirects the approval to a `PermissionCondition` if this was specified in the setup.
/// @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 The optional data passed to the `PermissionCondition` registered.
function _auth(
IDAO _dao,
address _where,
address _who,
bytes32 _permissionId,
bytes calldata _data
) view {
if (!_dao.hasPermission(_where, _who, _permissionId, _data))
revert DaoUnauthorized({
dao: address(_dao),
where: _where,
who: _who,
permissionId: _permissionId
});
}// 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 (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
}
}
}{
"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":"uint16","name":"fromBuild","type":"uint16"},{"internalType":"uint16","name":"thisBuild","type":"uint16"}],"name":"InvalidUpdatePath","type":"error"},{"inputs":[],"name":"implementation","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_dao","type":"address"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"prepareInstallation","outputs":[{"internalType":"address","name":"plugin","type":"address"},{"components":[{"internalType":"address[]","name":"helpers","type":"address[]"},{"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":"permissions","type":"tuple[]"}],"internalType":"struct IPluginSetup.PreparedSetupData","name":"preparedSetupData","type":"tuple"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_dao","type":"address"},{"components":[{"internalType":"address","name":"plugin","type":"address"},{"internalType":"address[]","name":"currentHelpers","type":"address[]"},{"internalType":"bytes","name":"data","type":"bytes"}],"internalType":"struct IPluginSetup.SetupPayload","name":"_payload","type":"tuple"}],"name":"prepareUninstallation","outputs":[{"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":"permissions","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_dao","type":"address"},{"internalType":"uint16","name":"_fromBuild","type":"uint16"},{"components":[{"internalType":"address","name":"plugin","type":"address"},{"internalType":"address[]","name":"currentHelpers","type":"address[]"},{"internalType":"bytes","name":"data","type":"bytes"}],"internalType":"struct IPluginSetup.SetupPayload","name":"_payload","type":"tuple"}],"name":"prepareUpdate","outputs":[{"internalType":"bytes","name":"initData","type":"bytes"},{"components":[{"internalType":"address[]","name":"helpers","type":"address[]"},{"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":"permissions","type":"tuple[]"}],"internalType":"struct IPluginSetup.PreparedSetupData","name":"preparedSetupData","type":"tuple"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"protocolVersion","outputs":[{"internalType":"uint8[3]","name":"","type":"uint8[3]"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"bytes4","name":"_interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"}]Contract Creation Code
60a0806040523461008b576140078181016001600160401b03811183821017610077578291611b82833903905ff0801561006c576001600160a01b0316608052604051611af2908161009082396080518181816102da0152818161084401528181610d980152610f550152f35b6040513d5f823e3d90fd5b634e487b7160e01b5f52604160045260245ffd5b5f80fdfe6080806040526004361015610012575f80fd5b5f3560e01c90816301ffc9a714611001575080632ae9c60014610f845780635c60da1b14610f405780639cb0a12414610b7a578063a8a9c29e146106b45763f10832f11461005e575f80fd5b346106285760403660031901126106285761007761106b565b602435906001600160401b03821161062857366023830112156106285781600401356001600160401b038111610628578201906024820190368211610628576024846100c16112ef565b9403019160c06023198401126106285760248501356001600160401b038111610628578501948160438701121561062857602486013595610101876111f5565b9661010f60405198896111d4565b80885260206024818a019260051b840101019184831161062857604401905b82821061069c5750505060406043198501126106285760405192610151846111b9565b6044820135801515810361062857845260648201359461ffff86168603610628576040906020860196875260831901126106285760405190610192826111b9565b61019e60848401611081565b825260a4830135926002841015610628576020830193845260c4810135906001600160401b038211610628570190846043830112156106285760248201356001600160401b0381116106745760405195610202601f8301601f1916602001886111d4565b81875260448483010111610628576020815f92604461ffff9601838a01378701015260018060a01b0316956102596040519963370466ab60e21b60208c01528860248c015260e060448c01526101048b019061110b565b9551151560648a015251166084880152516001600160a01b031660a4870152516002811015610688576102b09286926102a29260c48501526023198483030160e48501526110e7565b03601f1981018552846111d4565b6040516103c693848201948286106001600160401b03871117610674578291610317916116f784397f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316808852604060208901819052909701906110e7565b03905ff080156106345760018060a01b0316916040516103ee808201908282106001600160401b0383111761067457602091839161130983398681520301905ff08015610634576001600160a01b03169361037061120c565b9060405161037d8161119e565b5f81528560208201528460408201525f60608201527fb1750e46d35a0069c8465b8643e7838d2149a842a2db8ee233d9835590040cad60808201526103c18361127e565b526103cb8261127e565b506040516103d88161119e565b5f81528460208201528560408201525f60608201527fbf04b4486c9663d805744005c3da000eda93de6e3308a4a7a812eb565327b78d608082015261041c8361129f565b526104268261129f565b50604051630239c48760e31b8152602081600481855afa908115610634575f9161063f575b5090600494602092604051906104608261119e565b600282528482018990526001600160a01b036040830152606082018a9052608082015261048c856112af565b52610496846112af565b506040516104a38161119e565b5f815287848201528160408201525f60608201527f568cc693d84eb1901f8bcecba154cbdef23ca3cf67efc0a0b698528a06c660f760808201526104e6856112bf565b526104f0846112bf565b50604051906104fe8261119e565b5f8252878483015260408201525f60608201527f4707e94b25cfce1a7c363508fbb838c35864388ad77284b248282b9746982b9b6080820152610540846112cf565b5261054a836112cf565b506040516319f9d6b160e31b815294859182905afa8015610634575f906105fc575b6105f893506040519061057e8261119e565b5f808352602083018790526001600160a01b036040840152606083015260808201526105a9826112df565b526105b3816112df565b5060208201526040936105e285516105cb87826111d4565b60018152601f19870136602083013780845261127e565b5283519384938452806020850152830190611147565b0390f35b506020833d60201161062c575b81610616602093836111d4565b81010312610628576105f8925161056c565b5f80fd5b3d9150610609565b6040513d5f823e3d90fd5b9190506020823d60201161066c575b8161065b602093836111d4565b81010312610628579051600461044b565b3d915061064e565b634e487b7160e01b5f52604160045260245ffd5b634e487b7160e01b5f52602160045260245ffd5b602080916106a984611081565b81520191019061012e565b34610628576060366003190112610628576106cd61106b565b60243561ffff811680910361062857604435916001600160401b03831161062857826004019183360360606003198201126106285760609461070d6112ef565b9460038410610741575b610733876105f8886040519384936040855260408501906110e7565b908382036020850152611147565b6107508197929394959761126a565b604051906103ee8083018381106001600160401b0382111761067457602092849261130984396001600160a01b031681520301905ff08015610634576001600160a01b0316966040519260c06107a681866111d4565b60058552601f19015f5b818110610b465750506107c28361126a565b91604051926107d08461119e565b600184526001600160a01b03908116602085015216604083018190525f828401527f821b6e3a557148015a918c89e5d092e878a69854a2d1a410635f771bd5a8a3f56080840152916108218561127e565b5261082b8461127e565b506108358361126a565b604051630239c48760e31b81527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316949190602081600481895afa908115610634578c905f92610b0a575b50946109b09260209492600497604051926108a28461119e565b600284526001600160a01b039081168885015260408401528783015260808201526108cc8961129f565b526108d68861129f565b506108e08261126a565b604051906108ed8261119e565b5f825260018060a01b0316858201528160408201525f868201527f568cc693d84eb1901f8bcecba154cbdef23ca3cf67efc0a0b698528a06c660f76080820152610936896112af565b52610940886112af565b5061094a8261126a565b90604051916109588361119e565b5f835260018060a01b03168583015260408201525f858201527f4707e94b25cfce1a7c363508fbb838c35864388ad77284b248282b9746982b9b60808201526109a0886112bf565b526109aa876112bf565b5061126a565b93604051938480926319f9d6b160e31b82525afa918215610634575f92610ad6575b505f90604051936109e28561119e565b8285526001600160a01b03908116602086015260408501528301526080820152610a0b826112cf565b52610a15816112cf565b506020850152604094610a448651610a2d88826111d4565b60018152601f19880136602083013780875261127e565b52604481013591602219018212156106285701926004840135936001600160401b038511610628576024019380360385136106285760846105f89382610acd936107339886519687946308641fa760e11b602087015260248601526044850152816064850152848401375f838284010152601f801991011681010301601f1981018352826111d4565b92848080610717565b9091506020813d602011610b02575b81610af2602093836111d4565b810103126106285751905f6109d2565b3d9150610ae5565b92939150506020823d602011610b3e575b81610b28602093836111d4565b810103126106285790519091908b6109b0610888565b3d9150610b1b565b602090604051610b558161119e565b5f81525f838201525f60408201525f858201525f6080820152828289010152016107b0565b3461062857604036600319011261062857610b9361106b565b6024356001600160401b0381116106285760608160040191600319903603011261062857610bbf61120c565b91610bc98261126a565b9060405191610bd78361119e565b600183526001600160a01b03908116602084015216604082018190525f60608301527fb1750e46d35a0069c8465b8643e7838d2149a842a2db8ee233d9835590040cad608083015290610c298461127e565b52610c338361127e565b50610c3d8261126a565b60405190610c4a8261119e565b60018252602082018390526001600160a01b031660408201525f60608201527fbf04b4486c9663d805744005c3da000eda93de6e3308a4a7a812eb565327b78d6080820152610c988461129f565b52610ca28361129f565b50610cac8261126a565b60405190610cb98261119e565b600182526001600160a01b03166020820152604081018290525f60608201527f568cc693d84eb1901f8bcecba154cbdef23ca3cf67efc0a0b698528a06c660f76080820152610d07846112af565b52610d11836112af565b50610d1b8261126a565b9060405191610d298361119e565b600183526001600160a01b0316602083015260408201525f60608201527f4707e94b25cfce1a7c363508fbb838c35864388ad77284b248282b9746982b9b6080820152610d75836112bf565b52610d7f826112bf565b50610d898161126a565b604051630239c48760e31b81527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316929190602081600481875afa908115610634575f91610f0d575b50600492602092610e289260405191610df28361119e565b600183526001600160a01b039081168684015260408301525f60608301526080820152610e1e876112cf565b526109aa866112cf565b92604051928380926319f9d6b160e31b82525afa908115610634575f91610edb575b5060405191610e588361119e565b600183526001600160a01b03908116602084015260408301525f60608301526080820152610e85826112df565b52610e8f816112df565b506040518091602082016020835281518091526020604084019201905f5b818110610ebb575050500390f35b919350916020610ece6001928651611095565b9401910191849392610ead565b90506020813d602011610f05575b81610ef6602093836111d4565b81010312610628575183610e4a565b3d9150610ee9565b90506020813d602011610f38575b81610f28602093836111d4565b8101031261062857516004610dda565b3d9150610f1b565b34610628575f366003190112610628576040517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602090f35b34610628575f36600319011261062857606080604051610fa482826111d4565b3690376040518181018181106001600160401b038211176106745760405260018152600460208201525f604082015260405190815f905b60038210610fe857505050f35b60208060019260ff865116815201930191019091610fdb565b34610628576020366003190112610628576004359063ffffffff60e01b82168092036106285760209163099718b560e41b811490811561105b575b811561104a575b5015158152f35b6301ffc9a760e01b14905083611043565b621574e360e91b8114915061103c565b600435906001600160a01b038216820361062857565b35906001600160a01b038216820361062857565b90815160038110156106885760a0926080918352600180851b036020820151166020840152600180851b036040820151166040840152600180851b036060820151166060840152015160808201520190565b805180835260209291819084018484015e5f828201840152601f01601f1916010190565b90602080835192838152019201905f5b8181106111285750505090565b82516001600160a01b031684526020938401939092019160010161111b565b602061115c825160408552604085019061110b565b91015182820360209384015280518083529183019201905f5b8181106111825750505090565b90919260206111946001928651611095565b9401929101611175565b60a081019081106001600160401b0382111761067457604052565b604081019081106001600160401b0382111761067457604052565b90601f801991011681019081106001600160401b0382111761067457604052565b6001600160401b0381116106745760051b60200190565b60405160e0919061121d83826111d4565b6006815291601f1901825f5b82811061123557505050565b6020906040516112448161119e565b5f81525f838201525f60408201525f60608201525f608082015282828501015201611229565b356001600160a01b03811681036106285790565b80511561128b5760200190565b634e487b7160e01b5f52603260045260245ffd5b80516001101561128b5760400190565b80516002101561128b5760600190565b80516003101561128b5760800190565b80516004101561128b5760a00190565b80516005101561128b5760c00190565b604051906112fc826111b9565b6060602083828152015256fe60a034606857601f6103ee38819003918201601f19168301916001600160401b03831184841017606c57808492602094604052833981010312606857516001600160a01b0381169081900360685760805260405161036d90816100818239608051816102110152f35b5f80fd5b634e487b7160e01b5f52604160045260245ffdfe6080806040526004361015610012575f80fd5b5f3560e01c90816301ffc9a714610151575080632675fdd0146100d357632ae9c6001461003d575f80fd5b346100cf575f3660031901126100cf5760608060405161005d82826101d1565b36903760405181810181811067ffffffffffffffff8211176100bb5760405260018152600460208201525f604082015260405190815f905b600382106100a257505050f35b60208060019260ff865116815201930191019091610095565b634e487b7160e01b5f52604160045260245ffd5b5f80fd5b346100cf5760803660031901126100cf576100ec6101bb565b506024356001600160a01b03811681036100cf5760643567ffffffffffffffff81116100cf57366023820112156100cf57806004013567ffffffffffffffff81116100cf57369101602401116100cf57610147602091610200565b6040519015158152f35b346100cf5760203660031901126100cf576004359063ffffffff60e01b82168092036100cf576020916302675fdd60e41b81149081156101ab575b811561019a575b5015158152f35b6301ffc9a760e01b14905083610193565b621574e360e91b8114915061018c565b600435906001600160a01b03821682036100cf57565b90601f8019910116810190811067ffffffffffffffff8211176100bb57604052565b519081151582036100cf57565b6040805163e097b3ff60e01b8152917f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169183600481855afa9283156102e1575f936102ec575b5082610265575b505061026157600190565b5f90565b604051637bca031760e11b81526001600160a01b0390911660048201529150602090829060249082905afa9081156102e1575f916102a7575b50155f80610256565b90506020813d6020116102d9575b816102c2602093836101d1565b810103126100cf576102d3906101f3565b5f61029e565b3d91506102b5565b6040513d5f823e3d90fd5b9092506040813d60401161032f575b81610308604093836101d1565b810103126100cf57602061031b826101f3565b91015161ffff8116036100cf57915f61024f565b3d91506102fb56fea26469706673582212205aeaf15076ce6f4b55b0d041e4bd71e6b993c63941431759b3816b69d2e5bf3464736f6c634300081c003360806040526103c680380380610014816101f2565b9283398101906040818303126101ee5780516001600160a01b038116918282036101ee576020810151906001600160401b0382116101ee57019183601f840112156101ee57825161006c6100678261022b565b6101f2565b938185526020850195602083830101116101ee57815f926020809301885e85010152813b15610193577f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc80546001600160a01b031916821790557fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b5f80a281511580159061018c575b610108575b60405160cb90816102fb8239f35b5f8061017b9461011860606101f2565b94602786527f416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c6020870152660819985a5b195960ca1b60408701525190845af43d15610184573d9161016c6100678461022b565b9283523d5f602085013e610246565b505f80806100fa565b606091610246565b505f6100f5565b60405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b6064820152608490fd5b5f80fd5b6040519190601f01601f191682016001600160401b0381118382101761021757604052565b634e487b7160e01b5f52604160045260245ffd5b6001600160401b03811161021757601f01601f191660200190565b919290156102a8575081511561025a575090565b3b156102635790565b60405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606490fd5b8251909150156102bb5750805190602001fd5b604460209160405192839162461bcd60e51b83528160048401528051918291826024860152018484015e5f828201840152601f01601f19168101030190fdfe608060405236156051577f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc545f9081906001600160a01b0316368280378136915af43d5f803e15604d573d5ff35b3d5ffd5b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc545f9081906001600160a01b0316368280378136915af43d5f803e15604d573d5ff3fea26469706673582212203bf93d98380d30a31ff94676bcd53f6cf4fd06145a15d34fda5d76afee117ce864736f6c634300081c0033a2646970667358221220594a9d2c51151c2c59af09fbbd611784365e9f60d9e3896de2125c33f8f727ab64736f6c634300081c003360a080604052346100da57306080525f549060ff8260081c16610088575060ff8082160361004e575b604051613f2890816100df823960805181818161087f01528181610b6c0152610c9f0152f35b60ff90811916175f557f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498602060405160ff8152a15f610028565b62461bcd60e51b815260206004820152602760248201527f496e697469616c697a61626c653a20636f6e747261637420697320696e697469604482015266616c697a696e6760c81b6064820152608490fd5b5f80fdfe60806040526004361015610011575f80fd5b5f3560e01c806301ffc9a7146102af57806310c83f4e146102aa57806311ce2438146102a55780632358d5a8146102a057806327f1608d1461029b57806329245f56146102965780632ae9c600146102915780632caf024b1461028c578063303f4336146102875780633628731c146102825780633659cfe61461027d5780633d3f4b1b146102785780634162169f1461027357806341de68301461026e5780634f1ef2861461026957806352d1902d146102645780635c60da1b1461025f5780636a6b2d861461025a578063747442d3146102555780637a5b4f59146102505780638cb750591461024b578063a230c524146101f1578063a84eb99914610246578063b1bb8d2614610241578063bb225da21461023c578063bc20830214610237578063c218c13214610232578063c7f758a81461022d578063c98425ee14610228578063c9c4bfca14610223578063cc63604a1461021e578063cfceb58814610219578063da35c66414610214578063dc119aac1461020f578063dd63c06f1461020a578063e097b3ff14610205578063e306bee714610200578063ea65ab82146101fb578063ee57e36f146101f6578063f794062e146101f1578063fbd56e41146101ec5763fe0d94c1146101e7575f80fd5b611a2a565b61199e565b611026565b611888565b6117e7565b611755565b611726565b61170c565b611648565b611629565b611602565b6115b9565b61157f565b61154e565b6114ac565b61130a565b6112e3565b6111cf565b6111a4565b61104d565b610fec565b610efe565b610ed6565b610d84565b610d50565b610c8d565b610b30565b610a0e565b6109d2565b610942565b61085a565b6107b3565b610716565b6106a9565b61063c565b6105c9565b61059e565b610548565b6104fd565b610444565b346104075760203660031901126104075760043563ffffffff60e01b81168091036104075761031290630c1d75df60e01b81149081156103f6575b81156103e5575b81156103d4575b8115610316575b5060405190151581529081906020820190565b0390f35b63368d719960e21b8114915081156103c3575b8115610337575b505f6102ff565b63041de68360e41b8114915081156103b3575b81156103a2575b8115610391575b8115610366575b505f610330565b634a06561b60e11b811491508115610380575b505f61035f565b6301ffc9a760e01b1490505f610379565b63afc5b82360e01b81149150610358565b6352d1902d60e01b81149150610351565b621574e360e91b8114915061034a565b633f4644d160e21b81149150610329565b63288c314960e21b811491506102f8565b630bb5c60360e01b811491506102f1565b63d200f62360e01b811491506102ea565b5f80fd5b61ffff81160361040757565b9181601f84011215610407578235916001600160401b038311610407576020838186019501011161040757565b34610407576040366003190112610407576004356104618161040b565b602435906001600160401b038211610407576104846104ae923690600401610417565b916101025f5460ff8160081c1615806104f0575b6104a190611b11565b61ffff1916175f55611baf565b6104bc61ff00195f54165f55565b604051600281527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989080602081015b0390a1005b50600260ff821610610498565b34610407575f3660031901126104075760206040517f8c433a4cd6b51969eca37f974940894297b9fcf4b282a213fea5cd8f85289c908152f35b6001600160a01b0381160361040757565b3461040757604036600319011261040757602060ff61059260243560043561056f82610537565b5f526101918452600260405f20019060018060a01b03165f5260205260405f2090565b54166040519015158152f35b34610407575f3660031901126104075760206001600160e01b036105c0612da2565b16604051908152f35b34610407576040366003190112610407576004356024356105e981610537565b61060e825f526101916020526001600160401b03600160405f20015460101c16151590565b156106295761061f90602092612e12565b6040519015158152f35b50630853c2a360e41b5f5260045260245ffd5b34610407575f36600319011261040757606060405161065b8282610a92565b36903760405161066a81610a3c565b60018152600460208201525f604082015260405190815f905b6003821061069057606084f35b60208060019260ff865116815201930191019091610683565b34610407575f3660031901126104075760206040517fb1750e46d35a0069c8465b8643e7838d2149a842a2db8ee233d9835590040cad8152f35b604090600319011261040757600490565b604090604319011261040757604490565b604090608319011261040757608490565b3461040757604036600319011261040757610753610733366106e3565b60c95461074e903690339030906001600160a01b0316612e7f565b613188565b005b9181601f84011215610407578235916001600160401b038311610407576020808501948460051b01011161040757565b602060031982011261040757600435906001600160401b038211610407576107af91600401610755565b9091565b34610407576107c136610785565b60c9546107dc903690339030906001600160a01b0316612e7f565b6001600160e01b036107ec612da2565b16918183018093116108555761ffff831161083d577f11ba20e083ffba533caf1d501ce171aa2acdc05a5601e4e473e449460b0718d8925061082e82826132b0565b6104eb60405192839283611c28565b8262496b8d60e61b5f5261ffff60045260245260445ffd5b611c06565b346104075760203660031901126104075761075360043561087a81610537565b6108d17f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166108b330821415611c6f565b5f516020613ed35f395f51905f52546001600160a01b031614611cd0565b60c9546108ec903690339030906001600160a01b0316612f64565b604051906108fb602083610a92565b5f8083523660208401376133e3565b805180835260209291819084018484015e5f828201840152601f01601f1916010190565b90602061093f92818152019061090a565b90565b34610407575f36600319011261040757610312604051610963608082610a92565b604281527f2875696e7432353620616c6c6f774661696c7572654d61702c20626f6f6c206160208201527f7070726f766550726f706f73616c2c20626f6f6c20747279457865637574696f6040820152616e2960f01b606082015260405191829160208352602083019061090a565b34610407575f3660031901126104075760c9546040516001600160a01b039091168152602090f35b634e487b7160e01b5f52602160045260245ffd5b34610407575f3660031901126104075760206040515f8152f35b634e487b7160e01b5f52604160045260245ffd5b606081019081106001600160401b03821117610a5757604052565b610a28565b608081019081106001600160401b03821117610a5757604052565b604081019081106001600160401b03821117610a5757604052565b90601f801991011681019081106001600160401b03821117610a5757604052565b60405190610ac2604083610a92565b565b6001600160401b038111610a5757601f01601f191660200190565b929192610aeb82610ac4565b91610af96040519384610a92565b829481845281830111610407578281602093845f960137010152565b9080601f830112156104075781602061093f93359101610adf565b604036600319011261040757600435610b4881610537565b6024356001600160401b03811161040757610b67903690600401610b15565b610ba07f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166108b330821415611c6f565b60c954610bbb903690339030906001600160a01b0316612f64565b7f4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd91435460ff1615610bef57506107539061397a565b6040516352d1902d60e01b8152906020826004816001600160a01b0387165afa5f9281610c5c575b50610c395760405162461bcd60e51b815280610c3560048201613394565b0390fd5b61075392610c575f516020613ed35f395f51905f5260019414613336565b6138bf565b610c7f91935060203d602011610c86575b610c778183610a92565b810190613327565b915f610c17565b503d610c6d565b34610407575f366003190112610407577f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03163003610ce5576040515f516020613ed35f395f51905f528152602090f35b60405162461bcd60e51b815260206004820152603860248201527f555550535570677261646561626c653a206d757374206e6f742062652063616c60448201527f6c6564207468726f7567682064656c656761746563616c6c00000000000000006064820152608490fd5b34610407575f366003190112610407575f516020613ed35f395f51905f52546040516001600160a01b039091168152602090f35b346104075760203660031901126104075760043543811015610e8857610da990613a11565b610160549063ffffffff165f5b828110610e22578280610ddb575060205f5b6040516001600160e01b03919091168152f35b610e1d610e16610dec602093612009565b6101605f527fec7e130cdeeae65215fabbcddb1de429e603c4887cc659532eda903e493396630190565b5460201c90565b610dc8565b90918082169080831860011c8201809211610855576101605f527fec7e130cdeeae65215fabbcddb1de429e603c4887cc659532eda903e4933966382015463ffffffff16841015610e765750915b90610db6565b929150610e8290611c1a565b90610e70565b606460405162461bcd60e51b815260206004820152602060248201527f436865636b706f696e74733a20626c6f636b206e6f7420796574206d696e65646044820152fd5b8015150361040757565b3461040757604036600319011261040757610753602435600435610ef982610ecc565b611ddf565b34610407575f366003190112610407576040515f5f516020613e935f395f51905f5254610f2a81611f33565b8084529060018116908115610fc85750600114610f5e575b61031283610f5281850382610a92565b6040519182918261092e565b5f516020613e935f395f51905f525f9081527f20120d26379ad35b0c68e58a20f1251f24acf3aee87d3a8d8759c48671c8cace939250905b808210610fae57509091508101602001610f52610f42565b919260018160209254838588010152019101909291610f96565b60ff191660208086019190915291151560051b84019091019150610f529050610f42565b34610407575f3660031901126104075760206040517f568cc693d84eb1901f8bcecba154cbdef23ca3cf67efc0a0b698528a06c660f78152f35b3461040757602036600319011261040757602061061f60043561104881610537565b61239d565b346104075761105b36610785565b60c954611076903690339030906001600160a01b0316612e7f565b6001600160e01b03611086612da2565b168181039081116108555761ffff1661ffff6101925460081c16908181106111875750505f5b8181106110f057507f0ba413f7646035cae0a4ee999d676078fc8a763d1a36a8ef25e4c10f67d8615d916110df8261389e565b50506104eb60405192839283611c28565b6111086110fe8284866132a0565b3561104881610537565b15611153578061111b60019284866132a0565b3561112581610537565b828060a01b03165f5261015f60205261114b5f6040812061114543613a11565b90613ceb565b5050016110ac565b9061115d926132a0565b3561116781610537565b63c0b7477d60e01b5f9081526001600160a01b0391909116600452602490fd5b6317b10ead60e11b5f5261ffff9081166004521660245260445b5ffd5b3461040757604036600319011261040757602061061f6004356111c681610537565b60243590612017565b34610407576040366003190112610407576111e9366106e3565b60c954604051637ef7c88360e11b81526001600160a01b03909116906020818061123a365f7f568cc693d84eb1901f8bcecba154cbdef23ca3cf67efc0a0b698528a06c660f7333060048701611da3565b0381855afa9081156112de575f916112af575b5015611265576107536112603684611b74565b612b1a565b60849060405190630cb6f8ed60e21b825260048201523060248201523360448201527f568cc693d84eb1901f8bcecba154cbdef23ca3cf67efc0a0b698528a06c660f76064820152fd5b6112d1915060203d6020116112d7575b6112c98183610a92565b810190611d31565b5f61124d565b503d6112bf565b611dd4565b34610407575f3660031901126104075760206001600160401b036101935416604051908152f35b3461040757602036600319011261040757600435611343815f526101916020526001600160401b03600160405f20015460101c16151590565b1561137e575f5261019160205261031260405f2061ffff600181835460081c1692015416111560405191829182919091602081019215159052565b630853c2a360e41b5f5260045260245ffd5b9080602083519182815201916020808360051b8301019401925f915b8383106113bb57505050505090565b90919293946020806113fb600193601f19868203018752606060408b51878060a01b0381511684528581015186850152015191816040820152019061090a565b970193019301919392906113ac565b6002111561141457565b6109fa565b80516001600160a01b03168252602001519060028210156114145760200152565b91936001600160401b0360606101009561ffff610ac2999b9a9861149f961515885216602087015261ffff8151166040870152826020820151168287015282604082015116608087015201511660a084015261014060c0840152610140830190611390565b9560e08201520190611419565b34610407576020366003190112610407576004355f60606040516114cf81610a5c565b82815282602082015282604082015201526114e86120e1565b505f5261019160205260405f208054610312611506600184016120f9565b9261151360038201612150565b90611525600560048301549201612208565b91604051958560ff61ffff899860081c1691168761143a565b604081019291610ac29190611419565b34610407575f366003190112610407576115666120e1565b5060406115716121d9565b61157d82518092611419565bf35b34610407575f3660031901126104075760206040517f821b6e3a557148015a918c89e5d092e878a69854a2d1a410635f771bd5a8a3f58152f35b34610407576020366003190112610407576004356115f2815f526101916020526001600160401b03600160405f20015460101c16151590565b1561137e5761061f6020916134a2565b34610407575f3660031901126104075760206040515f516020613eb35f395f51905f528152f35b34610407575f36600319011261040757631bebc11560e01b5f5260045ffd5b346104075760e03660031901126104075760043561166581610537565b6024356001600160401b03811161040757611684903690600401610755565b9061168e366106f4565b61169736610705565b9060c4356001600160401b038111610407576116b7903690600401610417565b9490935f549660ff8816806116fe57886116e66101029260ff6104ae9c60081c161590816116f3575b50611b11565b61ffff1916175f55612235565b60029150105f6116e0565b62dc149f60e41b5f5260045ffd5b34610407575f3660031901126104075760406115716122f2565b34610407575f3660031901126104075760406101925461ffff82519160ff81161515835260081c166020820152f35b34610407575f3660031901126104075760206040517f4707e94b25cfce1a7c363508fbb838c35864388ad77284b248282b9746982b9b8152f35b604435906001600160401b038216820361040757565b606435906001600160401b038216820361040757565b60a435906001600160401b038216820361040757565b60c435906001600160401b038216820361040757565b346104075760a0366003190112610407576004356001600160401b03811161040757611817903690600401610417565b906024356001600160401b03811161040757611837903690600401610755565b61184292919261178f565b61184a6117a5565b91608435946001600160401b0386116104075761031296611872611878973690600401610b15565b9561233b565b6040519081529081906020820190565b34610407576020366003190112610407576004356001600160401b038111610407576118b8903690600401610417565b60c954604051637ef7c88360e11b81526001600160a01b039091169060208180611909365f7f4707e94b25cfce1a7c363508fbb838c35864388ad77284b248282b9746982b9b333060048701611da3565b0381855afa9081156112de575f9161197f575b501561193557610753611930368486610adf565b612c39565b60849060405190630cb6f8ed60e21b825260048201523060248201523360448201527f4707e94b25cfce1a7c363508fbb838c35864388ad77284b248282b9746982b9b6064820152fd5b611998915060203d6020116112d7576112c98183610a92565b5f61191c565b346104075760e0366003190112610407576004356001600160401b038111610407576119ce903690600401610417565b90602435906001600160401b03821161040757610312926119f6611878933690600401610755565b60443560643591611a0683610ecc565b60843593611a1385610ecc565b611a1b6117bb565b95611a246117d1565b976123ce565b346104075760203660031901126104075760043560018060a01b0360c95416604051637ef7c88360e11b815260208180611a78365f5f516020613eb35f395f51905f52333060048701611da3565b0381855afa9081156112de575f91611af2575b5015611abb5750611a9b816134a2565b15611aa957610753906134d6565b639fefd0f160e01b5f5260045260245ffd5b60849060405190630cb6f8ed60e21b825260048201523060248201523360448201525f516020613eb35f395f51905f526064820152fd5b611b0b915060203d6020116112d7576112c98183610a92565b5f611a8b565b15611b1857565b60405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b6064820152608490fd5b919082604091031261040757604051611b8c81610a77565b602081938035611b9b81610537565b835201359060028210156104075760200152565b61ffff6003919392931610611bc2575050565b81019060608183031261040757611bd98282611b74565b906040810135906001600160401b03821161040757610ac29361193092611c009201610b15565b91612b1a565b634e487b7160e01b5f52601160045260245ffd5b906001820180921161085557565b60208082528101839052604001915f5b818110611c455750505090565b9091926020806001928635611c5981610537565b848060a01b031681520194019101919091611c38565b15611c7657565b60405162461bcd60e51b815260206004820152602c60248201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060448201526b19195b1959d85d1958d85b1b60a21b6064820152608490fd5b15611cd757565b60405162461bcd60e51b815260206004820152602c60248201527f46756e6374696f6e206d7573742062652063616c6c6564207468726f7567682060448201526b6163746976652070726f787960a01b6064820152608490fd5b90816020910312610407575161093f81610ecc565b908060209392818452848401375f828201840152601f01601f1916010190565b6001600160a01b039182168152911660208201525f516020613eb35f395f51905f52604082015260806060820181905261093f929101905f611d46565b6001600160a01b03918216815291166020820152604081019190915260806060820181905261093f93910191611d46565b6040513d5f823e3d90fd5b90611df1611ded3384612e12565b1590565b611f1b57611e68611e5b611e0e845f5261019160205260405f2090565b611e46611e2e611e24835461ffff9060081c1690565b60010161ffff1690565b825462ffff00191660089190911b62ffff0016178255565b335f9081526002919091016020526040902090565b805460ff19166001179055565b33827f7b39c92a7e1a86e846edaeff6eba715a046352c596794c2a374269c126a997685f80a315611f1857611e9c816134a2565b80611eb2575b611ea95750565b610ac2906134d6565b5060c9546001600160a01b031660206040518092637ef7c88360e11b82528180611ee136333060048501611d66565b03915afa9081156112de575f91611ef9575b50611ea2565b611f12915060203d6020116112d7576112c98183610a92565b5f611ef3565b50565b631bf6d43960e11b5f5260048290523360245260445ffd5b90600182811c92168015611f61575b6020831014611f4d57565b634e487b7160e01b5f52602260045260245ffd5b91607f1691611f42565b9060405191825f825492611f7e84611f33565b8084529360018116908115611fe75750600114611fa3575b50610ac292500383610a92565b90505f9291925260205f20905f915b818310611fcb575050906020610ac2928201015f611f96565b6020919350806001915483858901015201910190918492611fb2565b905060209250610ac294915060ff191682840152151560051b8201015f611f96565b5f1981019190821161085557565b6001600160a01b03165f90815261015f602052604090209043811015610e885761204090613a11565b8154919063ffffffff165f5b83811061208d5750508161206b57505060015f5b818060e01b03161490565b610e166120889161207d600194612009565b905f5260205f200190565b612060565b90928082169080831860011c820180921161085557835f528463ffffffff6120bf8460205f200163ffffffff90541690565b1611156120cf5750925b9061204c565b9391506120db90611c1a565b906120c9565b604051906120ee82610a77565b5f6020838281520152565b9060405161210681610a5c565b60606001600160401b0382945461ffff81168452818160101c166020850152818160501c16604085015260901c16910152565b6001600160401b038111610a575760051b60200190565b90815461215c81612139565b9261216a6040519485610a92565b81845260208401905f5260205f205f915b8383106121885750505050565b6003602060019260405161219b81610a3c565b848060a01b03865416815284860154838201526121ba60028701611f6b565b604082015281520192019201919061217b565b60028210156114145752565b604051906121e682610a77565b60fb546001600160a01b0381168352610ac29060a01c60ff16602084016121cd565b90610ac260405161221881610a77565b92546001600160a01b038116845260a01c60ff16602084016121cd565b95939561225160ff5f5460081c1661224c8161361f565b61361f565b60018060a01b03166001600160601b0360a01b60c954161760c95561ffff82116122da5793610ac295936122cc6122d3947f11ba20e083ffba533caf1d501ce171aa2acdc05a5601e4e473e449460b0718d885896122b5611930986112609c6132b0565b6122c460405192839283611c28565b0390a1613188565b3691610adf565b3690611b74565b5062496b8d60e61b5f5261ffff60045260245260445ffd5b6122fa6120e1565b506123036121d9565b80516001600160a01b0316156123165790565b5060c954604051906001600160a01b031661233082610a77565b81525f602082015290565b929190915f915f935f958951998a612359575b5061093f99506123ce565b809750809296506060939a9195500103126104075761093f96602085015193606060408701519661238988610ecc565b015161239481610ecc565b9594935f61234e565b6001600160a01b03165f90815261015f602052604090206001906001600160e01b03906123c990612de8565b161490565b92909394959796976123ef60018060a01b0360c95416369033903090613049565b886001600160401b035f196124034361367f565b0116998a6001600160401b03612422610193546001600160401b031690565b161161269d576001600160401b03811680612649575050506124434261367f565b965b6001600160401b0388166001600160401b038a16106126275761249060405160208101906124888161247a8b8b8a8c886126b0565b03601f198101835282610a92565b5190206136ed565b996124a48b5f5261019160205260405f2090565b906124ca8c5f526101916020526001600160401b03600160405f20015460101c16151590565b61261357612566906125016001840191829069ffffffffffffffff000082549160101b169069ffffffffffffffff00001916179055565b805467ffffffffffffffff60501b191660508c901b67ffffffffffffffff60501b16178155805467ffffffffffffffff60901b191660908d901b67ffffffffffffffff60901b161781556101925460081c61ffff1661ffff1661ffff19825416179055565b61257a6125716122f2565b600583016127d8565b87612608575b908a98969499979593929160035f9101905b8481106125d4575050986125be93926125b69261093f9b6125c4575b503691612a66565b923691610adf565b9061371e565b6125ce908b611ddf565b5f6125ae565b8b96989a506125f66125f08287600195969798999b9d9f612831565b846129cb565b01908b9997959a989694939291612592565b876004820155612580565b6312dba68f60e01b5f5260048c905260245ffd5b631332703d60e21b5f526001600160401b03808916600452891660245260445ffd5b6126646126589a939a4261367f565b6001600160401b031690565b1161266f5750612445565b6111a19061267c4261367f565b631332703d60e21b5f526001600160401b0390811660045216602452604490565b633aae64d160e21b5f523360045260245ffd5b949391929083604087016040885252606086019360608160051b88010194825f90605e19813603015b8483106126f85750505050505084602061093f95968503910152611d46565b909192939497605f198b8203018552883582811215610407578301803561271e81610537565b6001600160a01b0316825260208181013590830152604081013536829003601e19018112156104075701602081359101906001600160401b03811161040757803603821361040757612780602092839260608681604060019901520191611d46565b9a01969501930191906126d9565b60209060018060a01b038151166001600160601b0360a01b60fb54161760fb55015160028110156114145760fb805460ff60a01b191660a09290921b60ff60a01b16919091179055565b815181546001600160a01b0319166001600160a01b03919091161781559060200151600281101561141457815460ff60a01b191660a09190911b60ff60a01b16179055565b634e487b7160e01b5f52603260045260245ffd5b91908110156128535760051b81013590605e1981360301821215610407570190565b61281d565b601f8111612864575050565b5f516020613e935f395f51905f525f5260205f20906020601f840160051c830193106128aa575b601f0160051c01905b81811061289f575050565b5f8155600101612894565b909150819061288b565b601f82116128c157505050565b5f5260205f20906020601f840160051c830193106128f9575b601f0160051c01905b8181106128ee575050565b5f81556001016128e3565b90915081906128da565b9092916001600160401b038111610a5757612928816129228454611f33565b846128b4565b5f601f82116001146129665781906129579394955f9261295b575b50508160011b915f199060031b1c19161790565b9055565b013590505f80612943565b601f19821694612979845f5260205f2090565b915f5b8781106129b357508360019596971061299a575b505050811b019055565b01355f19600384901b60f8161c191690555f8080612990565b9092602060018192868601358155019401910161297c565b805490600160401b821015610a575760018201808255821015612853575f52600360205f2091020190612a1e8135612a0281610537565b83546001600160a01b0319166001600160a01b03909116178355565b60208101356001830155604081013590601e198136030182121561040757018035906001600160401b038211610407576020018136038113610407576002610ac29301612903565b92919092612a7384612139565b93612a816040519586610a92565b602085828152019060051b8201918383116104075780915b838310612aa7575050505050565b82356001600160401b0381116104075782016060818703126104075760405191612ad083610a3c565b8135612adb81610537565b8352602082013560208401526040820135926001600160401b03841161040757612b0a88602095869501610b15565b6040820152815201920191612a99565b60018060a01b0381511660205f604051828101906301ffc9a760e01b82526301ffc9a760e01b602482015260248152612b54604482610a92565b519084617530fa903d5f519083612c2d575b5082612c23575b5081612c11575b81612c01575b5080612be1575b612bc457612bbf81612bb37f88e879ae0d71faf3aa708f2978daccb99b95243615dc104835b8c5a21c884ae69361278e565b6040519182918261153e565b0390a1565b60405163266d0fb960e01b8152908190610c35906004830161153e565b5060016020820151612bf28161140a565b612bfb8161140a565b14612b81565b612c0b9150613c03565b5f612b7a565b9050612c1c81613ba6565b1590612b74565b151591505f612b6d565b6020111592505f612b66565b908151916001600160401b038311610a5757612c6b83612c665f516020613e935f395f51905f5254611f33565b612858565b602092601f8111600114612ce55790612cbf82612bbf937fbb39ebb37e60fb5d606ffdb749d2336e56b88e6c88c4bd6513b308f643186eed95965f91612cda575b508160011b915f199060031b1c19161790565b5f516020613e935f395f51905f52556040519182918261092e565b90508301515f612cac565b5f516020613e935f395f51905f525f52601f1981167f20120d26379ad35b0c68e58a20f1251f24acf3aee87d3a8d8759c48671c8cace905f5b818110612d8a5750916001917fbb39ebb37e60fb5d606ffdb749d2336e56b88e6c88c4bd6513b308f643186eed959682612bbf969510612d72575b5050811b015f516020613e935f395f51905f5255610f52565b8401515f1960f88460031b161c191690555f80612d59565b84870151835560209687019660019093019201612d1e565b6101605480612db057505f90565b805f19810111610855576101605f527fec7e130cdeeae65215fabbcddb1de429e603c4887cc659532eda903e49339662015460201c90565b80549081612df65750505f90565b815f19810111610855575f525f199060205f2001015460201c90565b5f5261019160205260405f20612e278161378d565b15612e7957612e466001600160401b03600183015460101c1683612017565b15612e795760ff916002612e6a92019060018060a01b03165f5260205260405f2090565b5416612e7557600190565b5f90565b50505f90565b604051637ef7c88360e11b81526001600160a01b039091169360209082908190612ed0905f7fb1750e46d35a0069c8465b8643e7838d2149a842a2db8ee233d9835590040cad898960048701611da3565b0381875afa9081156112de575f91612f45575b5015612eee57505050565b604051630cb6f8ed60e21b815260048101939093526001600160a01b0390811660248401521660448201527fb1750e46d35a0069c8465b8643e7838d2149a842a2db8ee233d9835590040cad606482015260849150fd5b612f5e915060203d6020116112d7576112c98183610a92565b5f612ee3565b604051637ef7c88360e11b81526001600160a01b039091169360209082908190612fb5905f7f821b6e3a557148015a918c89e5d092e878a69854a2d1a410635f771bd5a8a3f5898960048701611da3565b0381875afa9081156112de575f9161302a575b5015612fd357505050565b604051630cb6f8ed60e21b815260048101939093526001600160a01b0390811660248401521660448201527f821b6e3a557148015a918c89e5d092e878a69854a2d1a410635f771bd5a8a3f5606482015260849150fd5b613043915060203d6020116112d7576112c98183610a92565b5f612fc8565b604051637ef7c88360e11b81526001600160a01b03909116936020908290819061309a905f7f8c433a4cd6b51969eca37f974940894297b9fcf4b282a213fea5cd8f85289c90898960048701611da3565b0381875afa9081156112de575f9161310f575b50156130b857505050565b604051630cb6f8ed60e21b815260048101939093526001600160a01b0390811660248401521660448201527f8c433a4cd6b51969eca37f974940894297b9fcf4b282a213fea5cd8f85289c90606482015260849150fd5b613128915060203d6020116112d7576112c98183610a92565b5f6130ad565b3561093f8161040b565b3561093f81610ecc565b602090803561315081610ecc565b60ff80196101925416911515161761019255013561316d8161040b565b6101929062ffff0082549160081b169062ffff001916179055565b61319a613193612da2565b61ffff1690565b9060208101916131a98361312e565b61ffff8083169116116132775750600161ffff6131c58461312e565b16106132505761324b61ffff613237613231846132027f7d8a9a57630acbcfb28eb55b1ce0ff7b3d0dc9edea594075a8a6af35278a4cf996613142565b61322c61320e4361367f565b6001600160401b03166001600160401b031961019354161761019355565b613138565b9461312e565b604051941515855216929081906020820190565b0390a2565b6111a161325c8361312e565b6317b10ead60e11b5f52600160045261ffff16602452604490565b6111a1906132848461312e565b6317b10ead60e11b5f5261ffff91821660045216602452604490565b91908110156128535760051b0190565b91905f5b8181106132cb57506132c791925061387d565b5050565b6132d96110fe8284876132a0565b61331d57806132eb60019284876132a0565b356132f581610537565b828060a01b03165f5261015f6020526133158260405f2061114543613a11565b5050016132b4565b61115d91846132a0565b90816020910312610407575190565b1561333d57565b60405162461bcd60e51b815260206004820152602960248201527f45524331393637557067726164653a20756e737570706f727465642070726f786044820152681a58589b195555525160ba1b6064820152608490fd5b60809060208152602e60208201527f45524331393637557067726164653a206e657720696d706c656d656e7461746960408201526d6f6e206973206e6f74205555505360901b60608201520190565b9061340f7f4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd91435460ff1690565b1561341e5750610ac29061397a565b6040516352d1902d60e01b8152906020826004816001600160a01b0387165afa5f9281613481575b506134645760405162461bcd60e51b815280610c3560048201613394565b610ac292610c575f516020613ed35f395f51905f525f9414613336565b61349b91935060203d602011610c8657610c778183610a92565b915f613446565b5f5261019160205260405f206134b78161378d565b156134d15761ffff600181835460081c1692015416111590565b505f90565b805f5261019160205260405f20600160ff19825416178155600581015460018060a01b038116906001613517600360ff60048701549460a01c169501612150565b936135218161140a565b036135bc57905f9261247a613550859460405192839160208301956331c6fcc960e21b87528a60248501613b55565b51915af461355c613b77565b901561359e578060208061357593518301019101613a79565b50505b7f712ae1383f79ac853f8d882153778e0260ef8f03b504e2866e0593e04d2b291f5f80a2565b8051156135ad57805190602001fd5b6318cecad560e01b5f5260045ffd5b5f916135e093836040518096819582946331c6fcc960e21b84528a60048501613b55565b03925af180156112de575f915f916135fb575b505050613578565b905061361991503d805f833e6136118183610a92565b810190613a79565b5f6135f3565b1561362657565b60405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b6064820152608490fd5b6001600160401b038111613699576001600160401b031690565b60405162461bcd60e51b815260206004820152602660248201527f53616665436173743a2076616c756520646f65736e27742066697420696e203660448201526534206269747360d01b6064820152608490fd5b604051602081019146835243604083015230606083015260808201526080815261371860a082610a92565b51902090565b61377161377f926001600160401b037fa6c1f8f4276dc3f243459e13b557c84e8f4e90b2e09070bad5f6909cee687c9296959897816040519716875216602086015260a0604086015260a085019061090a565b908382036060850152611390565b9360808201528033940390a3565b6137964261367f565b60ff8254161591826137c8575b826137ad57505090565b6001015460901c6001600160401b0390811691161115919050565b91506001600160401b03600183015460501c166001600160401b0382161015916137a3565b6137f643613a11565b6001600160e01b03831161382857613817926001600160e01b031691613ceb565b6001600160e01b0391821692911690565b60405162461bcd60e51b815260206004820152602760248201527f53616665436173743a2076616c756520646f65736e27742066697420696e20326044820152663234206269747360c81b6064820152608490fd5b6107af906001600160e01b03613894610160612de8565b16016101606137ed565b6107af906001600160e01b036138b5610160612de8565b16036101606137ed565b916138c98361397a565b6001600160a01b0383167fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b5f80a281511590811591613972575b5061390c575050565b611f18915f8060405193613921606086610a92565b602785527f416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c6020860152660819985a5b195960ca1b6040860152602081519101845af461396c613b77565b91613e01565b90505f613903565b803b156139b65760018060a01b03166001600160601b0360a01b5f516020613ed35f395f51905f525416175f516020613ed35f395f51905f5255565b60405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b6064820152608490fd5b63ffffffff8111613a255763ffffffff1690565b60405162461bcd60e51b815260206004820152602660248201527f53616665436173743a2076616c756520646f65736e27742066697420696e203360448201526532206269747360d01b6064820152608490fd5b91906040838203126104075782516001600160401b0381116104075783019080601f8301121561040757815191613aaf83612139565b92613abd6040519485610a92565b80845260208085019160051b830101918383116104075760208101915b838310613aef57505050505060209092015190565b82516001600160401b03811161040757820185603f8201121561040757602081015191613b1b83610ac4565b613b286040519182610a92565b8381526040838501018810610407575f602085819660408397018386015e83010152815201920191613ada565b939291613b72906040928652606060208701526060860190611390565b930152565b3d15613ba1573d90613b8882610ac4565b91613b966040519384610a92565b82523d5f602084013e565b606090565b5f602091604051838101906301ffc9a760e01b825263ffffffff60e01b602482015260248152613bd7604482610a92565b5191617530fa5f513d82613bf7575b5081613bf0575090565b9050151590565b6020111591505f613be6565b5f602091604051838101906301ffc9a760e01b8252632a4f53ad60e11b602482015260248152613bd7604482610a92565b908154600160401b811015610a575760018101808455811015612853575f92835260209283902082519284015190931b63ffffffff191663ffffffff9290921691909117910155565b90604051613c8a81610a77565b602081935463ffffffff81168352811c910152565b15613ca657565b60405162461bcd60e51b815260206004820152601b60248201527f436865636b706f696e743a2064656372656173696e67206b65797300000000006044820152606490fd5b909291928382548015155f14613dd757926020929184613d23613d1e613d13613d9d98612009565b855f5260205f200190565b613c7d565b9363ffffffff613d48613d3a875163ffffffff1690565b828416928391161115613c9f565b613d62613d59875163ffffffff1690565b63ffffffff1690565b03613da15750613d8f9261207d613d7892612009565b9063ffffffff82549181199060201b169116179055565b01516001600160e01b031690565b9190565b915050613dd291613dbf613db3610ab3565b63ffffffff9093168352565b6001600160e01b03881682860152613c34565b613d8f565b5050613dfc91613de8613db3610ab3565b6001600160e01b0385166020830152613c34565b5f9190565b91929015613e635750815115613e15575090565b3b15613e1e5790565b60405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606490fd5b825190915015613e765750805190602001fd5b60405162461bcd60e51b8152908190610c35906004830161092e56fe47ff9796f72d439c6e5c30a24b9fad985a00c85a9f2258074c400a94f8746b00f281525e53675515a6ba7cc7bea8a81e649b3608423ee2d73be1752cea887889360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbca2646970667358221220aae299ef4fb975e82201a669f98caba4d36a682a5467d94c317aec4cc0f4437964736f6c634300081c0033
Deployed Bytecode
0x6080806040526004361015610012575f80fd5b5f3560e01c90816301ffc9a714611001575080632ae9c60014610f845780635c60da1b14610f405780639cb0a12414610b7a578063a8a9c29e146106b45763f10832f11461005e575f80fd5b346106285760403660031901126106285761007761106b565b602435906001600160401b03821161062857366023830112156106285781600401356001600160401b038111610628578201906024820190368211610628576024846100c16112ef565b9403019160c06023198401126106285760248501356001600160401b038111610628578501948160438701121561062857602486013595610101876111f5565b9661010f60405198896111d4565b80885260206024818a019260051b840101019184831161062857604401905b82821061069c5750505060406043198501126106285760405192610151846111b9565b6044820135801515810361062857845260648201359461ffff86168603610628576040906020860196875260831901126106285760405190610192826111b9565b61019e60848401611081565b825260a4830135926002841015610628576020830193845260c4810135906001600160401b038211610628570190846043830112156106285760248201356001600160401b0381116106745760405195610202601f8301601f1916602001886111d4565b81875260448483010111610628576020815f92604461ffff9601838a01378701015260018060a01b0316956102596040519963370466ab60e21b60208c01528860248c015260e060448c01526101048b019061110b565b9551151560648a015251166084880152516001600160a01b031660a4870152516002811015610688576102b09286926102a29260c48501526023198483030160e48501526110e7565b03601f1981018552846111d4565b6040516103c693848201948286106001600160401b03871117610674578291610317916116f784397f0000000000000000000000009a09363c4b886025f9182e10b1081690b0b498d06001600160a01b0316808852604060208901819052909701906110e7565b03905ff080156106345760018060a01b0316916040516103ee808201908282106001600160401b0383111761067457602091839161130983398681520301905ff08015610634576001600160a01b03169361037061120c565b9060405161037d8161119e565b5f81528560208201528460408201525f60608201527fb1750e46d35a0069c8465b8643e7838d2149a842a2db8ee233d9835590040cad60808201526103c18361127e565b526103cb8261127e565b506040516103d88161119e565b5f81528460208201528560408201525f60608201527fbf04b4486c9663d805744005c3da000eda93de6e3308a4a7a812eb565327b78d608082015261041c8361129f565b526104268261129f565b50604051630239c48760e31b8152602081600481855afa908115610634575f9161063f575b5090600494602092604051906104608261119e565b600282528482018990526001600160a01b036040830152606082018a9052608082015261048c856112af565b52610496846112af565b506040516104a38161119e565b5f815287848201528160408201525f60608201527f568cc693d84eb1901f8bcecba154cbdef23ca3cf67efc0a0b698528a06c660f760808201526104e6856112bf565b526104f0846112bf565b50604051906104fe8261119e565b5f8252878483015260408201525f60608201527f4707e94b25cfce1a7c363508fbb838c35864388ad77284b248282b9746982b9b6080820152610540846112cf565b5261054a836112cf565b506040516319f9d6b160e31b815294859182905afa8015610634575f906105fc575b6105f893506040519061057e8261119e565b5f808352602083018790526001600160a01b036040840152606083015260808201526105a9826112df565b526105b3816112df565b5060208201526040936105e285516105cb87826111d4565b60018152601f19870136602083013780845261127e565b5283519384938452806020850152830190611147565b0390f35b506020833d60201161062c575b81610616602093836111d4565b81010312610628576105f8925161056c565b5f80fd5b3d9150610609565b6040513d5f823e3d90fd5b9190506020823d60201161066c575b8161065b602093836111d4565b81010312610628579051600461044b565b3d915061064e565b634e487b7160e01b5f52604160045260245ffd5b634e487b7160e01b5f52602160045260245ffd5b602080916106a984611081565b81520191019061012e565b34610628576060366003190112610628576106cd61106b565b60243561ffff811680910361062857604435916001600160401b03831161062857826004019183360360606003198201126106285760609461070d6112ef565b9460038410610741575b610733876105f8886040519384936040855260408501906110e7565b908382036020850152611147565b6107508197929394959761126a565b604051906103ee8083018381106001600160401b0382111761067457602092849261130984396001600160a01b031681520301905ff08015610634576001600160a01b0316966040519260c06107a681866111d4565b60058552601f19015f5b818110610b465750506107c28361126a565b91604051926107d08461119e565b600184526001600160a01b03908116602085015216604083018190525f828401527f821b6e3a557148015a918c89e5d092e878a69854a2d1a410635f771bd5a8a3f56080840152916108218561127e565b5261082b8461127e565b506108358361126a565b604051630239c48760e31b81527f0000000000000000000000009a09363c4b886025f9182e10b1081690b0b498d06001600160a01b0316949190602081600481895afa908115610634578c905f92610b0a575b50946109b09260209492600497604051926108a28461119e565b600284526001600160a01b039081168885015260408401528783015260808201526108cc8961129f565b526108d68861129f565b506108e08261126a565b604051906108ed8261119e565b5f825260018060a01b0316858201528160408201525f868201527f568cc693d84eb1901f8bcecba154cbdef23ca3cf67efc0a0b698528a06c660f76080820152610936896112af565b52610940886112af565b5061094a8261126a565b90604051916109588361119e565b5f835260018060a01b03168583015260408201525f858201527f4707e94b25cfce1a7c363508fbb838c35864388ad77284b248282b9746982b9b60808201526109a0886112bf565b526109aa876112bf565b5061126a565b93604051938480926319f9d6b160e31b82525afa918215610634575f92610ad6575b505f90604051936109e28561119e565b8285526001600160a01b03908116602086015260408501528301526080820152610a0b826112cf565b52610a15816112cf565b506020850152604094610a448651610a2d88826111d4565b60018152601f19880136602083013780875261127e565b52604481013591602219018212156106285701926004840135936001600160401b038511610628576024019380360385136106285760846105f89382610acd936107339886519687946308641fa760e11b602087015260248601526044850152816064850152848401375f838284010152601f801991011681010301601f1981018352826111d4565b92848080610717565b9091506020813d602011610b02575b81610af2602093836111d4565b810103126106285751905f6109d2565b3d9150610ae5565b92939150506020823d602011610b3e575b81610b28602093836111d4565b810103126106285790519091908b6109b0610888565b3d9150610b1b565b602090604051610b558161119e565b5f81525f838201525f60408201525f858201525f6080820152828289010152016107b0565b3461062857604036600319011261062857610b9361106b565b6024356001600160401b0381116106285760608160040191600319903603011261062857610bbf61120c565b91610bc98261126a565b9060405191610bd78361119e565b600183526001600160a01b03908116602084015216604082018190525f60608301527fb1750e46d35a0069c8465b8643e7838d2149a842a2db8ee233d9835590040cad608083015290610c298461127e565b52610c338361127e565b50610c3d8261126a565b60405190610c4a8261119e565b60018252602082018390526001600160a01b031660408201525f60608201527fbf04b4486c9663d805744005c3da000eda93de6e3308a4a7a812eb565327b78d6080820152610c988461129f565b52610ca28361129f565b50610cac8261126a565b60405190610cb98261119e565b600182526001600160a01b03166020820152604081018290525f60608201527f568cc693d84eb1901f8bcecba154cbdef23ca3cf67efc0a0b698528a06c660f76080820152610d07846112af565b52610d11836112af565b50610d1b8261126a565b9060405191610d298361119e565b600183526001600160a01b0316602083015260408201525f60608201527f4707e94b25cfce1a7c363508fbb838c35864388ad77284b248282b9746982b9b6080820152610d75836112bf565b52610d7f826112bf565b50610d898161126a565b604051630239c48760e31b81527f0000000000000000000000009a09363c4b886025f9182e10b1081690b0b498d06001600160a01b0316929190602081600481875afa908115610634575f91610f0d575b50600492602092610e289260405191610df28361119e565b600183526001600160a01b039081168684015260408301525f60608301526080820152610e1e876112cf565b526109aa866112cf565b92604051928380926319f9d6b160e31b82525afa908115610634575f91610edb575b5060405191610e588361119e565b600183526001600160a01b03908116602084015260408301525f60608301526080820152610e85826112df565b52610e8f816112df565b506040518091602082016020835281518091526020604084019201905f5b818110610ebb575050500390f35b919350916020610ece6001928651611095565b9401910191849392610ead565b90506020813d602011610f05575b81610ef6602093836111d4565b81010312610628575183610e4a565b3d9150610ee9565b90506020813d602011610f38575b81610f28602093836111d4565b8101031261062857516004610dda565b3d9150610f1b565b34610628575f366003190112610628576040517f0000000000000000000000009a09363c4b886025f9182e10b1081690b0b498d06001600160a01b03168152602090f35b34610628575f36600319011261062857606080604051610fa482826111d4565b3690376040518181018181106001600160401b038211176106745760405260018152600460208201525f604082015260405190815f905b60038210610fe857505050f35b60208060019260ff865116815201930191019091610fdb565b34610628576020366003190112610628576004359063ffffffff60e01b82168092036106285760209163099718b560e41b811490811561105b575b811561104a575b5015158152f35b6301ffc9a760e01b14905083611043565b621574e360e91b8114915061103c565b600435906001600160a01b038216820361062857565b35906001600160a01b038216820361062857565b90815160038110156106885760a0926080918352600180851b036020820151166020840152600180851b036040820151166040840152600180851b036060820151166060840152015160808201520190565b805180835260209291819084018484015e5f828201840152601f01601f1916010190565b90602080835192838152019201905f5b8181106111285750505090565b82516001600160a01b031684526020938401939092019160010161111b565b602061115c825160408552604085019061110b565b91015182820360209384015280518083529183019201905f5b8181106111825750505090565b90919260206111946001928651611095565b9401929101611175565b60a081019081106001600160401b0382111761067457604052565b604081019081106001600160401b0382111761067457604052565b90601f801991011681019081106001600160401b0382111761067457604052565b6001600160401b0381116106745760051b60200190565b60405160e0919061121d83826111d4565b6006815291601f1901825f5b82811061123557505050565b6020906040516112448161119e565b5f81525f838201525f60408201525f60608201525f608082015282828501015201611229565b356001600160a01b03811681036106285790565b80511561128b5760200190565b634e487b7160e01b5f52603260045260245ffd5b80516001101561128b5760400190565b80516002101561128b5760600190565b80516003101561128b5760800190565b80516004101561128b5760a00190565b80516005101561128b5760c00190565b604051906112fc826111b9565b6060602083828152015256fe60a034606857601f6103ee38819003918201601f19168301916001600160401b03831184841017606c57808492602094604052833981010312606857516001600160a01b0381169081900360685760805260405161036d90816100818239608051816102110152f35b5f80fd5b634e487b7160e01b5f52604160045260245ffdfe6080806040526004361015610012575f80fd5b5f3560e01c90816301ffc9a714610151575080632675fdd0146100d357632ae9c6001461003d575f80fd5b346100cf575f3660031901126100cf5760608060405161005d82826101d1565b36903760405181810181811067ffffffffffffffff8211176100bb5760405260018152600460208201525f604082015260405190815f905b600382106100a257505050f35b60208060019260ff865116815201930191019091610095565b634e487b7160e01b5f52604160045260245ffd5b5f80fd5b346100cf5760803660031901126100cf576100ec6101bb565b506024356001600160a01b03811681036100cf5760643567ffffffffffffffff81116100cf57366023820112156100cf57806004013567ffffffffffffffff81116100cf57369101602401116100cf57610147602091610200565b6040519015158152f35b346100cf5760203660031901126100cf576004359063ffffffff60e01b82168092036100cf576020916302675fdd60e41b81149081156101ab575b811561019a575b5015158152f35b6301ffc9a760e01b14905083610193565b621574e360e91b8114915061018c565b600435906001600160a01b03821682036100cf57565b90601f8019910116810190811067ffffffffffffffff8211176100bb57604052565b519081151582036100cf57565b6040805163e097b3ff60e01b8152917f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169183600481855afa9283156102e1575f936102ec575b5082610265575b505061026157600190565b5f90565b604051637bca031760e11b81526001600160a01b0390911660048201529150602090829060249082905afa9081156102e1575f916102a7575b50155f80610256565b90506020813d6020116102d9575b816102c2602093836101d1565b810103126100cf576102d3906101f3565b5f61029e565b3d91506102b5565b6040513d5f823e3d90fd5b9092506040813d60401161032f575b81610308604093836101d1565b810103126100cf57602061031b826101f3565b91015161ffff8116036100cf57915f61024f565b3d91506102fb56fea26469706673582212205aeaf15076ce6f4b55b0d041e4bd71e6b993c63941431759b3816b69d2e5bf3464736f6c634300081c003360806040526103c680380380610014816101f2565b9283398101906040818303126101ee5780516001600160a01b038116918282036101ee576020810151906001600160401b0382116101ee57019183601f840112156101ee57825161006c6100678261022b565b6101f2565b938185526020850195602083830101116101ee57815f926020809301885e85010152813b15610193577f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc80546001600160a01b031916821790557fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b5f80a281511580159061018c575b610108575b60405160cb90816102fb8239f35b5f8061017b9461011860606101f2565b94602786527f416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c6020870152660819985a5b195960ca1b60408701525190845af43d15610184573d9161016c6100678461022b565b9283523d5f602085013e610246565b505f80806100fa565b606091610246565b505f6100f5565b60405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b6064820152608490fd5b5f80fd5b6040519190601f01601f191682016001600160401b0381118382101761021757604052565b634e487b7160e01b5f52604160045260245ffd5b6001600160401b03811161021757601f01601f191660200190565b919290156102a8575081511561025a575090565b3b156102635790565b60405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606490fd5b8251909150156102bb5750805190602001fd5b604460209160405192839162461bcd60e51b83528160048401528051918291826024860152018484015e5f828201840152601f01601f19168101030190fdfe608060405236156051577f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc545f9081906001600160a01b0316368280378136915af43d5f803e15604d573d5ff35b3d5ffd5b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc545f9081906001600160a01b0316368280378136915af43d5f803e15604d573d5ff3fea26469706673582212203bf93d98380d30a31ff94676bcd53f6cf4fd06145a15d34fda5d76afee117ce864736f6c634300081c0033a2646970667358221220594a9d2c51151c2c59af09fbbd611784365e9f60d9e3896de2125c33f8f727ab64736f6c634300081c0033
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 34 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|
Loading...
Loading
Loading...
Loading
Loading...
Loading
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.