Source Code
Overview
ETH Balance
0 ETH
More Info
ContractCreator
Multichain Info
N/A
Latest 11 from a total of 11 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Deploy | 6704139 | 78 days ago | IN | 0 ETH | 0.00909026 | ||||
Deploy | 6703303 | 79 days ago | IN | 0 ETH | 0.00262753 | ||||
Deploy | 6697035 | 80 days ago | IN | 0 ETH | 0.00129436 | ||||
Deploy | 6697018 | 80 days ago | IN | 0 ETH | 0.00136248 | ||||
Deploy | 6696967 | 80 days ago | IN | 0 ETH | 0.00125497 | ||||
Deploy | 6696836 | 80 days ago | IN | 0 ETH | 0.00110278 | ||||
Deploy | 6696808 | 80 days ago | IN | 0 ETH | 0.00085052 | ||||
Deploy | 6184162 | 162 days ago | IN | 0 ETH | 0.04047184 | ||||
Deploy | 6149649 | 166 days ago | IN | 0 ETH | 0.00057775 | ||||
Deploy | 6024906 | 185 days ago | IN | 0 ETH | 0.00419964 | ||||
Deploy Determini... | 5846696 | 212 days ago | IN | 0 ETH | 0.10715312 |
Latest 12 internal transactions
Advanced mode:
Parent Transaction Hash | Block | From | To | |||
---|---|---|---|---|---|---|
6704139 | 78 days ago | Contract Creation | 0 ETH | |||
6703303 | 79 days ago | Contract Creation | 0 ETH | |||
6697035 | 80 days ago | Contract Creation | 0 ETH | |||
6697018 | 80 days ago | Contract Creation | 0 ETH | |||
6696967 | 80 days ago | Contract Creation | 0 ETH | |||
6696836 | 80 days ago | Contract Creation | 0 ETH | |||
6696808 | 80 days ago | Contract Creation | 0 ETH | |||
6184162 | 162 days ago | Contract Creation | 0 ETH | |||
6149649 | 166 days ago | Contract Creation | 0 ETH | |||
6024906 | 185 days ago | Contract Creation | 0 ETH | |||
5846696 | 212 days ago | Contract Creation | 0 ETH | |||
5846660 | 212 days ago | Contract Creation | 0 ETH |
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:
MiyaMints
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: AGPL-3.0 pragma solidity ^0.8.23; import {MiyaAVFactory, Ownable, LibClone, EnumerableSetLib} from "./MiyaAVFactory.sol"; import {IERC20} from "../lib/openzeppelin-contracts/contracts/interfaces/IERC20.sol"; import {IERC721} from "../lib/openzeppelin-contracts/contracts/interfaces/IERC721.sol"; import {IERC1155} from "../lib/openzeppelin-contracts/contracts/interfaces/IERC1155.sol"; interface IERC721MiyaInitialize { function initialize( string memory name, // NFT collection name string memory symbol, // NFT collection symbol/ticker string memory baseURI, // Base URI for NFT metadata, preferably on IPFS uint40 maxSupply, // Max mint supply uint16 royalty, // Percentage of royalty fees in basis points (0 - 10000) uint16 allocation, // Percentage of mint funds allocated to aligned collection in basis points (500 - 10000) address owner, // Collection owner address alignedNft, // Address of aligned NFT collection mint funds are being dedicated to uint80 price, // Standard mint price uint96 vaultId, // NFTX vault ID, bytes32 salt // AV deployment salt ) external; function disableInitializers() external; } contract MiyaMints is Ownable { using EnumerableSetLib for EnumerableSetLib.Uint256Set; error Invalid(); error TransferFailed(); event ERC721MiyaImplementation(address indexed implementation); event MiyaIdSet(address indexed erc721, uint256 indexed vaultId); event Deployed(address indexed deployer, address indexed collection, address indexed aligned, bytes32 salt); event OwnershipChanged(address indexed erc721m, address indexed oldOwner, address indexed newOwner); address public erc721MiyaImplementation; MiyaAVFactory public miyaAVFactory; mapping(address alignedNft => uint256 vaultId) public miyaIds; mapping(address erc721Miya => bool isMiyaMints) private isMiyaMintsContract; constructor(address newOwner, address newErc721MiyaImplementation, address newMiyaAVImplementation) payable { _initializeOwner(newOwner); erc721MiyaImplementation = newErc721MiyaImplementation; emit ERC721MiyaImplementation(newErc721MiyaImplementation); miyaAVFactory = new MiyaAVFactory(newOwner, newMiyaAVImplementation); } function renounceOwnership() public payable virtual override(Ownable) onlyOwner {} // Set preferred NFTX vault ID for a specific NFT to be used when vaultId 0 is specified for lazy deployments function setMiyaId(address alignedNft, uint256 vaultId) external onlyOwner { miyaIds[alignedNft] = vaultId; emit MiyaIdSet(alignedNft, vaultId); } // Update implementation address for new ERC721Miya clones // NOTE: Does not update implementation of prior clones function updateERC721MiyaImplementation(address newErc721MiyaImplementation) external onlyOwner { erc721MiyaImplementation = newErc721MiyaImplementation; emit ERC721MiyaImplementation(newErc721MiyaImplementation); } // Update implementation address for new MiyaAV clones // NOTE: Does not update implementation of prior clones function updateMiyaAVImplementation(address newMiyaAVImplementation) external onlyOwner { miyaAVFactory.updateImplementation(newMiyaAVImplementation); } function miyaAVImplementation() external view returns (address) { return miyaAVFactory.implementation(); } // Helper functions to get vault info from MiyaAVFactory in MiyaMints function getVault(address alignedNft, uint256 vaultId) external view returns (address) { return miyaAVFactory.vaults(alignedNft, vaultId); } function getAlignedNfts() external view returns (address[] memory) { return miyaAVFactory.getAlignedNfts(); } function getVaultIds(address alignedNft) external view returns (uint256[] memory) { return miyaAVFactory.getVaultIds(alignedNft); } // Deploy ERC721Miya collection and fully initialize it function deploy( string memory name, // NFT collection name string memory symbol, // NFT collection symbol/ticker string memory baseURI, // Base URI for NFT metadata, preferably on IPFS uint40 maxSupply, // Max mint supply uint16 royalty, // Percentage of royalty fees in basis points (0 - 10000) uint16 allocation, // Percentage of mint funds allocated to aligned collection in basis points (500 - 10000) address owner_, // Collection owner address alignedNft, // Address of aligned NFT collection mint funds are being dedicated to uint80 price, // Standard mint price uint96 vaultId, // NFTX vault ID bytes32 saltAlignmentVault // AV deployment salt ) external returns (address deployment) { deployment = LibClone.clone(erc721MiyaImplementation); isMiyaMintsContract[deployment] = true; IERC721MiyaInitialize(deployment).initialize( name, symbol, baseURI, maxSupply, royalty, allocation, owner_, alignedNft, price, vaultId, saltAlignmentVault ); IERC721MiyaInitialize(deployment).disableInitializers(); emit Deployed(msg.sender, deployment, alignedNft, bytes32("")); } // Deploy ERC721M collection to deterministic address function deployDeterministic( string memory name, // NFT collection name string memory symbol, // NFT collection symbol/ticker string memory baseURI, // Base URI for NFT metadata, preferably on IPFS uint40 maxSupply, // Max mint supply uint16 royalty, // Percentage of royalty fees in basis points (0 - 10000) uint16 allocation, // Percentage of mint funds allocated to aligned collection in basis points (500 - 10000) address owner_, // Collection owner address alignedNft, // Address of aligned NFT collection mint funds are being dedicated to uint80 price, // Standard mint price uint96 vaultId, // NFTX vault ID bytes32 saltAlignmentVault, // AV deployment salt bytes32 saltERC721Miya // ERC721Miya deployment salt ) external returns (address deployment) { deployment = LibClone.cloneDeterministic(erc721MiyaImplementation, saltERC721Miya); isMiyaMintsContract[deployment] = true; IERC721MiyaInitialize(deployment).initialize( name, symbol, baseURI, maxSupply, royalty, allocation, owner_, alignedNft, price, vaultId, saltAlignmentVault ); IERC721MiyaInitialize(deployment).disableInitializers(); emit Deployed(msg.sender, deployment, alignedNft, saltERC721Miya); } // Return initialization code hash of a clone of the current ERC721Miya implementation function initCodeHash() external view returns (bytes32 hash) { hash = LibClone.initCodeHash(erc721MiyaImplementation); } // Predict address of deterministic clone of the current ERC721Miya implementation function predictDeterministicAddress(bytes32 salt) external view returns (address predicted) { predicted = LibClone.predictDeterministicAddress(erc721MiyaImplementation, salt, address(this)); } // Deploy vault if required, else return the already deployed vault function deployVault(address alignedNft, uint96 vaultId, bytes32 salt) external returns (address vault) { // If no vaultId is specified, overwrite with preferred, if any exists if (vaultId == 0) vaultId = uint96(miyaIds[alignedNft]); if (salt == bytes32("")) vault = miyaAVFactory.deploy(alignedNft, vaultId); else vault = miyaAVFactory.deployDeterministic(alignedNft, vaultId, salt); } // Allows deployed collections to update ownership status subgraph for frontend using events function ownershipChanged(address oldOwner, address newOwner) external { if (!isMiyaMintsContract[msg.sender]) revert Invalid(); emit OwnershipChanged(msg.sender, oldOwner, newOwner); } function withdrawEth(address recipient) external payable virtual onlyOwner { if (recipient == address(0) || recipient == address(0xdead)) revert TransferFailed(); (bool success,) = payable(recipient).call{value: address(this).balance}(""); if (!success) revert TransferFailed(); } function withdrawERC20(address token, address recipient) external payable virtual onlyOwner { if (recipient == address(0) || recipient == address(0xdead)) revert TransferFailed(); IERC20(token).transfer(recipient, IERC20(token).balanceOf(address(this))); } function withdrawERC721(address token, uint256 tokenId, address recipient) external payable virtual onlyOwner { if (recipient == address(0) || recipient == address(0xdead)) revert TransferFailed(); IERC721(token).transferFrom(address(this), recipient, tokenId); } function withdrawERC1155( address token, uint256 tokenId, uint256 amount, address recipient ) external payable virtual onlyOwner { if (recipient == address(0) || recipient == address(0xdead)) revert TransferFailed(); IERC1155(token).safeTransferFrom(address(this), recipient, tokenId, amount, ""); } function withdrawERC1155Batch( address token, uint256[] memory tokenIds, uint256[] memory amounts, address recipient ) external payable virtual onlyOwner { if (recipient == address(0) || recipient == address(0xdead)) revert TransferFailed(); IERC1155(token).safeBatchTransferFrom(address(this), recipient, tokenIds, amounts, ""); } }
// SPDX-License-Identifier: AGPL-3.0 pragma solidity ^0.8.23; import {AlignmentVaultFactory, Ownable, LibClone, IInitialize} from "../lib/AlignmentVault/src/testnet/AlignmentVaultFactory.sol"; import {EnumerableSetLib} from "../lib/solady/src/utils/EnumerableSetLib.sol"; interface IMiyaAV { function vaultId() external view returns (uint96); } contract MiyaAVFactory is AlignmentVaultFactory { using EnumerableSetLib for EnumerableSetLib.Uint256Set; using EnumerableSetLib for EnumerableSetLib.AddressSet; event MAV_Deployed(address indexed vault, address indexed erc721, uint256 indexed vaultId, bytes32 salt); // ERC721 address => NFTX VaultID => MiyaAV address mapping(address => mapping(uint256 => address)) public vaults; mapping(address => EnumerableSetLib.Uint256Set) internal _vaultIds; EnumerableSetLib.AddressSet internal _alignedNfts; address public miyaMints; modifier onlyDeployer() { if (msg.sender != miyaMints) revert Unauthorized(); _; } constructor(address owner_, address implementation_) AlignmentVaultFactory(owner_, implementation_) { miyaMints = msg.sender; } function _checkOwner() internal view override { if (msg.sender != owner()) revert Unauthorized(); } function owner() public view override returns (address) { return Ownable(miyaMints).owner(); } function renounceOwnership() public payable virtual override(Ownable) onlyOwner {} /** * @notice Deploys a new AlignmentVault and fully initializes it. * @param alignedNft Address of the ERC721 token associated with the vault. * @param vaultId NFTX Vault ID associated with alignedNft * @return deployment Address of the newly deployed AlignmentVault. */ function deploy(address alignedNft, uint96 vaultId) external payable override onlyDeployer returns (address deployment) { // Return if a vault for this erc721 + vaultId combo already exists deployment = vaults[alignedNft][vaultId]; if (deployment != address(0)) return deployment; // Otherwise deploy and initialize vault deployment = LibClone.clone(implementation); IInitialize(deployment).initialize(owner(), alignedNft, vaultId); IInitialize(deployment).disableInitializers(); // Store enumerable vault metadata if (vaultId == 0) vaultId = IMiyaAV(deployment).vaultId(); vaults[alignedNft][vaultId] = deployment; _alignedNfts.add(alignedNft); _vaultIds[alignedNft].add(vaultId); emit MAV_Deployed(deployment, alignedNft, vaultId, bytes32("")); } /** * @notice Deploys a new AlignmentVault to a deterministic address based on the provided salt. * @param alignedNft Address of the ERC721 token associated with the vault. * @param vaultId NFTX Vault ID associated with alignedNft * @param salt A unique salt to determine the address. * @return deployment Address of the newly deployed AlignmentVault. */ function deployDeterministic(address alignedNft, uint96 vaultId, bytes32 salt) external payable override onlyDeployer returns (address deployment) { // Return if a vault for this erc721 + vaultId combo already exists deployment = vaults[alignedNft][vaultId]; if (deployment != address(0)) return deployment; // Otherwise deploy and initialize vault deployment = LibClone.cloneDeterministic(implementation, salt); IInitialize(deployment).initialize(owner(), alignedNft, vaultId); IInitialize(deployment).disableInitializers(); // Store enumerable vault metadata if (vaultId == 0) vaultId = IMiyaAV(deployment).vaultId(); vaults[alignedNft][vaultId] = deployment; _alignedNfts.add(alignedNft); _vaultIds[alignedNft].add(vaultId); emit MAV_Deployed(deployment, alignedNft, vaultId, salt); } function updateImplementation(address newImplementation) external payable override onlyDeployer { if (newImplementation == implementation) return; implementation = newImplementation; emit AVF_ImplementationSet(newImplementation); } function getAlignedNfts() external view returns (address[] memory) { return _alignedNfts.values(); } function getVaultIds(address alignedNft) external view returns (uint256[] memory) { return _vaultIds[alignedNft].values(); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (interfaces/IERC20.sol) pragma solidity ^0.8.20; import {IERC20} from "../token/ERC20/IERC20.sol";
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (interfaces/IERC721.sol) pragma solidity ^0.8.20; import {IERC721} from "../token/ERC721/IERC721.sol";
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (interfaces/IERC1155.sol) pragma solidity ^0.8.20; import {IERC1155} from "../token/ERC1155/IERC1155.sol";
// SPDX-License-Identifier: AGPL-3.0 pragma solidity ^0.8.23; // Inheritance and Libraries import {Ownable} from "../../lib/solady/src/auth/Ownable.sol"; import {IAlignmentVaultFactory} from "../IAlignmentVaultFactory.sol"; import {LibClone} from "../../lib/solady/src/utils/LibClone.sol"; // Interfaces import {IERC20} from "../../lib/openzeppelin-contracts-v5/contracts/interfaces/IERC20.sol"; import {IERC721} from "../../lib/openzeppelin-contracts-v5/contracts/interfaces/IERC721.sol"; import {IERC1155} from "../../lib/openzeppelin-contracts-v5/contracts/interfaces/IERC1155.sol"; interface IInitialize { function initialize(address owner, address alignedNft, uint96 vaultId) external payable; function disableInitializers() external payable; } /** * @title AlignmentVaultFactory * @notice This can be used by any EOA or contract to deploy an AlignmentVault owned by the deployer. * @dev deploy() will perform a normal deployment. deployDeterministic() allows you to mine a deployment address. * @author Zodomo.eth (X: @0xZodomo, Telegram: @zodomo, GitHub: Zodomo, Email: [email protected]) * @custom:github https://github.com/Zodomo/AlignmentVault * @custom:miyamaker https://miyamaker.com */ contract AlignmentVaultFactory is Ownable, IAlignmentVaultFactory { // >>>>>>>>>>>> [ STORAGE VARIABLES ] <<<<<<<<<<<< address public implementation; // >>>>>>>>>>>> [ CONSTRUCTOR ] <<<<<<<<<<<< constructor(address owner_, address implementation_) payable { _initializeOwner(owner_); implementation = implementation_; emit AVF_ImplementationSet(implementation_); } // >>>>>>>>>>>> [ DEPLOYMENT FUNCTIONS ] <<<<<<<<<<<< /** * @notice Deploys a new AlignmentVault and fully initializes it. * @param alignedNft Address of the ERC721/1155 token associated with the vault. * @param vaultId NFTX Vault ID associated with alignedNft * @return deployment Address of the newly deployed AlignmentVault. */ function deploy(address alignedNft, uint96 vaultId) external payable virtual returns (address deployment) { deployment = LibClone.clone(implementation); IInitialize(deployment).initialize(msg.sender, alignedNft, vaultId); IInitialize(deployment).disableInitializers(); emit AVF_Deployed(msg.sender, deployment, alignedNft); } /** * @notice Deploys a new AlignmentVault to a deterministic address based on the provided salt. * @param alignedNft Address of the ERC721/1155 token associated with the vault. * @param vaultId NFTX Vault ID associated with alignedNft * @param salt A unique salt to determine the address. * @return deployment Address of the newly deployed AlignmentVault. */ function deployDeterministic( address alignedNft, uint96 vaultId, bytes32 salt ) external payable virtual returns (address deployment) { deployment = LibClone.cloneDeterministic(implementation, salt); IInitialize(deployment).initialize(msg.sender, alignedNft, vaultId); IInitialize(deployment).disableInitializers(); emit AVF_Deployed(msg.sender, deployment, alignedNft); } /** * @notice Returns the initialization code hash of the clone of the implementation. * @dev This is used primarily for tools like create2crunch to find vanity addresses. * @return codeHash The initialization code hash of the clone. */ function initCodeHash() external view virtual returns (bytes32 codeHash) { return LibClone.initCodeHash(implementation); } /** * @notice Predicts the address of the deterministic clone with the given salt. * @param salt The unique salt used to determine the address. * @return addr Address of the deterministic clone. */ function predictDeterministicAddress(bytes32 salt) external view virtual returns (address addr) { return LibClone.predictDeterministicAddress(implementation, salt, address(this)); } // >>>>>>>>>>>> [ MANAGEMENT FUNCTIONS ] <<<<<<<<<<<< /** * @notice Updates the implementation address used for new clones. * @dev Does not affect previously deployed clones. * @param newImplementation The new implementation address for clones. */ function updateImplementation(address newImplementation) external payable virtual onlyOwner { if (newImplementation == implementation) return; implementation = newImplementation; emit AVF_ImplementationSet(newImplementation); } /** * @notice Used to withdraw any ETH sent to the factory */ function withdrawEth(address recipient) external payable virtual onlyOwner { if (recipient == address(0) || recipient == address(0xdead)) revert AVF_WithdrawalFailed(); (bool success,) = payable(recipient).call{value: address(this).balance}(""); if (!success) revert AVF_WithdrawalFailed(); } /** * @notice Used to withdraw any ERC20 tokens sent to the factory */ function withdrawERC20(address token, address recipient) external payable virtual onlyOwner { if (recipient == address(0) || recipient == address(0xdead)) revert AVF_WithdrawalFailed(); IERC20(token).transfer(recipient, IERC20(token).balanceOf(address(this))); } /** * @notice Used to withdraw any ERC721 tokens sent to the factory */ function withdrawERC721(address token, uint256 tokenId, address recipient) external payable virtual onlyOwner { if (recipient == address(0) || recipient == address(0xdead)) revert AVF_WithdrawalFailed(); IERC721(token).transferFrom(address(this), recipient, tokenId); } /** * @notice Used to withdraw any ERC1155 tokens sent to the factory */ function withdrawERC1155( address token, uint256 tokenId, uint256 amount, address recipient ) external payable virtual onlyOwner { if (recipient == address(0) || recipient == address(0xdead)) revert AVF_WithdrawalFailed(); IERC1155(token).safeTransferFrom(address(this), recipient, tokenId, amount, ""); } /** * @notice Used to batch withdraw any ERC1155 tokens sent to the factory */ function withdrawERC1155Batch( address token, uint256[] calldata tokenIds, uint256[] calldata amounts, address recipient ) external payable virtual onlyOwner { if (recipient == address(0) || recipient == address(0xdead)) revert AVF_WithdrawalFailed(); IERC1155(token).safeBatchTransferFrom(address(this), recipient, tokenIds, amounts, ""); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.4; /// @notice Library for managing enumerable sets in storage. /// @author Solady (https://github.com/vectorized/solady/blob/main/src/utils/LibMap.sol) /// /// @dev Note: /// In many applications, the number of elements in an enumerable set is small. /// This enumerable set implementation avoids storing the length and indices /// for up to 3 elements. Once the length exceeds 3 for the first time, the length /// and indices will be initialized. The amortized cost of adding elements is O(1). /// /// The AddressSet implementation packs the length with the 0th entry. library EnumerableSetLib { /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ /* CUSTOM ERRORS */ /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ /// @dev The index must be less than the length. error IndexOutOfBounds(); /// @dev The value cannot be the zero sentinel. error ValueIsZeroSentinel(); /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ /* CONSTANTS */ /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ /// @dev A sentinel value to denote the zero value in storage. /// No elements can be equal to this value. /// `uint72(bytes9(keccak256(bytes("_ZERO_SENTINEL"))))`. uint256 private constant _ZERO_SENTINEL = 0xfbb67fda52d4bfb8bf; /// @dev The storage layout is given by: /// ``` /// mstore(0x04, _ENUMERABLE_ADDRESS_SET_SLOT_SEED) /// mstore(0x00, set.slot) /// let rootSlot := keccak256(0x00, 0x24) /// mstore(0x20, rootSlot) /// mstore(0x00, shr(96, shl(96, value))) /// let positionSlot := keccak256(0x00, 0x40) /// let valueSlot := add(rootSlot, sload(positionSlot)) /// let valueInStorage := shr(96, sload(valueSlot)) /// let lazyLength := shr(160, shl(160, sload(rootSlot))) /// ``` uint256 private constant _ENUMERABLE_ADDRESS_SET_SLOT_SEED = 0x978aab92; /// @dev The storage layout is given by: /// ``` /// mstore(0x04, _ENUMERABLE_WORD_SET_SLOT_SEED) /// mstore(0x00, set.slot) /// let rootSlot := keccak256(0x00, 0x24) /// mstore(0x20, rootSlot) /// mstore(0x00, value) /// let positionSlot := keccak256(0x00, 0x40) /// let valueSlot := add(rootSlot, sload(positionSlot)) /// let valueInStorage := sload(valueSlot) /// let lazyLength := sload(not(rootSlot)) /// ``` uint256 private constant _ENUMERABLE_WORD_SET_SLOT_SEED = 0x18fb5864; /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ /* STRUCTS */ /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ /// @dev An enumerable address set in storage. struct AddressSet { uint256 _spacer; } /// @dev An enumerable bytes32 set in storage. struct Bytes32Set { uint256 _spacer; } /// @dev An enumerable uint256 set in storage. struct Uint256Set { uint256 _spacer; } /// @dev An enumerable int256 set in storage. struct Int256Set { uint256 _spacer; } /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ /* GETTERS / SETTERS */ /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ /// @dev Returns the number of elements in the set. function length(AddressSet storage set) internal view returns (uint256 result) { bytes32 rootSlot = _rootSlot(set); /// @solidity memory-safe-assembly assembly { let rootPacked := sload(rootSlot) let n := shr(160, shl(160, rootPacked)) result := shr(1, n) for {} iszero(or(iszero(shr(96, rootPacked)), n)) {} { result := 1 if iszero(sload(add(rootSlot, result))) { break } result := 2 if iszero(sload(add(rootSlot, result))) { break } result := 3 break } } } /// @dev Returns the number of elements in the set. function length(Bytes32Set storage set) internal view returns (uint256 result) { bytes32 rootSlot = _rootSlot(set); /// @solidity memory-safe-assembly assembly { let n := sload(not(rootSlot)) result := shr(1, n) for {} iszero(n) {} { result := 0 if iszero(sload(add(rootSlot, result))) { break } result := 1 if iszero(sload(add(rootSlot, result))) { break } result := 2 if iszero(sload(add(rootSlot, result))) { break } result := 3 break } } } /// @dev Returns the number of elements in the set. function length(Uint256Set storage set) internal view returns (uint256 result) { result = length(_toBytes32Set(set)); } /// @dev Returns the number of elements in the set. function length(Int256Set storage set) internal view returns (uint256 result) { result = length(_toBytes32Set(set)); } /// @dev Returns whether `value` is in the set. function contains(AddressSet storage set, address value) internal view returns (bool result) { bytes32 rootSlot = _rootSlot(set); /// @solidity memory-safe-assembly assembly { value := shr(96, shl(96, value)) if eq(value, _ZERO_SENTINEL) { mstore(0x00, 0xf5a267f1) // `ValueIsZeroSentinel()`. revert(0x1c, 0x04) } if iszero(value) { value := _ZERO_SENTINEL } let rootPacked := sload(rootSlot) for {} 1 {} { if iszero(shr(160, shl(160, rootPacked))) { result := 1 if eq(shr(96, rootPacked), value) { break } if eq(shr(96, sload(add(rootSlot, 1))), value) { break } if eq(shr(96, sload(add(rootSlot, 2))), value) { break } result := 0 break } mstore(0x20, rootSlot) mstore(0x00, value) result := iszero(iszero(sload(keccak256(0x00, 0x40)))) break } } } /// @dev Returns whether `value` is in the set. function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool result) { bytes32 rootSlot = _rootSlot(set); /// @solidity memory-safe-assembly assembly { if eq(value, _ZERO_SENTINEL) { mstore(0x00, 0xf5a267f1) // `ValueIsZeroSentinel()`. revert(0x1c, 0x04) } if iszero(value) { value := _ZERO_SENTINEL } for {} 1 {} { if iszero(sload(not(rootSlot))) { result := 1 if eq(sload(rootSlot), value) { break } if eq(sload(add(rootSlot, 1)), value) { break } if eq(sload(add(rootSlot, 2)), value) { break } result := 0 break } mstore(0x20, rootSlot) mstore(0x00, value) result := iszero(iszero(sload(keccak256(0x00, 0x40)))) break } } } /// @dev Returns whether `value` is in the set. function contains(Uint256Set storage set, uint256 value) internal view returns (bool result) { result = contains(_toBytes32Set(set), bytes32(value)); } /// @dev Returns whether `value` is in the set. function contains(Int256Set storage set, int256 value) internal view returns (bool result) { result = contains(_toBytes32Set(set), bytes32(uint256(value))); } /// @dev Adds `value` to the set. Returns whether `value` was not in the set. function add(AddressSet storage set, address value) internal returns (bool result) { bytes32 rootSlot = _rootSlot(set); /// @solidity memory-safe-assembly assembly { value := shr(96, shl(96, value)) if eq(value, _ZERO_SENTINEL) { mstore(0x00, 0xf5a267f1) // `ValueIsZeroSentinel()`. revert(0x1c, 0x04) } if iszero(value) { value := _ZERO_SENTINEL } let rootPacked := sload(rootSlot) for { let n := shr(160, shl(160, rootPacked)) } 1 {} { mstore(0x20, rootSlot) if iszero(n) { let v0 := shr(96, rootPacked) if iszero(v0) { sstore(rootSlot, shl(96, value)) result := 1 break } if eq(v0, value) { break } let v1 := shr(96, sload(add(rootSlot, 1))) if iszero(v1) { sstore(add(rootSlot, 1), shl(96, value)) result := 1 break } if eq(v1, value) { break } let v2 := shr(96, sload(add(rootSlot, 2))) if iszero(v2) { sstore(add(rootSlot, 2), shl(96, value)) result := 1 break } if eq(v2, value) { break } mstore(0x00, v0) sstore(keccak256(0x00, 0x40), 1) mstore(0x00, v1) sstore(keccak256(0x00, 0x40), 2) mstore(0x00, v2) sstore(keccak256(0x00, 0x40), 3) rootPacked := or(rootPacked, 7) n := 7 } mstore(0x00, value) let p := keccak256(0x00, 0x40) if iszero(sload(p)) { n := shr(1, n) sstore(add(rootSlot, n), shl(96, value)) sstore(p, add(1, n)) sstore(rootSlot, add(2, rootPacked)) result := 1 break } break } } } /// @dev Adds `value` to the set. Returns whether `value` was not in the set. function add(Bytes32Set storage set, bytes32 value) internal returns (bool result) { bytes32 rootSlot = _rootSlot(set); /// @solidity memory-safe-assembly assembly { if eq(value, _ZERO_SENTINEL) { mstore(0x00, 0xf5a267f1) // `ValueIsZeroSentinel()`. revert(0x1c, 0x04) } if iszero(value) { value := _ZERO_SENTINEL } for { let n := sload(not(rootSlot)) } 1 {} { mstore(0x20, rootSlot) if iszero(n) { let v0 := sload(rootSlot) if iszero(v0) { sstore(rootSlot, value) result := 1 break } if eq(v0, value) { break } let v1 := sload(add(rootSlot, 1)) if iszero(v1) { sstore(add(rootSlot, 1), value) result := 1 break } if eq(v1, value) { break } let v2 := sload(add(rootSlot, 2)) if iszero(v2) { sstore(add(rootSlot, 2), value) result := 1 break } if eq(v2, value) { break } mstore(0x00, v0) sstore(keccak256(0x00, 0x40), 1) mstore(0x00, v1) sstore(keccak256(0x00, 0x40), 2) mstore(0x00, v2) sstore(keccak256(0x00, 0x40), 3) n := 7 } mstore(0x00, value) let p := keccak256(0x00, 0x40) if iszero(sload(p)) { n := shr(1, n) sstore(add(rootSlot, n), value) sstore(p, add(1, n)) sstore(not(rootSlot), or(1, shl(1, add(1, n)))) result := 1 break } break } } } /// @dev Adds `value` to the set. Returns whether `value` was not in the set. function add(Uint256Set storage set, uint256 value) internal returns (bool result) { result = add(_toBytes32Set(set), bytes32(value)); } /// @dev Adds `value` to the set. Returns whether `value` was not in the set. function add(Int256Set storage set, int256 value) internal returns (bool result) { result = add(_toBytes32Set(set), bytes32(uint256(value))); } /// @dev Removes `value` from the set. Returns whether `value` was in the set. function remove(AddressSet storage set, address value) internal returns (bool result) { bytes32 rootSlot = _rootSlot(set); /// @solidity memory-safe-assembly assembly { value := shr(96, shl(96, value)) if eq(value, _ZERO_SENTINEL) { mstore(0x00, 0xf5a267f1) // `ValueIsZeroSentinel()`. revert(0x1c, 0x04) } if iszero(value) { value := _ZERO_SENTINEL } let rootPacked := sload(rootSlot) for { let n := shr(160, shl(160, rootPacked)) } 1 {} { if iszero(n) { result := 1 if eq(shr(96, rootPacked), value) { sstore(rootSlot, sload(add(rootSlot, 1))) sstore(add(rootSlot, 1), sload(add(rootSlot, 2))) sstore(add(rootSlot, 2), 0) break } if eq(shr(96, sload(add(rootSlot, 1))), value) { sstore(add(rootSlot, 1), sload(add(rootSlot, 2))) sstore(add(rootSlot, 2), 0) break } if eq(shr(96, sload(add(rootSlot, 2))), value) { sstore(add(rootSlot, 2), 0) break } result := 0 break } mstore(0x20, rootSlot) mstore(0x00, value) let p := keccak256(0x00, 0x40) let position := sload(p) if iszero(position) { break } n := sub(shr(1, n), 1) if iszero(eq(sub(position, 1), n)) { let lastValue := shr(96, sload(add(rootSlot, n))) sstore(add(rootSlot, sub(position, 1)), shl(96, lastValue)) sstore(add(rootSlot, n), 0) mstore(0x00, lastValue) sstore(keccak256(0x00, 0x40), position) } sstore(rootSlot, or(shl(96, shr(96, sload(rootSlot))), or(shl(1, n), 1))) sstore(p, 0) result := 1 break } } } /// @dev Removes `value` from the set. Returns whether `value` was in the set. function remove(Bytes32Set storage set, bytes32 value) internal returns (bool result) { bytes32 rootSlot = _rootSlot(set); /// @solidity memory-safe-assembly assembly { if eq(value, _ZERO_SENTINEL) { mstore(0x00, 0xf5a267f1) // `ValueIsZeroSentinel()`. revert(0x1c, 0x04) } if iszero(value) { value := _ZERO_SENTINEL } for { let n := sload(not(rootSlot)) } 1 {} { if iszero(n) { result := 1 if eq(sload(rootSlot), value) { sstore(rootSlot, sload(add(rootSlot, 1))) sstore(add(rootSlot, 1), sload(add(rootSlot, 2))) sstore(add(rootSlot, 2), 0) break } if eq(sload(add(rootSlot, 1)), value) { sstore(add(rootSlot, 1), sload(add(rootSlot, 2))) sstore(add(rootSlot, 2), 0) break } if eq(sload(add(rootSlot, 2)), value) { sstore(add(rootSlot, 2), 0) break } result := 0 break } mstore(0x20, rootSlot) mstore(0x00, value) let p := keccak256(0x00, 0x40) let position := sload(p) if iszero(position) { break } n := sub(shr(1, n), 1) if iszero(eq(sub(position, 1), n)) { let lastValue := sload(add(rootSlot, n)) sstore(add(rootSlot, sub(position, 1)), lastValue) sstore(add(rootSlot, n), 0) mstore(0x00, lastValue) sstore(keccak256(0x00, 0x40), position) } sstore(not(rootSlot), or(shl(1, n), 1)) sstore(p, 0) result := 1 break } } } /// @dev Removes `value` from the set. Returns whether `value` was in the set. function remove(Uint256Set storage set, uint256 value) internal returns (bool result) { result = remove(_toBytes32Set(set), bytes32(value)); } /// @dev Removes `value` from the set. Returns whether `value` was in the set. function remove(Int256Set storage set, int256 value) internal returns (bool result) { result = remove(_toBytes32Set(set), bytes32(uint256(value))); } /// @dev Returns all of the values in the set. /// Note: This can consume more gas than the block gas limit for large sets. function values(AddressSet storage set) internal view returns (address[] memory result) { bytes32 rootSlot = _rootSlot(set); /// @solidity memory-safe-assembly assembly { let zs := _ZERO_SENTINEL let rootPacked := sload(rootSlot) let n := shr(160, shl(160, rootPacked)) result := mload(0x40) let o := add(0x20, result) let v := shr(96, rootPacked) mstore(o, mul(v, iszero(eq(v, zs)))) for {} 1 {} { if iszero(n) { if v { n := 1 v := shr(96, sload(add(rootSlot, n))) if v { n := 2 mstore(add(o, 0x20), mul(v, iszero(eq(v, zs)))) v := shr(96, sload(add(rootSlot, n))) if v { n := 3 mstore(add(o, 0x40), mul(v, iszero(eq(v, zs)))) } } } break } n := shr(1, n) for { let i := 1 } lt(i, n) { i := add(i, 1) } { v := shr(96, sload(add(rootSlot, i))) mstore(add(o, shl(5, i)), mul(v, iszero(eq(v, zs)))) } break } mstore(result, n) mstore(0x40, add(o, shl(5, n))) } } /// @dev Returns all of the values in the set. /// Note: This can consume more gas than the block gas limit for large sets. function values(Bytes32Set storage set) internal view returns (bytes32[] memory result) { bytes32 rootSlot = _rootSlot(set); /// @solidity memory-safe-assembly assembly { let zs := _ZERO_SENTINEL let n := sload(not(rootSlot)) result := mload(0x40) let o := add(0x20, result) for {} 1 {} { if iszero(n) { let v := sload(rootSlot) if v { n := 1 mstore(o, mul(v, iszero(eq(v, zs)))) v := sload(add(rootSlot, n)) if v { n := 2 mstore(add(o, 0x20), mul(v, iszero(eq(v, zs)))) v := sload(add(rootSlot, n)) if v { n := 3 mstore(add(o, 0x40), mul(v, iszero(eq(v, zs)))) } } } break } n := shr(1, n) for { let i := 0 } lt(i, n) { i := add(i, 1) } { let v := sload(add(rootSlot, i)) mstore(add(o, shl(5, i)), mul(v, iszero(eq(v, zs)))) } break } mstore(result, n) mstore(0x40, add(o, shl(5, n))) } } /// @dev Returns all of the values in the set. /// Note: This can consume more gas than the block gas limit for large sets. function values(Uint256Set storage set) internal view returns (uint256[] memory result) { result = _toUints(values(_toBytes32Set(set))); } /// @dev Returns all of the values in the set. /// Note: This can consume more gas than the block gas limit for large sets. function values(Int256Set storage set) internal view returns (int256[] memory result) { result = _toInts(values(_toBytes32Set(set))); } /// @dev Returns the element at index `i` in the set. function at(AddressSet storage set, uint256 i) internal view returns (address result) { bytes32 rootSlot = _rootSlot(set); /// @solidity memory-safe-assembly assembly { result := shr(96, sload(add(rootSlot, i))) result := mul(result, iszero(eq(result, _ZERO_SENTINEL))) } if (i >= length(set)) revert IndexOutOfBounds(); } /// @dev Returns the element at index `i` in the set. function at(Bytes32Set storage set, uint256 i) internal view returns (bytes32 result) { result = _rootSlot(set); /// @solidity memory-safe-assembly assembly { result := sload(add(result, i)) result := mul(result, iszero(eq(result, _ZERO_SENTINEL))) } if (i >= length(set)) revert IndexOutOfBounds(); } /// @dev Returns the element at index `i` in the set. function at(Uint256Set storage set, uint256 i) internal view returns (uint256 result) { result = uint256(at(_toBytes32Set(set), i)); } /// @dev Returns the element at index `i` in the set. function at(Int256Set storage set, uint256 i) internal view returns (int256 result) { result = int256(uint256(at(_toBytes32Set(set), i))); } /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ /* PRIVATE HELPERS */ /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ /// @dev Returns the root slot. function _rootSlot(AddressSet storage s) private pure returns (bytes32 r) { /// @solidity memory-safe-assembly assembly { mstore(0x04, _ENUMERABLE_ADDRESS_SET_SLOT_SEED) mstore(0x00, s.slot) r := keccak256(0x00, 0x24) } } /// @dev Returns the root slot. function _rootSlot(Bytes32Set storage s) private pure returns (bytes32 r) { /// @solidity memory-safe-assembly assembly { mstore(0x04, _ENUMERABLE_WORD_SET_SLOT_SEED) mstore(0x00, s.slot) r := keccak256(0x00, 0x24) } } /// @dev Casts to a Bytes32Set. function _toBytes32Set(Uint256Set storage s) private pure returns (Bytes32Set storage c) { /// @solidity memory-safe-assembly assembly { c.slot := s.slot } } /// @dev Casts to a Bytes32Set. function _toBytes32Set(Int256Set storage s) private pure returns (Bytes32Set storage c) { /// @solidity memory-safe-assembly assembly { c.slot := s.slot } } /// @dev Casts to a uint256 array. function _toUints(bytes32[] memory a) private pure returns (uint256[] memory c) { /// @solidity memory-safe-assembly assembly { c := a } } /// @dev Casts to a int256 array. function _toInts(bytes32[] memory a) private pure returns (int256[] memory c) { /// @solidity memory-safe-assembly assembly { c := a } } }
// 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/ERC721/IERC721.sol) pragma solidity ^0.8.20; import {IERC165} from "../../utils/introspection/IERC165.sol"; /** * @dev Required interface of an ERC-721 compliant contract. */ interface IERC721 is IERC165 { /** * @dev Emitted when `tokenId` token is transferred from `from` to `to`. */ event Transfer(address indexed from, address indexed to, uint256 indexed tokenId); /** * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token. */ event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId); /** * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets. */ event ApprovalForAll(address indexed owner, address indexed operator, bool approved); /** * @dev Returns the number of tokens in ``owner``'s account. */ function balanceOf(address owner) external view returns (uint256 balance); /** * @dev Returns the owner of the `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function ownerOf(uint256 tokenId) external view returns (address owner); /** * @dev Safely transfers `tokenId` token from `from` to `to`. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon * a safe transfer. * * Emits a {Transfer} event. */ function safeTransferFrom(address from, address to, uint256 tokenId, bytes calldata data) external; /** * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients * are aware of the ERC-721 protocol to prevent tokens from being forever locked. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or * {setApprovalForAll}. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon * a safe transfer. * * Emits a {Transfer} event. */ function safeTransferFrom(address from, address to, uint256 tokenId) external; /** * @dev Transfers `tokenId` token from `from` to `to`. * * WARNING: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC-721 * or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must * understand this adds an external call which potentially creates a reentrancy vulnerability. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must be owned by `from`. * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. * * Emits a {Transfer} event. */ function transferFrom(address from, address to, uint256 tokenId) external; /** * @dev Gives permission to `to` to transfer `tokenId` token to another account. * The approval is cleared when the token is transferred. * * Only a single account can be approved at a time, so approving the zero address clears previous approvals. * * Requirements: * * - The caller must own the token or be an approved operator. * - `tokenId` must exist. * * Emits an {Approval} event. */ function approve(address to, uint256 tokenId) external; /** * @dev Approve or remove `operator` as an operator for the caller. * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller. * * Requirements: * * - The `operator` cannot be the address zero. * * Emits an {ApprovalForAll} event. */ function setApprovalForAll(address operator, bool approved) external; /** * @dev Returns the account approved for `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function getApproved(uint256 tokenId) external view returns (address operator); /** * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`. * * See {setApprovalForAll} */ function isApprovedForAll(address owner, address operator) external view returns (bool); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.1) (token/ERC1155/IERC1155.sol) pragma solidity ^0.8.20; import {IERC165} from "../../utils/introspection/IERC165.sol"; /** * @dev Required interface of an ERC-1155 compliant contract, as defined in the * https://eips.ethereum.org/EIPS/eip-1155[ERC]. */ interface IERC1155 is IERC165 { /** * @dev Emitted when `value` amount of tokens of type `id` are transferred from `from` to `to` by `operator`. */ event TransferSingle(address indexed operator, address indexed from, address indexed to, uint256 id, uint256 value); /** * @dev Equivalent to multiple {TransferSingle} events, where `operator`, `from` and `to` are the same for all * transfers. */ event TransferBatch( address indexed operator, address indexed from, address indexed to, uint256[] ids, uint256[] values ); /** * @dev Emitted when `account` grants or revokes permission to `operator` to transfer their tokens, according to * `approved`. */ event ApprovalForAll(address indexed account, address indexed operator, bool approved); /** * @dev Emitted when the URI for token type `id` changes to `value`, if it is a non-programmatic URI. * * If an {URI} event was emitted for `id`, the standard * https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[guarantees] that `value` will equal the value * returned by {IERC1155MetadataURI-uri}. */ event URI(string value, uint256 indexed id); /** * @dev Returns the value of tokens of token type `id` owned by `account`. */ function balanceOf(address account, uint256 id) external view returns (uint256); /** * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {balanceOf}. * * Requirements: * * - `accounts` and `ids` must have the same length. */ function balanceOfBatch( address[] calldata accounts, uint256[] calldata ids ) external view returns (uint256[] memory); /** * @dev Grants or revokes permission to `operator` to transfer the caller's tokens, according to `approved`, * * Emits an {ApprovalForAll} event. * * Requirements: * * - `operator` cannot be the zero address. */ function setApprovalForAll(address operator, bool approved) external; /** * @dev Returns true if `operator` is approved to transfer ``account``'s tokens. * * See {setApprovalForAll}. */ function isApprovedForAll(address account, address operator) external view returns (bool); /** * @dev Transfers a `value` amount of tokens of type `id` from `from` to `to`. * * WARNING: This function can potentially allow a reentrancy attack when transferring tokens * to an untrusted contract, when invoking {onERC1155Received} on the receiver. * Ensure to follow the checks-effects-interactions pattern and consider employing * reentrancy guards when interacting with untrusted contracts. * * Emits a {TransferSingle} event. * * Requirements: * * - `to` cannot be the zero address. * - If the caller is not `from`, it must have been approved to spend ``from``'s tokens via {setApprovalForAll}. * - `from` must have a balance of tokens of type `id` of at least `value` amount. * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the * acceptance magic value. */ function safeTransferFrom(address from, address to, uint256 id, uint256 value, bytes calldata data) external; /** * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {safeTransferFrom}. * * WARNING: This function can potentially allow a reentrancy attack when transferring tokens * to an untrusted contract, when invoking {onERC1155BatchReceived} on the receiver. * Ensure to follow the checks-effects-interactions pattern and consider employing * reentrancy guards when interacting with untrusted contracts. * * Emits either a {TransferSingle} or a {TransferBatch} event, depending on the length of the array arguments. * * Requirements: * * - `ids` and `values` must have the same length. * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the * acceptance magic value. */ function safeBatchTransferFrom( address from, address to, uint256[] calldata ids, uint256[] calldata values, bytes calldata data ) external; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.4; /// @notice Simple single owner authorization mixin. /// @author Solady (https://github.com/vectorized/solady/blob/main/src/auth/Ownable.sol) /// /// @dev Note: /// This implementation does NOT auto-initialize the owner to `msg.sender`. /// You MUST call the `_initializeOwner` in the constructor / initializer. /// /// While the ownable portion follows /// [EIP-173](https://eips.ethereum.org/EIPS/eip-173) for compatibility, /// the nomenclature for the 2-step ownership handover may be unique to this codebase. abstract contract Ownable { /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ /* CUSTOM ERRORS */ /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ /// @dev The caller is not authorized to call the function. error Unauthorized(); /// @dev The `newOwner` cannot be the zero address. error NewOwnerIsZeroAddress(); /// @dev The `pendingOwner` does not have a valid handover request. error NoHandoverRequest(); /// @dev Cannot double-initialize. error AlreadyInitialized(); /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ /* EVENTS */ /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ /// @dev The ownership is transferred from `oldOwner` to `newOwner`. /// This event is intentionally kept the same as OpenZeppelin's Ownable to be /// compatible with indexers and [EIP-173](https://eips.ethereum.org/EIPS/eip-173), /// despite it not being as lightweight as a single argument event. event OwnershipTransferred(address indexed oldOwner, address indexed newOwner); /// @dev An ownership handover to `pendingOwner` has been requested. event OwnershipHandoverRequested(address indexed pendingOwner); /// @dev The ownership handover to `pendingOwner` has been canceled. event OwnershipHandoverCanceled(address indexed pendingOwner); /// @dev `keccak256(bytes("OwnershipTransferred(address,address)"))`. uint256 private constant _OWNERSHIP_TRANSFERRED_EVENT_SIGNATURE = 0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0; /// @dev `keccak256(bytes("OwnershipHandoverRequested(address)"))`. uint256 private constant _OWNERSHIP_HANDOVER_REQUESTED_EVENT_SIGNATURE = 0xdbf36a107da19e49527a7176a1babf963b4b0ff8cde35ee35d6cd8f1f9ac7e1d; /// @dev `keccak256(bytes("OwnershipHandoverCanceled(address)"))`. uint256 private constant _OWNERSHIP_HANDOVER_CANCELED_EVENT_SIGNATURE = 0xfa7b8eab7da67f412cc9575ed43464468f9bfbae89d1675917346ca6d8fe3c92; /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ /* STORAGE */ /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ /// @dev The owner slot is given by: /// `bytes32(~uint256(uint32(bytes4(keccak256("_OWNER_SLOT_NOT")))))`. /// It is intentionally chosen to be a high value /// to avoid collision with lower slots. /// The choice of manual storage layout is to enable compatibility /// with both regular and upgradeable contracts. bytes32 internal constant _OWNER_SLOT = 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffff74873927; /// The ownership handover slot of `newOwner` is given by: /// ``` /// mstore(0x00, or(shl(96, user), _HANDOVER_SLOT_SEED)) /// let handoverSlot := keccak256(0x00, 0x20) /// ``` /// It stores the expiry timestamp of the two-step ownership handover. uint256 private constant _HANDOVER_SLOT_SEED = 0x389a75e1; /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ /* INTERNAL FUNCTIONS */ /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ /// @dev Override to return true to make `_initializeOwner` prevent double-initialization. function _guardInitializeOwner() internal pure virtual returns (bool guard) {} /// @dev Initializes the owner directly without authorization guard. /// This function must be called upon initialization, /// regardless of whether the contract is upgradeable or not. /// This is to enable generalization to both regular and upgradeable contracts, /// and to save gas in case the initial owner is not the caller. /// For performance reasons, this function will not check if there /// is an existing owner. function _initializeOwner(address newOwner) internal virtual { if (_guardInitializeOwner()) { /// @solidity memory-safe-assembly assembly { let ownerSlot := _OWNER_SLOT if sload(ownerSlot) { mstore(0x00, 0x0dc149f0) // `AlreadyInitialized()`. revert(0x1c, 0x04) } // Clean the upper 96 bits. newOwner := shr(96, shl(96, newOwner)) // Store the new value. sstore(ownerSlot, or(newOwner, shl(255, iszero(newOwner)))) // Emit the {OwnershipTransferred} event. log3(0, 0, _OWNERSHIP_TRANSFERRED_EVENT_SIGNATURE, 0, newOwner) } } else { /// @solidity memory-safe-assembly assembly { // Clean the upper 96 bits. newOwner := shr(96, shl(96, newOwner)) // Store the new value. sstore(_OWNER_SLOT, newOwner) // Emit the {OwnershipTransferred} event. log3(0, 0, _OWNERSHIP_TRANSFERRED_EVENT_SIGNATURE, 0, newOwner) } } } /// @dev Sets the owner directly without authorization guard. function _setOwner(address newOwner) internal virtual { if (_guardInitializeOwner()) { /// @solidity memory-safe-assembly assembly { let ownerSlot := _OWNER_SLOT // Clean the upper 96 bits. newOwner := shr(96, shl(96, newOwner)) // Emit the {OwnershipTransferred} event. log3(0, 0, _OWNERSHIP_TRANSFERRED_EVENT_SIGNATURE, sload(ownerSlot), newOwner) // Store the new value. sstore(ownerSlot, or(newOwner, shl(255, iszero(newOwner)))) } } else { /// @solidity memory-safe-assembly assembly { let ownerSlot := _OWNER_SLOT // Clean the upper 96 bits. newOwner := shr(96, shl(96, newOwner)) // Emit the {OwnershipTransferred} event. log3(0, 0, _OWNERSHIP_TRANSFERRED_EVENT_SIGNATURE, sload(ownerSlot), newOwner) // Store the new value. sstore(ownerSlot, newOwner) } } } /// @dev Throws if the sender is not the owner. function _checkOwner() internal view virtual { /// @solidity memory-safe-assembly assembly { // If the caller is not the stored owner, revert. if iszero(eq(caller(), sload(_OWNER_SLOT))) { mstore(0x00, 0x82b42900) // `Unauthorized()`. revert(0x1c, 0x04) } } } /// @dev Returns how long a two-step ownership handover is valid for in seconds. /// Override to return a different value if needed. /// Made internal to conserve bytecode. Wrap it in a public function if needed. function _ownershipHandoverValidFor() internal view virtual returns (uint64) { return 48 * 3600; } /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ /* PUBLIC UPDATE FUNCTIONS */ /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ /// @dev Allows the owner to transfer the ownership to `newOwner`. function transferOwnership(address newOwner) public payable virtual onlyOwner { /// @solidity memory-safe-assembly assembly { if iszero(shl(96, newOwner)) { mstore(0x00, 0x7448fbae) // `NewOwnerIsZeroAddress()`. revert(0x1c, 0x04) } } _setOwner(newOwner); } /// @dev Allows the owner to renounce their ownership. function renounceOwnership() public payable virtual onlyOwner { _setOwner(address(0)); } /// @dev Request a two-step ownership handover to the caller. /// The request will automatically expire in 48 hours (172800 seconds) by default. function requestOwnershipHandover() public payable virtual { unchecked { uint256 expires = block.timestamp + _ownershipHandoverValidFor(); /// @solidity memory-safe-assembly assembly { // Compute and set the handover slot to `expires`. mstore(0x0c, _HANDOVER_SLOT_SEED) mstore(0x00, caller()) sstore(keccak256(0x0c, 0x20), expires) // Emit the {OwnershipHandoverRequested} event. log2(0, 0, _OWNERSHIP_HANDOVER_REQUESTED_EVENT_SIGNATURE, caller()) } } } /// @dev Cancels the two-step ownership handover to the caller, if any. function cancelOwnershipHandover() public payable virtual { /// @solidity memory-safe-assembly assembly { // Compute and set the handover slot to 0. mstore(0x0c, _HANDOVER_SLOT_SEED) mstore(0x00, caller()) sstore(keccak256(0x0c, 0x20), 0) // Emit the {OwnershipHandoverCanceled} event. log2(0, 0, _OWNERSHIP_HANDOVER_CANCELED_EVENT_SIGNATURE, caller()) } } /// @dev Allows the owner to complete the two-step ownership handover to `pendingOwner`. /// Reverts if there is no existing ownership handover requested by `pendingOwner`. function completeOwnershipHandover(address pendingOwner) public payable virtual onlyOwner { /// @solidity memory-safe-assembly assembly { // Compute and set the handover slot to 0. mstore(0x0c, _HANDOVER_SLOT_SEED) mstore(0x00, pendingOwner) let handoverSlot := keccak256(0x0c, 0x20) // If the handover does not exist, or has expired. if gt(timestamp(), sload(handoverSlot)) { mstore(0x00, 0x6f5e8818) // `NoHandoverRequest()`. revert(0x1c, 0x04) } // Set the handover slot to 0. sstore(handoverSlot, 0) } _setOwner(pendingOwner); } /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ /* PUBLIC READ FUNCTIONS */ /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ /// @dev Returns the owner of the contract. function owner() public view virtual returns (address result) { /// @solidity memory-safe-assembly assembly { result := sload(_OWNER_SLOT) } } /// @dev Returns the expiry timestamp for the two-step ownership handover to `pendingOwner`. function ownershipHandoverExpiresAt(address pendingOwner) public view virtual returns (uint256 result) { /// @solidity memory-safe-assembly assembly { // Compute the handover slot. mstore(0x0c, _HANDOVER_SLOT_SEED) mstore(0x00, pendingOwner) // Load the handover slot. result := sload(keccak256(0x0c, 0x20)) } } /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ /* MODIFIERS */ /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ /// @dev Marks a function as only callable by the owner. modifier onlyOwner() virtual { _checkOwner(); _; } }
// SPDX-License-Identifier: AGPL-3.0 pragma solidity ^0.8.23; /** * @title IAlignmentVaultFactory * @notice This can be used by any EOA or contract to deploy an AlignmentVault owned by the deployer. * @dev deploy() will perform a normal deployment. deployDeterministic() allows you to mine a deployment address. * @author Zodomo.eth (X: @0xZodomo, Telegram: @zodomo, GitHub: Zodomo, Email: [email protected]) * @custom:github https://github.com/Zodomo/AlignmentVault * @custom:miyamaker https://miyamaker.com */ interface IAlignmentVaultFactory { // >>>>>>>>>>>> [ ERRORS ] <<<<<<<<<<<< error AVF_WithdrawalFailed(); // >>>>>>>>>>>> [ EVENTS ] <<<<<<<<<<<< event AVF_ImplementationSet(address indexed implementation); event AVF_Deployed(address indexed deployer, address indexed deployment, address indexed alignedNft); // >>>>>>>>>>>> [ STORAGE VARIABLES ] <<<<<<<<<<<< function implementation() external view returns (address); // >>>>>>>>>>>> [ DEPLOYMENT FUNCTIONS ] <<<<<<<<<<<< function deploy(address alignedNft, uint96 vaultId) external payable returns (address deployment); function deployDeterministic( address alignedNft, uint96 vaultId, bytes32 salt ) external payable returns (address deployment); function initCodeHash() external view returns (bytes32 codeHash); function predictDeterministicAddress(bytes32 salt) external view returns (address addr); // >>>>>>>>>>>> [ MANAGEMENT FUNCTIONS ] <<<<<<<<<<<< function updateImplementation(address newImplementation) external payable; function withdrawEth(address recipient) external payable; function withdrawERC20(address token, address recipient) external payable; function withdrawERC721(address token, uint256 tokenId, address recipient) external payable; function withdrawERC1155(address token, uint256 tokenId, uint256 amount, address recipient) external payable; function withdrawERC1155Batch( address token, uint256[] calldata tokenIds, uint256[] calldata amounts, address recipient ) external payable; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.4; /// @notice Minimal proxy library. /// @author Solady (https://github.com/vectorized/solady/blob/main/src/utils/LibClone.sol) /// @author Minimal proxy by 0age (https://github.com/0age) /// @author Clones with immutable args by wighawag, zefram.eth, Saw-mon & Natalie /// (https://github.com/Saw-mon-and-Natalie/clones-with-immutable-args) /// @author Minimal ERC1967 proxy by jtriley-eth (https://github.com/jtriley-eth/minimum-viable-proxy) /// /// @dev Minimal proxy: /// Although the sw0nt pattern saves 5 gas over the erc-1167 pattern during runtime, /// it is not supported out-of-the-box on Etherscan. Hence, we choose to use the 0age pattern, /// which saves 4 gas over the erc-1167 pattern during runtime, and has the smallest bytecode. /// /// @dev Minimal proxy (PUSH0 variant): /// This is a new minimal proxy that uses the PUSH0 opcode introduced during Shanghai. /// It is optimized first for minimal runtime gas, then for minimal bytecode. /// The PUSH0 clone functions are intentionally postfixed with a jarring "_PUSH0" as /// many EVM chains may not support the PUSH0 opcode in the early months after Shanghai. /// Please use with caution. /// /// @dev Clones with immutable args (CWIA): /// The implementation of CWIA here implements a `receive()` method that emits the /// `ReceiveETH(uint256)` event. This skips the `DELEGATECALL` when there is no calldata, /// enabling us to accept hard gas-capped `sends` & `transfers` for maximum backwards /// composability. The minimal proxy implementation does not offer this feature. /// /// @dev Minimal ERC1967 proxy: /// An minimal ERC1967 proxy, intended to be upgraded with UUPS. /// This is NOT the same as ERC1967Factory's transparent proxy, which includes admin logic. /// /// @dev ERC1967I proxy: /// An variant of the minimal ERC1967 proxy, with a special code path that activates /// if `calldatasize() == 1`. This code path skips the delegatecall and directly returns the /// `implementation` address. The returned implementation is guaranteed to be valid if the /// keccak256 of the proxy's code is equal to `ERC1967I_CODE_HASH`. library LibClone { /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ /* CONSTANTS */ /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ /// @dev The keccak256 of the deployed code for the ERC1967 proxy. bytes32 internal constant ERC1967_CODE_HASH = 0xaaa52c8cc8a0e3fd27ce756cc6b4e70c51423e9b597b11f32d3e49f8b1fc890d; /// @dev The keccak256 of the deployed code for the ERC1967I proxy. bytes32 internal constant ERC1967I_CODE_HASH = 0xce700223c0d4cea4583409accfc45adac4a093b3519998a9cbbe1504dadba6f7; /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ /* CUSTOM ERRORS */ /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ /// @dev Unable to deploy the clone. error DeploymentFailed(); /// @dev The salt must start with either the zero address or `by`. error SaltDoesNotStartWith(); /// @dev The ETH transfer has failed. error ETHTransferFailed(); /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ /* MINIMAL PROXY OPERATIONS */ /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ /// @dev Deploys a clone of `implementation`. function clone(address implementation) internal returns (address instance) { instance = clone(0, implementation); } /// @dev Deploys a clone of `implementation`. /// Deposits `value` ETH during deployment. function clone(uint256 value, address implementation) internal returns (address instance) { /// @solidity memory-safe-assembly assembly { /** * --------------------------------------------------------------------------+ * CREATION (9 bytes) | * --------------------------------------------------------------------------| * Opcode | Mnemonic | Stack | Memory | * --------------------------------------------------------------------------| * 60 runSize | PUSH1 runSize | r | | * 3d | RETURNDATASIZE | 0 r | | * 81 | DUP2 | r 0 r | | * 60 offset | PUSH1 offset | o r 0 r | | * 3d | RETURNDATASIZE | 0 o r 0 r | | * 39 | CODECOPY | 0 r | [0..runSize): runtime code | * f3 | RETURN | | [0..runSize): runtime code | * --------------------------------------------------------------------------| * RUNTIME (44 bytes) | * --------------------------------------------------------------------------| * Opcode | Mnemonic | Stack | Memory | * --------------------------------------------------------------------------| * | * ::: keep some values in stack ::::::::::::::::::::::::::::::::::::::::::: | * 3d | RETURNDATASIZE | 0 | | * 3d | RETURNDATASIZE | 0 0 | | * 3d | RETURNDATASIZE | 0 0 0 | | * 3d | RETURNDATASIZE | 0 0 0 0 | | * | * ::: copy calldata to memory ::::::::::::::::::::::::::::::::::::::::::::: | * 36 | CALLDATASIZE | cds 0 0 0 0 | | * 3d | RETURNDATASIZE | 0 cds 0 0 0 0 | | * 3d | RETURNDATASIZE | 0 0 cds 0 0 0 0 | | * 37 | CALLDATACOPY | 0 0 0 0 | [0..cds): calldata | * | * ::: delegate call to the implementation contract :::::::::::::::::::::::: | * 36 | CALLDATASIZE | cds 0 0 0 0 | [0..cds): calldata | * 3d | RETURNDATASIZE | 0 cds 0 0 0 0 | [0..cds): calldata | * 73 addr | PUSH20 addr | addr 0 cds 0 0 0 0 | [0..cds): calldata | * 5a | GAS | gas addr 0 cds 0 0 0 0 | [0..cds): calldata | * f4 | DELEGATECALL | success 0 0 | [0..cds): calldata | * | * ::: copy return data to memory :::::::::::::::::::::::::::::::::::::::::: | * 3d | RETURNDATASIZE | rds success 0 0 | [0..cds): calldata | * 3d | RETURNDATASIZE | rds rds success 0 0 | [0..cds): calldata | * 93 | SWAP4 | 0 rds success 0 rds | [0..cds): calldata | * 80 | DUP1 | 0 0 rds success 0 rds | [0..cds): calldata | * 3e | RETURNDATACOPY | success 0 rds | [0..rds): returndata | * | * 60 0x2a | PUSH1 0x2a | 0x2a success 0 rds | [0..rds): returndata | * 57 | JUMPI | 0 rds | [0..rds): returndata | * | * ::: revert :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: | * fd | REVERT | | [0..rds): returndata | * | * ::: return :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: | * 5b | JUMPDEST | 0 rds | [0..rds): returndata | * f3 | RETURN | | [0..rds): returndata | * --------------------------------------------------------------------------+ */ mstore(0x21, 0x5af43d3d93803e602a57fd5bf3) mstore(0x14, implementation) mstore(0x00, 0x602c3d8160093d39f33d3d3d3d363d3d37363d73) instance := create(value, 0x0c, 0x35) if iszero(instance) { mstore(0x00, 0x30116425) // `DeploymentFailed()`. revert(0x1c, 0x04) } mstore(0x21, 0) // Restore the overwritten part of the free memory pointer. } } /// @dev Deploys a deterministic clone of `implementation` with `salt`. function cloneDeterministic(address implementation, bytes32 salt) internal returns (address instance) { instance = cloneDeterministic(0, implementation, salt); } /// @dev Deploys a deterministic clone of `implementation` with `salt`. /// Deposits `value` ETH during deployment. function cloneDeterministic(uint256 value, address implementation, bytes32 salt) internal returns (address instance) { /// @solidity memory-safe-assembly assembly { mstore(0x21, 0x5af43d3d93803e602a57fd5bf3) mstore(0x14, implementation) mstore(0x00, 0x602c3d8160093d39f33d3d3d3d363d3d37363d73) instance := create2(value, 0x0c, 0x35, salt) if iszero(instance) { mstore(0x00, 0x30116425) // `DeploymentFailed()`. revert(0x1c, 0x04) } mstore(0x21, 0) // Restore the overwritten part of the free memory pointer. } } /// @dev Returns the initialization code of the clone of `implementation`. function initCode(address implementation) internal pure returns (bytes memory result) { /// @solidity memory-safe-assembly assembly { result := mload(0x40) mstore(add(result, 0x40), 0x5af43d3d93803e602a57fd5bf30000000000000000000000) mstore(add(result, 0x28), implementation) mstore(add(result, 0x14), 0x602c3d8160093d39f33d3d3d3d363d3d37363d73) mstore(result, 0x35) // Store the length. mstore(0x40, add(result, 0x60)) // Allocate memory. } } /// @dev Returns the initialization code hash of the clone of `implementation`. /// Used for mining vanity addresses with create2crunch. function initCodeHash(address implementation) internal pure returns (bytes32 hash) { /// @solidity memory-safe-assembly assembly { mstore(0x21, 0x5af43d3d93803e602a57fd5bf3) mstore(0x14, implementation) mstore(0x00, 0x602c3d8160093d39f33d3d3d3d363d3d37363d73) hash := keccak256(0x0c, 0x35) mstore(0x21, 0) // Restore the overwritten part of the free memory pointer. } } /// @dev Returns the address of the deterministic clone of `implementation`, /// with `salt` by `deployer`. /// Note: The returned result has dirty upper 96 bits. Please clean if used in assembly. function predictDeterministicAddress(address implementation, bytes32 salt, address deployer) internal pure returns (address predicted) { bytes32 hash = initCodeHash(implementation); predicted = predictDeterministicAddress(hash, salt, deployer); } /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ /* MINIMAL PROXY OPERATIONS (PUSH0 VARIANT) */ /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ /// @dev Deploys a PUSH0 clone of `implementation`. function clone_PUSH0(address implementation) internal returns (address instance) { instance = clone_PUSH0(0, implementation); } /// @dev Deploys a PUSH0 clone of `implementation`. /// Deposits `value` ETH during deployment. function clone_PUSH0(uint256 value, address implementation) internal returns (address instance) { /// @solidity memory-safe-assembly assembly { /** * --------------------------------------------------------------------------+ * CREATION (9 bytes) | * --------------------------------------------------------------------------| * Opcode | Mnemonic | Stack | Memory | * --------------------------------------------------------------------------| * 60 runSize | PUSH1 runSize | r | | * 5f | PUSH0 | 0 r | | * 81 | DUP2 | r 0 r | | * 60 offset | PUSH1 offset | o r 0 r | | * 5f | PUSH0 | 0 o r 0 r | | * 39 | CODECOPY | 0 r | [0..runSize): runtime code | * f3 | RETURN | | [0..runSize): runtime code | * --------------------------------------------------------------------------| * RUNTIME (45 bytes) | * --------------------------------------------------------------------------| * Opcode | Mnemonic | Stack | Memory | * --------------------------------------------------------------------------| * | * ::: keep some values in stack ::::::::::::::::::::::::::::::::::::::::::: | * 5f | PUSH0 | 0 | | * 5f | PUSH0 | 0 0 | | * | * ::: copy calldata to memory ::::::::::::::::::::::::::::::::::::::::::::: | * 36 | CALLDATASIZE | cds 0 0 | | * 5f | PUSH0 | 0 cds 0 0 | | * 5f | PUSH0 | 0 0 cds 0 0 | | * 37 | CALLDATACOPY | 0 0 | [0..cds): calldata | * | * ::: delegate call to the implementation contract :::::::::::::::::::::::: | * 36 | CALLDATASIZE | cds 0 0 | [0..cds): calldata | * 5f | PUSH0 | 0 cds 0 0 | [0..cds): calldata | * 73 addr | PUSH20 addr | addr 0 cds 0 0 | [0..cds): calldata | * 5a | GAS | gas addr 0 cds 0 0 | [0..cds): calldata | * f4 | DELEGATECALL | success | [0..cds): calldata | * | * ::: copy return data to memory :::::::::::::::::::::::::::::::::::::::::: | * 3d | RETURNDATASIZE | rds success | [0..cds): calldata | * 5f | PUSH0 | 0 rds success | [0..cds): calldata | * 5f | PUSH0 | 0 0 rds success | [0..cds): calldata | * 3e | RETURNDATACOPY | success | [0..rds): returndata | * | * 60 0x29 | PUSH1 0x29 | 0x29 success | [0..rds): returndata | * 57 | JUMPI | | [0..rds): returndata | * | * ::: revert :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: | * 3d | RETURNDATASIZE | rds | [0..rds): returndata | * 5f | PUSH0 | 0 rds | [0..rds): returndata | * fd | REVERT | | [0..rds): returndata | * | * ::: return :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: | * 5b | JUMPDEST | | [0..rds): returndata | * 3d | RETURNDATASIZE | rds | [0..rds): returndata | * 5f | PUSH0 | 0 rds | [0..rds): returndata | * f3 | RETURN | | [0..rds): returndata | * --------------------------------------------------------------------------+ */ mstore(0x24, 0x5af43d5f5f3e6029573d5ffd5b3d5ff3) // 16 mstore(0x14, implementation) // 20 mstore(0x00, 0x602d5f8160095f39f35f5f365f5f37365f73) // 9 + 9 instance := create(value, 0x0e, 0x36) if iszero(instance) { mstore(0x00, 0x30116425) // `DeploymentFailed()`. revert(0x1c, 0x04) } mstore(0x24, 0) // Restore the overwritten part of the free memory pointer. } } /// @dev Deploys a deterministic PUSH0 clone of `implementation` with `salt`. function cloneDeterministic_PUSH0(address implementation, bytes32 salt) internal returns (address instance) { instance = cloneDeterministic_PUSH0(0, implementation, salt); } /// @dev Deploys a deterministic PUSH0 clone of `implementation` with `salt`. /// Deposits `value` ETH during deployment. function cloneDeterministic_PUSH0(uint256 value, address implementation, bytes32 salt) internal returns (address instance) { /// @solidity memory-safe-assembly assembly { mstore(0x24, 0x5af43d5f5f3e6029573d5ffd5b3d5ff3) // 16 mstore(0x14, implementation) // 20 mstore(0x00, 0x602d5f8160095f39f35f5f365f5f37365f73) // 9 + 9 instance := create2(value, 0x0e, 0x36, salt) if iszero(instance) { mstore(0x00, 0x30116425) // `DeploymentFailed()`. revert(0x1c, 0x04) } mstore(0x24, 0) // Restore the overwritten part of the free memory pointer. } } /// @dev Returns the initialization code of the PUSH0 clone of `implementation`. function initCode_PUSH0(address implementation) internal pure returns (bytes memory result) { /// @solidity memory-safe-assembly assembly { result := mload(0x40) mstore(add(result, 0x40), 0x5af43d5f5f3e6029573d5ffd5b3d5ff300000000000000000000) // 16 mstore(add(result, 0x26), implementation) // 20 mstore(add(result, 0x12), 0x602d5f8160095f39f35f5f365f5f37365f73) // 9 + 9 mstore(result, 0x36) // Store the length. mstore(0x40, add(result, 0x60)) // Allocate memory. } } /// @dev Returns the initialization code hash of the PUSH0 clone of `implementation`. /// Used for mining vanity addresses with create2crunch. function initCodeHash_PUSH0(address implementation) internal pure returns (bytes32 hash) { /// @solidity memory-safe-assembly assembly { mstore(0x24, 0x5af43d5f5f3e6029573d5ffd5b3d5ff3) // 16 mstore(0x14, implementation) // 20 mstore(0x00, 0x602d5f8160095f39f35f5f365f5f37365f73) // 9 + 9 hash := keccak256(0x0e, 0x36) mstore(0x24, 0) // Restore the overwritten part of the free memory pointer. } } /// @dev Returns the address of the deterministic PUSH0 clone of `implementation`, /// with `salt` by `deployer`. /// Note: The returned result has dirty upper 96 bits. Please clean if used in assembly. function predictDeterministicAddress_PUSH0( address implementation, bytes32 salt, address deployer ) internal pure returns (address predicted) { bytes32 hash = initCodeHash_PUSH0(implementation); predicted = predictDeterministicAddress(hash, salt, deployer); } /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ /* CLONES WITH IMMUTABLE ARGS OPERATIONS */ /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ // Note: This implementation of CWIA differs from the original implementation. // If the calldata is empty, it will emit a `ReceiveETH(uint256)` event and skip the `DELEGATECALL`. /// @dev Deploys a clone of `implementation` with immutable arguments encoded in `data`. function clone(address implementation, bytes memory data) internal returns (address instance) { instance = clone(0, implementation, data); } /// @dev Deploys a clone of `implementation` with immutable arguments encoded in `data`. /// Deposits `value` ETH during deployment. function clone(uint256 value, address implementation, bytes memory data) internal returns (address instance) { assembly { // Compute the boundaries of the data and cache the memory slots around it. let mBefore3 := mload(sub(data, 0x60)) let mBefore2 := mload(sub(data, 0x40)) let mBefore1 := mload(sub(data, 0x20)) let dataLength := mload(data) let dataEnd := add(add(data, 0x20), dataLength) let mAfter1 := mload(dataEnd) // +2 bytes for telling how much data there is appended to the call. let extraLength := add(dataLength, 2) // The `creationSize` is `extraLength + 108` // The `runSize` is `creationSize - 10`. /** * ---------------------------------------------------------------------------------------------------+ * CREATION (10 bytes) | * ---------------------------------------------------------------------------------------------------| * Opcode | Mnemonic | Stack | Memory | * ---------------------------------------------------------------------------------------------------| * 61 runSize | PUSH2 runSize | r | | * 3d | RETURNDATASIZE | 0 r | | * 81 | DUP2 | r 0 r | | * 60 offset | PUSH1 offset | o r 0 r | | * 3d | RETURNDATASIZE | 0 o r 0 r | | * 39 | CODECOPY | 0 r | [0..runSize): runtime code | * f3 | RETURN | | [0..runSize): runtime code | * ---------------------------------------------------------------------------------------------------| * RUNTIME (98 bytes + extraLength) | * ---------------------------------------------------------------------------------------------------| * Opcode | Mnemonic | Stack | Memory | * ---------------------------------------------------------------------------------------------------| * | * ::: if no calldata, emit event & return w/o `DELEGATECALL` ::::::::::::::::::::::::::::::::::::::: | * 36 | CALLDATASIZE | cds | | * 60 0x2c | PUSH1 0x2c | 0x2c cds | | * 57 | JUMPI | | | * 34 | CALLVALUE | cv | | * 3d | RETURNDATASIZE | 0 cv | | * 52 | MSTORE | | [0..0x20): callvalue | * 7f sig | PUSH32 0x9e.. | sig | [0..0x20): callvalue | * 59 | MSIZE | 0x20 sig | [0..0x20): callvalue | * 3d | RETURNDATASIZE | 0 0x20 sig | [0..0x20): callvalue | * a1 | LOG1 | | [0..0x20): callvalue | * 00 | STOP | | [0..0x20): callvalue | * 5b | JUMPDEST | | | * | * ::: copy calldata to memory :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: | * 36 | CALLDATASIZE | cds | | * 3d | RETURNDATASIZE | 0 cds | | * 3d | RETURNDATASIZE | 0 0 cds | | * 37 | CALLDATACOPY | | [0..cds): calldata | * | * ::: keep some values in stack :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: | * 3d | RETURNDATASIZE | 0 | [0..cds): calldata | * 3d | RETURNDATASIZE | 0 0 | [0..cds): calldata | * 3d | RETURNDATASIZE | 0 0 0 | [0..cds): calldata | * 3d | RETURNDATASIZE | 0 0 0 0 | [0..cds): calldata | * 61 extra | PUSH2 extra | e 0 0 0 0 | [0..cds): calldata | * | * ::: copy extra data to memory :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: | * 80 | DUP1 | e e 0 0 0 0 | [0..cds): calldata | * 60 0x62 | PUSH1 0x62 | 0x62 e e 0 0 0 0 | [0..cds): calldata | * 36 | CALLDATASIZE | cds 0x62 e e 0 0 0 0 | [0..cds): calldata | * 39 | CODECOPY | e 0 0 0 0 | [0..cds): calldata, [cds..cds+e): extraData | * | * ::: delegate call to the implementation contract ::::::::::::::::::::::::::::::::::::::::::::::::: | * 36 | CALLDATASIZE | cds e 0 0 0 0 | [0..cds): calldata, [cds..cds+e): extraData | * 01 | ADD | cds+e 0 0 0 0 | [0..cds): calldata, [cds..cds+e): extraData | * 3d | RETURNDATASIZE | 0 cds+e 0 0 0 0 | [0..cds): calldata, [cds..cds+e): extraData | * 73 addr | PUSH20 addr | addr 0 cds+e 0 0 0 0 | [0..cds): calldata, [cds..cds+e): extraData | * 5a | GAS | gas addr 0 cds+e 0 0 0 0 | [0..cds): calldata, [cds..cds+e): extraData | * f4 | DELEGATECALL | success 0 0 | [0..cds): calldata, [cds..cds+e): extraData | * | * ::: copy return data to memory ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: | * 3d | RETURNDATASIZE | rds success 0 0 | [0..cds): calldata, [cds..cds+e): extraData | * 3d | RETURNDATASIZE | rds rds success 0 0 | [0..cds): calldata, [cds..cds+e): extraData | * 93 | SWAP4 | 0 rds success 0 rds | [0..cds): calldata, [cds..cds+e): extraData | * 80 | DUP1 | 0 0 rds success 0 rds | [0..cds): calldata, [cds..cds+e): extraData | * 3e | RETURNDATACOPY | success 0 rds | [0..rds): returndata | * | * 60 0x60 | PUSH1 0x60 | 0x60 success 0 rds | [0..rds): returndata | * 57 | JUMPI | 0 rds | [0..rds): returndata | * | * ::: revert ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: | * fd | REVERT | | [0..rds): returndata | * | * ::: return ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: | * 5b | JUMPDEST | 0 rds | [0..rds): returndata | * f3 | RETURN | | [0..rds): returndata | * ---------------------------------------------------------------------------------------------------+ */ mstore(data, 0x5af43d3d93803e606057fd5bf3) // Write the bytecode before the data. mstore(sub(data, 0x0d), implementation) // Write the address of the implementation. // Write the rest of the bytecode. mstore( sub(data, 0x21), or(shl(0x48, extraLength), 0x593da1005b363d3d373d3d3d3d610000806062363936013d73) ) // `keccak256("ReceiveETH(uint256)")` mstore( sub(data, 0x3a), 0x9e4ac34f21c619cefc926c8bd93b54bf5a39c7ab2127a895af1cc0691d7e3dff ) mstore( // Do a out-of-gas revert if `extraLength` is too big. 0xffff - 0x62 + 0x01 = 0xff9e. // The actual EVM limit may be smaller and may change over time. sub(data, add(0x59, lt(extraLength, 0xff9e))), or(shl(0x78, add(extraLength, 0x62)), 0xfd6100003d81600a3d39f336602c57343d527f) ) mstore(dataEnd, shl(0xf0, extraLength)) instance := create(value, sub(data, 0x4c), add(extraLength, 0x6c)) if iszero(instance) { mstore(0x00, 0x30116425) // `DeploymentFailed()`. revert(0x1c, 0x04) } // Restore the overwritten memory surrounding `data`. mstore(dataEnd, mAfter1) mstore(data, dataLength) mstore(sub(data, 0x20), mBefore1) mstore(sub(data, 0x40), mBefore2) mstore(sub(data, 0x60), mBefore3) } } /// @dev Deploys a deterministic clone of `implementation` /// with immutable arguments encoded in `data` and `salt`. function cloneDeterministic(address implementation, bytes memory data, bytes32 salt) internal returns (address instance) { instance = cloneDeterministic(0, implementation, data, salt); } /// @dev Deploys a deterministic clone of `implementation` /// with immutable arguments encoded in `data` and `salt`. function cloneDeterministic( uint256 value, address implementation, bytes memory data, bytes32 salt ) internal returns (address instance) { assembly { // Compute the boundaries of the data and cache the memory slots around it. let mBefore3 := mload(sub(data, 0x60)) let mBefore2 := mload(sub(data, 0x40)) let mBefore1 := mload(sub(data, 0x20)) let dataLength := mload(data) let dataEnd := add(add(data, 0x20), dataLength) let mAfter1 := mload(dataEnd) // +2 bytes for telling how much data there is appended to the call. let extraLength := add(dataLength, 2) mstore(data, 0x5af43d3d93803e606057fd5bf3) // Write the bytecode before the data. mstore(sub(data, 0x0d), implementation) // Write the address of the implementation. // Write the rest of the bytecode. mstore( sub(data, 0x21), or(shl(0x48, extraLength), 0x593da1005b363d3d373d3d3d3d610000806062363936013d73) ) // `keccak256("ReceiveETH(uint256)")` mstore( sub(data, 0x3a), 0x9e4ac34f21c619cefc926c8bd93b54bf5a39c7ab2127a895af1cc0691d7e3dff ) mstore( // Do a out-of-gas revert if `extraLength` is too big. 0xffff - 0x62 + 0x01 = 0xff9e. // The actual EVM limit may be smaller and may change over time. sub(data, add(0x59, lt(extraLength, 0xff9e))), or(shl(0x78, add(extraLength, 0x62)), 0xfd6100003d81600a3d39f336602c57343d527f) ) mstore(dataEnd, shl(0xf0, extraLength)) instance := create2(value, sub(data, 0x4c), add(extraLength, 0x6c), salt) if iszero(instance) { mstore(0x00, 0x30116425) // `DeploymentFailed()`. revert(0x1c, 0x04) } // Restore the overwritten memory surrounding `data`. mstore(dataEnd, mAfter1) mstore(data, dataLength) mstore(sub(data, 0x20), mBefore1) mstore(sub(data, 0x40), mBefore2) mstore(sub(data, 0x60), mBefore3) } } /// @dev Returns the initialization code hash of the clone of `implementation` /// using immutable arguments encoded in `data`. function initCode(address implementation, bytes memory data) internal pure returns (bytes memory result) { /// @solidity memory-safe-assembly assembly { result := mload(0x40) let dataLength := mload(data) // Do a out-of-gas revert if `dataLength` is too big. 0xffff - 0x02 - 0x62 = 0xff9b. // The actual EVM limit may be smaller and may change over time. returndatacopy(returndatasize(), returndatasize(), gt(dataLength, 0xff9b)) let o := add(result, 0x8c) let end := add(o, dataLength) // Copy the `data` into `result`. for { let d := sub(add(data, 0x20), o) } 1 {} { mstore(o, mload(add(o, d))) o := add(o, 0x20) if iszero(lt(o, end)) { break } } // +2 bytes for telling how much data there is appended to the call. let extraLength := add(dataLength, 2) mstore(add(result, 0x6c), 0x5af43d3d93803e606057fd5bf3) // Write the bytecode before the data. mstore(add(result, 0x5f), implementation) // Write the address of the implementation. // Write the rest of the bytecode. mstore( add(result, 0x4b), or(shl(0x48, extraLength), 0x593da1005b363d3d373d3d3d3d610000806062363936013d73) ) // `keccak256("ReceiveETH(uint256)")` mstore( add(result, 0x32), 0x9e4ac34f21c619cefc926c8bd93b54bf5a39c7ab2127a895af1cc0691d7e3dff ) mstore( add(result, 0x12), or(shl(0x78, add(extraLength, 0x62)), 0x6100003d81600a3d39f336602c57343d527f) ) mstore(end, shl(0xf0, extraLength)) mstore(add(end, 0x02), 0) // Zeroize the slot after the result. mstore(result, add(extraLength, 0x6c)) // Store the length. mstore(0x40, add(0x22, end)) // Allocate memory. } } /// @dev Returns the initialization code hash of the clone of `implementation` /// using immutable arguments encoded in `data`. /// Used for mining vanity addresses with create2crunch. function initCodeHash(address implementation, bytes memory data) internal pure returns (bytes32 hash) { assembly { // Compute the boundaries of the data and cache the memory slots around it. let mBefore3 := mload(sub(data, 0x60)) let mBefore2 := mload(sub(data, 0x40)) let mBefore1 := mload(sub(data, 0x20)) let dataLength := mload(data) let dataEnd := add(add(data, 0x20), dataLength) let mAfter1 := mload(dataEnd) // Do a out-of-gas revert if `dataLength` is too big. 0xffff - 0x02 - 0x62 = 0xff9b. // The actual EVM limit may be smaller and may change over time. returndatacopy(returndatasize(), returndatasize(), gt(dataLength, 0xff9b)) // +2 bytes for telling how much data there is appended to the call. let extraLength := add(dataLength, 2) mstore(data, 0x5af43d3d93803e606057fd5bf3) // Write the bytecode before the data. mstore(sub(data, 0x0d), implementation) // Write the address of the implementation. // Write the rest of the bytecode. mstore( sub(data, 0x21), or(shl(0x48, extraLength), 0x593da1005b363d3d373d3d3d3d610000806062363936013d73) ) // `keccak256("ReceiveETH(uint256)")` mstore( sub(data, 0x3a), 0x9e4ac34f21c619cefc926c8bd93b54bf5a39c7ab2127a895af1cc0691d7e3dff ) mstore( sub(data, 0x5a), or(shl(0x78, add(extraLength, 0x62)), 0x6100003d81600a3d39f336602c57343d527f) ) mstore(dataEnd, shl(0xf0, extraLength)) hash := keccak256(sub(data, 0x4c), add(extraLength, 0x6c)) // Restore the overwritten memory surrounding `data`. mstore(dataEnd, mAfter1) mstore(data, dataLength) mstore(sub(data, 0x20), mBefore1) mstore(sub(data, 0x40), mBefore2) mstore(sub(data, 0x60), mBefore3) } } /// @dev Returns the address of the deterministic clone of /// `implementation` using immutable arguments encoded in `data`, with `salt`, by `deployer`. /// Note: The returned result has dirty upper 96 bits. Please clean if used in assembly. function predictDeterministicAddress( address implementation, bytes memory data, bytes32 salt, address deployer ) internal pure returns (address predicted) { bytes32 hash = initCodeHash(implementation, data); predicted = predictDeterministicAddress(hash, salt, deployer); } /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ /* MINIMAL ERC1967 PROXY OPERATIONS */ /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ // Note: The ERC1967 proxy here is intended to be upgraded with UUPS. // This is NOT the same as ERC1967Factory's transparent proxy, which includes admin logic. /// @dev Deploys a minimal ERC1967 proxy with `implementation`. function deployERC1967(address implementation) internal returns (address instance) { instance = deployERC1967(0, implementation); } /// @dev Deploys a minimal ERC1967 proxy with `implementation`. /// Deposits `value` ETH during deployment. function deployERC1967(uint256 value, address implementation) internal returns (address instance) { /// @solidity memory-safe-assembly assembly { /** * ---------------------------------------------------------------------------------+ * CREATION (34 bytes) | * ---------------------------------------------------------------------------------| * Opcode | Mnemonic | Stack | Memory | * ---------------------------------------------------------------------------------| * 60 runSize | PUSH1 runSize | r | | * 3d | RETURNDATASIZE | 0 r | | * 81 | DUP2 | r 0 r | | * 60 offset | PUSH1 offset | o r 0 r | | * 3d | RETURNDATASIZE | 0 o r 0 r | | * 39 | CODECOPY | 0 r | [0..runSize): runtime code | * 73 impl | PUSH20 impl | impl 0 r | [0..runSize): runtime code | * 60 slotPos | PUSH1 slotPos | slotPos impl 0 r | [0..runSize): runtime code | * 51 | MLOAD | slot impl 0 r | [0..runSize): runtime code | * 55 | SSTORE | 0 r | [0..runSize): runtime code | * f3 | RETURN | | [0..runSize): runtime code | * ---------------------------------------------------------------------------------| * RUNTIME (61 bytes) | * ---------------------------------------------------------------------------------| * Opcode | Mnemonic | Stack | Memory | * ---------------------------------------------------------------------------------| * | * ::: copy calldata to memory :::::::::::::::::::::::::::::::::::::::::::::::::::: | * 36 | CALLDATASIZE | cds | | * 3d | RETURNDATASIZE | 0 cds | | * 3d | RETURNDATASIZE | 0 0 cds | | * 37 | CALLDATACOPY | | [0..calldatasize): calldata | * | * ::: delegatecall to implementation ::::::::::::::::::::::::::::::::::::::::::::: | * 3d | RETURNDATASIZE | 0 | | * 3d | RETURNDATASIZE | 0 0 | | * 36 | CALLDATASIZE | cds 0 0 | [0..calldatasize): calldata | * 3d | RETURNDATASIZE | 0 cds 0 0 | [0..calldatasize): calldata | * 7f slot | PUSH32 slot | s 0 cds 0 0 | [0..calldatasize): calldata | * 54 | SLOAD | i 0 cds 0 0 | [0..calldatasize): calldata | * 5a | GAS | g i 0 cds 0 0 | [0..calldatasize): calldata | * f4 | DELEGATECALL | succ | [0..calldatasize): calldata | * | * ::: copy returndata to memory :::::::::::::::::::::::::::::::::::::::::::::::::: | * 3d | RETURNDATASIZE | rds succ | [0..calldatasize): calldata | * 60 0x00 | PUSH1 0x00 | 0 rds succ | [0..calldatasize): calldata | * 80 | DUP1 | 0 0 rds succ | [0..calldatasize): calldata | * 3e | RETURNDATACOPY | succ | [0..returndatasize): returndata | * | * ::: branch on delegatecall status :::::::::::::::::::::::::::::::::::::::::::::: | * 60 0x38 | PUSH1 0x38 | dest succ | [0..returndatasize): returndata | * 57 | JUMPI | | [0..returndatasize): returndata | * | * ::: delegatecall failed, revert :::::::::::::::::::::::::::::::::::::::::::::::: | * 3d | RETURNDATASIZE | rds | [0..returndatasize): returndata | * 60 0x00 | PUSH1 0x00 | 0 rds | [0..returndatasize): returndata | * fd | REVERT | | [0..returndatasize): returndata | * | * ::: delegatecall succeeded, return ::::::::::::::::::::::::::::::::::::::::::::: | * 5b | JUMPDEST | | [0..returndatasize): returndata | * 3d | RETURNDATASIZE | rds | [0..returndatasize): returndata | * 60 0x00 | PUSH1 0x00 | 0 rds | [0..returndatasize): returndata | * f3 | RETURN | | [0..returndatasize): returndata | * ---------------------------------------------------------------------------------+ */ let m := mload(0x40) // Cache the free memory pointer. mstore(0x60, 0xcc3735a920a3ca505d382bbc545af43d6000803e6038573d6000fd5b3d6000f3) mstore(0x40, 0x5155f3363d3d373d3d363d7f360894a13ba1a3210667c828492db98dca3e2076) mstore(0x20, 0x6009) mstore(0x1e, implementation) mstore(0x0a, 0x603d3d8160223d3973) instance := create(value, 0x21, 0x5f) if iszero(instance) { mstore(0x00, 0x30116425) // `DeploymentFailed()`. revert(0x1c, 0x04) } mstore(0x40, m) // Restore the free memory pointer. mstore(0x60, 0) // Restore the zero slot. } } /// @dev Deploys a deterministic minimal ERC1967 proxy with `implementation` and `salt`. function deployDeterministicERC1967(address implementation, bytes32 salt) internal returns (address instance) { instance = deployDeterministicERC1967(0, implementation, salt); } /// @dev Deploys a deterministic minimal ERC1967 proxy with `implementation` and `salt`. /// Deposits `value` ETH during deployment. function deployDeterministicERC1967(uint256 value, address implementation, bytes32 salt) internal returns (address instance) { /// @solidity memory-safe-assembly assembly { let m := mload(0x40) // Cache the free memory pointer. mstore(0x60, 0xcc3735a920a3ca505d382bbc545af43d6000803e6038573d6000fd5b3d6000f3) mstore(0x40, 0x5155f3363d3d373d3d363d7f360894a13ba1a3210667c828492db98dca3e2076) mstore(0x20, 0x6009) mstore(0x1e, implementation) mstore(0x0a, 0x603d3d8160223d3973) instance := create2(value, 0x21, 0x5f, salt) if iszero(instance) { mstore(0x00, 0x30116425) // `DeploymentFailed()`. revert(0x1c, 0x04) } mstore(0x40, m) // Restore the free memory pointer. mstore(0x60, 0) // Restore the zero slot. } } /// @dev Creates a deterministic minimal ERC1967 proxy with `implementation` and `salt`. /// Note: This method is intended for use in ERC4337 factories, /// which are expected to NOT revert if the proxy is already deployed. function createDeterministicERC1967(address implementation, bytes32 salt) internal returns (bool alreadyDeployed, address instance) { return createDeterministicERC1967(0, implementation, salt); } /// @dev Creates a deterministic minimal ERC1967 proxy with `implementation` and `salt`. /// Deposits `value` ETH during deployment. /// Note: This method is intended for use in ERC4337 factories, /// which are expected to NOT revert if the proxy is already deployed. function createDeterministicERC1967(uint256 value, address implementation, bytes32 salt) internal returns (bool alreadyDeployed, address instance) { /// @solidity memory-safe-assembly assembly { let m := mload(0x40) // Cache the free memory pointer. mstore(0x60, 0xcc3735a920a3ca505d382bbc545af43d6000803e6038573d6000fd5b3d6000f3) mstore(0x40, 0x5155f3363d3d373d3d363d7f360894a13ba1a3210667c828492db98dca3e2076) mstore(0x20, 0x6009) mstore(0x1e, implementation) mstore(0x0a, 0x603d3d8160223d3973) // Compute and store the bytecode hash. mstore(add(m, 0x35), keccak256(0x21, 0x5f)) mstore(m, shl(88, address())) mstore8(m, 0xff) // Write the prefix. mstore(add(m, 0x15), salt) instance := keccak256(m, 0x55) for {} 1 {} { if iszero(extcodesize(instance)) { instance := create2(value, 0x21, 0x5f, salt) if iszero(instance) { mstore(0x00, 0x30116425) // `DeploymentFailed()`. revert(0x1c, 0x04) } break } alreadyDeployed := 1 if iszero(value) { break } if iszero(call(gas(), instance, value, codesize(), 0x00, codesize(), 0x00)) { mstore(0x00, 0xb12d13eb) // `ETHTransferFailed()`. revert(0x1c, 0x04) } break } mstore(0x40, m) // Restore the free memory pointer. mstore(0x60, 0) // Restore the zero slot. } } /// @dev Returns the initialization code of the minimal ERC1967 proxy of `implementation`. function initCodeERC1967(address implementation) internal pure returns (bytes memory result) { /// @solidity memory-safe-assembly assembly { result := mload(0x40) mstore( add(result, 0x60), 0x3735a920a3ca505d382bbc545af43d6000803e6038573d6000fd5b3d6000f300 ) mstore( add(result, 0x40), 0x55f3363d3d373d3d363d7f360894a13ba1a3210667c828492db98dca3e2076cc ) mstore(add(result, 0x20), or(shl(24, implementation), 0x600951)) mstore(add(result, 0x09), 0x603d3d8160223d3973) mstore(result, 0x5f) // Store the length. mstore(0x40, add(result, 0x80)) // Allocate memory. } } /// @dev Returns the initialization code hash of the minimal ERC1967 proxy of `implementation`. /// Used for mining vanity addresses with create2crunch. function initCodeHashERC1967(address implementation) internal pure returns (bytes32 hash) { /// @solidity memory-safe-assembly assembly { let m := mload(0x40) // Cache the free memory pointer. mstore(0x60, 0xcc3735a920a3ca505d382bbc545af43d6000803e6038573d6000fd5b3d6000f3) mstore(0x40, 0x5155f3363d3d373d3d363d7f360894a13ba1a3210667c828492db98dca3e2076) mstore(0x20, 0x6009) mstore(0x1e, implementation) mstore(0x0a, 0x603d3d8160223d3973) hash := keccak256(0x21, 0x5f) mstore(0x40, m) // Restore the free memory pointer. mstore(0x60, 0) // Restore the zero slot. } } /// @dev Returns the address of the deterministic ERC1967 proxy of `implementation`, /// with `salt` by `deployer`. /// Note: The returned result has dirty upper 96 bits. Please clean if used in assembly. function predictDeterministicAddressERC1967( address implementation, bytes32 salt, address deployer ) internal pure returns (address predicted) { bytes32 hash = initCodeHashERC1967(implementation); predicted = predictDeterministicAddress(hash, salt, deployer); } /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ /* ERC1967I PROXY OPERATIONS */ /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ // Note: This proxy has a special code path that activates if `calldatasize() == 1`. // This code path skips the delegatecall and directly returns the `implementation` address. // The returned implementation is guaranteed to be valid if the keccak256 of the // proxy's code is equal to `ERC1967I_CODE_HASH`. /// @dev Deploys a minimal ERC1967I proxy with `implementation`. function deployERC1967I(address implementation) internal returns (address instance) { instance = deployERC1967I(0, implementation); } /// @dev Deploys a ERC1967I proxy with `implementation`. /// Deposits `value` ETH during deployment. function deployERC1967I(uint256 value, address implementation) internal returns (address instance) { /// @solidity memory-safe-assembly assembly { /** * ---------------------------------------------------------------------------------+ * CREATION (34 bytes) | * ---------------------------------------------------------------------------------| * Opcode | Mnemonic | Stack | Memory | * ---------------------------------------------------------------------------------| * 60 runSize | PUSH1 runSize | r | | * 3d | RETURNDATASIZE | 0 r | | * 81 | DUP2 | r 0 r | | * 60 offset | PUSH1 offset | o r 0 r | | * 3d | RETURNDATASIZE | 0 o r 0 r | | * 39 | CODECOPY | 0 r | [0..runSize): runtime code | * 73 impl | PUSH20 impl | impl 0 r | [0..runSize): runtime code | * 60 slotPos | PUSH1 slotPos | slotPos impl 0 r | [0..runSize): runtime code | * 51 | MLOAD | slot impl 0 r | [0..runSize): runtime code | * 55 | SSTORE | 0 r | [0..runSize): runtime code | * f3 | RETURN | | [0..runSize): runtime code | * ---------------------------------------------------------------------------------| * RUNTIME (82 bytes) | * ---------------------------------------------------------------------------------| * Opcode | Mnemonic | Stack | Memory | * ---------------------------------------------------------------------------------| * | * ::: check calldatasize ::::::::::::::::::::::::::::::::::::::::::::::::::::::::: | * 36 | CALLDATASIZE | cds | | * 58 | PC | 1 cds | | * 14 | EQ | eqs | | * 60 0x43 | PUSH1 0x43 | dest eqs | | * 57 | JUMPI | | | * | * ::: copy calldata to memory :::::::::::::::::::::::::::::::::::::::::::::::::::: | * 36 | CALLDATASIZE | cds | | * 3d | RETURNDATASIZE | 0 cds | | * 3d | RETURNDATASIZE | 0 0 cds | | * 37 | CALLDATACOPY | | [0..calldatasize): calldata | * | * ::: delegatecall to implementation ::::::::::::::::::::::::::::::::::::::::::::: | * 3d | RETURNDATASIZE | 0 | | * 3d | RETURNDATASIZE | 0 0 | | * 36 | CALLDATASIZE | cds 0 0 | [0..calldatasize): calldata | * 3d | RETURNDATASIZE | 0 cds 0 0 | [0..calldatasize): calldata | * 7f slot | PUSH32 slot | s 0 cds 0 0 | [0..calldatasize): calldata | * 54 | SLOAD | i 0 cds 0 0 | [0..calldatasize): calldata | * 5a | GAS | g i 0 cds 0 0 | [0..calldatasize): calldata | * f4 | DELEGATECALL | succ | [0..calldatasize): calldata | * | * ::: copy returndata to memory :::::::::::::::::::::::::::::::::::::::::::::::::: | * 3d | RETURNDATASIZE | rds succ | [0..calldatasize): calldata | * 60 0x00 | PUSH1 0x00 | 0 rds succ | [0..calldatasize): calldata | * 80 | DUP1 | 0 0 rds succ | [0..calldatasize): calldata | * 3e | RETURNDATACOPY | succ | [0..returndatasize): returndata | * | * ::: branch on delegatecall status :::::::::::::::::::::::::::::::::::::::::::::: | * 60 0x3E | PUSH1 0x3E | dest succ | [0..returndatasize): returndata | * 57 | JUMPI | | [0..returndatasize): returndata | * | * ::: delegatecall failed, revert :::::::::::::::::::::::::::::::::::::::::::::::: | * 3d | RETURNDATASIZE | rds | [0..returndatasize): returndata | * 60 0x00 | PUSH1 0x00 | 0 rds | [0..returndatasize): returndata | * fd | REVERT | | [0..returndatasize): returndata | * | * ::: delegatecall succeeded, return ::::::::::::::::::::::::::::::::::::::::::::: | * 5b | JUMPDEST | | [0..returndatasize): returndata | * 3d | RETURNDATASIZE | rds | [0..returndatasize): returndata | * 60 0x00 | PUSH1 0x00 | 0 rds | [0..returndatasize): returndata | * f3 | RETURN | | [0..returndatasize): returndata | * | * ::: implementation , return :::::::::::::::::::::::::::::::::::::::::::::::::::: | * 5b | JUMPDEST | | | * 60 0x20 | PUSH1 0x20 | 32 | | * 60 0x0F | PUSH1 0x0F | o 32 | | * 3d | RETURNDATASIZE | 0 o 32 | | * 39 | CODECOPY | | [0..32): implementation slot | * 3d | RETURNDATASIZE | 0 | [0..32): implementation slot | * 51 | MLOAD | slot | [0..32): implementation slot | * 54 | SLOAD | impl | [0..32): implementation slot | * 3d | RETURNDATASIZE | 0 impl | [0..32): implementation slot | * 52 | MSTORE | | [0..32): implementation address | * 59 | MSIZE | 32 | [0..32): implementation address | * 3d | RETURNDATASIZE | 0 32 | [0..32): implementation address | * f3 | RETURN | | [0..32): implementation address | * | * ---------------------------------------------------------------------------------+ */ let m := mload(0x40) // Cache the free memory pointer. mstore(0x60, 0x3d6000803e603e573d6000fd5b3d6000f35b6020600f3d393d51543d52593df3) mstore(0x40, 0xa13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc545af4) mstore(0x20, 0x600f5155f3365814604357363d3d373d3d363d7f360894) mstore(0x09, or(shl(160, 0x60523d8160223d3973), shr(96, shl(96, implementation)))) instance := create(value, 0x0c, 0x74) if iszero(instance) { mstore(0x00, 0x30116425) // `DeploymentFailed()`. revert(0x1c, 0x04) } mstore(0x40, m) // Restore the free memory pointer. mstore(0x60, 0) // Restore the zero slot. } } /// @dev Deploys a deterministic ERC1967I proxy with `implementation` and `salt`. function deployDeterministicERC1967I(address implementation, bytes32 salt) internal returns (address instance) { instance = deployDeterministicERC1967I(0, implementation, salt); } /// @dev Deploys a deterministic ERC1967I proxy with `implementation` and `salt`. /// Deposits `value` ETH during deployment. function deployDeterministicERC1967I(uint256 value, address implementation, bytes32 salt) internal returns (address instance) { /// @solidity memory-safe-assembly assembly { let m := mload(0x40) // Cache the free memory pointer. mstore(0x60, 0x3d6000803e603e573d6000fd5b3d6000f35b6020600f3d393d51543d52593df3) mstore(0x40, 0xa13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc545af4) mstore(0x20, 0x600f5155f3365814604357363d3d373d3d363d7f360894) mstore(0x09, or(shl(160, 0x60523d8160223d3973), shr(96, shl(96, implementation)))) instance := create2(value, 0x0c, 0x74, salt) if iszero(instance) { mstore(0x00, 0x30116425) // `DeploymentFailed()`. revert(0x1c, 0x04) } mstore(0x40, m) // Restore the free memory pointer. mstore(0x60, 0) // Restore the zero slot. } } /// @dev Creates a deterministic ERC1967I proxy with `implementation` and `salt`. /// Note: This method is intended for use in ERC4337 factories, /// which are expected to NOT revert if the proxy is already deployed. function createDeterministicERC1967I(address implementation, bytes32 salt) internal returns (bool alreadyDeployed, address instance) { return createDeterministicERC1967I(0, implementation, salt); } /// @dev Creates a deterministic ERC1967I proxy with `implementation` and `salt`. /// Deposits `value` ETH during deployment. /// Note: This method is intended for use in ERC4337 factories, /// which are expected to NOT revert if the proxy is already deployed. function createDeterministicERC1967I(uint256 value, address implementation, bytes32 salt) internal returns (bool alreadyDeployed, address instance) { /// @solidity memory-safe-assembly assembly { let m := mload(0x40) // Cache the free memory pointer. mstore(0x60, 0x3d6000803e603e573d6000fd5b3d6000f35b6020600f3d393d51543d52593df3) mstore(0x40, 0xa13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc545af4) mstore(0x20, 0x600f5155f3365814604357363d3d373d3d363d7f360894) mstore(0x09, or(shl(160, 0x60523d8160223d3973), shr(96, shl(96, implementation)))) // Compute and store the bytecode hash. mstore(add(m, 0x35), keccak256(0x0c, 0x74)) mstore(m, shl(88, address())) mstore8(m, 0xff) // Write the prefix. mstore(add(m, 0x15), salt) instance := keccak256(m, 0x55) for {} 1 {} { if iszero(extcodesize(instance)) { instance := create2(value, 0x0c, 0x74, salt) if iszero(instance) { mstore(0x00, 0x30116425) // `DeploymentFailed()`. revert(0x1c, 0x04) } break } alreadyDeployed := 1 if iszero(value) { break } if iszero(call(gas(), instance, value, codesize(), 0x00, codesize(), 0x00)) { mstore(0x00, 0xb12d13eb) // `ETHTransferFailed()`. revert(0x1c, 0x04) } break } mstore(0x40, m) // Restore the free memory pointer. mstore(0x60, 0) // Restore the zero slot. } } /// @dev Returns the initialization code of the minimal ERC1967 proxy of `implementation`. function initCodeERC1967I(address implementation) internal pure returns (bytes memory result) { /// @solidity memory-safe-assembly assembly { result := mload(0x40) mstore( add(result, 0x74), 0x3d6000803e603e573d6000fd5b3d6000f35b6020600f3d393d51543d52593df3 ) mstore( add(result, 0x54), 0xa13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc545af4 ) mstore(add(result, 0x34), 0x600f5155f3365814604357363d3d373d3d363d7f360894) mstore(add(result, 0x1d), implementation) mstore(add(result, 0x09), 0x60523d8160223d3973) mstore(add(result, 0x94), 0) mstore(result, 0x74) // Store the length. mstore(0x40, add(result, 0xa0)) // Allocate memory. } } /// @dev Returns the initialization code hash of the minimal ERC1967 proxy of `implementation`. /// Used for mining vanity addresses with create2crunch. function initCodeHashERC1967I(address implementation) internal pure returns (bytes32 hash) { /// @solidity memory-safe-assembly assembly { let m := mload(0x40) // Cache the free memory pointer. mstore(0x60, 0x3d6000803e603e573d6000fd5b3d6000f35b6020600f3d393d51543d52593df3) mstore(0x40, 0xa13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc545af4) mstore(0x20, 0x600f5155f3365814604357363d3d373d3d363d7f360894) mstore(0x09, or(shl(160, 0x60523d8160223d3973), shr(96, shl(96, implementation)))) hash := keccak256(0x0c, 0x74) mstore(0x40, m) // Restore the free memory pointer. mstore(0x60, 0) // Restore the zero slot. } } /// @dev Returns the address of the deterministic ERC1967I proxy of `implementation`, /// with `salt` by `deployer`. /// Note: The returned result has dirty upper 96 bits. Please clean if used in assembly. function predictDeterministicAddressERC1967I( address implementation, bytes32 salt, address deployer ) internal pure returns (address predicted) { bytes32 hash = initCodeHashERC1967I(implementation); predicted = predictDeterministicAddress(hash, salt, deployer); } /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ /* CONSTANT ERC1967 BOOTSTRAP OPERATIONS */ /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ // Note: This enables an ERC1967 proxy to be deployed at a deterministic address // independent of the implementation: // ``` // address bootstrap = LibClone.constantERC1967Bootstrap(); // address instance = LibClone.deployDeterministicERC1967(0, bootstrap, salt); // LibClone.bootstrapConstantERC1967(bootstrap, implementation); // ``` /// @dev Deploys the constant ERC1967 bootstrap if it has not been deployed. function constantERC1967Bootstrap() internal returns (address bootstrap) { bootstrap = constantERC1967BootstrapAddress(); /// @solidity memory-safe-assembly assembly { if iszero(extcodesize(bootstrap)) { mstore(0x20, 0x0894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc55) mstore(0x00, 0x60258060093d393df358357f36) if iszero(create2(0, 0x13, 0x2e, 0)) { mstore(0x00, 0x30116425) // `DeploymentFailed()`. revert(0x1c, 0x04) } } } } /// @dev Returns the implementation address of the ERC1967 bootstrap for this contract. function constantERC1967BootstrapAddress() internal view returns (address bootstrap) { bytes32 hash = 0xfe1a42b9c571a6a8c083c94ac67b9cfd74e2582923426aa3b762e3431d717cd1; bootstrap = predictDeterministicAddress(hash, bytes32(0), address(this)); } /// @dev Replaces the implementation at `instance`. function bootstrapERC1967(address instance, address implementation) internal { /// @solidity memory-safe-assembly assembly { mstore(0x00, shr(96, shl(96, implementation))) if iszero(call(gas(), instance, 0, 0x00, 0x20, codesize(), 0x00)) { mstore(0x00, 0x30116425) // `DeploymentFailed()`. revert(0x1c, 0x04) } } } /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/ /* OTHER OPERATIONS */ /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/ /// @dev Returns the address when a contract with initialization code hash, /// `hash`, is deployed with `salt`, by `deployer`. /// Note: The returned result has dirty upper 96 bits. Please clean if used in assembly. function predictDeterministicAddress(bytes32 hash, bytes32 salt, address deployer) internal pure returns (address predicted) { /// @solidity memory-safe-assembly assembly { // Compute and store the bytecode hash. mstore8(0x00, 0xff) // Write the prefix. mstore(0x35, hash) mstore(0x01, shl(96, deployer)) mstore(0x15, salt) predicted := keccak256(0x00, 0x55) mstore(0x35, 0) // Restore the overwritten part of the free memory pointer. } } /// @dev Requires that `salt` starts with either the zero address or `by`. function checkStartsWith(bytes32 salt, address by) internal pure { /// @solidity memory-safe-assembly assembly { // If the salt does not start with the zero address or `by`. if iszero(or(iszero(shr(96, salt)), eq(shr(96, shl(96, by)), shr(96, salt)))) { mstore(0x00, 0x0c4549ef) // `SaltDoesNotStartWith()`. revert(0x1c, 0x04) } } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (interfaces/IERC20.sol) pragma solidity ^0.8.20; import {IERC20} from "../token/ERC20/IERC20.sol";
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (interfaces/IERC721.sol) pragma solidity ^0.8.20; import {IERC721} from "../token/ERC721/IERC721.sol";
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (interfaces/IERC1155.sol) pragma solidity ^0.8.20; import {IERC1155} from "../token/ERC1155/IERC1155.sol";
// 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) (token/ERC20/IERC20.sol) pragma solidity ^0.8.20; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ 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/ERC721/IERC721.sol) pragma solidity ^0.8.20; import {IERC165} from "../../utils/introspection/IERC165.sol"; /** * @dev Required interface of an ERC721 compliant contract. */ interface IERC721 is IERC165 { /** * @dev Emitted when `tokenId` token is transferred from `from` to `to`. */ event Transfer(address indexed from, address indexed to, uint256 indexed tokenId); /** * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token. */ event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId); /** * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets. */ event ApprovalForAll(address indexed owner, address indexed operator, bool approved); /** * @dev Returns the number of tokens in ``owner``'s account. */ function balanceOf(address owner) external view returns (uint256 balance); /** * @dev Returns the owner of the `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function ownerOf(uint256 tokenId) external view returns (address owner); /** * @dev Safely transfers `tokenId` token from `from` to `to`. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon * a safe transfer. * * Emits a {Transfer} event. */ function safeTransferFrom(address from, address to, uint256 tokenId, bytes calldata data) external; /** * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients * are aware of the ERC721 protocol to prevent tokens from being forever locked. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or * {setApprovalForAll}. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon * a safe transfer. * * Emits a {Transfer} event. */ function safeTransferFrom(address from, address to, uint256 tokenId) external; /** * @dev Transfers `tokenId` token from `from` to `to`. * * WARNING: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC721 * or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must * understand this adds an external call which potentially creates a reentrancy vulnerability. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must be owned by `from`. * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. * * Emits a {Transfer} event. */ function transferFrom(address from, address to, uint256 tokenId) external; /** * @dev Gives permission to `to` to transfer `tokenId` token to another account. * The approval is cleared when the token is transferred. * * Only a single account can be approved at a time, so approving the zero address clears previous approvals. * * Requirements: * * - The caller must own the token or be an approved operator. * - `tokenId` must exist. * * Emits an {Approval} event. */ function approve(address to, uint256 tokenId) external; /** * @dev Approve or remove `operator` as an operator for the caller. * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller. * * Requirements: * * - The `operator` cannot be the address zero. * * Emits an {ApprovalForAll} event. */ function setApprovalForAll(address operator, bool approved) external; /** * @dev Returns the account approved for `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function getApproved(uint256 tokenId) external view returns (address operator); /** * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`. * * See {setApprovalForAll} */ function isApprovedForAll(address owner, address operator) external view returns (bool); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.1) (token/ERC1155/IERC1155.sol) pragma solidity ^0.8.20; import {IERC165} from "../../utils/introspection/IERC165.sol"; /** * @dev Required interface of an ERC1155 compliant contract, as defined in the * https://eips.ethereum.org/EIPS/eip-1155[EIP]. */ interface IERC1155 is IERC165 { /** * @dev Emitted when `value` amount of tokens of type `id` are transferred from `from` to `to` by `operator`. */ event TransferSingle(address indexed operator, address indexed from, address indexed to, uint256 id, uint256 value); /** * @dev Equivalent to multiple {TransferSingle} events, where `operator`, `from` and `to` are the same for all * transfers. */ event TransferBatch( address indexed operator, address indexed from, address indexed to, uint256[] ids, uint256[] values ); /** * @dev Emitted when `account` grants or revokes permission to `operator` to transfer their tokens, according to * `approved`. */ event ApprovalForAll(address indexed account, address indexed operator, bool approved); /** * @dev Emitted when the URI for token type `id` changes to `value`, if it is a non-programmatic URI. * * If an {URI} event was emitted for `id`, the standard * https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[guarantees] that `value` will equal the value * returned by {IERC1155MetadataURI-uri}. */ event URI(string value, uint256 indexed id); /** * @dev Returns the value of tokens of token type `id` owned by `account`. * * Requirements: * * - `account` cannot be the zero address. */ function balanceOf(address account, uint256 id) external view returns (uint256); /** * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {balanceOf}. * * Requirements: * * - `accounts` and `ids` must have the same length. */ function balanceOfBatch( address[] calldata accounts, uint256[] calldata ids ) external view returns (uint256[] memory); /** * @dev Grants or revokes permission to `operator` to transfer the caller's tokens, according to `approved`, * * Emits an {ApprovalForAll} event. * * Requirements: * * - `operator` cannot be the caller. */ function setApprovalForAll(address operator, bool approved) external; /** * @dev Returns true if `operator` is approved to transfer ``account``'s tokens. * * See {setApprovalForAll}. */ function isApprovedForAll(address account, address operator) external view returns (bool); /** * @dev Transfers a `value` amount of tokens of type `id` from `from` to `to`. * * WARNING: This function can potentially allow a reentrancy attack when transferring tokens * to an untrusted contract, when invoking {onERC1155Received} on the receiver. * Ensure to follow the checks-effects-interactions pattern and consider employing * reentrancy guards when interacting with untrusted contracts. * * Emits a {TransferSingle} event. * * Requirements: * * - `to` cannot be the zero address. * - If the caller is not `from`, it must have been approved to spend ``from``'s tokens via {setApprovalForAll}. * - `from` must have a balance of tokens of type `id` of at least `value` amount. * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the * acceptance magic value. */ function safeTransferFrom(address from, address to, uint256 id, uint256 value, bytes calldata data) external; /** * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {safeTransferFrom}. * * WARNING: This function can potentially allow a reentrancy attack when transferring tokens * to an untrusted contract, when invoking {onERC1155BatchReceived} on the receiver. * Ensure to follow the checks-effects-interactions pattern and consider employing * reentrancy guards when interacting with untrusted contracts. * * Emits either a {TransferSingle} or a {TransferBatch} event, depending on the length of the array arguments. * * Requirements: * * - `ids` and `values` must have the same length. * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the * acceptance magic value. */ function safeBatchTransferFrom( address from, address to, uint256[] calldata ids, uint256[] calldata values, bytes calldata data ) external; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (utils/introspection/IERC165.sol) pragma solidity ^0.8.20; /** * @dev Interface of the ERC165 standard, as defined in the * https://eips.ethereum.org/EIPS/eip-165[EIP]. * * Implementers can declare support of contract interfaces, which can then be * queried by others ({ERC165Checker}). * * For an implementation, see {ERC165}. */ interface IERC165 { /** * @dev Returns true if this contract implements the interface defined by * `interfaceId`. See the corresponding * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] * to learn more about how these ids are created. * * This function call must use less than 30 000 gas. */ function supportsInterface(bytes4 interfaceId) external view returns (bool); }
{ "remappings": [ "@openzeppelin-upgradeable/=lib/AlignmentVault/lib/nftx-protocol-v3/lib/openzeppelin-contracts-upgradeable/", "@openzeppelin/=lib/AlignmentVault/lib/nftx-protocol-v3/lib/openzeppelin-contracts/", "@openzeppelin/contracts/=lib/AlignmentVault/lib/nftx-protocol-v3/lib/openzeppelin-contracts/contracts/", "@mocks/=lib/AlignmentVault/lib/nftx-protocol-v3/src/mocks/", "@openzeppelin/contracts-upgradeable/=lib/ERC721M/lib/ERC721x/lib/openzeppelin-contracts-upgradeable/contracts/", "@permit2/=lib/AlignmentVault/lib/nftx-protocol-v3/lib/permit2/src/", "@src/=lib/AlignmentVault/lib/nftx-protocol-v3/src/", "@test/=lib/AlignmentVault/lib/nftx-protocol-v3/test/", "@uni-core/=lib/AlignmentVault/lib/nftx-protocol-v3/src/uniswap/v3-core/", "@uni-periphery/=lib/AlignmentVault/lib/nftx-protocol-v3/src/uniswap/v3-periphery/", "@uniswap/lib/=lib/AlignmentVault/lib/nftx-protocol-v3/lib/solidity-lib/", "@uniswap/v2-core/=lib/AlignmentVault/lib/nftx-protocol-v3/lib/v2-core/", "@uniswap/v3-core/contracts/=lib/AlignmentVault/lib/nftx-protocol-v3/src/uniswap/v3-core/", "AlignmentVault/=lib/AlignmentVault/", "ERC721A-Upgradeable/=lib/ERC721M/lib/ERC721x/lib/ERC721A-Upgradeable/contracts/", "ERC721A/=lib/ERC721M/lib/ERC721x/lib/ERC721A/contracts/", "ERC721M/=lib/ERC721M/", "ERC721x/=lib/ERC721M/lib/ERC721x/", "base64-sol/=lib/AlignmentVault/lib/nftx-protocol-v3/src/uniswap/v3-periphery/libraries/", "delegate-registry/=lib/AlignmentVault/lib/delegate-registry/", "ds-test/=lib/AlignmentVault/lib/forge-std/lib/ds-test/src/", "erc4626-tests/=lib/openzeppelin-contracts/lib/erc4626-tests/", "forge-gas-snapshot/=lib/AlignmentVault/lib/nftx-protocol-v3/lib/permit2/lib/forge-gas-snapshot/src/", "forge-std/=lib/forge-std/src/", "murky/=lib/AlignmentVault/lib/delegate-registry/lib/murky/", "nftx-protocol-v3/=lib/AlignmentVault/lib/nftx-protocol-v3/src/", "openzeppelin-contracts-upgradeable/=lib/ERC721M/lib/ERC721x/lib/openzeppelin-contracts-upgradeable/", "openzeppelin-contracts-v5/=lib/AlignmentVault/lib/openzeppelin-contracts-v5/", "openzeppelin-contracts/=lib/openzeppelin-contracts/", "openzeppelin/=lib/AlignmentVault/lib/delegate-registry/lib/openzeppelin-contracts/contracts/", "permit2/=lib/AlignmentVault/lib/nftx-protocol-v3/lib/permit2/", "solady/=lib/solady/src/", "solidity-lib/=lib/AlignmentVault/lib/nftx-protocol-v3/lib/solidity-lib/contracts/", "solmate/=lib/AlignmentVault/lib/solmate/src/", "v2-core/=lib/AlignmentVault/lib/v2-core/contracts/", "v2-periphery/=lib/AlignmentVault/lib/v2-periphery/contracts/" ], "optimizer": { "enabled": true, "runs": 200 }, "metadata": { "useLiteralContent": false, "bytecodeHash": "ipfs", "appendCBOR": true }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "evmVersion": "paris", "viaIR": false, "libraries": {} }
[{"inputs":[{"internalType":"address","name":"newOwner","type":"address"},{"internalType":"address","name":"newErc721MiyaImplementation","type":"address"},{"internalType":"address","name":"newMiyaAVImplementation","type":"address"}],"stateMutability":"payable","type":"constructor"},{"inputs":[],"name":"AlreadyInitialized","type":"error"},{"inputs":[],"name":"Invalid","type":"error"},{"inputs":[],"name":"NewOwnerIsZeroAddress","type":"error"},{"inputs":[],"name":"NoHandoverRequest","type":"error"},{"inputs":[],"name":"TransferFailed","type":"error"},{"inputs":[],"name":"Unauthorized","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"deployer","type":"address"},{"indexed":true,"internalType":"address","name":"collection","type":"address"},{"indexed":true,"internalType":"address","name":"aligned","type":"address"},{"indexed":false,"internalType":"bytes32","name":"salt","type":"bytes32"}],"name":"Deployed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"implementation","type":"address"}],"name":"ERC721MiyaImplementation","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"erc721","type":"address"},{"indexed":true,"internalType":"uint256","name":"vaultId","type":"uint256"}],"name":"MiyaIdSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"erc721m","type":"address"},{"indexed":true,"internalType":"address","name":"oldOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"pendingOwner","type":"address"}],"name":"OwnershipHandoverCanceled","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"pendingOwner","type":"address"}],"name":"OwnershipHandoverRequested","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"oldOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"inputs":[],"name":"cancelOwnershipHandover","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"pendingOwner","type":"address"}],"name":"completeOwnershipHandover","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"string","name":"name","type":"string"},{"internalType":"string","name":"symbol","type":"string"},{"internalType":"string","name":"baseURI","type":"string"},{"internalType":"uint40","name":"maxSupply","type":"uint40"},{"internalType":"uint16","name":"royalty","type":"uint16"},{"internalType":"uint16","name":"allocation","type":"uint16"},{"internalType":"address","name":"owner_","type":"address"},{"internalType":"address","name":"alignedNft","type":"address"},{"internalType":"uint80","name":"price","type":"uint80"},{"internalType":"uint96","name":"vaultId","type":"uint96"},{"internalType":"bytes32","name":"saltAlignmentVault","type":"bytes32"}],"name":"deploy","outputs":[{"internalType":"address","name":"deployment","type":"address"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"name","type":"string"},{"internalType":"string","name":"symbol","type":"string"},{"internalType":"string","name":"baseURI","type":"string"},{"internalType":"uint40","name":"maxSupply","type":"uint40"},{"internalType":"uint16","name":"royalty","type":"uint16"},{"internalType":"uint16","name":"allocation","type":"uint16"},{"internalType":"address","name":"owner_","type":"address"},{"internalType":"address","name":"alignedNft","type":"address"},{"internalType":"uint80","name":"price","type":"uint80"},{"internalType":"uint96","name":"vaultId","type":"uint96"},{"internalType":"bytes32","name":"saltAlignmentVault","type":"bytes32"},{"internalType":"bytes32","name":"saltERC721Miya","type":"bytes32"}],"name":"deployDeterministic","outputs":[{"internalType":"address","name":"deployment","type":"address"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"alignedNft","type":"address"},{"internalType":"uint96","name":"vaultId","type":"uint96"},{"internalType":"bytes32","name":"salt","type":"bytes32"}],"name":"deployVault","outputs":[{"internalType":"address","name":"vault","type":"address"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"erc721MiyaImplementation","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getAlignedNfts","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"alignedNft","type":"address"},{"internalType":"uint256","name":"vaultId","type":"uint256"}],"name":"getVault","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"alignedNft","type":"address"}],"name":"getVaultIds","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"initCodeHash","outputs":[{"internalType":"bytes32","name":"hash","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"miyaAVFactory","outputs":[{"internalType":"contract MiyaAVFactory","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"miyaAVImplementation","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"alignedNft","type":"address"}],"name":"miyaIds","outputs":[{"internalType":"uint256","name":"vaultId","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"result","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"oldOwner","type":"address"},{"internalType":"address","name":"newOwner","type":"address"}],"name":"ownershipChanged","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"pendingOwner","type":"address"}],"name":"ownershipHandoverExpiresAt","outputs":[{"internalType":"uint256","name":"result","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"salt","type":"bytes32"}],"name":"predictDeterministicAddress","outputs":[{"internalType":"address","name":"predicted","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"requestOwnershipHandover","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"alignedNft","type":"address"},{"internalType":"uint256","name":"vaultId","type":"uint256"}],"name":"setMiyaId","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"newErc721MiyaImplementation","type":"address"}],"name":"updateERC721MiyaImplementation","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newMiyaAVImplementation","type":"address"}],"name":"updateMiyaAVImplementation","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"address","name":"recipient","type":"address"}],"name":"withdrawERC1155","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256[]","name":"tokenIds","type":"uint256[]"},{"internalType":"uint256[]","name":"amounts","type":"uint256[]"},{"internalType":"address","name":"recipient","type":"address"}],"name":"withdrawERC1155Batch","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"address","name":"recipient","type":"address"}],"name":"withdrawERC20","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"address","name":"recipient","type":"address"}],"name":"withdrawERC721","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"recipient","type":"address"}],"name":"withdrawEth","outputs":[],"stateMutability":"payable","type":"function"}]
Contract Creation Code
60806040526040516200392a3803806200392a83398101604081905262000026916200014c565b6200003183620000e5565b600080546001600160a01b0319166001600160a01b038416908117825560405190917f86587754a7c1b5416d014e448fdb1d745a6f657dcbe010541f65993a7eccfee191a28281604051620000869062000121565b6001600160a01b03928316815291166020820152604001604051809103906000f080158015620000ba573d6000803e3d6000fd5b50600180546001600160a01b0319166001600160a01b03929092169190911790555062000196915050565b6001600160a01b0316638b78c6d8198190558060007f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e08180a350565b611aee8062001e3c83390190565b80516001600160a01b03811681146200014757600080fd5b919050565b6000806000606084860312156200016257600080fd5b6200016d846200012f565b92506200017d602085016200012f565b91506200018d604085016200012f565b90509250925092565b611c9680620001a66000396000f3fe6080604052600436106101b75760003560e01c806375f0ebf4116100ec578063db4c545e1161008a578063f2fde38b11610064578063f2fde38b14610493578063f724fa6f146104a6578063fd8e2c84146104c6578063fee81cf4146104e657600080fd5b8063db4c545e14610417578063e98778841461046d578063f04e283e1461048057600080fd5b80639456fbcc116100c65780639456fbcc14610397578063c952c865146103aa578063cf4c3606146103ca578063d99d13f5146103f757600080fd5b806375f0ebf41461034b5780637b9f76b51461036b5780638da5cb5b1461037e57600080fd5b806354d1f13d116101595780635fa78f80116101335780635fa78f80146102c85780636149a6bc146102e85780636437a1aa14610308578063715018a61461034357600080fd5b806354d1f13d14610280578063565068a8146102885780635d92051b146102a857600080fd5b80632854f1b2116101955780632854f1b2146101ec5780632b002e731461021e57806334a365241461023e5780635414dff01461026057600080fd5b8063256451ac146101bc57806325692962146101d157806325e16063146101d9575b600080fd5b6101cf6101ca366004611347565b610519565b005b6101cf6105e3565b6101cf6101e7366004611391565b610633565b3480156101f857600080fd5b506102016106f1565b6040516001600160a01b0390911681526020015b60405180910390f35b34801561022a57600080fd5b506101cf610239366004611391565b610764565b34801561024a57600080fd5b506102536107b4565b60405161021591906113ae565b34801561026c57600080fd5b5061020161027b3660046113fb565b610826565b6101cf610844565b34801561029457600080fd5b50600054610201906001600160a01b031681565b3480156102b457600080fd5b506101cf6102c3366004611414565b610880565b3480156102d457600080fd5b506102016102e3366004611464565b6108ef565b3480156102f457600080fd5b5061020161030336600461159a565b610a39565b34801561031457600080fd5b50610335610323366004611391565b60026020526000908152604090205481565b604051908152602001610215565b6101cf610b97565b34801561035757600080fd5b506101cf6103663660046116a5565b610ba1565b6101cf6103793660046116d1565b610bf0565b34801561038a57600080fd5b50638b78c6d81954610201565b6101cf6103a5366004611414565b610ca3565b3480156103b657600080fd5b506102016103c5366004611713565b610dcf565b3480156103d657600080fd5b506103ea6103e5366004611391565b610f52565b6040516102159190611871565b34801561040357600080fd5b506102016104123660046116a5565b610fc5565b34801561042357600080fd5b50600080546c5af43d3d93803e602a57fd5bf360219081526001600160a01b0390911660145273602c3d8160093d39f33d3d3d3d363d3d37363d7382526035600c20919052610335565b6101cf61047b366004611917565b61103b565b6101cf61048e366004611391565b6110b3565b6101cf6104a1366004611391565b6110f3565b3480156104b257600080fd5b506101cf6104c1366004611391565b61111a565b3480156104d257600080fd5b50600154610201906001600160a01b031681565b3480156104f257600080fd5b50610335610501366004611391565b63389a75e1600c908152600091909152602090205490565b610521611183565b6001600160a01b038116158061054157506001600160a01b03811661dead145b1561055f576040516312171d8360e31b815260040160405180910390fd5b604051637921219560e11b81523060048201526001600160a01b038281166024830152604482018590526064820184905260a06084830152600060a483015285169063f242432a9060c4015b600060405180830381600087803b1580156105c557600080fd5b505af11580156105d9573d6000803e3d6000fd5b5050505050505050565b60006202a30067ffffffffffffffff164201905063389a75e1600c5233600052806020600c2055337fdbf36a107da19e49527a7176a1babf963b4b0ff8cde35ee35d6cd8f1f9ac7e1d600080a250565b61063b611183565b6001600160a01b038116158061065b57506001600160a01b03811661dead145b15610679576040516312171d8360e31b815260040160405180910390fd5b6000816001600160a01b03164760405160006040518083038185875af1925050503d80600081146106c6576040519150601f19603f3d011682016040523d82523d6000602084013e6106cb565b606091505b50509050806106ed576040516312171d8360e31b815260040160405180910390fd5b5050565b60015460408051635c60da1b60e01b815290516000926001600160a01b031691635c60da1b9160048083019260209291908290030181865afa15801561073b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061075f9190611995565b905090565b61076c611183565b600080546001600160a01b0319166001600160a01b038316908117825560405190917f86587754a7c1b5416d014e448fdb1d745a6f657dcbe010541f65993a7eccfee191a250565b60015460408051630d28d94960e21b815290516060926001600160a01b0316916334a365249160048083019260009291908290030181865afa1580156107fe573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261075f91908101906119b2565b6000805461083e906001600160a01b0316833061119e565b92915050565b63389a75e1600c523360005260006020600c2055337ffa7b8eab7da67f412cc9575ed43464468f9bfbae89d1675917346ca6d8fe3c92600080a2565b3360009081526003602052604090205460ff166108b057604051636dac6a0960e01b815260040160405180910390fd5b6040516001600160a01b03808316919084169033907f60b760b15c562c07ca8faad5fab184dfc5d58d1e57d9f2fa4fd93b7380c9981b90600090a45050565b6000826001600160601b031660000361091e576001600160a01b03841660009081526002602052604090205492505b816109a957600154604051633b8cd70f60e01b81526001600160a01b0386811660048301526001600160601b038616602483015290911690633b8cd70f906044016020604051808303816000875af115801561097e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109a29190611995565b9050610a32565b60015460405163b1983f9360e01b81526001600160a01b0386811660048301526001600160601b0386166024830152604482018590529091169063b1983f93906064016020604051808303816000875af1158015610a0b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a2f9190611995565b90505b9392505050565b60008054610a4f906001600160a01b03166111fb565b6001600160a01b03811660008181526003602052604090819020805460ff19166001179055516307e1fdd960e21b815291925090631f87f76490610aab908f908f908f908f908f908f908f908f908f908f908f90600401611a92565b600060405180830381600087803b158015610ac557600080fd5b505af1158015610ad9573d6000803e3d6000fd5b50505050806001600160a01b03166331f449006040518163ffffffff1660e01b8152600401600060405180830381600087803b158015610b1857600080fd5b505af1158015610b2c573d6000803e3d6000fd5b50505050846001600160a01b0316816001600160a01b0316336001600160a01b03167ffe0b790c72ed3156887ce7a0bcfe2d4d72ecadef8a529eb9c8a40e7cff968b166000604051610b8091815260200190565b60405180910390a49b9a5050505050505050505050565b610b9f611183565b565b610ba9611183565b6001600160a01b038216600081815260026020526040808220849055518392917fecfc5799f71e577b2e57c8cec6535d089d0e392d1a5d0a704c8f327f55b0108d91a35050565b610bf8611183565b6001600160a01b0381161580610c1857506001600160a01b03811661dead145b15610c36576040516312171d8360e31b815260040160405180910390fd5b6040516323b872dd60e01b81523060048201526001600160a01b038281166024830152604482018490528416906323b872dd90606401600060405180830381600087803b158015610c8657600080fd5b505af1158015610c9a573d6000803e3d6000fd5b50505050505050565b610cab611183565b6001600160a01b0381161580610ccb57506001600160a01b03811661dead145b15610ce9576040516312171d8360e31b815260040160405180910390fd5b6040516370a0823160e01b81523060048201526001600160a01b0383169063a9059cbb90839083906370a0823190602401602060405180830381865afa158015610d37573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d5b9190611b44565b6040516001600160e01b031960e085901b1681526001600160a01b03909216600483015260248201526044016020604051808303816000875af1158015610da6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610dca9190611b5d565b505050565b60008054610de6906001600160a01b031683611208565b9050600160036000836001600160a01b03166001600160a01b0316815260200190815260200160002060006101000a81548160ff021916908315150217905550806001600160a01b0316631f87f7648e8e8e8e8e8e8e8e8e8e8e6040518c63ffffffff1660e01b8152600401610e669b9a99989796959493929190611a92565b600060405180830381600087803b158015610e8057600080fd5b505af1158015610e94573d6000803e3d6000fd5b50505050806001600160a01b03166331f449006040518163ffffffff1660e01b8152600401600060405180830381600087803b158015610ed357600080fd5b505af1158015610ee7573d6000803e3d6000fd5b50505050856001600160a01b0316816001600160a01b0316336001600160a01b03167ffe0b790c72ed3156887ce7a0bcfe2d4d72ecadef8a529eb9c8a40e7cff968b1685604051610f3a91815260200190565b60405180910390a49c9b505050505050505050505050565b6001546040516367a61b0360e11b81526001600160a01b038381166004830152606092169063cf4c360690602401600060405180830381865afa158015610f9d573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261083e9190810190611b7f565b600154604051633ddfe34f60e11b81526001600160a01b038481166004830152602482018490526000921690637bbfc69e90604401602060405180830381865afa158015611017573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a329190611995565b611043611183565b6001600160a01b038116158061106357506001600160a01b03811661dead145b15611081576040516312171d8360e31b815260040160405180910390fd5b604051631759616b60e11b81526001600160a01b03851690632eb2c2d6906105ab903090859088908890600401611c05565b6110bb611183565b63389a75e1600c52806000526020600c2080544211156110e357636f5e88186000526004601cfd5b600090556110f081611216565b50565b6110fb611183565b8060601b61111157637448fbae6000526004601cfd5b6110f081611216565b611122611183565b6001546040516296c8af60e21b81526001600160a01b0383811660048301529091169063025b22bc90602401600060405180830381600087803b15801561116857600080fd5b505af115801561117c573d6000803e3d6000fd5b5050505050565b638b78c6d819543314610b9f576382b429006000526004601cfd5b6000806111e58560006c5af43d3d93803e602a57fd5bf36021528160145273602c3d8160093d39f33d3d3d3d363d3d37363d736000526035600c2090506000602152919050565b90506111f2818585611254565b95945050505050565b600061083e600083611276565b6000610a32600084846112cb565b638b78c6d81980546001600160a01b039092169182907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0600080a355565b600060ff60005350603592835260601b60015260155260556000908120915290565b60006c5af43d3d93803e602a57fd5bf36021528160145273602c3d8160093d39f33d3d3d3d363d3d37363d736000526035600c84f09050806112c05763301164256000526004601cfd5b600060215292915050565b60006c5af43d3d93803e602a57fd5bf36021528260145273602c3d8160093d39f33d3d3d3d363d3d37363d73600052816035600c86f59050806113165763301164256000526004601cfd5b60006021529392505050565b6001600160a01b03811681146110f057600080fd5b803561134281611322565b919050565b6000806000806080858703121561135d57600080fd5b843561136881611322565b93506020850135925060408501359150606085013561138681611322565b939692955090935050565b6000602082840312156113a357600080fd5b8135610a3281611322565b6020808252825182820181905260009190848201906040850190845b818110156113ef5783516001600160a01b0316835292840192918401916001016113ca565b50909695505050505050565b60006020828403121561140d57600080fd5b5035919050565b6000806040838503121561142757600080fd5b823561143281611322565b9150602083013561144281611322565b809150509250929050565b80356001600160601b038116811461134257600080fd5b60008060006060848603121561147957600080fd5b833561148481611322565b92506114926020850161144d565b9150604084013590509250925092565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff811182821017156114e1576114e16114a2565b604052919050565b600082601f8301126114fa57600080fd5b813567ffffffffffffffff811115611514576115146114a2565b611527601f8201601f19166020016114b8565b81815284602083860101111561153c57600080fd5b816020850160208301376000918101602001919091529392505050565b803564ffffffffff8116811461134257600080fd5b803561ffff8116811461134257600080fd5b803569ffffffffffffffffffff8116811461134257600080fd5b60008060008060008060008060008060006101608c8e0312156115bc57600080fd5b67ffffffffffffffff808d3511156115d357600080fd5b6115e08e8e358f016114e9565b9b508060208e013511156115f357600080fd5b6116038e60208f01358f016114e9565b9a508060408e0135111561161657600080fd5b506116278d60408e01358e016114e9565b985061163560608d01611559565b975061164360808d0161156e565b965061165160a08d0161156e565b955061165f60c08d01611337565b945061166d60e08d01611337565b935061167c6101008d01611580565b925061168b6101208d0161144d565b91506101408c013590509295989b509295989b9093969950565b600080604083850312156116b857600080fd5b82356116c381611322565b946020939093013593505050565b6000806000606084860312156116e657600080fd5b83356116f181611322565b925060208401359150604084013561170881611322565b809150509250925092565b6000806000806000806000806000806000806101808d8f03121561173657600080fd5b67ffffffffffffffff8d35111561174c57600080fd5b6117598e8e358f016114e9565b9b5067ffffffffffffffff60208e0135111561177457600080fd5b6117848e60208f01358f016114e9565b9a5067ffffffffffffffff60408e0135111561179f57600080fd5b6117af8e60408f01358f016114e9565b99506117bd60608e01611559565b98506117cb60808e0161156e565b97506117d960a08e0161156e565b96506117e760c08e01611337565b95506117f560e08e01611337565b94506118046101008e01611580565b93506118136101208e0161144d565b92506101408d013591506101608d013590509295989b509295989b509295989b565b60008151808452602080850194506020840160005b838110156118665781518752958201959082019060010161184a565b509495945050505050565b602081526000610a326020830184611835565b600067ffffffffffffffff82111561189e5761189e6114a2565b5060051b60200190565b600082601f8301126118b957600080fd5b813560206118ce6118c983611884565b6114b8565b8083825260208201915060208460051b8701019350868411156118f057600080fd5b602086015b8481101561190c57803583529183019183016118f5565b509695505050505050565b6000806000806080858703121561192d57600080fd5b843561193881611322565b9350602085013567ffffffffffffffff8082111561195557600080fd5b611961888389016118a8565b9450604087013591508082111561197757600080fd5b50611984878288016118a8565b925050606085013561138681611322565b6000602082840312156119a757600080fd5b8151610a3281611322565b600060208083850312156119c557600080fd5b825167ffffffffffffffff8111156119dc57600080fd5b8301601f810185136119ed57600080fd5b80516119fb6118c982611884565b81815260059190911b82018301908381019087831115611a1a57600080fd5b928401925b82841015611a41578351611a3281611322565b82529284019290840190611a1f565b979650505050505050565b6000815180845260005b81811015611a7257602081850181015186830182015201611a56565b506000602082860101526020601f19601f83011685010191505092915050565b6000610160808352611aa68184018f611a4c565b90508281036020840152611aba818e611a4c565b90508281036040840152611ace818d611a4c565b64ffffffffff8c16606085015261ffff8b811660808601528a1660a08501526001600160a01b0389811660c0860152881660e085015269ffffffffffffffffffff87166101008501529150611b209050565b6001600160601b039390931661012082015261014001529998505050505050505050565b600060208284031215611b5657600080fd5b5051919050565b600060208284031215611b6f57600080fd5b81518015158114610a3257600080fd5b60006020808385031215611b9257600080fd5b825167ffffffffffffffff811115611ba957600080fd5b8301601f81018513611bba57600080fd5b8051611bc86118c982611884565b81815260059190911b82018301908381019087831115611be757600080fd5b928401925b82841015611a4157835182529284019290840190611bec565b6001600160a01b0385811682528416602082015260a060408201819052600090611c3190830185611835565b8281036060840152611c438185611835565b83810360809094019390935250506000815260200194935050505056fea26469706673582212204ef33568a3b68d46eb14ee7632a349974e5102292c3f11e2779d9406f7d6a15a64736f6c6343000817003360806040523480156200001157600080fd5b5060405162001aee38038062001aee8339810160408190526200003491620000fc565b81816200004182620000a3565b600080546001600160a01b0319166001600160a01b038316908117825560405190917f1d83655f7ea9272ca6ce199d8142c5dd00133e0c1224729ef2a7b5058003030491a25050600480546001600160a01b0319163317905550620001349050565b6001600160a01b0316638b78c6d8198190558060007f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e08180a350565b80516001600160a01b0381168114620000f757600080fd5b919050565b600080604083850312156200011057600080fd5b6200011b83620000df565b91506200012b60208401620000df565b90509250929050565b6119aa80620001446000396000f3fe6080604052600436106101355760003560e01c80637b9f76b5116100ab578063cf4c36061161006f578063cf4c3606146102d2578063db4c545e146102ff578063e98778841461035f578063f04e283e14610372578063f2fde38b14610385578063fee81cf41461039857600080fd5b80637b9f76b5146102435780637bbfc69e146102565780638da5cb5b146102975780639456fbcc146102ac578063b1983f93146102bf57600080fd5b80633b8cd70f116100fd5780633b8cd70f146101a85780635414dff0146101d357806354d1f13d146101f35780635c60da1b146101fb578063600041a01461021b578063715018a61461023b57600080fd5b8063025b22bc1461013a578063256451ac1461014f578063256929621461016257806325e160631461016a57806334a365241461017d575b600080fd5b61014d61014836600461155d565b6103cb565b005b61014d61015d36600461157a565b610453565b61014d61051c565b61014d61017836600461155d565b61056c565b34801561018957600080fd5b5061019261062a565b60405161019f91906115c4565b60405180910390f35b6101bb6101b6366004611626565b61063b565b6040516001600160a01b03909116815260200161019f565b3480156101df57600080fd5b506101bb6101ee36600461165f565b6108dd565b61014d6108f5565b34801561020757600080fd5b506000546101bb906001600160a01b031681565b34801561022757600080fd5b506004546101bb906001600160a01b031681565b61014d610931565b61014d610251366004611678565b61093b565b34801561026257600080fd5b506101bb6102713660046116ba565b60016020908152600092835260408084209091529082529020546001600160a01b031681565b3480156102a357600080fd5b506101bb6109ee565b61014d6102ba3660046116e6565b610a67565b6101bb6102cd366004611714565b610b93565b3480156102de57600080fd5b506102f26102ed36600461155d565b610e36565b60405161019f9190611755565b34801561030b57600080fd5b50600080546c5af43d3d93803e602a57fd5bf360219081526001600160a01b0390911660145273602c3d8160093d39f33d3d3d3d363d3d37363d7382526035600c209190525b60405190815260200161019f565b61014d61036d3660046117d9565b610e5a565b61014d61038036600461155d565b610f10565b61014d61039336600461155d565b610f4d565b3480156103a457600080fd5b506103516103b336600461155d565b63389a75e1600c908152600091909152602090205490565b6004546001600160a01b031633146103f5576040516282b42960e81b815260040160405180910390fd5b6000546001600160a01b0382811691161461045057600080546001600160a01b0319166001600160a01b038316908117825560405190917f1d83655f7ea9272ca6ce199d8142c5dd00133e0c1224729ef2a7b5058003030491a25b50565b61045b610f74565b6001600160a01b038116158061047b57506001600160a01b03811661dead145b156104995760405163dfad6a2360e01b815260040160405180910390fd5b604051637921219560e11b81523060048201526001600160a01b038281166024830152604482018590526064820184905260a06084830152600060a483015285169063f242432a9060c401600060405180830381600087803b1580156104fe57600080fd5b505af1158015610512573d6000803e3d6000fd5b5050505050505050565b60006202a30067ffffffffffffffff164201905063389a75e1600c5233600052806020600c2055337fdbf36a107da19e49527a7176a1babf963b4b0ff8cde35ee35d6cd8f1f9ac7e1d600080a250565b610574610f74565b6001600160a01b038116158061059457506001600160a01b03811661dead145b156105b25760405163dfad6a2360e01b815260040160405180910390fd5b6000816001600160a01b03164760405160006040518083038185875af1925050503d80600081146105ff576040519150601f19603f3d011682016040523d82523d6000602084013e610604565b606091505b50509050806106265760405163dfad6a2360e01b815260040160405180910390fd5b5050565b60606106366003610fac565b905090565b6004546000906001600160a01b03163314610668576040516282b42960e81b815260040160405180910390fd5b506001600160a01b0380831660009081526001602090815260408083206001600160601b038616845290915290205416806108d7576000546106b2906001600160a01b0316611081565b9050806001600160a01b031663c861c2506106cb6109ee565b6040516001600160e01b031960e084901b1681526001600160a01b03918216600482015290861660248201526001600160601b0385166044820152606401600060405180830381600087803b15801561072357600080fd5b505af1158015610737573d6000803e3d6000fd5b50505050806001600160a01b03166331f449006040518163ffffffff1660e01b8152600401600060405180830381600087803b15801561077657600080fd5b505af115801561078a573d6000803e3d6000fd5b50505050816001600160601b031660000361080457806001600160a01b03166333194c0a6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156107dd573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610801919061186e565b91505b6001600160a01b0383811660009081526001602090815260408083206001600160601b0387168452909152902080546001600160a01b03191691831691909117905561085160038461108e565b506001600160a01b038316600090815260026020526040902061087d906001600160601b0384166111de565b50816001600160601b0316836001600160a01b0316826001600160a01b03167fe9c573b8597bcb5e44e22c9a179f71106bfd46ac62c1b933951c58891eee8f9460006040516108ce91815260200190565b60405180910390a45b92915050565b600080546108d7906001600160a01b031683306111ea565b63389a75e1600c523360005260006020600c2055337ffa7b8eab7da67f412cc9575ed43464468f9bfbae89d1675917346ca6d8fe3c92600080a2565b610939610f74565b565b610943610f74565b6001600160a01b038116158061096357506001600160a01b03811661dead145b156109815760405163dfad6a2360e01b815260040160405180910390fd5b6040516323b872dd60e01b81523060048201526001600160a01b038281166024830152604482018490528416906323b872dd90606401600060405180830381600087803b1580156109d157600080fd5b505af11580156109e5573d6000803e3d6000fd5b50505050505050565b6000600460009054906101000a90046001600160a01b03166001600160a01b0316638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610a43573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610636919061188b565b610a6f610f74565b6001600160a01b0381161580610a8f57506001600160a01b03811661dead145b15610aad5760405163dfad6a2360e01b815260040160405180910390fd5b6040516370a0823160e01b81523060048201526001600160a01b0383169063a9059cbb90839083906370a0823190602401602060405180830381865afa158015610afb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b1f91906118a8565b6040516001600160e01b031960e085901b1681526001600160a01b03909216600483015260248201526044016020604051808303816000875af1158015610b6a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b8e91906118c1565b505050565b6004546000906001600160a01b03163314610bc0576040516282b42960e81b815260040160405180910390fd5b506001600160a01b0380841660009081526001602090815260408083206001600160601b03871684529091529020541680610e2f57600054610c0b906001600160a01b031683611247565b9050806001600160a01b031663c861c250610c246109ee565b6040516001600160e01b031960e084901b1681526001600160a01b03918216600482015290871660248201526001600160601b0386166044820152606401600060405180830381600087803b158015610c7c57600080fd5b505af1158015610c90573d6000803e3d6000fd5b50505050806001600160a01b03166331f449006040518163ffffffff1660e01b8152600401600060405180830381600087803b158015610ccf57600080fd5b505af1158015610ce3573d6000803e3d6000fd5b50505050826001600160601b0316600003610d5d57806001600160a01b03166333194c0a6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610d36573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d5a919061186e565b92505b6001600160a01b0384811660009081526001602090815260408083206001600160601b0388168452909152902080546001600160a01b031916918316919091179055610daa60038561108e565b506001600160a01b0384166000908152600260205260409020610dd6906001600160601b0385166111de565b50826001600160601b0316846001600160a01b0316826001600160a01b03167fe9c573b8597bcb5e44e22c9a179f71106bfd46ac62c1b933951c58891eee8f9485604051610e2691815260200190565b60405180910390a45b9392505050565b6001600160a01b03811660009081526002602052604090206060906108d790611255565b610e62610f74565b6001600160a01b0381161580610e8257506001600160a01b03811661dead145b15610ea05760405163dfad6a2360e01b815260040160405180910390fd5b604051631759616b60e11b81526001600160a01b03871690632eb2c2d690610ed690309085908a908a908a908a90600401611915565b600060405180830381600087803b158015610ef057600080fd5b505af1158015610f04573d6000803e3d6000fd5b50505050505050505050565b610f18610f74565b63389a75e1600c52806000526020600c208054421115610f4057636f5e88186000526004601cfd5b6000905561045081611266565b610f55610f74565b8060601b610f6b57637448fbae6000526004601cfd5b61045081611266565b610f7c6109ee565b6001600160a01b0316336001600160a01b031614610939576040516282b42960e81b815260040160405180910390fd5b63978aab926004526000818152602481206060915068fbb67fda52d4bfb8bf81548060a01b60a01c6040519450846020018260601c925083831415830281528161103b57821561103657600191508185015460601c92508215611036578284141590920260208301525060028381015460601c918215611036576003915083831415830260408201525b61106b565b600191821c915b82811015611069578581015460601c858114158102600583901b8401529350600101611042565b505b8186528160051b81016040525050505050919050565b60006108d76000836112a4565b63978aab926004526000828152602481206001600160a01b03929092169168fbb67fda52d4bfb8be1983016110cb5763f5a267f16000526004601cfd5b826110dd5768fbb67fda52d4bfb8bf92505b80546001600160601b03811682602052806111a0578160601c8061110b578560601b845560019450506111d5565b85810361111857506111d5565b600184015460601c80611139578660601b60018601556001955050506111d5565b8681036111475750506111d5565b600285015460601c80611169578760601b6002870155600196505050506111d5565b878103611178575050506111d5565b6000928352604080842060019055918352818320600290558252902060039055506007908117905b84600052604060002080546111d3578160011c91508560601b8285015581600101815582600201845560019450506111d5565b505b50505092915050565b6000610e2f83836112f9565b6000806112318560006c5af43d3d93803e602a57fd5bf36021528160145273602c3d8160093d39f33d3d3d3d363d3d37363d736000526035600c2090506000602152919050565b905061123e818585611414565b95945050505050565b6000610e2f60008484611436565b60606108d76112638361148d565b90565b638b78c6d81980546001600160a01b039092169182907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0600080a355565b60006c5af43d3d93803e602a57fd5bf36021528160145273602c3d8160093d39f33d3d3d3d363d3d37363d736000526035600c84f09050806112ee5763301164256000526004601cfd5b600060215292915050565b6318fb586460045260008281526024812068fbb67fda52d4bfb8bf83036113285763f5a267f16000526004601cfd5b8261133a5768fbb67fda52d4bfb8bf92505b80195481602052806113df5781548061135a57848355600193505061140c565b848103611367575061140c565b6001830154806113825785600185015560019450505061140c565b85810361139057505061140c565b6002840154806113ac578660028601556001955050505061140c565b8681036113bb5750505061140c565b60009283526040808420600190559183528183206002905582529020600390555060075b83600052604060002080546111d557600191821c8381018690558083019182905590821b82178319559092505b505092915050565b600060ff60005350603592835260601b60015260155260556000908120915290565b60006c5af43d3d93803e602a57fd5bf36021528260145273602c3d8160093d39f33d3d3d3d363d3d37363d73600052816035600c86f59050806114815763301164256000526004601cfd5b60006021529392505050565b6318fb5864600452600081815260249020801954604051919068fbb67fda52d4bfb8bf90602084018161150757835480156115015780841415028152600184810154909250801561150157808414150260208201526002848101549092508015611501576003925083811415810260408301525b50611533565b8160011c915060005b8281101561153157848101548481141502600582901b830152600101611510565b505b8185528160051b810160405250505050919050565b6001600160a01b038116811461045057600080fd5b60006020828403121561156f57600080fd5b8135610e2f81611548565b6000806000806080858703121561159057600080fd5b843561159b81611548565b9350602085013592506040850135915060608501356115b981611548565b939692955090935050565b6020808252825182820181905260009190848201906040850190845b818110156116055783516001600160a01b0316835292840192918401916001016115e0565b50909695505050505050565b6001600160601b038116811461045057600080fd5b6000806040838503121561163957600080fd5b823561164481611548565b9150602083013561165481611611565b809150509250929050565b60006020828403121561167157600080fd5b5035919050565b60008060006060848603121561168d57600080fd5b833561169881611548565b92506020840135915060408401356116af81611548565b809150509250925092565b600080604083850312156116cd57600080fd5b82356116d881611548565b946020939093013593505050565b600080604083850312156116f957600080fd5b823561170481611548565b9150602083013561165481611548565b60008060006060848603121561172957600080fd5b833561173481611548565b9250602084013561174481611611565b929592945050506040919091013590565b6020808252825182820181905260009190848201906040850190845b8181101561160557835183529284019291840191600101611771565b60008083601f84011261179f57600080fd5b50813567ffffffffffffffff8111156117b757600080fd5b6020830191508360208260051b85010111156117d257600080fd5b9250929050565b600080600080600080608087890312156117f257600080fd5b86356117fd81611548565b9550602087013567ffffffffffffffff8082111561181a57600080fd5b6118268a838b0161178d565b9097509550604089013591508082111561183f57600080fd5b5061184c89828a0161178d565b909450925050606087013561186081611548565b809150509295509295509295565b60006020828403121561188057600080fd5b8151610e2f81611611565b60006020828403121561189d57600080fd5b8151610e2f81611548565b6000602082840312156118ba57600080fd5b5051919050565b6000602082840312156118d357600080fd5b81518015158114610e2f57600080fd5b81835260006001600160fb1b038311156118fc57600080fd5b8260051b80836020870137939093016020019392505050565b6001600160a01b0387811682528616602082015260a06040820181905260009061194290830186886118e3565b82810360608401526119558185876118e3565b838103608090940193909352505060008152602001969550505050505056fea2646970667358221220b8ab599890be8c29f239439c189b1da7626091d8a573fada4ce2c1dcae01dd5564736f6c63430008170033000000000000000000000000a779fc675db318dab004ab8d538cb320d0013f42000000000000000000000000c44b143c5abe84f418b50ad30be31afa7117a2b400000000000000000000000002d5af73501010cfc986045ff36c9ab3a4428787
Deployed Bytecode
0x6080604052600436106101b75760003560e01c806375f0ebf4116100ec578063db4c545e1161008a578063f2fde38b11610064578063f2fde38b14610493578063f724fa6f146104a6578063fd8e2c84146104c6578063fee81cf4146104e657600080fd5b8063db4c545e14610417578063e98778841461046d578063f04e283e1461048057600080fd5b80639456fbcc116100c65780639456fbcc14610397578063c952c865146103aa578063cf4c3606146103ca578063d99d13f5146103f757600080fd5b806375f0ebf41461034b5780637b9f76b51461036b5780638da5cb5b1461037e57600080fd5b806354d1f13d116101595780635fa78f80116101335780635fa78f80146102c85780636149a6bc146102e85780636437a1aa14610308578063715018a61461034357600080fd5b806354d1f13d14610280578063565068a8146102885780635d92051b146102a857600080fd5b80632854f1b2116101955780632854f1b2146101ec5780632b002e731461021e57806334a365241461023e5780635414dff01461026057600080fd5b8063256451ac146101bc57806325692962146101d157806325e16063146101d9575b600080fd5b6101cf6101ca366004611347565b610519565b005b6101cf6105e3565b6101cf6101e7366004611391565b610633565b3480156101f857600080fd5b506102016106f1565b6040516001600160a01b0390911681526020015b60405180910390f35b34801561022a57600080fd5b506101cf610239366004611391565b610764565b34801561024a57600080fd5b506102536107b4565b60405161021591906113ae565b34801561026c57600080fd5b5061020161027b3660046113fb565b610826565b6101cf610844565b34801561029457600080fd5b50600054610201906001600160a01b031681565b3480156102b457600080fd5b506101cf6102c3366004611414565b610880565b3480156102d457600080fd5b506102016102e3366004611464565b6108ef565b3480156102f457600080fd5b5061020161030336600461159a565b610a39565b34801561031457600080fd5b50610335610323366004611391565b60026020526000908152604090205481565b604051908152602001610215565b6101cf610b97565b34801561035757600080fd5b506101cf6103663660046116a5565b610ba1565b6101cf6103793660046116d1565b610bf0565b34801561038a57600080fd5b50638b78c6d81954610201565b6101cf6103a5366004611414565b610ca3565b3480156103b657600080fd5b506102016103c5366004611713565b610dcf565b3480156103d657600080fd5b506103ea6103e5366004611391565b610f52565b6040516102159190611871565b34801561040357600080fd5b506102016104123660046116a5565b610fc5565b34801561042357600080fd5b50600080546c5af43d3d93803e602a57fd5bf360219081526001600160a01b0390911660145273602c3d8160093d39f33d3d3d3d363d3d37363d7382526035600c20919052610335565b6101cf61047b366004611917565b61103b565b6101cf61048e366004611391565b6110b3565b6101cf6104a1366004611391565b6110f3565b3480156104b257600080fd5b506101cf6104c1366004611391565b61111a565b3480156104d257600080fd5b50600154610201906001600160a01b031681565b3480156104f257600080fd5b50610335610501366004611391565b63389a75e1600c908152600091909152602090205490565b610521611183565b6001600160a01b038116158061054157506001600160a01b03811661dead145b1561055f576040516312171d8360e31b815260040160405180910390fd5b604051637921219560e11b81523060048201526001600160a01b038281166024830152604482018590526064820184905260a06084830152600060a483015285169063f242432a9060c4015b600060405180830381600087803b1580156105c557600080fd5b505af11580156105d9573d6000803e3d6000fd5b5050505050505050565b60006202a30067ffffffffffffffff164201905063389a75e1600c5233600052806020600c2055337fdbf36a107da19e49527a7176a1babf963b4b0ff8cde35ee35d6cd8f1f9ac7e1d600080a250565b61063b611183565b6001600160a01b038116158061065b57506001600160a01b03811661dead145b15610679576040516312171d8360e31b815260040160405180910390fd5b6000816001600160a01b03164760405160006040518083038185875af1925050503d80600081146106c6576040519150601f19603f3d011682016040523d82523d6000602084013e6106cb565b606091505b50509050806106ed576040516312171d8360e31b815260040160405180910390fd5b5050565b60015460408051635c60da1b60e01b815290516000926001600160a01b031691635c60da1b9160048083019260209291908290030181865afa15801561073b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061075f9190611995565b905090565b61076c611183565b600080546001600160a01b0319166001600160a01b038316908117825560405190917f86587754a7c1b5416d014e448fdb1d745a6f657dcbe010541f65993a7eccfee191a250565b60015460408051630d28d94960e21b815290516060926001600160a01b0316916334a365249160048083019260009291908290030181865afa1580156107fe573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261075f91908101906119b2565b6000805461083e906001600160a01b0316833061119e565b92915050565b63389a75e1600c523360005260006020600c2055337ffa7b8eab7da67f412cc9575ed43464468f9bfbae89d1675917346ca6d8fe3c92600080a2565b3360009081526003602052604090205460ff166108b057604051636dac6a0960e01b815260040160405180910390fd5b6040516001600160a01b03808316919084169033907f60b760b15c562c07ca8faad5fab184dfc5d58d1e57d9f2fa4fd93b7380c9981b90600090a45050565b6000826001600160601b031660000361091e576001600160a01b03841660009081526002602052604090205492505b816109a957600154604051633b8cd70f60e01b81526001600160a01b0386811660048301526001600160601b038616602483015290911690633b8cd70f906044016020604051808303816000875af115801561097e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109a29190611995565b9050610a32565b60015460405163b1983f9360e01b81526001600160a01b0386811660048301526001600160601b0386166024830152604482018590529091169063b1983f93906064016020604051808303816000875af1158015610a0b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a2f9190611995565b90505b9392505050565b60008054610a4f906001600160a01b03166111fb565b6001600160a01b03811660008181526003602052604090819020805460ff19166001179055516307e1fdd960e21b815291925090631f87f76490610aab908f908f908f908f908f908f908f908f908f908f908f90600401611a92565b600060405180830381600087803b158015610ac557600080fd5b505af1158015610ad9573d6000803e3d6000fd5b50505050806001600160a01b03166331f449006040518163ffffffff1660e01b8152600401600060405180830381600087803b158015610b1857600080fd5b505af1158015610b2c573d6000803e3d6000fd5b50505050846001600160a01b0316816001600160a01b0316336001600160a01b03167ffe0b790c72ed3156887ce7a0bcfe2d4d72ecadef8a529eb9c8a40e7cff968b166000604051610b8091815260200190565b60405180910390a49b9a5050505050505050505050565b610b9f611183565b565b610ba9611183565b6001600160a01b038216600081815260026020526040808220849055518392917fecfc5799f71e577b2e57c8cec6535d089d0e392d1a5d0a704c8f327f55b0108d91a35050565b610bf8611183565b6001600160a01b0381161580610c1857506001600160a01b03811661dead145b15610c36576040516312171d8360e31b815260040160405180910390fd5b6040516323b872dd60e01b81523060048201526001600160a01b038281166024830152604482018490528416906323b872dd90606401600060405180830381600087803b158015610c8657600080fd5b505af1158015610c9a573d6000803e3d6000fd5b50505050505050565b610cab611183565b6001600160a01b0381161580610ccb57506001600160a01b03811661dead145b15610ce9576040516312171d8360e31b815260040160405180910390fd5b6040516370a0823160e01b81523060048201526001600160a01b0383169063a9059cbb90839083906370a0823190602401602060405180830381865afa158015610d37573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d5b9190611b44565b6040516001600160e01b031960e085901b1681526001600160a01b03909216600483015260248201526044016020604051808303816000875af1158015610da6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610dca9190611b5d565b505050565b60008054610de6906001600160a01b031683611208565b9050600160036000836001600160a01b03166001600160a01b0316815260200190815260200160002060006101000a81548160ff021916908315150217905550806001600160a01b0316631f87f7648e8e8e8e8e8e8e8e8e8e8e6040518c63ffffffff1660e01b8152600401610e669b9a99989796959493929190611a92565b600060405180830381600087803b158015610e8057600080fd5b505af1158015610e94573d6000803e3d6000fd5b50505050806001600160a01b03166331f449006040518163ffffffff1660e01b8152600401600060405180830381600087803b158015610ed357600080fd5b505af1158015610ee7573d6000803e3d6000fd5b50505050856001600160a01b0316816001600160a01b0316336001600160a01b03167ffe0b790c72ed3156887ce7a0bcfe2d4d72ecadef8a529eb9c8a40e7cff968b1685604051610f3a91815260200190565b60405180910390a49c9b505050505050505050505050565b6001546040516367a61b0360e11b81526001600160a01b038381166004830152606092169063cf4c360690602401600060405180830381865afa158015610f9d573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261083e9190810190611b7f565b600154604051633ddfe34f60e11b81526001600160a01b038481166004830152602482018490526000921690637bbfc69e90604401602060405180830381865afa158015611017573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a329190611995565b611043611183565b6001600160a01b038116158061106357506001600160a01b03811661dead145b15611081576040516312171d8360e31b815260040160405180910390fd5b604051631759616b60e11b81526001600160a01b03851690632eb2c2d6906105ab903090859088908890600401611c05565b6110bb611183565b63389a75e1600c52806000526020600c2080544211156110e357636f5e88186000526004601cfd5b600090556110f081611216565b50565b6110fb611183565b8060601b61111157637448fbae6000526004601cfd5b6110f081611216565b611122611183565b6001546040516296c8af60e21b81526001600160a01b0383811660048301529091169063025b22bc90602401600060405180830381600087803b15801561116857600080fd5b505af115801561117c573d6000803e3d6000fd5b5050505050565b638b78c6d819543314610b9f576382b429006000526004601cfd5b6000806111e58560006c5af43d3d93803e602a57fd5bf36021528160145273602c3d8160093d39f33d3d3d3d363d3d37363d736000526035600c2090506000602152919050565b90506111f2818585611254565b95945050505050565b600061083e600083611276565b6000610a32600084846112cb565b638b78c6d81980546001600160a01b039092169182907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0600080a355565b600060ff60005350603592835260601b60015260155260556000908120915290565b60006c5af43d3d93803e602a57fd5bf36021528160145273602c3d8160093d39f33d3d3d3d363d3d37363d736000526035600c84f09050806112c05763301164256000526004601cfd5b600060215292915050565b60006c5af43d3d93803e602a57fd5bf36021528260145273602c3d8160093d39f33d3d3d3d363d3d37363d73600052816035600c86f59050806113165763301164256000526004601cfd5b60006021529392505050565b6001600160a01b03811681146110f057600080fd5b803561134281611322565b919050565b6000806000806080858703121561135d57600080fd5b843561136881611322565b93506020850135925060408501359150606085013561138681611322565b939692955090935050565b6000602082840312156113a357600080fd5b8135610a3281611322565b6020808252825182820181905260009190848201906040850190845b818110156113ef5783516001600160a01b0316835292840192918401916001016113ca565b50909695505050505050565b60006020828403121561140d57600080fd5b5035919050565b6000806040838503121561142757600080fd5b823561143281611322565b9150602083013561144281611322565b809150509250929050565b80356001600160601b038116811461134257600080fd5b60008060006060848603121561147957600080fd5b833561148481611322565b92506114926020850161144d565b9150604084013590509250925092565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff811182821017156114e1576114e16114a2565b604052919050565b600082601f8301126114fa57600080fd5b813567ffffffffffffffff811115611514576115146114a2565b611527601f8201601f19166020016114b8565b81815284602083860101111561153c57600080fd5b816020850160208301376000918101602001919091529392505050565b803564ffffffffff8116811461134257600080fd5b803561ffff8116811461134257600080fd5b803569ffffffffffffffffffff8116811461134257600080fd5b60008060008060008060008060008060006101608c8e0312156115bc57600080fd5b67ffffffffffffffff808d3511156115d357600080fd5b6115e08e8e358f016114e9565b9b508060208e013511156115f357600080fd5b6116038e60208f01358f016114e9565b9a508060408e0135111561161657600080fd5b506116278d60408e01358e016114e9565b985061163560608d01611559565b975061164360808d0161156e565b965061165160a08d0161156e565b955061165f60c08d01611337565b945061166d60e08d01611337565b935061167c6101008d01611580565b925061168b6101208d0161144d565b91506101408c013590509295989b509295989b9093969950565b600080604083850312156116b857600080fd5b82356116c381611322565b946020939093013593505050565b6000806000606084860312156116e657600080fd5b83356116f181611322565b925060208401359150604084013561170881611322565b809150509250925092565b6000806000806000806000806000806000806101808d8f03121561173657600080fd5b67ffffffffffffffff8d35111561174c57600080fd5b6117598e8e358f016114e9565b9b5067ffffffffffffffff60208e0135111561177457600080fd5b6117848e60208f01358f016114e9565b9a5067ffffffffffffffff60408e0135111561179f57600080fd5b6117af8e60408f01358f016114e9565b99506117bd60608e01611559565b98506117cb60808e0161156e565b97506117d960a08e0161156e565b96506117e760c08e01611337565b95506117f560e08e01611337565b94506118046101008e01611580565b93506118136101208e0161144d565b92506101408d013591506101608d013590509295989b509295989b509295989b565b60008151808452602080850194506020840160005b838110156118665781518752958201959082019060010161184a565b509495945050505050565b602081526000610a326020830184611835565b600067ffffffffffffffff82111561189e5761189e6114a2565b5060051b60200190565b600082601f8301126118b957600080fd5b813560206118ce6118c983611884565b6114b8565b8083825260208201915060208460051b8701019350868411156118f057600080fd5b602086015b8481101561190c57803583529183019183016118f5565b509695505050505050565b6000806000806080858703121561192d57600080fd5b843561193881611322565b9350602085013567ffffffffffffffff8082111561195557600080fd5b611961888389016118a8565b9450604087013591508082111561197757600080fd5b50611984878288016118a8565b925050606085013561138681611322565b6000602082840312156119a757600080fd5b8151610a3281611322565b600060208083850312156119c557600080fd5b825167ffffffffffffffff8111156119dc57600080fd5b8301601f810185136119ed57600080fd5b80516119fb6118c982611884565b81815260059190911b82018301908381019087831115611a1a57600080fd5b928401925b82841015611a41578351611a3281611322565b82529284019290840190611a1f565b979650505050505050565b6000815180845260005b81811015611a7257602081850181015186830182015201611a56565b506000602082860101526020601f19601f83011685010191505092915050565b6000610160808352611aa68184018f611a4c565b90508281036020840152611aba818e611a4c565b90508281036040840152611ace818d611a4c565b64ffffffffff8c16606085015261ffff8b811660808601528a1660a08501526001600160a01b0389811660c0860152881660e085015269ffffffffffffffffffff87166101008501529150611b209050565b6001600160601b039390931661012082015261014001529998505050505050505050565b600060208284031215611b5657600080fd5b5051919050565b600060208284031215611b6f57600080fd5b81518015158114610a3257600080fd5b60006020808385031215611b9257600080fd5b825167ffffffffffffffff811115611ba957600080fd5b8301601f81018513611bba57600080fd5b8051611bc86118c982611884565b81815260059190911b82018301908381019087831115611be757600080fd5b928401925b82841015611a4157835182529284019290840190611bec565b6001600160a01b0385811682528416602082015260a060408201819052600090611c3190830185611835565b8281036060840152611c438185611835565b83810360809094019390935250506000815260200194935050505056fea26469706673582212204ef33568a3b68d46eb14ee7632a349974e5102292c3f11e2779d9406f7d6a15a64736f6c63430008170033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000a779fc675db318dab004ab8d538cb320d0013f42000000000000000000000000c44b143c5abe84f418b50ad30be31afa7117a2b400000000000000000000000002d5af73501010cfc986045ff36c9ab3a4428787
-----Decoded View---------------
Arg [0] : newOwner (address): 0xA779fC675Db318dab004Ab8D538CB320D0013F42
Arg [1] : newErc721MiyaImplementation (address): 0xC44B143C5aBe84F418B50Ad30Be31aFA7117a2B4
Arg [2] : newMiyaAVImplementation (address): 0x02d5aF73501010CFC986045Ff36C9ab3a4428787
-----Encoded View---------------
3 Constructor Arguments found :
Arg [0] : 000000000000000000000000a779fc675db318dab004ab8d538cb320d0013f42
Arg [1] : 000000000000000000000000c44b143c5abe84f418b50ad30be31afa7117a2b4
Arg [2] : 00000000000000000000000002d5af73501010cfc986045ff36c9ab3a4428787
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.