Overview
ETH Balance
0 ETH
Eth Value
$0.00More Info
Private Name Tags
ContractCreator
Latest 25 from a total of 267 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Create Superform | 20890922 | 44 hrs ago | IN | 0 ETH | 0.0021871 | ||||
Create Superform | 20890916 | 44 hrs ago | IN | 0 ETH | 0.00201284 | ||||
Create Superform | 20890904 | 44 hrs ago | IN | 0 ETH | 0.00200842 | ||||
Create Superform | 20871812 | 4 days ago | IN | 0 ETH | 0.00671687 | ||||
Create Superform | 20837994 | 9 days ago | IN | 0 ETH | 0.00494663 | ||||
Create Superform | 20828373 | 10 days ago | IN | 0 ETH | 0.00855646 | ||||
Create Superform | 20828371 | 10 days ago | IN | 0 ETH | 0.00840692 | ||||
Create Superform | 20828369 | 10 days ago | IN | 0 ETH | 0.00798889 | ||||
Create Superform | 20828367 | 10 days ago | IN | 0 ETH | 0.00742485 | ||||
Create Superform | 20828360 | 10 days ago | IN | 0 ETH | 0.00804176 | ||||
Create Superform | 20828351 | 10 days ago | IN | 0 ETH | 0.00736304 | ||||
Create Superform | 20823495 | 11 days ago | IN | 0 ETH | 0.00482668 | ||||
Create Superform | 20764165 | 19 days ago | IN | 0 ETH | 0.00372244 | ||||
Create Superform | 20759998 | 20 days ago | IN | 0 ETH | 0.00064647 | ||||
Create Superform | 20759953 | 20 days ago | IN | 0 ETH | 0.000622 | ||||
Create Superform | 20759904 | 20 days ago | IN | 0 ETH | 0.00063215 | ||||
Create Superform | 20759719 | 20 days ago | IN | 0 ETH | 0.00059086 | ||||
Create Superform | 20759511 | 20 days ago | IN | 0 ETH | 0.0005287 | ||||
Create Superform | 20742866 | 22 days ago | IN | 0 ETH | 0.00199021 | ||||
Create Superform | 20742817 | 22 days ago | IN | 0 ETH | 0.00226587 | ||||
Create Superform | 20735629 | 23 days ago | IN | 0 ETH | 0.00287674 | ||||
Create Superform | 20729823 | 24 days ago | IN | 0 ETH | 0.00115517 | ||||
Create Superform | 20729206 | 24 days ago | IN | 0 ETH | 0.00114091 | ||||
Create Superform | 20729202 | 24 days ago | IN | 0 ETH | 0.00115015 | ||||
Create Superform | 20729199 | 24 days ago | IN | 0 ETH | 0.00121672 |
Latest 25 internal transactions (View All)
Advanced mode:
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:
SuperformFactory
Compiler Version
v0.8.23+commit.f704f362
Optimization Enabled:
Yes with 200 runs
Other Settings:
paris EvmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.23; import { ISuperformFactory } from "src/interfaces/ISuperformFactory.sol"; import { Broadcastable } from "src/crosschain-data/utils/Broadcastable.sol"; import { BaseForm } from "src/BaseForm.sol"; import { BroadcastMessage } from "src/types/DataTypes.sol"; import { IBaseForm } from "src/interfaces/IBaseForm.sol"; import { ISuperRBAC } from "src/interfaces/ISuperRBAC.sol"; import { ISuperRegistry } from "src/interfaces/ISuperRegistry.sol"; import { DataLib } from "src/libraries/DataLib.sol"; import { Error } from "src/libraries/Error.sol"; import { ERC165Checker } from "openzeppelin-contracts/contracts/utils/introspection/ERC165Checker.sol"; import { IERC4626 } from "openzeppelin-contracts/contracts/interfaces/IERC4626.sol"; import { Clones } from "openzeppelin-contracts/contracts/proxy/Clones.sol"; /// @title SuperformFactory /// @dev Central point of read & write access for all Superforms on this chain /// @author Zeropoint Labs contract SuperformFactory is ISuperformFactory, Broadcastable { using DataLib for uint256; using Clones for address; ////////////////////////////////////////////////////////////// // CONSTANTS // ////////////////////////////////////////////////////////////// ISuperRegistry public immutable superRegistry; uint64 public immutable CHAIN_ID; bytes32 constant SYNC_IMPLEMENTATION_STATUS = keccak256("SYNC_IMPLEMENTATION_STATUS"); ////////////////////////////////////////////////////////////// // STATE VARIABLES // ////////////////////////////////////////////////////////////// uint256 public xChainPayloadCounter; /// @dev all form implementation addresses address[] public formImplementations; /// @dev all superform ids uint256[] public superforms; mapping(uint256 superformId => bool superformIdExists) public isSuperform; /// @notice If formImplementationId is 0, formImplementation is not part of the protocol mapping(uint32 formImplementationId => address formImplementationAddress) public formImplementation; /// @dev each form implementation address can correspond only to a single formImplementationId mapping(address formImplementationAddress => uint32 formImplementationId) public formImplementationIds; /// @dev this mapping is used only for crosschain cases and should be same across all the chains mapping(uint32 formImplementationId => uint8 formRegistryId) public formStateRegistryId; mapping(uint32 formImplementationId => PauseStatus) public formImplementationPaused; mapping(address vault => uint256[] superformIds) public vaultToSuperforms; mapping(address vault => uint256[] formImplementationId) public vaultToFormImplementationId; mapping(bytes32 vaultFormImplementationCombination => uint256 superformIds) public vaultFormImplCombinationToSuperforms; ////////////////////////////////////////////////////////////// // MODIFIERS // ////////////////////////////////////////////////////////////// modifier onlyEmergencyAdmin() { if (!ISuperRBAC(superRegistry.getAddress(keccak256("SUPER_RBAC"))).hasEmergencyAdminRole(msg.sender)) { revert Error.NOT_EMERGENCY_ADMIN(); } _; } modifier onlyProtocolAdmin() { if (!ISuperRBAC(superRegistry.getAddress(keccak256("SUPER_RBAC"))).hasProtocolAdminRole(msg.sender)) { revert Error.NOT_PROTOCOL_ADMIN(); } _; } modifier onlyBroadcastRegistry() { /// @dev this function is only accessible through broadcast registry if (msg.sender != superRegistry.getAddress(keccak256("BROADCAST_REGISTRY"))) { revert Error.NOT_BROADCAST_REGISTRY(); } _; } ////////////////////////////////////////////////////////////// // CONSTRUCTOR // ////////////////////////////////////////////////////////////// /// @param superRegistry_ the superform registry contract constructor(address superRegistry_) { if (superRegistry_ == address(0)) { revert Error.ZERO_ADDRESS(); } if (block.chainid > type(uint64).max) { revert Error.BLOCK_CHAIN_ID_OUT_OF_BOUNDS(); } CHAIN_ID = uint64(block.chainid); superRegistry = ISuperRegistry(superRegistry_); } ////////////////////////////////////////////////////////////// // EXTERNAL VIEW FUNCTIONS // ////////////////////////////////////////////////////////////// /// @inheritdoc ISuperformFactory function getFormCount() external view override returns (uint256 forms_) { forms_ = formImplementations.length; } /// @inheritdoc ISuperformFactory function getSuperformCount() external view override returns (uint256 superforms_) { superforms_ = superforms.length; } /// @inheritdoc ISuperformFactory function getFormImplementation(uint32 formImplementationId_) external view override returns (address) { return formImplementation[formImplementationId_]; } /// @inheritdoc ISuperformFactory function getFormStateRegistryId(uint32 formImplementationId_) external view override returns (uint8 formStateRegistryId_) { formStateRegistryId_ = formStateRegistryId[formImplementationId_]; if (formStateRegistryId_ == 0) revert Error.INVALID_FORM_REGISTRY_ID(); } /// @inheritdoc ISuperformFactory function isFormImplementationPaused(uint32 formImplementationId_) external view override returns (bool) { return formImplementationPaused[formImplementationId_] == PauseStatus.PAUSED; } /// @inheritdoc ISuperformFactory function getSuperform(uint256 superformId_) external pure override returns (address superform_, uint32 formImplementationId_, uint64 chainId_) { (superform_, formImplementationId_, chainId_) = superformId_.getSuperform(); } /// @inheritdoc ISuperformFactory function getAllSuperformsFromVault(address vault_) external view override returns (uint256[] memory superformIds_, address[] memory superforms_) { superformIds_ = vaultToSuperforms[vault_]; uint256 len = superformIds_.length; superforms_ = new address[](len); for (uint256 i; i < len; ++i) { (superforms_[i],,) = superformIds_[i].getSuperform(); } } ////////////////////////////////////////////////////////////// // EXTERNAL WRITE FUNCTIONS // ////////////////////////////////////////////////////////////// /// @inheritdoc ISuperformFactory function addFormImplementation( address formImplementation_, uint32 formImplementationId_, uint8 formStateRegistryId_ ) public override onlyProtocolAdmin { if (formImplementation_ == address(0)) revert Error.ZERO_ADDRESS(); if (!ERC165Checker.supportsERC165(formImplementation_)) revert Error.ERC165_UNSUPPORTED(); if (formImplementation[formImplementationId_] != address(0)) { revert Error.FORM_IMPLEMENTATION_ALREADY_EXISTS(); } if (formImplementationIds[formImplementation_] != 0) { revert Error.FORM_IMPLEMENTATION_ID_ALREADY_EXISTS(); } if (!ERC165Checker.supportsInterface(formImplementation_, type(IBaseForm).interfaceId)) { revert Error.FORM_INTERFACE_UNSUPPORTED(); } /// @dev save the newly added address in the mapping and array registry formImplementation[formImplementationId_] = formImplementation_; formImplementationIds[formImplementation_] = formImplementationId_; /// @dev set CoreStateRegistry if the form implementation needs no special state registry /// @dev if the form needs any special state registry, set this value to the id of the special state registry /// and core state registry can be used by default. /// @dev if this value is != 1, then the form supports two state registries (CoreStateRegistry + its special /// state registry) if (formStateRegistryId_ == 0) { revert Error.INVALID_FORM_REGISTRY_ID(); } formStateRegistryId[formImplementationId_] = formStateRegistryId_; formImplementations.push(formImplementation_); emit FormImplementationAdded(formImplementation_, formImplementationId_, formStateRegistryId_); } /// @inheritdoc ISuperformFactory function createSuperform( uint32 formImplementationId_, address vault_ ) public override returns (uint256 superformId_, address superform_) { if (vault_ == address(0)) revert Error.ZERO_ADDRESS(); address tFormImplementation = formImplementation[formImplementationId_]; if (tFormImplementation == address(0)) revert Error.FORM_DOES_NOT_EXIST(); /// @dev Same vault and implementation can be used only once to create superform bytes32 vaultFormImplementationCombination = keccak256(abi.encode(tFormImplementation, vault_)); if (vaultFormImplCombinationToSuperforms[vaultFormImplementationCombination] != 0) { revert Error.VAULT_FORM_IMPLEMENTATION_COMBINATION_EXISTS(); } /// @dev instantiate the superform superform_ = tFormImplementation.cloneDeterministic( keccak256(abi.encode(uint256(CHAIN_ID), formImplementationId_, vault_)) ); BaseForm(payable(superform_)).initialize(address(superRegistry), vault_, address(IERC4626(vault_).asset())); /// @dev this will always be unique because all chainIds are unique superformId_ = DataLib.packSuperform(superform_, formImplementationId_, CHAIN_ID); vaultToSuperforms[vault_].push(superformId_); /// @dev map vaults to formImplementationId vaultToFormImplementationId[vault_].push(formImplementationId_); vaultFormImplCombinationToSuperforms[vaultFormImplementationCombination] = superformId_; superforms.push(superformId_); isSuperform[superformId_] = true; emit SuperformCreated(formImplementationId_, vault_, superformId_, superform_); } /// @inheritdoc ISuperformFactory function changeFormImplementationPauseStatus( uint32 formImplementationId_, PauseStatus status_, bytes memory extraData_ ) external payable override onlyEmergencyAdmin { if (formImplementation[formImplementationId_] == address(0)) revert Error.INVALID_FORM_ID(); formImplementationPaused[formImplementationId_] = status_; /// @dev broadcast the change in status to the other destination chains if (extraData_.length != 0) { BroadcastMessage memory factoryPayload = BroadcastMessage( "SUPERFORM_FACTORY", SYNC_IMPLEMENTATION_STATUS, abi.encode(CHAIN_ID, ++xChainPayloadCounter, formImplementationId_, status_) ); _broadcast( superRegistry.getAddress(keccak256("BROADCAST_REGISTRY")), superRegistry.getAddress(keccak256("PAYMASTER")), abi.encode(factoryPayload), extraData_ ); } else if (msg.value != 0) { revert Error.MSG_VALUE_NOT_ZERO(); } emit FormImplementationPaused(formImplementationId_, status_); } /// @inheritdoc ISuperformFactory function stateSyncBroadcast(bytes memory data_) external payable override onlyBroadcastRegistry { BroadcastMessage memory factoryPayload = abi.decode(data_, (BroadcastMessage)); if (factoryPayload.messageType == SYNC_IMPLEMENTATION_STATUS) { _syncFormPausedStatus(factoryPayload.message); } } ////////////////////////////////////////////////////////////// // INTERNAL FUNCTIONS // ////////////////////////////////////////////////////////////// /// @dev synchronize paused status update message from remote chain /// @notice is a part of broadcasting / dispatching through factory state registry /// @param message_ is the crosschain message received. function _syncFormPausedStatus(bytes memory message_) internal { (,, uint32 formImplementationId, PauseStatus paused) = abi.decode(message_, (uint64, uint256, uint32, PauseStatus)); if (formImplementation[formImplementationId] == address(0)) revert Error.INVALID_FORM_ID(); formImplementationPaused[formImplementationId] = paused; emit FormImplementationPaused(formImplementationId, paused); } }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.23; /// @title ISuperformFactory /// @dev Interface for SuperformFactory /// @author ZeroPoint Labs interface ISuperformFactory { ////////////////////////////////////////////////////////////// // CONSTANTS // ////////////////////////////////////////////////////////////// enum PauseStatus { NON_PAUSED, PAUSED } ////////////////////////////////////////////////////////////// // EVENTS // ////////////////////////////////////////////////////////////// /// @dev emitted when a new formImplementation is entered into the factory /// @param formImplementation is the address of the new form implementation /// @param formImplementationId is the id of the formImplementation /// @param formStateRegistryId is any additional state registry id of the formImplementation event FormImplementationAdded( address indexed formImplementation, uint256 indexed formImplementationId, uint8 indexed formStateRegistryId ); /// @dev emitted when a new Superform is created /// @param formImplementationId is the id of the form implementation /// @param vault is the address of the vault /// @param superformId is the id of the superform /// @param superform is the address of the superform event SuperformCreated( uint256 indexed formImplementationId, address indexed vault, uint256 indexed superformId, address superform ); /// @dev emitted when a new SuperRegistry is set /// @param superRegistry is the address of the super registry event SuperRegistrySet(address indexed superRegistry); /// @dev emitted when a form implementation is paused /// @param formImplementationId is the id of the form implementation /// @param paused is the new paused status event FormImplementationPaused(uint256 indexed formImplementationId, PauseStatus indexed paused); ////////////////////////////////////////////////////////////// // EXTERNAL VIEW FUNCTIONS // ////////////////////////////////////////////////////////////// /// @dev returns the number of forms /// @return forms_ is the number of forms function getFormCount() external view returns (uint256 forms_); /// @dev returns the number of superforms /// @return superforms_ is the number of superforms function getSuperformCount() external view returns (uint256 superforms_); /// @dev returns the address of a form implementation /// @param formImplementationId_ is the id of the form implementation /// @return formImplementation_ is the address of the form implementation function getFormImplementation(uint32 formImplementationId_) external view returns (address formImplementation_); /// @dev returns the form state registry id of a form implementation /// @param formImplementationId_ is the id of the form implementation /// @return stateRegistryId_ is the additional state registry id of the form function getFormStateRegistryId(uint32 formImplementationId_) external view returns (uint8 stateRegistryId_); /// @dev returns the paused status of form implementation /// @param formImplementationId_ is the id of the form implementation /// @return paused_ is the current paused status of the form formImplementationId_ function isFormImplementationPaused(uint32 formImplementationId_) external view returns (bool paused_); /// @dev returns the address of a superform /// @param superformId_ is the id of the superform /// @return superform_ is the address of the superform /// @return formImplementationId_ is the id of the form implementation /// @return chainId_ is the chain id function getSuperform(uint256 superformId_) external pure returns (address superform_, uint32 formImplementationId_, uint64 chainId_); /// @dev returns if an address has been added to a Form /// @param superformId_ is the id of the superform /// @return isSuperform_ bool if it exists function isSuperform(uint256 superformId_) external view returns (bool isSuperform_); /// @dev Reverse query of getSuperform, returns all superforms for a given vault /// @param vault_ is the address of a vault /// @return superformIds_ is the id of the superform /// @return superforms_ is the address of the superform function getAllSuperformsFromVault(address vault_) external view returns (uint256[] memory superformIds_, address[] memory superforms_); ////////////////////////////////////////////////////////////// // EXTERNAL WRITE FUNCTIONS // ////////////////////////////////////////////////////////////// /// @dev allows an admin to add a Form implementation to the factory /// @param formImplementation_ is the address of a form implementation /// @param formImplementationId_ is the id of the form implementation (generated off-chain and equal in all chains) /// @param formStateRegistryId_ is the id of any additional state registry for that form /// @dev formStateRegistryId_ 1 is default for all form implementations, pass in formStateRegistryId_ only if an /// additional state registry is required function addFormImplementation( address formImplementation_, uint32 formImplementationId_, uint8 formStateRegistryId_ ) external; /// @dev To add new vaults to Form implementations, fusing them together into Superforms /// @param formImplementationId_ is the form implementation we want to attach the vault to /// @param vault_ is the address of the vault /// @return superformId_ is the id of the created superform /// @return superform_ is the address of the created superform function createSuperform( uint32 formImplementationId_, address vault_ ) external returns (uint256 superformId_, address superform_); /// @dev to synchronize superforms added to different chains using broadcast registry /// @param data_ is the cross-chain superform id function stateSyncBroadcast(bytes memory data_) external payable; /// @dev allows an admin to change the status of a form /// @param formImplementationId_ is the id of the form implementation /// @param status_ is the new status /// @param extraData_ is optional & passed when broadcasting of status is needed function changeFormImplementationPauseStatus( uint32 formImplementationId_, PauseStatus status_, bytes memory extraData_ ) external payable; }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.23; import { IBroadcastRegistry } from "src/interfaces/IBroadcastRegistry.sol"; import { Error } from "src/libraries/Error.sol"; /// @title Broadcastable /// @dev Can be inherited in contracts that wish to support broadcasting /// @author ZeroPoint Labs abstract contract Broadcastable { ////////////////////////////////////////////////////////////// // INTERNAL FUNCTIONS // ////////////////////////////////////////////////////////////// /// @dev broadcasts state changes to all connected remote chains /// @param broadcastRegistry_ is the address of the broadcast registry contract. /// @param payMaster_ is the address of the paymaster contract. /// @param message_ is the crosschain message to be sent. /// @param extraData_ is the amb override information. function _broadcast( address broadcastRegistry_, address payMaster_, bytes memory message_, bytes memory extraData_ ) internal { (uint8 ambId, bytes memory broadcastParams) = abi.decode(extraData_, (uint8, bytes)); /// @dev if the broadcastParams are wrong this will revert (uint256 gasFee, bytes memory extraData) = abi.decode(broadcastParams, (uint256, bytes)); if (msg.value < gasFee) { revert Error.INVALID_BROADCAST_FEE(); } /// @dev ambIds are validated inside the broadcast state registry IBroadcastRegistry(broadcastRegistry_).broadcastPayload{ value: gasFee }( msg.sender, ambId, gasFee, message_, extraData ); if (msg.value > gasFee) { /// @dev forwards the rest to paymaster (bool success,) = payable(payMaster_).call{ value: msg.value - gasFee }(""); if (!success) { revert Error.FAILED_TO_SEND_NATIVE(); } } } }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.23; import { IBaseForm } from "src/interfaces/IBaseForm.sol"; import { ISuperRegistry } from "src/interfaces/ISuperRegistry.sol"; import { ISuperformFactory } from "src/interfaces/ISuperformFactory.sol"; import { IEmergencyQueue } from "src/interfaces/IEmergencyQueue.sol"; import { DataLib } from "src/libraries/DataLib.sol"; import { Error } from "src/libraries/Error.sol"; import { InitSingleVaultData } from "src/types/DataTypes.sol"; import { Initializable } from "openzeppelin-contracts/contracts/proxy/utils/Initializable.sol"; import { ERC165 } from "openzeppelin-contracts/contracts/utils/introspection/ERC165.sol"; import { IERC165 } from "openzeppelin-contracts/contracts/utils/introspection/IERC165.sol"; /// @title BaseForm /// @dev Abstract contract to be inherited by different Form implementations /// @author Zeropoint Labs abstract contract BaseForm is IBaseForm, Initializable, ERC165 { using DataLib for uint256; ////////////////////////////////////////////////////////////// // CONSTANTS // ////////////////////////////////////////////////////////////// ISuperRegistry public immutable superRegistry; uint64 public immutable CHAIN_ID; ////////////////////////////////////////////////////////////// // STATE VARIABLES // ////////////////////////////////////////////////////////////// /// @dev the address of the vault that was added address public vault; /// @dev underlying asset of vault this form pertains to address public asset; ////////////////////////////////////////////////////////////// // MODIFIERS // ////////////////////////////////////////////////////////////// modifier notPaused(InitSingleVaultData memory singleVaultData_) { if ( !ISuperformFactory(superRegistry.getAddress(keccak256("SUPERFORM_FACTORY"))).isSuperform( singleVaultData_.superformId ) ) { revert Error.SUPERFORM_ID_NONEXISTENT(); } (, uint32 formImplementationId_,) = singleVaultData_.superformId.getSuperform(); if ( ISuperformFactory(superRegistry.getAddress(keccak256("SUPERFORM_FACTORY"))).isFormImplementationPaused( formImplementationId_ ) ) revert Error.PAUSED(); _; } modifier onlySuperRouter() { if (superRegistry.getAddress(keccak256("SUPERFORM_ROUTER")) != msg.sender) revert Error.NOT_SUPERFORM_ROUTER(); _; } modifier onlyCoreStateRegistry() { if (superRegistry.getAddress(keccak256("CORE_STATE_REGISTRY")) != msg.sender) { revert Error.NOT_CORE_STATE_REGISTRY(); } _; } modifier onlyEmergencyQueue() { if (msg.sender != superRegistry.getAddress(keccak256("EMERGENCY_QUEUE"))) { revert Error.NOT_EMERGENCY_QUEUE(); } _; } ////////////////////////////////////////////////////////////// // CONSTRUCTOR // ////////////////////////////////////////////////////////////// constructor(address superRegistry_) { if (superRegistry_ == address(0)) { revert Error.ZERO_ADDRESS(); } if (block.chainid > type(uint64).max) { revert Error.BLOCK_CHAIN_ID_OUT_OF_BOUNDS(); } CHAIN_ID = uint64(block.chainid); superRegistry = ISuperRegistry(superRegistry_); _disableInitializers(); } ////////////////////////////////////////////////////////////// // EXTERNAL VIEW FUNCTIONS // ////////////////////////////////////////////////////////////// /// @inheritdoc IBaseForm function superformYieldTokenName() external view virtual override returns (string memory); /// @inheritdoc IBaseForm function superformYieldTokenSymbol() external view virtual override returns (string memory); /// @inheritdoc IBaseForm function getStateRegistryId() external view virtual override returns (uint8); // @inheritdoc IBaseForm function getVaultAddress() external view override returns (address) { return vault; } // @inheritdoc IBaseForm function getVaultAsset() public view override returns (address) { return asset; } /// @inheritdoc IBaseForm function getVaultName() public view virtual override returns (string memory); /// @inheritdoc IBaseForm function getVaultSymbol() public view virtual override returns (string memory); /// @inheritdoc IBaseForm function getVaultDecimals() public view virtual override returns (uint256); /// @inheritdoc IBaseForm function getPricePerVaultShare() public view virtual override returns (uint256); /// @inheritdoc IBaseForm function getVaultShareBalance() public view virtual override returns (uint256); /// @inheritdoc IBaseForm function getTotalAssets() public view virtual override returns (uint256); /// @inheritdoc IBaseForm function getTotalSupply() public view virtual override returns (uint256); // @inheritdoc IBaseForm function getPreviewPricePerVaultShare() public view virtual override returns (uint256); /// @inheritdoc IBaseForm function previewDepositTo(uint256 assets_) public view virtual override returns (uint256); /// @inheritdoc IBaseForm function previewWithdrawFrom(uint256 assets_) public view virtual override returns (uint256); /// @inheritdoc IBaseForm function previewRedeemFrom(uint256 shares_) public view virtual override returns (uint256); ////////////////////////////////////////////////////////////// // EXTERNAL WRITE FUNCTIONS // ////////////////////////////////////////////////////////////// /// @param superRegistry_ ISuperRegistry address deployed /// @param vault_ The vault address this form pertains to /// @param asset_ The underlying asset address of the vault this form pertains to function initialize(address superRegistry_, address vault_, address asset_) external initializer { if (ISuperRegistry(superRegistry_) != superRegistry) revert Error.NOT_SUPER_REGISTRY(); if (vault_ == address(0) || asset_ == address(0)) revert Error.ZERO_ADDRESS(); vault = vault_; asset = asset_; } /// @inheritdoc IBaseForm function directDepositIntoVault( InitSingleVaultData memory singleVaultData_, address srcSender_ ) external payable override onlySuperRouter notPaused(singleVaultData_) returns (uint256 shares) { shares = _directDepositIntoVault(singleVaultData_, srcSender_); } /// @inheritdoc IBaseForm function directWithdrawFromVault( InitSingleVaultData memory singleVaultData_, address srcSender_ ) external override onlySuperRouter returns (uint256 assets) { if (!_isPaused(singleVaultData_.superformId)) { assets = _directWithdrawFromVault(singleVaultData_, srcSender_); } else { IEmergencyQueue(superRegistry.getAddress(keccak256("EMERGENCY_QUEUE"))).queueWithdrawal(singleVaultData_); } } /// @inheritdoc IBaseForm function xChainDepositIntoVault( InitSingleVaultData memory singleVaultData_, address srcSender_, uint64 srcChainId_ ) external override onlyCoreStateRegistry notPaused(singleVaultData_) returns (uint256 shares) { if (srcChainId_ != 0 && srcChainId_ != CHAIN_ID) { shares = _xChainDepositIntoVault(singleVaultData_, srcSender_, srcChainId_); } else { revert Error.INVALID_CHAIN_ID(); } } /// @inheritdoc IBaseForm function xChainWithdrawFromVault( InitSingleVaultData memory singleVaultData_, address srcSender_, uint64 srcChainId_ ) external override onlyCoreStateRegistry returns (uint256 assets) { if (srcChainId_ != 0 && srcChainId_ != CHAIN_ID) { if (!_isPaused(singleVaultData_.superformId)) { assets = _xChainWithdrawFromVault(singleVaultData_, srcSender_, srcChainId_); } else { IEmergencyQueue(superRegistry.getAddress(keccak256("EMERGENCY_QUEUE"))).queueWithdrawal( singleVaultData_ ); } } else { revert Error.INVALID_CHAIN_ID(); } } /// @inheritdoc IBaseForm function emergencyWithdraw(address receiverAddress_, uint256 amount_) external override onlyEmergencyQueue { _emergencyWithdraw(receiverAddress_, amount_); } /// @inheritdoc IBaseForm function forwardDustToPaymaster(address token_) external override { if (token_ == vault) revert Error.CANNOT_FORWARD_4646_TOKEN(); _forwardDustToPaymaster(token_); } /// @dev Checks if the Form implementation has the appropriate interface support /// @param interfaceId_ is the interfaceId to check function supportsInterface(bytes4 interfaceId_) public view virtual override(ERC165, IERC165) returns (bool) { return interfaceId_ == type(IBaseForm).interfaceId || super.supportsInterface(interfaceId_); } ////////////////////////////////////////////////////////////// // INTERNAL FUNCTIONS // ////////////////////////////////////////////////////////////// /// @dev Deposits underlying tokens into a vault function _directDepositIntoVault( InitSingleVaultData memory singleVaultData_, address srcSender_ ) internal virtual returns (uint256 shares); /// @dev Deposits underlying tokens into a vault function _xChainDepositIntoVault( InitSingleVaultData memory singleVaultData_, address srcSender_, uint64 srcChainId_ ) internal virtual returns (uint256 shares); /// @dev Withdraws underlying tokens from a vault function _directWithdrawFromVault( InitSingleVaultData memory singleVaultData_, address srcSender_ ) internal virtual returns (uint256 assets); /// @dev Withdraws underlying tokens from a vault function _xChainWithdrawFromVault( InitSingleVaultData memory singleVaultData_, address srcSender_, uint64 srcChainId_ ) internal virtual returns (uint256 assets); /// @dev withdraws vault shares from form during emergency function _emergencyWithdraw(address receiverAddress_, uint256 amount_) internal virtual; /// @dev forwards dust to paymaster function _forwardDustToPaymaster(address token_) internal virtual; /// @dev returns if a form id is paused function _isPaused(uint256 superformId) internal view returns (bool) { address factory = superRegistry.getAddress(keccak256("SUPERFORM_FACTORY")); if (!ISuperformFactory(factory).isSuperform(superformId)) { revert Error.SUPERFORM_ID_NONEXISTENT(); } (, uint32 formImplementationId_,) = superformId.getSuperform(); return ISuperformFactory(factory).isFormImplementationPaused(formImplementationId_); } }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.23; /// @dev contains all the common struct and enums used for data communication between chains. /// @dev There are two transaction types in Superform Protocol enum TransactionType { DEPOSIT, WITHDRAW } /// @dev Message types can be INIT, RETURN (for successful Deposits) and FAIL (for failed withdraws) enum CallbackType { INIT, RETURN, FAIL } /// @dev Payloads are stored, updated (deposits) or processed (finalized) enum PayloadState { STORED, UPDATED, PROCESSED } /// @dev contains all the common struct used for interchain token transfers. struct LiqRequest { /// @dev generated data bytes txData; /// @dev input token for deposits, desired output token on target liqDstChainId for withdraws. Must be set for /// txData to be updated on destination for withdraws address token; /// @dev intermediary token on destination. Relevant for xChain deposits where a destination swap is needed for /// validation purposes address interimToken; /// @dev what bridge to use to move tokens uint8 bridgeId; /// @dev dstChainId = liqDstchainId for deposits. For withdraws it is the target chain id for where the underlying /// is to be delivered uint64 liqDstChainId; /// @dev currently this amount is used as msg.value in the txData call. uint256 nativeAmount; } /// @dev main struct that holds required multi vault data for an action struct MultiVaultSFData { // superformids must have same destination. Can have different underlyings uint256[] superformIds; uint256[] amounts; // on deposits, amount of token to deposit on dst, on withdrawals, superpositions to burn uint256[] outputAmounts; // on deposits, amount of shares to receive, on withdrawals, amount of assets to receive uint256[] maxSlippages; LiqRequest[] liqRequests; // if length = 1; amount = sum(amounts) | else amounts must match the amounts being sent bytes permit2data; bool[] hasDstSwaps; bool[] retain4626s; // if true, we don't mint SuperPositions, and send the 4626 back to the user instead address receiverAddress; /// this address must always be an EOA otherwise funds may be lost address receiverAddressSP; /// this address can be a EOA or a contract that implements onERC1155Receiver. must always be set for deposits bytes extraFormData; // extraFormData } /// @dev main struct that holds required single vault data for an action struct SingleVaultSFData { // superformids must have same destination. Can have different underlyings uint256 superformId; uint256 amount; uint256 outputAmount; // on deposits, amount of shares to receive, on withdrawals, amount of assets to receive uint256 maxSlippage; LiqRequest liqRequest; // if length = 1; amount = sum(amounts)| else amounts must match the amounts being sent bytes permit2data; bool hasDstSwap; bool retain4626; // if true, we don't mint SuperPositions, and send the 4626 back to the user instead address receiverAddress; /// this address must always be an EOA otherwise funds may be lost address receiverAddressSP; /// this address can be a EOA or a contract that implements onERC1155Receiver. must always be set for deposits bytes extraFormData; // extraFormData } /// @dev overarching struct for multiDst requests with multi vaults struct MultiDstMultiVaultStateReq { uint8[][] ambIds; uint64[] dstChainIds; MultiVaultSFData[] superformsData; } /// @dev overarching struct for single cross chain requests with multi vaults struct SingleXChainMultiVaultStateReq { uint8[] ambIds; uint64 dstChainId; MultiVaultSFData superformsData; } /// @dev overarching struct for multiDst requests with single vaults struct MultiDstSingleVaultStateReq { uint8[][] ambIds; uint64[] dstChainIds; SingleVaultSFData[] superformsData; } /// @dev overarching struct for single cross chain requests with single vaults struct SingleXChainSingleVaultStateReq { uint8[] ambIds; uint64 dstChainId; SingleVaultSFData superformData; } /// @dev overarching struct for single direct chain requests with single vaults struct SingleDirectSingleVaultStateReq { SingleVaultSFData superformData; } /// @dev overarching struct for single direct chain requests with multi vaults struct SingleDirectMultiVaultStateReq { MultiVaultSFData superformData; } /// @dev struct for SuperRouter with re-arranged data for the message (contains the payloadId) /// @dev realize that receiverAddressSP is not passed, only needed on source chain to mint struct InitMultiVaultData { uint256 payloadId; uint256[] superformIds; uint256[] amounts; uint256[] outputAmounts; uint256[] maxSlippages; LiqRequest[] liqData; bool[] hasDstSwaps; bool[] retain4626s; address receiverAddress; bytes extraFormData; } /// @dev struct for SuperRouter with re-arranged data for the message (contains the payloadId) struct InitSingleVaultData { uint256 payloadId; uint256 superformId; uint256 amount; uint256 outputAmount; uint256 maxSlippage; LiqRequest liqData; bool hasDstSwap; bool retain4626; address receiverAddress; bytes extraFormData; } /// @dev struct for Emergency Queue struct QueuedWithdrawal { address receiverAddress; uint256 superformId; uint256 amount; uint256 srcPayloadId; bool isProcessed; } /// @dev all statuses of the timelock payload enum TimelockStatus { UNAVAILABLE, PENDING, PROCESSED } /// @dev holds information about the timelock payload struct TimelockPayload { uint8 isXChain; uint64 srcChainId; uint256 lockedTill; InitSingleVaultData data; TimelockStatus status; } /// @dev struct that contains the type of transaction, callback flags and other identification, as well as the vaults /// data in params struct AMBMessage { uint256 txInfo; // tight packing of TransactionType txType, CallbackType flag if multi/single vault, registry id, // srcSender and srcChainId bytes params; // decoding txInfo will point to the right datatype of params. Refer PayloadHelper.sol } /// @dev struct that contains the information required for broadcasting changes struct BroadcastMessage { bytes target; bytes32 messageType; bytes message; } /// @dev struct that contains info on returned data from destination struct ReturnMultiData { uint256 payloadId; uint256[] superformIds; uint256[] amounts; } /// @dev struct that contains info on returned data from destination struct ReturnSingleData { uint256 payloadId; uint256 superformId; uint256 amount; } /// @dev struct that contains the data on the fees to pay to the AMBs struct AMBExtraData { uint256[] gasPerAMB; bytes[] extraDataPerAMB; } /// @dev struct that contains the data on the fees to pay to the AMBs on broadcasts struct BroadCastAMBExtraData { uint256[] gasPerDst; bytes[] extraDataPerDst; }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.23; import { InitSingleVaultData } from "src/types/DataTypes.sol"; import { IERC165 } from "openzeppelin-contracts/contracts/utils/introspection/IERC165.sol"; import { IERC4626 } from "openzeppelin-contracts/contracts/interfaces/IERC4626.sol"; /// @title IBaseForm /// @dev Interface for BaseForm /// @author ZeroPoint Labs interface IBaseForm is IERC165 { ////////////////////////////////////////////////////////////// // EVENTS // ////////////////////////////////////////////////////////////// /// @dev is emitted when a new vault is added by the admin. event VaultAdded(uint256 indexed id, IERC4626 indexed vault); /// @dev is emitted when a payload is processed by the destination contract. event Processed( uint64 indexed srcChainID, uint64 indexed dstChainId, uint256 indexed srcPayloadId, uint256 amount, address vault ); /// @dev is emitted when an emergency withdrawal is processed event EmergencyWithdrawalProcessed(address indexed refundAddress, uint256 indexed amount); /// @dev is emitted when dust is forwarded to the paymaster event FormDustForwardedToPaymaster(address indexed token, uint256 indexed amount); ////////////////////////////////////////////////////////////// // EXTERNAL VIEW FUNCTIONS // ////////////////////////////////////////////////////////////// /// @notice get Superform name of the ERC20 vault representation /// @return The ERC20 name function superformYieldTokenName() external view returns (string memory); /// @notice get Superform symbol of the ERC20 vault representation /// @return The ERC20 symbol function superformYieldTokenSymbol() external view returns (string memory); /// @notice get the state registry id associated with the vault function getStateRegistryId() external view returns (uint8); /// @notice Returns the vault address /// @return The address of the vault function getVaultAddress() external view returns (address); /// @notice Returns the vault address /// @return The address of the vault asset function getVaultAsset() external view returns (address); /// @notice Returns the name of the vault. /// @return The name of the vault function getVaultName() external view returns (string memory); /// @notice Returns the symbol of a vault. /// @return The symbol associated with a vault function getVaultSymbol() external view returns (string memory); /// @notice Returns the number of decimals in a vault for accounting purposes /// @return The number of decimals in the vault balance function getVaultDecimals() external view returns (uint256); /// @notice Returns the amount of underlying tokens each share of a vault is worth. /// @return The pricePerVaultShare value function getPricePerVaultShare() external view returns (uint256); /// @notice Returns the amount of vault shares owned by the form. /// @return The form's vault share balance function getVaultShareBalance() external view returns (uint256); /// @notice get the total amount of underlying managed in the ERC4626 vault function getTotalAssets() external view returns (uint256); /// @notice get the total amount of unredeemed vault shares in circulation function getTotalSupply() external view returns (uint256); /// @notice get the total amount of assets received if shares are actually redeemed /// @notice https://eips.ethereum.org/EIPS/eip-4626 function getPreviewPricePerVaultShare() external view returns (uint256); /// @dev API may need to know state of funds deployed function previewDepositTo(uint256 assets_) external view returns (uint256); /// @notice positionBalance() -> .vaultIds&destAmounts /// @return how much of an asset + interest (accrued) is to withdraw from the Vault function previewWithdrawFrom(uint256 assets_) external view returns (uint256); /// @dev API may need to know state of funds deployed function previewRedeemFrom(uint256 shares_) external view returns (uint256); ////////////////////////////////////////////////////////////// // EXTERNAL WRITE FUNCTIONS // ////////////////////////////////////////////////////////////// /// @dev process same chain id deposits /// @param singleVaultData_ A bytes representation containing all the data required to make a form action /// @param srcSender_ The address of the sender of the transaction /// @return shares The amount of vault shares received function directDepositIntoVault( InitSingleVaultData memory singleVaultData_, address srcSender_ ) external payable returns (uint256 shares); /// @dev process same chain id deposits /// @param singleVaultData_ A bytes representation containing all the data required to make a form action /// @param srcSender_ The address of the sender of the transaction /// @param srcChainId_ The chain id of the source chain /// @return shares The amount of vault shares received /// @dev is shares is `0` then no further action/acknowledgement needs to be sent function xChainDepositIntoVault( InitSingleVaultData memory singleVaultData_, address srcSender_, uint64 srcChainId_ ) external returns (uint256 shares); /// @dev process withdrawal of asset from a vault /// @param singleVaultData_ A bytes representation containing all the data required to make a form action /// @param srcSender_ The address of the sender of the transaction /// @return assets The amount of assets received function directWithdrawFromVault( InitSingleVaultData memory singleVaultData_, address srcSender_ ) external returns (uint256 assets); /// @dev process withdrawal of asset from a vault /// @param singleVaultData_ A bytes representation containing all the data required to make a form action /// @param srcSender_ The address of the sender of the transaction /// @param srcChainId_ The chain id of the source chain /// @return assets The amount of assets received function xChainWithdrawFromVault( InitSingleVaultData memory singleVaultData_, address srcSender_, uint64 srcChainId_ ) external returns (uint256 assets); /// @dev process withdrawal of shares if form is paused /// @param receiverAddress_ The address to refund the shares to /// @param amount_ The amount of vault shares to refund function emergencyWithdraw(address receiverAddress_, uint256 amount_) external; /// @dev moves all dust in the contract to Paymaster contract /// @param token_ The address of the token to forward function forwardDustToPaymaster(address token_) external; }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.23; import { IAccessControl } from "openzeppelin-contracts/contracts/access/IAccessControl.sol"; /// @title ISuperRBAC /// @dev Interface for SuperRBAC /// @author Zeropoint Labs interface ISuperRBAC is IAccessControl { ////////////////////////////////////////////////////////////// // STRUCTS // ////////////////////////////////////////////////////////////// struct InitialRoleSetup { address admin; address emergencyAdmin; address paymentAdmin; address csrProcessor; address tlProcessor; address brProcessor; address csrUpdater; address srcVaaRelayer; address dstSwapper; address csrRescuer; address csrDisputer; } ////////////////////////////////////////////////////////////// // EVENTS // ////////////////////////////////////////////////////////////// /// @dev is emitted when superRegistry is set event SuperRegistrySet(address indexed superRegistry); /// @dev is emitted when an admin is set for a role event RoleAdminSet(bytes32 role, bytes32 adminRole); ////////////////////////////////////////////////////////////// // EXTERNAL VIEW FUNCTIONS // ////////////////////////////////////////////////////////////// /// @dev returns the id of the protocol admin role function PROTOCOL_ADMIN_ROLE() external view returns (bytes32); /// @dev returns the id of the emergency admin role function EMERGENCY_ADMIN_ROLE() external view returns (bytes32); /// @dev returns the id of the payment admin role function PAYMENT_ADMIN_ROLE() external view returns (bytes32); /// @dev returns the id of the broadcaster role function BROADCASTER_ROLE() external view returns (bytes32); /// @dev returns the id of the core state registry processor role function CORE_STATE_REGISTRY_PROCESSOR_ROLE() external view returns (bytes32); /// @dev returns the id of the timelock state registry processor role function TIMELOCK_STATE_REGISTRY_PROCESSOR_ROLE() external view returns (bytes32); /// @dev returns the id of the broadcast state registry processor role function BROADCAST_STATE_REGISTRY_PROCESSOR_ROLE() external view returns (bytes32); /// @dev returns the id of the core state registry updater role function CORE_STATE_REGISTRY_UPDATER_ROLE() external view returns (bytes32); /// @dev returns the id of the dst swapper role function DST_SWAPPER_ROLE() external view returns (bytes32); /// @dev returns the id of the core state registry rescuer role function CORE_STATE_REGISTRY_RESCUER_ROLE() external view returns (bytes32); /// @dev returns the id of the core state registry rescue disputer role function CORE_STATE_REGISTRY_DISPUTER_ROLE() external view returns (bytes32); /// @dev returns the id of wormhole vaa relayer role function WORMHOLE_VAA_RELAYER_ROLE() external view returns (bytes32); /// @dev returns whether the given address has the protocol admin role /// @param admin_ the address to check function hasProtocolAdminRole(address admin_) external view returns (bool); /// @dev returns whether the given address has the emergency admin role /// @param admin_ the address to check function hasEmergencyAdminRole(address admin_) external view returns (bool); ////////////////////////////////////////////////////////////// // EXTERNAL WRITE FUNCTIONS // ////////////////////////////////////////////////////////////// /// @dev updates the super registry address function setSuperRegistry(address superRegistry_) external; /// @dev configures a new role in superForm /// @param role_ the role to set /// @param adminRole_ the admin role to set as admin function setRoleAdmin(bytes32 role_, bytes32 adminRole_) external; /// @dev revokes the role_ from superRegistryAddressId_ on all chains /// @param role_ the role to revoke /// @param extraData_ amb config if broadcasting is required /// @param superRegistryAddressId_ the super registry address id function revokeRoleSuperBroadcast( bytes32 role_, bytes memory extraData_, bytes32 superRegistryAddressId_ ) external payable; /// @dev allows sync of global roles from different chains using broadcast registry /// @notice may not work for all roles function stateSyncBroadcast(bytes memory data_) external; }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.23; /// @title ISuperRegistry /// @dev Interface for SuperRegistry /// @author Zeropoint Labs interface ISuperRegistry { ////////////////////////////////////////////////////////////// // EVENTS // ////////////////////////////////////////////////////////////// /// @dev emitted when permit2 is set. event SetPermit2(address indexed permit2); /// @dev is emitted when an address is set. event AddressUpdated( bytes32 indexed protocolAddressId, uint64 indexed chainId, address indexed oldAddress, address newAddress ); /// @dev is emitted when a new token bridge is configured. event SetBridgeAddress(uint256 indexed bridgeId, address indexed bridgeAddress); /// @dev is emitted when a new bridge validator is configured. event SetBridgeValidator(uint256 indexed bridgeId, address indexed bridgeValidator); /// @dev is emitted when a new amb is configured. event SetAmbAddress(uint8 indexed ambId_, address indexed ambAddress_, bool indexed isBroadcastAMB_); /// @dev is emitted when a new state registry is configured. event SetStateRegistryAddress(uint8 indexed registryId_, address indexed registryAddress_); /// @dev is emitted when a new delay is configured. event SetDelay(uint256 indexed oldDelay_, uint256 indexed newDelay_); /// @dev is emitted when a new vault limit is configured event SetVaultLimitPerDestination(uint64 indexed chainId_, uint256 indexed vaultLimit_); ////////////////////////////////////////////////////////////// // EXTERNAL VIEW FUNCTIONS // ////////////////////////////////////////////////////////////// /// @dev gets the deposit rescue delay function delay() external view returns (uint256); /// @dev returns the permit2 address function PERMIT2() external view returns (address); /// @dev returns the id of the superform router module function SUPERFORM_ROUTER() external view returns (bytes32); /// @dev returns the id of the superform factory module function SUPERFORM_FACTORY() external view returns (bytes32); /// @dev returns the id of the superform paymaster contract function PAYMASTER() external view returns (bytes32); /// @dev returns the id of the superform payload helper contract function PAYMENT_HELPER() external view returns (bytes32); /// @dev returns the id of the core state registry module function CORE_STATE_REGISTRY() external view returns (bytes32); /// @dev returns the id of the timelock form state registry module function TIMELOCK_STATE_REGISTRY() external view returns (bytes32); /// @dev returns the id of the broadcast state registry module function BROADCAST_REGISTRY() external view returns (bytes32); /// @dev returns the id of the super positions module function SUPER_POSITIONS() external view returns (bytes32); /// @dev returns the id of the super rbac module function SUPER_RBAC() external view returns (bytes32); /// @dev returns the id of the payload helper module function PAYLOAD_HELPER() external view returns (bytes32); /// @dev returns the id of the dst swapper keeper function DST_SWAPPER() external view returns (bytes32); /// @dev returns the id of the emergency queue function EMERGENCY_QUEUE() external view returns (bytes32); /// @dev returns the id of the superform receiver function SUPERFORM_RECEIVER() external view returns (bytes32); /// @dev returns the id of the payment admin keeper function PAYMENT_ADMIN() external view returns (bytes32); /// @dev returns the id of the core state registry processor keeper function CORE_REGISTRY_PROCESSOR() external view returns (bytes32); /// @dev returns the id of the broadcast registry processor keeper function BROADCAST_REGISTRY_PROCESSOR() external view returns (bytes32); /// @dev returns the id of the timelock form state registry processor keeper function TIMELOCK_REGISTRY_PROCESSOR() external view returns (bytes32); /// @dev returns the id of the core state registry updater keeper function CORE_REGISTRY_UPDATER() external view returns (bytes32); /// @dev returns the id of the core state registry updater keeper function CORE_REGISTRY_RESCUER() external view returns (bytes32); /// @dev returns the id of the core state registry updater keeper function CORE_REGISTRY_DISPUTER() external view returns (bytes32); /// @dev returns the id of the core state registry updater keeper function DST_SWAPPER_PROCESSOR() external view returns (bytes32); /// @dev gets the address of a contract on current chain /// @param id_ is the id of the contract function getAddress(bytes32 id_) external view returns (address); /// @dev gets the address of a contract on a target chain /// @param id_ is the id of the contract /// @param chainId_ is the chain id of that chain function getAddressByChainId(bytes32 id_, uint64 chainId_) external view returns (address); /// @dev gets the address of a bridge /// @param bridgeId_ is the id of a bridge /// @return bridgeAddress_ is the address of the form function getBridgeAddress(uint8 bridgeId_) external view returns (address bridgeAddress_); /// @dev gets the address of a bridge validator /// @param bridgeId_ is the id of a bridge /// @return bridgeValidator_ is the address of the form function getBridgeValidator(uint8 bridgeId_) external view returns (address bridgeValidator_); /// @dev gets the address of a amb /// @param ambId_ is the id of a bridge /// @return ambAddress_ is the address of the form function getAmbAddress(uint8 ambId_) external view returns (address ambAddress_); /// @dev gets the id of the amb /// @param ambAddress_ is the address of an amb /// @return ambId_ is the identifier of an amb function getAmbId(address ambAddress_) external view returns (uint8 ambId_); /// @dev gets the address of the registry /// @param registryId_ is the id of the state registry /// @return registryAddress_ is the address of the state registry function getStateRegistry(uint8 registryId_) external view returns (address registryAddress_); /// @dev gets the id of the registry /// @notice reverts if the id is not found /// @param registryAddress_ is the address of the state registry /// @return registryId_ is the id of the state registry function getStateRegistryId(address registryAddress_) external view returns (uint8 registryId_); /// @dev gets the safe vault limit /// @param chainId_ is the id of the remote chain /// @return vaultLimitPerDestination_ is the safe number of vaults to deposit /// without hitting out of gas error function getVaultLimitPerDestination(uint64 chainId_) external view returns (uint256 vaultLimitPerDestination_); /// @dev helps validate if an address is a valid state registry /// @param registryAddress_ is the address of the state registry /// @return valid_ a flag indicating if its valid. function isValidStateRegistry(address registryAddress_) external view returns (bool valid_); /// @dev helps validate if an address is a valid amb implementation /// @param ambAddress_ is the address of the amb implementation /// @return valid_ a flag indicating if its valid. function isValidAmbImpl(address ambAddress_) external view returns (bool valid_); /// @dev helps validate if an address is a valid broadcast amb implementation /// @param ambAddress_ is the address of the broadcast amb implementation /// @return valid_ a flag indicating if its valid. function isValidBroadcastAmbImpl(address ambAddress_) external view returns (bool valid_); ////////////////////////////////////////////////////////////// // EXTERNAL WRITE FUNCTIONS // ////////////////////////////////////////////////////////////// /// @dev sets the deposit rescue delay /// @param delay_ the delay in seconds before the deposit rescue can be finalized function setDelay(uint256 delay_) external; /// @dev sets the permit2 address /// @param permit2_ the address of the permit2 contract function setPermit2(address permit2_) external; /// @dev sets the safe vault limit /// @param chainId_ is the remote chain identifier /// @param vaultLimit_ is the max limit of vaults per transaction function setVaultLimitPerDestination(uint64 chainId_, uint256 vaultLimit_) external; /// @dev sets new addresses on specific chains. /// @param ids_ are the identifiers of the address on that chain /// @param newAddresses_ are the new addresses on that chain /// @param chainIds_ are the chain ids of that chain function batchSetAddress( bytes32[] calldata ids_, address[] calldata newAddresses_, uint64[] calldata chainIds_ ) external; /// @dev sets a new address on a specific chain. /// @param id_ the identifier of the address on that chain /// @param newAddress_ the new address on that chain /// @param chainId_ the chain id of that chain function setAddress(bytes32 id_, address newAddress_, uint64 chainId_) external; /// @dev allows admin to set the bridge address for an bridge id. /// @notice this function operates in an APPEND-ONLY fashion. /// @param bridgeId_ represents the bridge unique identifier. /// @param bridgeAddress_ represents the bridge address. /// @param bridgeValidator_ represents the bridge validator address. function setBridgeAddresses( uint8[] memory bridgeId_, address[] memory bridgeAddress_, address[] memory bridgeValidator_ ) external; /// @dev allows admin to set the amb address for an amb id. /// @notice this function operates in an APPEND-ONLY fashion. /// @param ambId_ represents the bridge unique identifier. /// @param ambAddress_ represents the bridge address. /// @param isBroadcastAMB_ represents whether the amb implementation supports broadcasting function setAmbAddress( uint8[] memory ambId_, address[] memory ambAddress_, bool[] memory isBroadcastAMB_ ) external; /// @dev allows admin to set the state registry address for an state registry id. /// @notice this function operates in an APPEND-ONLY fashion. /// @param registryId_ represents the state registry's unique identifier. /// @param registryAddress_ represents the state registry's address. function setStateRegistryAddress(uint8[] memory registryId_, address[] memory registryAddress_) external; }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.23; import { Error } from "src/libraries/Error.sol"; library DataLib { function packTxInfo( uint8 txType_, uint8 callbackType_, uint8 multi_, uint8 registryId_, address srcSender_, uint64 srcChainId_ ) internal pure returns (uint256 txInfo) { txInfo = uint256(txType_); txInfo |= uint256(callbackType_) << 8; txInfo |= uint256(multi_) << 16; txInfo |= uint256(registryId_) << 24; txInfo |= uint256(uint160(srcSender_)) << 32; txInfo |= uint256(srcChainId_) << 192; } function decodeTxInfo(uint256 txInfo_) internal pure returns (uint8 txType, uint8 callbackType, uint8 multi, uint8 registryId, address srcSender, uint64 srcChainId) { txType = uint8(txInfo_); callbackType = uint8(txInfo_ >> 8); multi = uint8(txInfo_ >> 16); registryId = uint8(txInfo_ >> 24); srcSender = address(uint160(txInfo_ >> 32)); srcChainId = uint64(txInfo_ >> 192); } /// @dev returns the vault-form-chain pair of a superform /// @param superformId_ is the id of the superform /// @return superform_ is the address of the superform /// @return formImplementationId_ is the form id /// @return chainId_ is the chain id function getSuperform(uint256 superformId_) internal pure returns (address superform_, uint32 formImplementationId_, uint64 chainId_) { superform_ = address(uint160(superformId_)); formImplementationId_ = uint32(superformId_ >> 160); chainId_ = uint64(superformId_ >> 192); if (chainId_ == 0) { revert Error.INVALID_CHAIN_ID(); } } /// @dev returns the vault-form-chain pair of an array of superforms /// @param superformIds_ array of superforms /// @return superforms_ are the address of the vaults function getSuperforms(uint256[] memory superformIds_) internal pure returns (address[] memory superforms_) { uint256 len = superformIds_.length; superforms_ = new address[](len); for (uint256 i; i < len; ++i) { (superforms_[i],,) = getSuperform(superformIds_[i]); } } /// @dev returns the destination chain of a given superform /// @param superformId_ is the id of the superform /// @return chainId_ is the chain id function getDestinationChain(uint256 superformId_) internal pure returns (uint64 chainId_) { chainId_ = uint64(superformId_ >> 192); if (chainId_ == 0) { revert Error.INVALID_CHAIN_ID(); } } /// @dev generates the superformId /// @param superform_ is the address of the superform /// @param formImplementationId_ is the type of the form /// @param chainId_ is the chain id on which the superform is deployed function packSuperform( address superform_, uint32 formImplementationId_, uint64 chainId_ ) internal pure returns (uint256 superformId_) { superformId_ = uint256(uint160(superform_)); superformId_ |= uint256(formImplementationId_) << 160; superformId_ |= uint256(chainId_) << 192; } }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.23; library Error { ////////////////////////////////////////////////////////////// // CONFIGURATION ERRORS // ////////////////////////////////////////////////////////////// ///@notice errors thrown in protocol setup /// @dev thrown if chain id exceeds max(uint64) error BLOCK_CHAIN_ID_OUT_OF_BOUNDS(); /// @dev thrown if not possible to revoke a role in broadcasting error CANNOT_REVOKE_NON_BROADCASTABLE_ROLES(); /// @dev thrown if not possible to revoke last admin error CANNOT_REVOKE_LAST_ADMIN(); /// @dev thrown if trying to set again pseudo immutables in super registry error DISABLED(); /// @dev thrown if rescue delay is not yet set for a chain error DELAY_NOT_SET(); /// @dev thrown if get native token price estimate in paymentHelper is 0 error INVALID_NATIVE_TOKEN_PRICE(); /// @dev thrown if wormhole refund chain id is not set error REFUND_CHAIN_ID_NOT_SET(); /// @dev thrown if wormhole relayer is not set error RELAYER_NOT_SET(); /// @dev thrown if a role to be revoked is not assigned error ROLE_NOT_ASSIGNED(); ////////////////////////////////////////////////////////////// // AUTHORIZATION ERRORS // ////////////////////////////////////////////////////////////// ///@notice errors thrown if functions cannot be called /// COMMON AUTHORIZATION ERRORS /// --------------------------------------------------------- /// @dev thrown if caller is not address(this), internal call error INVALID_INTERNAL_CALL(); /// @dev thrown if msg.sender is not a valid amb implementation error NOT_AMB_IMPLEMENTATION(); /// @dev thrown if msg.sender is not an allowed broadcaster error NOT_ALLOWED_BROADCASTER(); /// @dev thrown if msg.sender is not broadcast amb implementation error NOT_BROADCAST_AMB_IMPLEMENTATION(); /// @dev thrown if msg.sender is not broadcast state registry error NOT_BROADCAST_REGISTRY(); /// @dev thrown if msg.sender is not core state registry error NOT_CORE_STATE_REGISTRY(); /// @dev thrown if msg.sender is not emergency admin error NOT_EMERGENCY_ADMIN(); /// @dev thrown if msg.sender is not emergency queue error NOT_EMERGENCY_QUEUE(); /// @dev thrown if msg.sender is not minter error NOT_MINTER(); /// @dev thrown if msg.sender is not minter state registry error NOT_MINTER_STATE_REGISTRY_ROLE(); /// @dev thrown if msg.sender is not paymaster error NOT_PAYMASTER(); /// @dev thrown if msg.sender is not payment admin error NOT_PAYMENT_ADMIN(); /// @dev thrown if msg.sender is not protocol admin error NOT_PROTOCOL_ADMIN(); /// @dev thrown if msg.sender is not state registry error NOT_STATE_REGISTRY(); /// @dev thrown if msg.sender is not super registry error NOT_SUPER_REGISTRY(); /// @dev thrown if msg.sender is not superform router error NOT_SUPERFORM_ROUTER(); /// @dev thrown if msg.sender is not a superform error NOT_SUPERFORM(); /// @dev thrown if msg.sender is not superform factory error NOT_SUPERFORM_FACTORY(); /// @dev thrown if msg.sender is not timelock form error NOT_TIMELOCK_SUPERFORM(); /// @dev thrown if msg.sender is not timelock state registry error NOT_TIMELOCK_STATE_REGISTRY(); /// @dev thrown if msg.sender is not user or disputer error NOT_VALID_DISPUTER(); /// @dev thrown if the msg.sender is not privileged caller error NOT_PRIVILEGED_CALLER(bytes32 role); /// STATE REGISTRY AUTHORIZATION ERRORS /// --------------------------------------------------------- /// @dev layerzero adapter specific error, thrown if caller not layerzero endpoint error CALLER_NOT_ENDPOINT(); /// @dev hyperlane adapter specific error, thrown if caller not hyperlane mailbox error CALLER_NOT_MAILBOX(); /// @dev wormhole relayer specific error, thrown if caller not wormhole relayer error CALLER_NOT_RELAYER(); /// @dev thrown if src chain sender is not valid error INVALID_SRC_SENDER(); ////////////////////////////////////////////////////////////// // INPUT VALIDATION ERRORS // ////////////////////////////////////////////////////////////// ///@notice errors thrown if input variables are not valid /// COMMON INPUT VALIDATION ERRORS /// --------------------------------------------------------- /// @dev thrown if there is an array length mismatch error ARRAY_LENGTH_MISMATCH(); /// @dev thrown if payload id does not exist error INVALID_PAYLOAD_ID(); /// @dev error thrown when msg value should be zero in certain payable functions error MSG_VALUE_NOT_ZERO(); /// @dev thrown if amb ids length is 0 error ZERO_AMB_ID_LENGTH(); /// @dev thrown if address input is address 0 error ZERO_ADDRESS(); /// @dev thrown if amount input is 0 error ZERO_AMOUNT(); /// @dev thrown if final token is address 0 error ZERO_FINAL_TOKEN(); /// @dev thrown if value input is 0 error ZERO_INPUT_VALUE(); /// SUPERFORM ROUTER INPUT VALIDATION ERRORS /// --------------------------------------------------------- /// @dev thrown if the vaults data is invalid error INVALID_SUPERFORMS_DATA(); /// @dev thrown if receiver address is not set error RECEIVER_ADDRESS_NOT_SET(); /// SUPERFORM FACTORY INPUT VALIDATION ERRORS /// --------------------------------------------------------- /// @dev thrown if a form is not ERC165 compatible error ERC165_UNSUPPORTED(); /// @dev thrown if a form is not form interface compatible error FORM_INTERFACE_UNSUPPORTED(); /// @dev error thrown if form implementation address already exists error FORM_IMPLEMENTATION_ALREADY_EXISTS(); /// @dev error thrown if form implementation id already exists error FORM_IMPLEMENTATION_ID_ALREADY_EXISTS(); /// @dev thrown if a form does not exist error FORM_DOES_NOT_EXIST(); /// @dev thrown if form id is larger than max uint16 error INVALID_FORM_ID(); /// @dev thrown if superform not on factory error SUPERFORM_ID_NONEXISTENT(); /// @dev thrown if same vault and form implementation is used to create new superform error VAULT_FORM_IMPLEMENTATION_COMBINATION_EXISTS(); /// FORM INPUT VALIDATION ERRORS /// --------------------------------------------------------- /// @dev thrown if in case of no txData, if liqData.token != vault.asset() /// in case of txData, if token output of swap != vault.asset() error DIFFERENT_TOKENS(); /// @dev thrown if the amount in direct withdraw is not correct error DIRECT_WITHDRAW_INVALID_LIQ_REQUEST(); /// @dev thrown if the amount in xchain withdraw is not correct error XCHAIN_WITHDRAW_INVALID_LIQ_REQUEST(); /// LIQUIDITY BRIDGE INPUT VALIDATION ERRORS /// --------------------------------------------------------- /// @dev thrown if route id is blacklisted in socket error BLACKLISTED_ROUTE_ID(); /// @dev thrown if route id is not blacklisted in socket error NOT_BLACKLISTED_ROUTE_ID(); /// @dev error thrown when txData selector of lifi bridge is a blacklisted selector error BLACKLISTED_SELECTOR(); /// @dev error thrown when txData selector of lifi bridge is not a blacklisted selector error NOT_BLACKLISTED_SELECTOR(); /// @dev thrown if a certain action of the user is not allowed given the txData provided error INVALID_ACTION(); /// @dev thrown if in deposits, the liqDstChainId doesn't match the stateReq dstChainId error INVALID_DEPOSIT_LIQ_DST_CHAIN_ID(); /// @dev thrown if index is invalid error INVALID_INDEX(); /// @dev thrown if the chain id in the txdata is invalid error INVALID_TXDATA_CHAIN_ID(); /// @dev thrown if the validation of bridge txData fails due to a destination call present error INVALID_TXDATA_NO_DESTINATIONCALL_ALLOWED(); /// @dev thrown if the validation of bridge txData fails due to wrong receiver error INVALID_TXDATA_RECEIVER(); /// @dev thrown if the validation of bridge txData fails due to wrong token error INVALID_TXDATA_TOKEN(); /// @dev thrown if txData is not present (in case of xChain actions) error NO_TXDATA_PRESENT(); /// STATE REGISTRY INPUT VALIDATION ERRORS /// --------------------------------------------------------- /// @dev thrown if payload is being updated with final amounts length different than amounts length error DIFFERENT_PAYLOAD_UPDATE_AMOUNTS_LENGTH(); /// @dev thrown if payload is being updated with tx data length different than liq data length error DIFFERENT_PAYLOAD_UPDATE_TX_DATA_LENGTH(); /// @dev thrown if keeper update final token is different than the vault underlying error INVALID_UPDATE_FINAL_TOKEN(); /// @dev thrown if broadcast finality for wormhole is invalid error INVALID_BROADCAST_FINALITY(); /// @dev thrown if amb id is not valid leading to an address 0 of the implementation error INVALID_BRIDGE_ID(); /// @dev thrown if chain id involved in xchain message is invalid error INVALID_CHAIN_ID(); /// @dev thrown if payload update amount isn't equal to dst swapper amount error INVALID_DST_SWAP_AMOUNT(); /// @dev thrown if message amb and proof amb are the same error INVALID_PROOF_BRIDGE_ID(); /// @dev thrown if order of proof AMBs is incorrect, either duplicated or not incrementing error INVALID_PROOF_BRIDGE_IDS(); /// @dev thrown if rescue data lengths are invalid error INVALID_RESCUE_DATA(); /// @dev thrown if delay is invalid error INVALID_TIMELOCK_DELAY(); /// @dev thrown if amounts being sent in update payload mean a negative slippage error NEGATIVE_SLIPPAGE(); /// @dev thrown if slippage is outside of bounds error SLIPPAGE_OUT_OF_BOUNDS(); /// SUPERPOSITION INPUT VALIDATION ERRORS /// --------------------------------------------------------- /// @dev thrown if src senders mismatch in state sync error SRC_SENDER_MISMATCH(); /// @dev thrown if src tx types mismatch in state sync error SRC_TX_TYPE_MISMATCH(); ////////////////////////////////////////////////////////////// // EXECUTION ERRORS // ////////////////////////////////////////////////////////////// ///@notice errors thrown due to function execution logic /// COMMON EXECUTION ERRORS /// --------------------------------------------------------- /// @dev thrown if the swap in a direct deposit resulted in insufficient tokens error DIRECT_DEPOSIT_SWAP_FAILED(); /// @dev thrown if payload is not unique error DUPLICATE_PAYLOAD(); /// @dev thrown if native tokens fail to be sent to superform contracts error FAILED_TO_SEND_NATIVE(); /// @dev thrown if allowance is not correct to deposit error INSUFFICIENT_ALLOWANCE_FOR_DEPOSIT(); /// @dev thrown if contract has insufficient balance for operations error INSUFFICIENT_BALANCE(); /// @dev thrown if native amount is not at least equal to the amount in the request error INSUFFICIENT_NATIVE_AMOUNT(); /// @dev thrown if payload cannot be decoded error INVALID_PAYLOAD(); /// @dev thrown if payload status is invalid error INVALID_PAYLOAD_STATUS(); /// @dev thrown if payload type is invalid error INVALID_PAYLOAD_TYPE(); /// LIQUIDITY BRIDGE EXECUTION ERRORS /// --------------------------------------------------------- /// @dev thrown if we try to decode the final swap output token in a xChain liquidity bridging action error CANNOT_DECODE_FINAL_SWAP_OUTPUT_TOKEN(); /// @dev thrown if liquidity bridge fails for erc20 or native tokens error FAILED_TO_EXECUTE_TXDATA(address token); /// @dev thrown if asset being used for deposit mismatches in multivault deposits error INVALID_DEPOSIT_TOKEN(); /// STATE REGISTRY EXECUTION ERRORS /// --------------------------------------------------------- /// @dev thrown if bridge tokens haven't arrived to destination error BRIDGE_TOKENS_PENDING(); /// @dev thrown if withdrawal tx data cannot be updated error CANNOT_UPDATE_WITHDRAW_TX_DATA(); /// @dev thrown if rescue passed dispute deadline error DISPUTE_TIME_ELAPSED(); /// @dev thrown if message failed to reach the specified level of quorum needed error INSUFFICIENT_QUORUM(); /// @dev thrown if broadcast payload is invalid error INVALID_BROADCAST_PAYLOAD(); /// @dev thrown if broadcast fee is invalid error INVALID_BROADCAST_FEE(); /// @dev thrown if retry fees is less than required error INVALID_RETRY_FEE(); /// @dev thrown if broadcast message type is wrong error INVALID_MESSAGE_TYPE(); /// @dev thrown if payload hash is invalid during `retryMessage` on Layezero implementation error INVALID_PAYLOAD_HASH(); /// @dev thrown if update payload function was called on a wrong payload error INVALID_PAYLOAD_UPDATE_REQUEST(); /// @dev thrown if a state registry id is 0 error INVALID_REGISTRY_ID(); /// @dev thrown if a form state registry id is 0 error INVALID_FORM_REGISTRY_ID(); /// @dev thrown if trying to finalize the payload but the withdraw is still locked error LOCKED(); /// @dev thrown if payload is already updated (during xChain deposits) error PAYLOAD_ALREADY_UPDATED(); /// @dev thrown if payload is already processed error PAYLOAD_ALREADY_PROCESSED(); /// @dev thrown if payload is not in UPDATED state error PAYLOAD_NOT_UPDATED(); /// @dev thrown if rescue is still in timelocked state error RESCUE_LOCKED(); /// @dev thrown if rescue is already proposed error RESCUE_ALREADY_PROPOSED(); /// @dev thrown if payload hash is zero during `retryMessage` on Layezero implementation error ZERO_PAYLOAD_HASH(); /// DST SWAPPER EXECUTION ERRORS /// --------------------------------------------------------- /// @dev thrown if process dst swap is tried for processed payload id error DST_SWAP_ALREADY_PROCESSED(); /// @dev thrown if indices have duplicates error DUPLICATE_INDEX(); /// @dev thrown if failed dst swap is already updated error FAILED_DST_SWAP_ALREADY_UPDATED(); /// @dev thrown if indices are out of bounds error INDEX_OUT_OF_BOUNDS(); /// @dev thrown if failed swap token amount is 0 error INVALID_DST_SWAPPER_FAILED_SWAP(); /// @dev thrown if failed swap token amount is not 0 and if token balance is less than amount (non zero) error INVALID_DST_SWAPPER_FAILED_SWAP_NO_TOKEN_BALANCE(); /// @dev thrown if failed swap token amount is not 0 and if native amount is less than amount (non zero) error INVALID_DST_SWAPPER_FAILED_SWAP_NO_NATIVE_BALANCE(); /// @dev forbid xChain deposits with destination swaps without interim token set (for user protection) error INVALID_INTERIM_TOKEN(); /// @dev thrown if dst swap output is less than minimum expected error INVALID_SWAP_OUTPUT(); /// FORM EXECUTION ERRORS /// --------------------------------------------------------- /// @dev thrown if try to forward 4626 share from the superform error CANNOT_FORWARD_4646_TOKEN(); /// @dev thrown in KYCDAO form if no KYC token is present error NO_VALID_KYC_TOKEN(); /// @dev thrown in forms where a certain functionality is not allowed or implemented error NOT_IMPLEMENTED(); /// @dev thrown if form implementation is PAUSED, users cannot perform any action error PAUSED(); /// @dev thrown if shares != deposit output or assets != redeem output when minting SuperPositions error VAULT_IMPLEMENTATION_FAILED(); /// @dev thrown if withdrawal tx data is not updated error WITHDRAW_TOKEN_NOT_UPDATED(); /// @dev thrown if withdrawal tx data is not updated error WITHDRAW_TX_DATA_NOT_UPDATED(); /// @dev thrown when redeeming from vault yields zero collateral error WITHDRAW_ZERO_COLLATERAL(); /// PAYMENT HELPER EXECUTION ERRORS /// --------------------------------------------------------- /// @dev thrown if chainlink is reporting an improper price error CHAINLINK_MALFUNCTION(); /// @dev thrown if chainlink is reporting an incomplete round error CHAINLINK_INCOMPLETE_ROUND(); /// @dev thrown if feed decimals is not 8 error CHAINLINK_UNSUPPORTED_DECIMAL(); /// EMERGENCY QUEUE EXECUTION ERRORS /// --------------------------------------------------------- /// @dev thrown if emergency withdraw is not queued error EMERGENCY_WITHDRAW_NOT_QUEUED(); /// @dev thrown if emergency withdraw is already processed error EMERGENCY_WITHDRAW_PROCESSED_ALREADY(); /// SUPERPOSITION EXECUTION ERRORS /// --------------------------------------------------------- /// @dev thrown if uri cannot be updated error DYNAMIC_URI_FROZEN(); /// @dev thrown if tx history is not found while state sync error TX_HISTORY_NOT_FOUND(); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (utils/introspection/ERC165Checker.sol) pragma solidity ^0.8.20; import {IERC165} from "./IERC165.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 ERC165Checker { // As per the ERC-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 ERC-165 must explicitly indicate support of // InterfaceId_ERC165 and explicitly indicate non-support of InterfaceId_Invalid return supportsERC165InterfaceUnchecked(account, type(IERC165).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 ERC-165 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}. */ 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 ERC-165 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 ERC-165 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 ERC-165 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 ERC-165, 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.encodeCall(IERC165.supportsInterface, (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: MIT // OpenZeppelin Contracts (last updated v5.0.0) (interfaces/IERC4626.sol) pragma solidity ^0.8.20; import {IERC20} from "../token/ERC20/IERC20.sol"; import {IERC20Metadata} from "../token/ERC20/extensions/IERC20Metadata.sol"; /** * @dev Interface of the ERC-4626 "Tokenized Vault Standard", as defined in * https://eips.ethereum.org/EIPS/eip-4626[ERC-4626]. */ interface IERC4626 is IERC20, IERC20Metadata { event Deposit(address indexed sender, address indexed owner, uint256 assets, uint256 shares); event Withdraw( address indexed sender, address indexed receiver, address indexed owner, uint256 assets, uint256 shares ); /** * @dev Returns the address of the underlying token used for the Vault for accounting, depositing, and withdrawing. * * - MUST be an ERC-20 token contract. * - MUST NOT revert. */ function asset() external view returns (address assetTokenAddress); /** * @dev Returns the total amount of the underlying asset that is “managed” by Vault. * * - SHOULD include any compounding that occurs from yield. * - MUST be inclusive of any fees that are charged against assets in the Vault. * - MUST NOT revert. */ function totalAssets() external view returns (uint256 totalManagedAssets); /** * @dev Returns the amount of shares that the Vault would exchange for the amount of assets provided, in an ideal * scenario where all the conditions are met. * * - MUST NOT be inclusive of any fees that are charged against assets in the Vault. * - MUST NOT show any variations depending on the caller. * - MUST NOT reflect slippage or other on-chain conditions, when performing the actual exchange. * - MUST NOT revert. * * NOTE: This calculation MAY NOT reflect the “per-user” price-per-share, and instead should reflect the * “average-user’s” price-per-share, meaning what the average user should expect to see when exchanging to and * from. */ function convertToShares(uint256 assets) external view returns (uint256 shares); /** * @dev Returns the amount of assets that the Vault would exchange for the amount of shares provided, in an ideal * scenario where all the conditions are met. * * - MUST NOT be inclusive of any fees that are charged against assets in the Vault. * - MUST NOT show any variations depending on the caller. * - MUST NOT reflect slippage or other on-chain conditions, when performing the actual exchange. * - MUST NOT revert. * * NOTE: This calculation MAY NOT reflect the “per-user” price-per-share, and instead should reflect the * “average-user’s” price-per-share, meaning what the average user should expect to see when exchanging to and * from. */ function convertToAssets(uint256 shares) external view returns (uint256 assets); /** * @dev Returns the maximum amount of the underlying asset that can be deposited into the Vault for the receiver, * through a deposit call. * * - MUST return a limited value if receiver is subject to some deposit limit. * - MUST return 2 ** 256 - 1 if there is no limit on the maximum amount of assets that may be deposited. * - MUST NOT revert. */ function maxDeposit(address receiver) external view returns (uint256 maxAssets); /** * @dev Allows an on-chain or off-chain user to simulate the effects of their deposit at the current block, given * current on-chain conditions. * * - MUST return as close to and no more than the exact amount of Vault shares that would be minted in a deposit * call in the same transaction. I.e. deposit should return the same or more shares as previewDeposit if called * in the same transaction. * - MUST NOT account for deposit limits like those returned from maxDeposit and should always act as though the * deposit would be accepted, regardless if the user has enough tokens approved, etc. * - MUST be inclusive of deposit fees. Integrators should be aware of the existence of deposit fees. * - MUST NOT revert. * * NOTE: any unfavorable discrepancy between convertToShares and previewDeposit SHOULD be considered slippage in * share price or some other type of condition, meaning the depositor will lose assets by depositing. */ function previewDeposit(uint256 assets) external view returns (uint256 shares); /** * @dev Mints shares Vault shares to receiver by depositing exactly amount of underlying tokens. * * - MUST emit the Deposit event. * - MAY support an additional flow in which the underlying tokens are owned by the Vault contract before the * deposit execution, and are accounted for during deposit. * - MUST revert if all of assets cannot be deposited (due to deposit limit being reached, slippage, the user not * approving enough underlying tokens to the Vault contract, etc). * * NOTE: most implementations will require pre-approval of the Vault with the Vault’s underlying asset token. */ function deposit(uint256 assets, address receiver) external returns (uint256 shares); /** * @dev Returns the maximum amount of the Vault shares that can be minted for the receiver, through a mint call. * - MUST return a limited value if receiver is subject to some mint limit. * - MUST return 2 ** 256 - 1 if there is no limit on the maximum amount of shares that may be minted. * - MUST NOT revert. */ function maxMint(address receiver) external view returns (uint256 maxShares); /** * @dev Allows an on-chain or off-chain user to simulate the effects of their mint at the current block, given * current on-chain conditions. * * - MUST return as close to and no fewer than the exact amount of assets that would be deposited in a mint call * in the same transaction. I.e. mint should return the same or fewer assets as previewMint if called in the * same transaction. * - MUST NOT account for mint limits like those returned from maxMint and should always act as though the mint * would be accepted, regardless if the user has enough tokens approved, etc. * - MUST be inclusive of deposit fees. Integrators should be aware of the existence of deposit fees. * - MUST NOT revert. * * NOTE: any unfavorable discrepancy between convertToAssets and previewMint SHOULD be considered slippage in * share price or some other type of condition, meaning the depositor will lose assets by minting. */ function previewMint(uint256 shares) external view returns (uint256 assets); /** * @dev Mints exactly shares Vault shares to receiver by depositing amount of underlying tokens. * * - MUST emit the Deposit event. * - MAY support an additional flow in which the underlying tokens are owned by the Vault contract before the mint * execution, and are accounted for during mint. * - MUST revert if all of shares cannot be minted (due to deposit limit being reached, slippage, the user not * approving enough underlying tokens to the Vault contract, etc). * * NOTE: most implementations will require pre-approval of the Vault with the Vault’s underlying asset token. */ function mint(uint256 shares, address receiver) external returns (uint256 assets); /** * @dev Returns the maximum amount of the underlying asset that can be withdrawn from the owner balance in the * Vault, through a withdraw call. * * - MUST return a limited value if owner is subject to some withdrawal limit or timelock. * - MUST NOT revert. */ function maxWithdraw(address owner) external view returns (uint256 maxAssets); /** * @dev Allows an on-chain or off-chain user to simulate the effects of their withdrawal at the current block, * given current on-chain conditions. * * - MUST return as close to and no fewer than the exact amount of Vault shares that would be burned in a withdraw * call in the same transaction. I.e. withdraw should return the same or fewer shares as previewWithdraw if * called * in the same transaction. * - MUST NOT account for withdrawal limits like those returned from maxWithdraw and should always act as though * the withdrawal would be accepted, regardless if the user has enough shares, etc. * - MUST be inclusive of withdrawal fees. Integrators should be aware of the existence of withdrawal fees. * - MUST NOT revert. * * NOTE: any unfavorable discrepancy between convertToShares and previewWithdraw SHOULD be considered slippage in * share price or some other type of condition, meaning the depositor will lose assets by depositing. */ function previewWithdraw(uint256 assets) external view returns (uint256 shares); /** * @dev Burns shares from owner and sends exactly assets of underlying tokens to receiver. * * - MUST emit the Withdraw event. * - MAY support an additional flow in which the underlying tokens are owned by the Vault contract before the * withdraw execution, and are accounted for during withdraw. * - MUST revert if all of assets cannot be withdrawn (due to withdrawal limit being reached, slippage, the owner * not having enough shares, etc). * * Note that some implementations will require pre-requesting to the Vault before a withdrawal may be performed. * Those methods should be performed separately. */ function withdraw(uint256 assets, address receiver, address owner) external returns (uint256 shares); /** * @dev Returns the maximum amount of Vault shares that can be redeemed from the owner balance in the Vault, * through a redeem call. * * - MUST return a limited value if owner is subject to some withdrawal limit or timelock. * - MUST return balanceOf(owner) if owner is not subject to any withdrawal limit or timelock. * - MUST NOT revert. */ function maxRedeem(address owner) external view returns (uint256 maxShares); /** * @dev Allows an on-chain or off-chain user to simulate the effects of their redeemption at the current block, * given current on-chain conditions. * * - MUST return as close to and no more than the exact amount of assets that would be withdrawn in a redeem call * in the same transaction. I.e. redeem should return the same or more assets as previewRedeem if called in the * same transaction. * - MUST NOT account for redemption limits like those returned from maxRedeem and should always act as though the * redemption would be accepted, regardless if the user has enough shares, etc. * - MUST be inclusive of withdrawal fees. Integrators should be aware of the existence of withdrawal fees. * - MUST NOT revert. * * NOTE: any unfavorable discrepancy between convertToAssets and previewRedeem SHOULD be considered slippage in * share price or some other type of condition, meaning the depositor will lose assets by redeeming. */ function previewRedeem(uint256 shares) external view returns (uint256 assets); /** * @dev Burns exactly shares from owner and sends assets of underlying tokens to receiver. * * - MUST emit the Withdraw event. * - MAY support an additional flow in which the underlying tokens are owned by the Vault contract before the * redeem execution, and are accounted for during redeem. * - MUST revert if all of shares cannot be redeemed (due to withdrawal limit being reached, slippage, the owner * not having enough shares, etc). * * NOTE: some implementations will require pre-requesting to the Vault before a withdrawal may be performed. * Those methods should be performed separately. */ function redeem(uint256 shares, address receiver, address owner) external returns (uint256 assets); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (proxy/Clones.sol) pragma solidity ^0.8.20; /** * @dev https://eips.ethereum.org/EIPS/eip-1167[ERC-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. */ library Clones { /** * @dev A clone instance deployment failed. */ error ERC1167FailedCreateClone(); /** * @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) } if (instance == address(0)) { revert ERC1167FailedCreateClone(); } } /** * @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) } if (instance == address(0)) { revert ERC1167FailedCreateClone(); } } /** * @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: BUSL-1.1 pragma solidity ^0.8.23; /// @title IBroadcastRegistry /// @dev Interface for BroadcastRegistry /// @author ZeroPoint Labs interface IBroadcastRegistry { ////////////////////////////////////////////////////////////// // EXTERNAL WRITE FUNCTIONS // ////////////////////////////////////////////////////////////// /// @dev emitted when a payload is broadcasted event PayloadSent(address indexed sender); /// @dev emitted when a broadcast payload is received event PayloadReceived(uint256 indexed payloadId, uint64 indexed srcChainId); ////////////////////////////////////////////////////////////// // EXTERNAL WRITE FUNCTIONS // ////////////////////////////////////////////////////////////// /// @dev allows core contracts to send payload to all configured destination chain. /// @param srcSender_ is the caller of the function (used for gas refunds). /// @param ambId_ is the identifier of the arbitrary message bridge to be used /// @param gasFee_ is the gas fee to be used for broadcasting /// @param message_ is the crosschain payload to be broadcasted /// @param extraData_ defines all the message bridge related overrides function broadcastPayload( address srcSender_, uint8 ambId_, uint256 gasFee_, bytes memory message_, bytes memory extraData_ ) external payable; /// @dev allows ambs to write broadcasted payloads function receiveBroadcastPayload(uint64 srcChainId_, bytes memory message_) external; /// @dev allows privileged actors to process broadcasted payloads /// @param payloadId_ is the identifier of the cross-chain payload function processPayload(uint256 payloadId_) external; }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity ^0.8.23; import { InitSingleVaultData } from "src/types/DataTypes.sol"; /// @title IEmergencyQueue /// @dev Interface for EmergencyQueue /// @author ZeroPoint Labs interface IEmergencyQueue { ////////////////////////////////////////////////////////////// // EVENTS // ////////////////////////////////////////////////////////////// event WithdrawalQueued( address indexed receiverAddress, uint256 indexed id, uint256 indexed superformId, uint256 amount, uint256 srcPayloadId ); event WithdrawalProcessed( address indexed refundAddress, uint256 indexed id, uint256 indexed superformId, uint256 amount ); ////////////////////////////////////////////////////////////// // EXTERNAL VIEW FUNCTIONS // ////////////////////////////////////////////////////////////// /// @dev returns the execution status of an id in the emergency queue /// @param id is the identifier of the queued action /// @return boolean representing the execution status function queuedWithdrawalStatus(uint256 id) external view returns (bool); ////////////////////////////////////////////////////////////// // EXTERNAL WRITE FUNCTIONS // ////////////////////////////////////////////////////////////// /// @dev called by paused forms to queue up withdrawals for exit /// @param data_ is the single vault data passed by the user function queueWithdrawal(InitSingleVaultData memory data_) external; /// @dev called by emergency admin to processed queued withdrawal /// @param id_ is the identifier of the queued action function executeQueuedWithdrawal(uint256 id_) external; /// @dev called by emergency admin to batch process queued withdrawals /// @param ids_ is the array of identifiers of the queued actions function batchExecuteQueuedWithdrawal(uint256[] memory ids_) external; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (proxy/utils/Initializable.sol) pragma solidity ^0.8.20; /** * @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 Storage of the initializable contract. * * It's implemented on a custom ERC-7201 namespace to reduce the risk of storage collisions * when using with upgradeable contracts. * * @custom:storage-location erc7201:openzeppelin.storage.Initializable */ struct InitializableStorage { /** * @dev Indicates that the contract has been initialized. */ uint64 _initialized; /** * @dev Indicates that the contract is in the process of being initialized. */ bool _initializing; } // keccak256(abi.encode(uint256(keccak256("openzeppelin.storage.Initializable")) - 1)) & ~bytes32(uint256(0xff)) bytes32 private constant INITIALIZABLE_STORAGE = 0xf0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00; /** * @dev The contract is already initialized. */ error InvalidInitialization(); /** * @dev The contract is not initializing. */ error NotInitializing(); /** * @dev Triggered when the contract has been initialized or reinitialized. */ event Initialized(uint64 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 in the context of a constructor an `initializer` may be invoked any * number of times. This behavior in the constructor can be useful during testing and is not expected to be used in * production. * * Emits an {Initialized} event. */ modifier initializer() { // solhint-disable-next-line var-name-mixedcase InitializableStorage storage $ = _getInitializableStorage(); // Cache values to avoid duplicated sloads bool isTopLevelCall = !$._initializing; uint64 initialized = $._initialized; // Allowed calls: // - initialSetup: the contract is not in the initializing state and no previous version was // initialized // - construction: the contract is initialized at version 1 (no reininitialization) and the // current contract is just being deployed bool initialSetup = initialized == 0 && isTopLevelCall; bool construction = initialized == 1 && address(this).code.length == 0; if (!initialSetup && !construction) { revert InvalidInitialization(); } $._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 2**64 - 1 will prevent any future reinitialization. * * Emits an {Initialized} event. */ modifier reinitializer(uint64 version) { // solhint-disable-next-line var-name-mixedcase InitializableStorage storage $ = _getInitializableStorage(); if ($._initializing || $._initialized >= version) { revert InvalidInitialization(); } $._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() { _checkInitializing(); _; } /** * @dev Reverts if the contract is not in an initializing state. See {onlyInitializing}. */ function _checkInitializing() internal view virtual { if (!_isInitializing()) { revert NotInitializing(); } } /** * @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 { // solhint-disable-next-line var-name-mixedcase InitializableStorage storage $ = _getInitializableStorage(); if ($._initializing) { revert InvalidInitialization(); } if ($._initialized != type(uint64).max) { $._initialized = type(uint64).max; emit Initialized(type(uint64).max); } } /** * @dev Returns the highest version that has been initialized. See {reinitializer}. */ function _getInitializedVersion() internal view returns (uint64) { return _getInitializableStorage()._initialized; } /** * @dev Returns `true` if the contract is currently initializing. See {onlyInitializing}. */ function _isInitializing() internal view returns (bool) { return _getInitializableStorage()._initializing; } /** * @dev Returns a pointer to the storage namespace. */ // solhint-disable-next-line var-name-mixedcase function _getInitializableStorage() private pure returns (InitializableStorage storage $) { assembly { $.slot := INITIALIZABLE_STORAGE } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (utils/introspection/ERC165.sol) pragma solidity ^0.8.20; import {IERC165} from "./IERC165.sol"; /** * @dev Implementation of the {IERC165} interface. * * Contracts that want to implement ERC-165 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); * } * ``` */ abstract contract ERC165 is IERC165 { /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual returns (bool) { return interfaceId == type(IERC165).interfaceId; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (utils/introspection/IERC165.sol) pragma solidity ^0.8.20; /** * @dev Interface of the ERC-165 standard, as defined in the * https://eips.ethereum.org/EIPS/eip-165[ERC]. * * 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[ERC 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 v5.0.0) (access/IAccessControl.sol) pragma solidity ^0.8.20; /** * @dev External interface of AccessControl declared to support ERC-165 detection. */ interface IAccessControl { /** * @dev The `account` is missing a role. */ error AccessControlUnauthorizedAccount(address account, bytes32 neededRole); /** * @dev The caller of a function is not the expected one. * * NOTE: Don't confuse with {AccessControlUnauthorizedAccount}. */ error AccessControlBadConfirmation(); /** * @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole` * * `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite * {RoleAdminChanged} not being emitted signaling this. */ event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole); /** * @dev Emitted when `account` is granted `role`. * * `sender` is the account that originated the contract call, an admin role * bearer except when using {AccessControl-_setupRole}. */ event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender); /** * @dev Emitted when `account` is revoked `role`. * * `sender` is the account that originated the contract call: * - if using `revokeRole`, it is the admin role bearer * - if using `renounceRole`, it is the role bearer (i.e. `account`) */ event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender); /** * @dev Returns `true` if `account` has been granted `role`. */ function hasRole(bytes32 role, address account) external view returns (bool); /** * @dev Returns the admin role that controls `role`. See {grantRole} and * {revokeRole}. * * To change a role's admin, use {AccessControl-_setRoleAdmin}. */ function getRoleAdmin(bytes32 role) external view returns (bytes32); /** * @dev Grants `role` to `account`. * * If `account` had not been already granted `role`, emits a {RoleGranted} * event. * * Requirements: * * - the caller must have ``role``'s admin role. */ function grantRole(bytes32 role, address account) external; /** * @dev Revokes `role` from `account`. * * If `account` had been granted `role`, emits a {RoleRevoked} event. * * Requirements: * * - the caller must have ``role``'s admin role. */ function revokeRole(bytes32 role, address account) external; /** * @dev Revokes `role` from the calling account. * * Roles are often managed via {grantRole} and {revokeRole}: this function's * purpose is to provide a mechanism for accounts to lose their privileges * if they are compromised (such as when a trusted device is misplaced). * * If the calling account had been granted `role`, emits a {RoleRevoked} * event. * * Requirements: * * - the caller must be `callerConfirmation`. */ function renounceRole(bytes32 role, address callerConfirmation) external; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/IERC20.sol) pragma solidity ^0.8.20; /** * @dev Interface of the ERC-20 standard as defined in the ERC. */ interface IERC20 { /** * @dev Emitted when `value` tokens are moved from one account (`from`) to * another (`to`). * * Note that `value` may be zero. */ event Transfer(address indexed from, address indexed to, uint256 value); /** * @dev Emitted when the allowance of a `spender` for an `owner` is set by * a call to {approve}. `value` is the new allowance. */ event Approval(address indexed owner, address indexed spender, uint256 value); /** * @dev Returns the value of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the value of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves a `value` amount of tokens from the caller's account to `to`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address to, uint256 value) external returns (bool); /** * @dev Returns the remaining number of tokens that `spender` will be * allowed to spend on behalf of `owner` through {transferFrom}. This is * zero by default. * * This value changes when {approve} or {transferFrom} are called. */ function allowance(address owner, address spender) external view returns (uint256); /** * @dev Sets a `value` amount of tokens as the allowance of `spender` over the * caller's tokens. * * Returns a boolean value indicating whether the operation succeeded. * * IMPORTANT: Beware that changing an allowance with this method brings the risk * that someone may use both the old and the new allowance by unfortunate * transaction ordering. One possible solution to mitigate this race * condition is to first reduce the spender's allowance to 0 and set the * desired value afterwards: * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 * * Emits an {Approval} event. */ function approve(address spender, uint256 value) external returns (bool); /** * @dev Moves a `value` amount of tokens from `from` to `to` using the * allowance mechanism. `value` is then deducted from the caller's * allowance. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transferFrom(address from, address to, uint256 value) external returns (bool); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/extensions/IERC20Metadata.sol) pragma solidity ^0.8.20; import {IERC20} from "../IERC20.sol"; /** * @dev Interface for the optional metadata functions from the ERC-20 standard. */ interface IERC20Metadata is IERC20 { /** * @dev Returns the name of the token. */ function name() external view returns (string memory); /** * @dev Returns the symbol of the token. */ function symbol() external view returns (string memory); /** * @dev Returns the decimals places of the token. */ function decimals() external view returns (uint8); }
{ "remappings": [ "solmate/=lib/ERC1155A/lib/solmate/src/", "ERC1155A/=lib/ERC1155A/src/", "@openzeppelin/contracts/=lib/ERC1155A/lib/openzeppelin-contracts/contracts/", "ds-test/=lib/ds-test/src/", "erc4626-tests/=lib/ERC1155A/lib/openzeppelin-contracts/lib/erc4626-tests/", "forge-std/=lib/forge-std/src/", "openzeppelin-contracts/=lib/ERC1155A/lib/openzeppelin-contracts/", "pigeon/=lib/pigeon/src/", "solady/=lib/pigeon/lib/solady/", "super-vaults/=lib/super-vaults/src/", "v2-core/=lib/super-vaults/lib/v2-core/contracts/", "v2-periphery/=lib/super-vaults/lib/v2-periphery/contracts/", "v3-core/=lib/super-vaults/lib/v3-core/" ], "optimizer": { "enabled": true, "runs": 200 }, "metadata": { "useLiteralContent": false, "bytecodeHash": "ipfs", "appendCBOR": true }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "evmVersion": "paris", "libraries": {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"address","name":"superRegistry_","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"BLOCK_CHAIN_ID_OUT_OF_BOUNDS","type":"error"},{"inputs":[],"name":"ERC1167FailedCreateClone","type":"error"},{"inputs":[],"name":"ERC165_UNSUPPORTED","type":"error"},{"inputs":[],"name":"FAILED_TO_SEND_NATIVE","type":"error"},{"inputs":[],"name":"FORM_DOES_NOT_EXIST","type":"error"},{"inputs":[],"name":"FORM_IMPLEMENTATION_ALREADY_EXISTS","type":"error"},{"inputs":[],"name":"FORM_IMPLEMENTATION_ID_ALREADY_EXISTS","type":"error"},{"inputs":[],"name":"FORM_INTERFACE_UNSUPPORTED","type":"error"},{"inputs":[],"name":"INVALID_BROADCAST_FEE","type":"error"},{"inputs":[],"name":"INVALID_CHAIN_ID","type":"error"},{"inputs":[],"name":"INVALID_FORM_ID","type":"error"},{"inputs":[],"name":"INVALID_FORM_REGISTRY_ID","type":"error"},{"inputs":[],"name":"MSG_VALUE_NOT_ZERO","type":"error"},{"inputs":[],"name":"NOT_BROADCAST_REGISTRY","type":"error"},{"inputs":[],"name":"NOT_EMERGENCY_ADMIN","type":"error"},{"inputs":[],"name":"NOT_PROTOCOL_ADMIN","type":"error"},{"inputs":[],"name":"VAULT_FORM_IMPLEMENTATION_COMBINATION_EXISTS","type":"error"},{"inputs":[],"name":"ZERO_ADDRESS","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"formImplementation","type":"address"},{"indexed":true,"internalType":"uint256","name":"formImplementationId","type":"uint256"},{"indexed":true,"internalType":"uint8","name":"formStateRegistryId","type":"uint8"}],"name":"FormImplementationAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"formImplementationId","type":"uint256"},{"indexed":true,"internalType":"enum ISuperformFactory.PauseStatus","name":"paused","type":"uint8"}],"name":"FormImplementationPaused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"superRegistry","type":"address"}],"name":"SuperRegistrySet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"formImplementationId","type":"uint256"},{"indexed":true,"internalType":"address","name":"vault","type":"address"},{"indexed":true,"internalType":"uint256","name":"superformId","type":"uint256"},{"indexed":false,"internalType":"address","name":"superform","type":"address"}],"name":"SuperformCreated","type":"event"},{"inputs":[],"name":"CHAIN_ID","outputs":[{"internalType":"uint64","name":"","type":"uint64"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"formImplementation_","type":"address"},{"internalType":"uint32","name":"formImplementationId_","type":"uint32"},{"internalType":"uint8","name":"formStateRegistryId_","type":"uint8"}],"name":"addFormImplementation","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint32","name":"formImplementationId_","type":"uint32"},{"internalType":"enum ISuperformFactory.PauseStatus","name":"status_","type":"uint8"},{"internalType":"bytes","name":"extraData_","type":"bytes"}],"name":"changeFormImplementationPauseStatus","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint32","name":"formImplementationId_","type":"uint32"},{"internalType":"address","name":"vault_","type":"address"}],"name":"createSuperform","outputs":[{"internalType":"uint256","name":"superformId_","type":"uint256"},{"internalType":"address","name":"superform_","type":"address"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint32","name":"formImplementationId","type":"uint32"}],"name":"formImplementation","outputs":[{"internalType":"address","name":"formImplementationAddress","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"formImplementationAddress","type":"address"}],"name":"formImplementationIds","outputs":[{"internalType":"uint32","name":"formImplementationId","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"formImplementationId","type":"uint32"}],"name":"formImplementationPaused","outputs":[{"internalType":"enum ISuperformFactory.PauseStatus","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"formImplementations","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"formImplementationId","type":"uint32"}],"name":"formStateRegistryId","outputs":[{"internalType":"uint8","name":"formRegistryId","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"vault_","type":"address"}],"name":"getAllSuperformsFromVault","outputs":[{"internalType":"uint256[]","name":"superformIds_","type":"uint256[]"},{"internalType":"address[]","name":"superforms_","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getFormCount","outputs":[{"internalType":"uint256","name":"forms_","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"formImplementationId_","type":"uint32"}],"name":"getFormImplementation","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"formImplementationId_","type":"uint32"}],"name":"getFormStateRegistryId","outputs":[{"internalType":"uint8","name":"formStateRegistryId_","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"superformId_","type":"uint256"}],"name":"getSuperform","outputs":[{"internalType":"address","name":"superform_","type":"address"},{"internalType":"uint32","name":"formImplementationId_","type":"uint32"},{"internalType":"uint64","name":"chainId_","type":"uint64"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"getSuperformCount","outputs":[{"internalType":"uint256","name":"superforms_","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"formImplementationId_","type":"uint32"}],"name":"isFormImplementationPaused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"superformId","type":"uint256"}],"name":"isSuperform","outputs":[{"internalType":"bool","name":"superformIdExists","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes","name":"data_","type":"bytes"}],"name":"stateSyncBroadcast","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"superRegistry","outputs":[{"internalType":"contract ISuperRegistry","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"superforms","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"vaultFormImplementationCombination","type":"bytes32"}],"name":"vaultFormImplCombinationToSuperforms","outputs":[{"internalType":"uint256","name":"superformIds","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"vault","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"vaultToFormImplementationId","outputs":[{"internalType":"uint256","name":"formImplementationId","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"vault","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"vaultToSuperforms","outputs":[{"internalType":"uint256","name":"superformIds","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"xChainPayloadCounter","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"}]
Contract Creation Code
60c06040523480156200001157600080fd5b5060405162002034380380620020348339810160408190526200003491620000a4565b6001600160a01b0381166200005c5760405163538ba4f960e01b815260040160405180910390fd5b6001600160401b034611156200008557604051637ecdf93360e01b815260040160405180910390fd5b6001600160401b03461660a0526001600160a01b0316608052620000d6565b600060208284031215620000b757600080fd5b81516001600160a01b0381168114620000cf57600080fd5b9392505050565b60805160a051611ef96200013b600039600081816103d4015281816108d90152818161102501526111b50152600081816101f1015281816107020152818161096c01528181610a1401528181610b4f015281816110af01526113280152611ef96000f3fe60806040526004361061014b5760003560e01c806380e8586b116100b6578063bb3808cc1161006f578063bb3808cc146104ab578063c4d6e6b2146104e7578063dfd6e4ab14610524578063e6ddad4c14610544578063e83310a214610557578063edf387c51461058d57600080fd5b806380e8586b1461037a57806385e1f4d0146103c25780638de833a91461040e5780639e0668381461042e578063b5c756971461044e578063b85225bb1461047e57600080fd5b8063479f3b8711610108578063479f3b871461026057806352fc069e14610280578063589434ca146102b2578063596db717146102c75780636fb86dd3146102f75780637239fe4f1461034a57600080fd5b80631547665d146101505780631bc089ed146101745780632085caec146101b157806324c73dda146101df5780632d75c56a1461022b5780633d2378f414610240575b600080fd5b34801561015c57600080fd5b506002545b6040519081526020015b60405180910390f35b34801561018057600080fd5b506101a461018f3660046117de565b60076020526000908152604090205460ff1681565b60405161016b9190611833565b3480156101bd57600080fd5b506101d16101cc366004611856565b6105a3565b60405161016b929190611873565b3480156101eb57600080fd5b506102137f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b03909116815260200161016b565b61023e6102393660046119c7565b6106cd565b005b34801561024c57600080fd5b5061023e61025b366004611a37565b610b1a565b34801561026c57600080fd5b5061016161027b366004611a82565b610e4a565b34801561028c57600080fd5b506102a061029b3660046117de565b610e6b565b60405160ff909116815260200161016b565b3480156102be57600080fd5b50600154610161565b3480156102d357600080fd5b506102e76102e23660046117de565b610eaa565b604051901515815260200161016b565b34801561030357600080fd5b50610317610312366004611a82565b610edf565b604080516001600160a01b03909416845263ffffffff90921660208401526001600160401b03169082015260600161016b565b34801561035657600080fd5b506102a06103653660046117de565b60066020526000908152604090205460ff1681565b34801561038657600080fd5b506103ad610395366004611856565b60056020526000908152604090205463ffffffff1681565b60405163ffffffff909116815260200161016b565b3480156103ce57600080fd5b506103f67f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160401b03909116815260200161016b565b34801561041a57600080fd5b50610161610429366004611a9b565b610efa565b34801561043a57600080fd5b50610161610449366004611a9b565b610f2b565b34801561045a57600080fd5b506102e7610469366004611a82565b60036020526000908152604090205460ff1681565b34801561048a57600080fd5b50610161610499366004611a82565b600a6020526000908152604090205481565b3480156104b757600080fd5b506102136104c63660046117de565b63ffffffff166000908152600460205260409020546001600160a01b031690565b3480156104f357600080fd5b50610507610502366004611ac7565b610f47565b604080519283526001600160a01b0390911660208301520161016b565b34801561053057600080fd5b5061021361053f366004611a82565b6112c9565b61023e610552366004611b00565b6112f3565b34801561056357600080fd5b506102136105723660046117de565b6004602052600090815260409020546001600160a01b031681565b34801561059957600080fd5b5061016160005481565b60608060086000846001600160a01b03166001600160a01b0316815260200190815260200160002080548060200260200160405190810160405280929190818152602001828054801561061557602002820191906000526020600020905b815481526020019060010190808311610601575b5050835193955083925050506001600160401b0381111561063857610638611904565b604051908082528060200260200182016040528015610661578160200160208202803683370190505b50915060005b818110156106c65761069184828151811061068457610684611b3c565b6020026020010151611420565b9050508382815181106106a6576106a6611b3c565b6001600160a01b0390921660209283029190910190910152600101610667565b5050915091565b6040516321f8a72160e01b81527f6b50fa17b77d24e42e27a04b69fe50cd6967cfb767d18de0bd5fe7e1a32aa86860048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906321f8a72190602401602060405180830381865afa158015610751573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107759190611b52565b6040516317a0e54b60e11b81523360048201526001600160a01b039190911690632f41ca9690602401602060405180830381865afa1580156107bb573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107df9190611b6f565b6107fc5760405163222d861d60e11b815260040160405180910390fd5b63ffffffff83166000908152600460205260409020546001600160a01b0316610838576040516303e1b5a760e11b815260040160405180910390fd5b63ffffffff83166000908152600760205260409020805483919060ff191660018381811115610869576108696117fb565b0217905550805115610ab35760006040518060600160405280604051806040016040528060118152602001705355504552464f524d5f464143544f525960781b81525081526020017ff32750c6acdf0a869f9f19cdbb49fd915b2636c74468ee5682c8ecd3b65ab38b81526020017f0000000000000000000000000000000000000000000000000000000000000000600080815461090690611ba7565b918290555060405161092092919089908990602001611bc0565b60408051808303601f190181529181529152516321f8a72160e01b81527f86a7f6b88da6de42c331676d4da78508adfef4970dc8aa541004f26b6eef4ab96004820152909150610aad907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906321f8a72190602401602060405180830381865afa1580156109bb573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109df9190611b52565b6040516321f8a72160e01b81527fbddfa8c39a1f6275bcfb3aa5c70638c466999edbf14e6162d81b3492caca9fce60048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906321f8a72190602401602060405180830381865afa158015610a63573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a879190611b52565b83604051602001610a989190611c49565b60405160208183030381529060405285611454565b50610ad2565b3415610ad25760405163308f275d60e01b815260040160405180910390fd5b816001811115610ae457610ae46117fb565b60405163ffffffff8516907f1cb88bdf176e51fa7c40e8e4683e78b1792a2ce649cfae1f26fec314eebe536e90600090a3505050565b6040516321f8a72160e01b81527f6b50fa17b77d24e42e27a04b69fe50cd6967cfb767d18de0bd5fe7e1a32aa86860048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906321f8a72190602401602060405180830381865afa158015610b9e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bc29190611b52565b6040516369ac88f960e11b81523360048201526001600160a01b03919091169063d35911f290602401602060405180830381865afa158015610c08573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c2c9190611b6f565b610c4957604051633721555560e21b815260040160405180910390fd5b6001600160a01b038316610c705760405163538ba4f960e01b815260040160405180910390fd5b610c79836115a0565b610c9657604051631848783960e31b815260040160405180910390fd5b63ffffffff82166000908152600460205260409020546001600160a01b031615610cd35760405163deca71e360e01b815260040160405180910390fd5b6001600160a01b03831660009081526005602052604090205463ffffffff1615610d1057604051633ee1bf6960e11b815260040160405180910390fd5b610d21836351fef14760e01b6115d4565b610d3e576040516324ea76c760e01b815260040160405180910390fd5b63ffffffff8216600081815260046020908152604080832080546001600160a01b0319166001600160a01b038916908117909155835260059091528120805463ffffffff191690921790915560ff82169003610dad576040516326886d6760e01b815260040160405180910390fd5b63ffffffff8216600081815260066020526040808220805460ff191660ff86169081179091556001805480820182559084527fb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf60180546001600160a01b0319166001600160a01b03891690811790915591519093927f57e36bd8ee2840c13ad182923b129cd3b97186aa7ac714bfa5e59425fc22eeeb91a4505050565b60028181548110610e5a57600080fd5b600091825260209091200154905081565b63ffffffff811660009081526006602052604081205460ff1690819003610ea5576040516326886d6760e01b815260040160405180910390fd5b919050565b6000600163ffffffff831660009081526007602052604090205460ff166001811115610ed857610ed86117fb565b1492915050565b6000806000610eed84611420565b9196909550909350915050565b60086020528160005260406000208181548110610f1657600080fd5b90600052602060002001600091509150505481565b60096020528160005260406000208181548110610f1657600080fd5b6000806001600160a01b038316610f715760405163538ba4f960e01b815260040160405180910390fd5b63ffffffff84166000908152600460205260409020546001600160a01b031680610fae576040516344976fc160e11b815260040160405180910390fd5b604080516001600160a01b03808416602083015286169181019190915260009060600160408051601f1981840301815291815281516020928301206000818152600a9093529120549091501561101757604051630205e78560e51b815260040160405180910390fd5b604080516001600160401b037f000000000000000000000000000000000000000000000000000000000000000016602082015263ffffffff8816918101919091526001600160a01b038616606082015261109c9060800160405160208183030381529060405280519060200120836001600160a01b03166115f790919063ffffffff16565b9250826001600160a01b031663c0c53b8b7f000000000000000000000000000000000000000000000000000000000000000087886001600160a01b03166338d52e0f6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561110d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111319190611b52565b60405160e085901b6001600160e01b03191681526001600160a01b03938416600482015291831660248301529091166044820152606401600060405180830381600087803b15801561118257600080fd5b505af1158015611196573d6000803e3d6000fd5b505050506001600160a01b03831660a087901b63ffffffff60a01b16177f000000000000000000000000000000000000000000000000000000000000000060c01b6001600160c01b031916176001600160a01b03868116600081815260086020908152604080832080546001808201835591855283852001879055848452600983528184208054808301825590855283852063ffffffff8f169101819055888552600a8452828520889055600280548084019091557f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ace018890558785526003845293829020805460ff191690911790555193881684529397508793919290917ff40fe66c44bcbe514dc449b1c700989fe0ace6e4e6c48a118cc9b452c285c72b910160405180910390a450509250929050565b600181815481106112d957600080fd5b6000918252602090912001546001600160a01b0316905081565b6040516321f8a72160e01b81527f86a7f6b88da6de42c331676d4da78508adfef4970dc8aa541004f26b6eef4ab960048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906321f8a72190602401602060405180830381865afa158015611377573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061139b9190611b52565b6001600160a01b0316336001600160a01b0316146113cc5760405163b0acaf9d60e01b815260040160405180910390fd5b6000818060200190518101906113e29190611cd1565b90507ff32750c6acdf0a869f9f19cdbb49fd915b2636c74468ee5682c8ecd3b65ab38b81602001510361141c5761141c8160400151611665565b5050565b8060a081901c60c082901c600081900361144d5760405163030042b760e01b815260040160405180910390fd5b9193909250565b6000808280602001905181019061146b9190611d81565b91509150600080828060200190518101906114869190611dd1565b91509150813410156114ab57604051631961e86760e01b815260040160405180910390fd5b604051636319827b60e11b81526001600160a01b0389169063c63304f69084906114e1903390899084908d908990600401611e01565b6000604051808303818588803b1580156114fa57600080fd5b505af115801561150e573d6000803e3d6000fd5b5050505050813411156115965760006001600160a01b0388166115318434611e4f565b604051600081818185875af1925050503d806000811461156d576040519150601f19603f3d011682016040523d82523d6000602084013e611572565b606091505b50509050806115945760405163220d375360e01b815260040160405180910390fd5b505b5050505050505050565b60006115b3826301ffc9a760e01b61173f565b80156115ce57506115cc826001600160e01b031961173f565b155b92915050565b60006115df836115a0565b80156115f057506115f0838361173f565b9392505050565b6000763d602d80600a3d3981f3363d3d373d3d3d363d730000008360601b60e81c176000526e5af43d82803e903d91602b57fd5bf38360781b1760205281603760096000f590506001600160a01b0381166115ce576040516330be1a3d60e21b815260040160405180910390fd5b6000808280602001905181019061167c9190611e62565b63ffffffff821660009081526004602052604090205491955093506001600160a01b031691506116c19050576040516303e1b5a760e11b815260040160405180910390fd5b63ffffffff82166000908152600760205260409020805482919060ff1916600183818111156116f2576116f26117fb565b0217905550806001811115611709576117096117fb565b60405163ffffffff8416907f1cb88bdf176e51fa7c40e8e4683e78b1792a2ce649cfae1f26fec314eebe536e90600090a3505050565b6040516001600160e01b031982166024820152600090819060440160408051601f19818403018152919052602080820180516001600160e01b03166301ffc9a760e01b178152825192935060009283928392909183918a617530fa92503d915060005190508280156117b2575060208210155b80156117be5750600081115b979650505050505050565b63ffffffff811681146117db57600080fd5b50565b6000602082840312156117f057600080fd5b81356115f0816117c9565b634e487b7160e01b600052602160045260246000fd5b6002811061182f57634e487b7160e01b600052602160045260246000fd5b9052565b602081016115ce8284611811565b6001600160a01b03811681146117db57600080fd5b60006020828403121561186857600080fd5b81356115f081611841565b604080825283519082018190526000906020906060840190828701845b828110156118ac57815184529284019290840190600101611890565b5050508381038285015284518082528583019183019060005b818110156118ea5783516001600160a01b0316835292840192918401916001016118c5565b5090979650505050505050565b600281106117db57600080fd5b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f191681016001600160401b038111828210171561194257611942611904565b604052919050565b60006001600160401b0382111561196357611963611904565b50601f01601f191660200190565b600082601f83011261198257600080fd5b81356119956119908261194a565b61191a565b8181528460208386010111156119aa57600080fd5b816020850160208301376000918101602001919091529392505050565b6000806000606084860312156119dc57600080fd5b83356119e7816117c9565b925060208401356119f7816118f7565b915060408401356001600160401b03811115611a1257600080fd5b611a1e86828701611971565b9150509250925092565b60ff811681146117db57600080fd5b600080600060608486031215611a4c57600080fd5b8335611a5781611841565b92506020840135611a67816117c9565b91506040840135611a7781611a28565b809150509250925092565b600060208284031215611a9457600080fd5b5035919050565b60008060408385031215611aae57600080fd5b8235611ab981611841565b946020939093013593505050565b60008060408385031215611ada57600080fd5b8235611ae5816117c9565b91506020830135611af581611841565b809150509250929050565b600060208284031215611b1257600080fd5b81356001600160401b03811115611b2857600080fd5b611b3484828501611971565b949350505050565b634e487b7160e01b600052603260045260246000fd5b600060208284031215611b6457600080fd5b81516115f081611841565b600060208284031215611b8157600080fd5b815180151581146115f057600080fd5b634e487b7160e01b600052601160045260246000fd5b600060018201611bb957611bb9611b91565b5060010190565b6001600160401b03851681526020810184905263ffffffff8316604082015260808101611bf06060830184611811565b95945050505050565b60005b83811015611c14578181015183820152602001611bfc565b50506000910152565b60008151808452611c35816020860160208601611bf9565b601f01601f19169290920160200192915050565b602081526000825160606020840152611c656080840182611c1d565b9050602084015160408401526040840151601f19848303016060850152611bf08282611c1d565b600082601f830112611c9d57600080fd5b8151611cab6119908261194a565b818152846020838601011115611cc057600080fd5b611b34826020830160208701611bf9565b600060208284031215611ce357600080fd5b81516001600160401b0380821115611cfa57600080fd5b9083019060608286031215611d0e57600080fd5b604051606081018181108382111715611d2957611d29611904565b604052825182811115611d3b57600080fd5b611d4787828601611c8c565b82525060208301516020820152604083015182811115611d6657600080fd5b611d7287828601611c8c565b60408301525095945050505050565b60008060408385031215611d9457600080fd5b8251611d9f81611a28565b60208401519092506001600160401b03811115611dbb57600080fd5b611dc785828601611c8c565b9150509250929050565b60008060408385031215611de457600080fd5b8251915060208301516001600160401b03811115611dbb57600080fd5b60018060a01b038616815260ff8516602082015283604082015260a060608201526000611e3160a0830185611c1d565b8281036080840152611e438185611c1d565b98975050505050505050565b818103818111156115ce576115ce611b91565b60008060008060808587031215611e7857600080fd5b84516001600160401b0381168114611e8f57600080fd5b602086015160408701519195509350611ea7816117c9565b6060860151909250611eb8816118f7565b93969295509093505056fea2646970667358221220ad9da98eb5e7f8056ab81f7b1fad4a9d6b8f7793237ae8de7065d58e6887f6c564736f6c6343000817003300000000000000000000000017a332dc7b40ae701485023b219e9d6f493a2514
Deployed Bytecode
0x60806040526004361061014b5760003560e01c806380e8586b116100b6578063bb3808cc1161006f578063bb3808cc146104ab578063c4d6e6b2146104e7578063dfd6e4ab14610524578063e6ddad4c14610544578063e83310a214610557578063edf387c51461058d57600080fd5b806380e8586b1461037a57806385e1f4d0146103c25780638de833a91461040e5780639e0668381461042e578063b5c756971461044e578063b85225bb1461047e57600080fd5b8063479f3b8711610108578063479f3b871461026057806352fc069e14610280578063589434ca146102b2578063596db717146102c75780636fb86dd3146102f75780637239fe4f1461034a57600080fd5b80631547665d146101505780631bc089ed146101745780632085caec146101b157806324c73dda146101df5780632d75c56a1461022b5780633d2378f414610240575b600080fd5b34801561015c57600080fd5b506002545b6040519081526020015b60405180910390f35b34801561018057600080fd5b506101a461018f3660046117de565b60076020526000908152604090205460ff1681565b60405161016b9190611833565b3480156101bd57600080fd5b506101d16101cc366004611856565b6105a3565b60405161016b929190611873565b3480156101eb57600080fd5b506102137f00000000000000000000000017a332dc7b40ae701485023b219e9d6f493a251481565b6040516001600160a01b03909116815260200161016b565b61023e6102393660046119c7565b6106cd565b005b34801561024c57600080fd5b5061023e61025b366004611a37565b610b1a565b34801561026c57600080fd5b5061016161027b366004611a82565b610e4a565b34801561028c57600080fd5b506102a061029b3660046117de565b610e6b565b60405160ff909116815260200161016b565b3480156102be57600080fd5b50600154610161565b3480156102d357600080fd5b506102e76102e23660046117de565b610eaa565b604051901515815260200161016b565b34801561030357600080fd5b50610317610312366004611a82565b610edf565b604080516001600160a01b03909416845263ffffffff90921660208401526001600160401b03169082015260600161016b565b34801561035657600080fd5b506102a06103653660046117de565b60066020526000908152604090205460ff1681565b34801561038657600080fd5b506103ad610395366004611856565b60056020526000908152604090205463ffffffff1681565b60405163ffffffff909116815260200161016b565b3480156103ce57600080fd5b506103f67f000000000000000000000000000000000000000000000000000000000000000181565b6040516001600160401b03909116815260200161016b565b34801561041a57600080fd5b50610161610429366004611a9b565b610efa565b34801561043a57600080fd5b50610161610449366004611a9b565b610f2b565b34801561045a57600080fd5b506102e7610469366004611a82565b60036020526000908152604090205460ff1681565b34801561048a57600080fd5b50610161610499366004611a82565b600a6020526000908152604090205481565b3480156104b757600080fd5b506102136104c63660046117de565b63ffffffff166000908152600460205260409020546001600160a01b031690565b3480156104f357600080fd5b50610507610502366004611ac7565b610f47565b604080519283526001600160a01b0390911660208301520161016b565b34801561053057600080fd5b5061021361053f366004611a82565b6112c9565b61023e610552366004611b00565b6112f3565b34801561056357600080fd5b506102136105723660046117de565b6004602052600090815260409020546001600160a01b031681565b34801561059957600080fd5b5061016160005481565b60608060086000846001600160a01b03166001600160a01b0316815260200190815260200160002080548060200260200160405190810160405280929190818152602001828054801561061557602002820191906000526020600020905b815481526020019060010190808311610601575b5050835193955083925050506001600160401b0381111561063857610638611904565b604051908082528060200260200182016040528015610661578160200160208202803683370190505b50915060005b818110156106c65761069184828151811061068457610684611b3c565b6020026020010151611420565b9050508382815181106106a6576106a6611b3c565b6001600160a01b0390921660209283029190910190910152600101610667565b5050915091565b6040516321f8a72160e01b81527f6b50fa17b77d24e42e27a04b69fe50cd6967cfb767d18de0bd5fe7e1a32aa86860048201527f00000000000000000000000017a332dc7b40ae701485023b219e9d6f493a25146001600160a01b0316906321f8a72190602401602060405180830381865afa158015610751573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107759190611b52565b6040516317a0e54b60e11b81523360048201526001600160a01b039190911690632f41ca9690602401602060405180830381865afa1580156107bb573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107df9190611b6f565b6107fc5760405163222d861d60e11b815260040160405180910390fd5b63ffffffff83166000908152600460205260409020546001600160a01b0316610838576040516303e1b5a760e11b815260040160405180910390fd5b63ffffffff83166000908152600760205260409020805483919060ff191660018381811115610869576108696117fb565b0217905550805115610ab35760006040518060600160405280604051806040016040528060118152602001705355504552464f524d5f464143544f525960781b81525081526020017ff32750c6acdf0a869f9f19cdbb49fd915b2636c74468ee5682c8ecd3b65ab38b81526020017f0000000000000000000000000000000000000000000000000000000000000001600080815461090690611ba7565b918290555060405161092092919089908990602001611bc0565b60408051808303601f190181529181529152516321f8a72160e01b81527f86a7f6b88da6de42c331676d4da78508adfef4970dc8aa541004f26b6eef4ab96004820152909150610aad907f00000000000000000000000017a332dc7b40ae701485023b219e9d6f493a25146001600160a01b0316906321f8a72190602401602060405180830381865afa1580156109bb573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109df9190611b52565b6040516321f8a72160e01b81527fbddfa8c39a1f6275bcfb3aa5c70638c466999edbf14e6162d81b3492caca9fce60048201527f00000000000000000000000017a332dc7b40ae701485023b219e9d6f493a25146001600160a01b0316906321f8a72190602401602060405180830381865afa158015610a63573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a879190611b52565b83604051602001610a989190611c49565b60405160208183030381529060405285611454565b50610ad2565b3415610ad25760405163308f275d60e01b815260040160405180910390fd5b816001811115610ae457610ae46117fb565b60405163ffffffff8516907f1cb88bdf176e51fa7c40e8e4683e78b1792a2ce649cfae1f26fec314eebe536e90600090a3505050565b6040516321f8a72160e01b81527f6b50fa17b77d24e42e27a04b69fe50cd6967cfb767d18de0bd5fe7e1a32aa86860048201527f00000000000000000000000017a332dc7b40ae701485023b219e9d6f493a25146001600160a01b0316906321f8a72190602401602060405180830381865afa158015610b9e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bc29190611b52565b6040516369ac88f960e11b81523360048201526001600160a01b03919091169063d35911f290602401602060405180830381865afa158015610c08573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c2c9190611b6f565b610c4957604051633721555560e21b815260040160405180910390fd5b6001600160a01b038316610c705760405163538ba4f960e01b815260040160405180910390fd5b610c79836115a0565b610c9657604051631848783960e31b815260040160405180910390fd5b63ffffffff82166000908152600460205260409020546001600160a01b031615610cd35760405163deca71e360e01b815260040160405180910390fd5b6001600160a01b03831660009081526005602052604090205463ffffffff1615610d1057604051633ee1bf6960e11b815260040160405180910390fd5b610d21836351fef14760e01b6115d4565b610d3e576040516324ea76c760e01b815260040160405180910390fd5b63ffffffff8216600081815260046020908152604080832080546001600160a01b0319166001600160a01b038916908117909155835260059091528120805463ffffffff191690921790915560ff82169003610dad576040516326886d6760e01b815260040160405180910390fd5b63ffffffff8216600081815260066020526040808220805460ff191660ff86169081179091556001805480820182559084527fb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf60180546001600160a01b0319166001600160a01b03891690811790915591519093927f57e36bd8ee2840c13ad182923b129cd3b97186aa7ac714bfa5e59425fc22eeeb91a4505050565b60028181548110610e5a57600080fd5b600091825260209091200154905081565b63ffffffff811660009081526006602052604081205460ff1690819003610ea5576040516326886d6760e01b815260040160405180910390fd5b919050565b6000600163ffffffff831660009081526007602052604090205460ff166001811115610ed857610ed86117fb565b1492915050565b6000806000610eed84611420565b9196909550909350915050565b60086020528160005260406000208181548110610f1657600080fd5b90600052602060002001600091509150505481565b60096020528160005260406000208181548110610f1657600080fd5b6000806001600160a01b038316610f715760405163538ba4f960e01b815260040160405180910390fd5b63ffffffff84166000908152600460205260409020546001600160a01b031680610fae576040516344976fc160e11b815260040160405180910390fd5b604080516001600160a01b03808416602083015286169181019190915260009060600160408051601f1981840301815291815281516020928301206000818152600a9093529120549091501561101757604051630205e78560e51b815260040160405180910390fd5b604080516001600160401b037f000000000000000000000000000000000000000000000000000000000000000116602082015263ffffffff8816918101919091526001600160a01b038616606082015261109c9060800160405160208183030381529060405280519060200120836001600160a01b03166115f790919063ffffffff16565b9250826001600160a01b031663c0c53b8b7f00000000000000000000000017a332dc7b40ae701485023b219e9d6f493a251487886001600160a01b03166338d52e0f6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561110d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111319190611b52565b60405160e085901b6001600160e01b03191681526001600160a01b03938416600482015291831660248301529091166044820152606401600060405180830381600087803b15801561118257600080fd5b505af1158015611196573d6000803e3d6000fd5b505050506001600160a01b03831660a087901b63ffffffff60a01b16177f000000000000000000000000000000000000000000000000000000000000000160c01b6001600160c01b031916176001600160a01b03868116600081815260086020908152604080832080546001808201835591855283852001879055848452600983528184208054808301825590855283852063ffffffff8f169101819055888552600a8452828520889055600280548084019091557f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ace018890558785526003845293829020805460ff191690911790555193881684529397508793919290917ff40fe66c44bcbe514dc449b1c700989fe0ace6e4e6c48a118cc9b452c285c72b910160405180910390a450509250929050565b600181815481106112d957600080fd5b6000918252602090912001546001600160a01b0316905081565b6040516321f8a72160e01b81527f86a7f6b88da6de42c331676d4da78508adfef4970dc8aa541004f26b6eef4ab960048201527f00000000000000000000000017a332dc7b40ae701485023b219e9d6f493a25146001600160a01b0316906321f8a72190602401602060405180830381865afa158015611377573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061139b9190611b52565b6001600160a01b0316336001600160a01b0316146113cc5760405163b0acaf9d60e01b815260040160405180910390fd5b6000818060200190518101906113e29190611cd1565b90507ff32750c6acdf0a869f9f19cdbb49fd915b2636c74468ee5682c8ecd3b65ab38b81602001510361141c5761141c8160400151611665565b5050565b8060a081901c60c082901c600081900361144d5760405163030042b760e01b815260040160405180910390fd5b9193909250565b6000808280602001905181019061146b9190611d81565b91509150600080828060200190518101906114869190611dd1565b91509150813410156114ab57604051631961e86760e01b815260040160405180910390fd5b604051636319827b60e11b81526001600160a01b0389169063c63304f69084906114e1903390899084908d908990600401611e01565b6000604051808303818588803b1580156114fa57600080fd5b505af115801561150e573d6000803e3d6000fd5b5050505050813411156115965760006001600160a01b0388166115318434611e4f565b604051600081818185875af1925050503d806000811461156d576040519150601f19603f3d011682016040523d82523d6000602084013e611572565b606091505b50509050806115945760405163220d375360e01b815260040160405180910390fd5b505b5050505050505050565b60006115b3826301ffc9a760e01b61173f565b80156115ce57506115cc826001600160e01b031961173f565b155b92915050565b60006115df836115a0565b80156115f057506115f0838361173f565b9392505050565b6000763d602d80600a3d3981f3363d3d373d3d3d363d730000008360601b60e81c176000526e5af43d82803e903d91602b57fd5bf38360781b1760205281603760096000f590506001600160a01b0381166115ce576040516330be1a3d60e21b815260040160405180910390fd5b6000808280602001905181019061167c9190611e62565b63ffffffff821660009081526004602052604090205491955093506001600160a01b031691506116c19050576040516303e1b5a760e11b815260040160405180910390fd5b63ffffffff82166000908152600760205260409020805482919060ff1916600183818111156116f2576116f26117fb565b0217905550806001811115611709576117096117fb565b60405163ffffffff8416907f1cb88bdf176e51fa7c40e8e4683e78b1792a2ce649cfae1f26fec314eebe536e90600090a3505050565b6040516001600160e01b031982166024820152600090819060440160408051601f19818403018152919052602080820180516001600160e01b03166301ffc9a760e01b178152825192935060009283928392909183918a617530fa92503d915060005190508280156117b2575060208210155b80156117be5750600081115b979650505050505050565b63ffffffff811681146117db57600080fd5b50565b6000602082840312156117f057600080fd5b81356115f0816117c9565b634e487b7160e01b600052602160045260246000fd5b6002811061182f57634e487b7160e01b600052602160045260246000fd5b9052565b602081016115ce8284611811565b6001600160a01b03811681146117db57600080fd5b60006020828403121561186857600080fd5b81356115f081611841565b604080825283519082018190526000906020906060840190828701845b828110156118ac57815184529284019290840190600101611890565b5050508381038285015284518082528583019183019060005b818110156118ea5783516001600160a01b0316835292840192918401916001016118c5565b5090979650505050505050565b600281106117db57600080fd5b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f191681016001600160401b038111828210171561194257611942611904565b604052919050565b60006001600160401b0382111561196357611963611904565b50601f01601f191660200190565b600082601f83011261198257600080fd5b81356119956119908261194a565b61191a565b8181528460208386010111156119aa57600080fd5b816020850160208301376000918101602001919091529392505050565b6000806000606084860312156119dc57600080fd5b83356119e7816117c9565b925060208401356119f7816118f7565b915060408401356001600160401b03811115611a1257600080fd5b611a1e86828701611971565b9150509250925092565b60ff811681146117db57600080fd5b600080600060608486031215611a4c57600080fd5b8335611a5781611841565b92506020840135611a67816117c9565b91506040840135611a7781611a28565b809150509250925092565b600060208284031215611a9457600080fd5b5035919050565b60008060408385031215611aae57600080fd5b8235611ab981611841565b946020939093013593505050565b60008060408385031215611ada57600080fd5b8235611ae5816117c9565b91506020830135611af581611841565b809150509250929050565b600060208284031215611b1257600080fd5b81356001600160401b03811115611b2857600080fd5b611b3484828501611971565b949350505050565b634e487b7160e01b600052603260045260246000fd5b600060208284031215611b6457600080fd5b81516115f081611841565b600060208284031215611b8157600080fd5b815180151581146115f057600080fd5b634e487b7160e01b600052601160045260246000fd5b600060018201611bb957611bb9611b91565b5060010190565b6001600160401b03851681526020810184905263ffffffff8316604082015260808101611bf06060830184611811565b95945050505050565b60005b83811015611c14578181015183820152602001611bfc565b50506000910152565b60008151808452611c35816020860160208601611bf9565b601f01601f19169290920160200192915050565b602081526000825160606020840152611c656080840182611c1d565b9050602084015160408401526040840151601f19848303016060850152611bf08282611c1d565b600082601f830112611c9d57600080fd5b8151611cab6119908261194a565b818152846020838601011115611cc057600080fd5b611b34826020830160208701611bf9565b600060208284031215611ce357600080fd5b81516001600160401b0380821115611cfa57600080fd5b9083019060608286031215611d0e57600080fd5b604051606081018181108382111715611d2957611d29611904565b604052825182811115611d3b57600080fd5b611d4787828601611c8c565b82525060208301516020820152604083015182811115611d6657600080fd5b611d7287828601611c8c565b60408301525095945050505050565b60008060408385031215611d9457600080fd5b8251611d9f81611a28565b60208401519092506001600160401b03811115611dbb57600080fd5b611dc785828601611c8c565b9150509250929050565b60008060408385031215611de457600080fd5b8251915060208301516001600160401b03811115611dbb57600080fd5b60018060a01b038616815260ff8516602082015283604082015260a060608201526000611e3160a0830185611c1d565b8281036080840152611e438185611c1d565b98975050505050505050565b818103818111156115ce576115ce611b91565b60008060008060808587031215611e7857600080fd5b84516001600160401b0381168114611e8f57600080fd5b602086015160408701519195509350611ea7816117c9565b6060860151909250611eb8816118f7565b93969295509093505056fea2646970667358221220ad9da98eb5e7f8056ab81f7b1fad4a9d6b8f7793237ae8de7065d58e6887f6c564736f6c63430008170033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
00000000000000000000000017a332dc7b40ae701485023b219e9d6f493a2514
-----Decoded View---------------
Arg [0] : superRegistry_ (address): 0x17A332dC7B40aE701485023b219E9D6f493a2514
-----Encoded View---------------
1 Constructor Arguments found :
Arg [0] : 00000000000000000000000017a332dc7b40ae701485023b219e9d6f493a2514
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 27 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
Loading...
Loading
[ Download: CSV Export ]
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.