// SPDX-License-Identifier: MIT
pragma solidity 0.8.18;
//
// ██████╗ █████╗ ███████╗███████╗██████╗ █████╗ ██████╗ ███████╗ ██████╗██╗ ██╗███████╗███╗ ███╗██╗███████╗████████╗██████╗ ██╗ ██╗ ██████╗██╗ ██╗ ██╗███╗ ██╗
// ██╔══██╗██╔══██╗██╔════╝██╔════╝██╔══██╗ ██╔══██╗██╔══██╗██╔════╝ ██╔════╝██║ ██║██╔════╝████╗ ████║██║██╔════╝╚══██╔══╝██╔══██╗╚██╗ ██╔╝ ██╔════╝██║ ██║ ██║████╗ ██║
// ██████╔╝███████║███████╗█████╗ ██║ ██║ ███████║██████╔╝█████╗ ██║ ███████║█████╗ ██╔████╔██║██║███████╗ ██║ ██████╔╝ ╚████╔╝ ██║ ██║ ██║ ██║██╔██╗ ██║
// ██╔══██╗██╔══██║╚════██║██╔══╝ ██║ ██║ ██╔══██║██╔═══╝ ██╔══╝ ██║ ██╔══██║██╔══╝ ██║╚██╔╝██║██║╚════██║ ██║ ██╔══██╗ ╚██╔╝ ██║ ██║ ██║ ██║██║╚██╗██║
// ██████╔╝██║ ██║███████║███████╗██████╔╝ ██║ ██║██║ ███████╗ ╚██████╗██║ ██║███████╗██║ ╚═╝ ██║██║███████║ ██║ ██║ ██║ ██║ ╚██████╗███████╗╚██████╔╝██║ ╚████║
// ╚═════╝ ╚═╝ ╚═╝╚══════╝╚══════╝╚═════╝ ╚═╝ ╚═╝╚═╝ ╚══════╝ ╚═════╝╚═╝ ╚═╝╚══════╝╚═╝ ╚═╝╚═╝╚══════╝ ╚═╝ ╚═╝ ╚═╝ ╚═╝ ╚═════╝╚══════╝ ╚═════╝ ╚═╝ ╚═══╝
//
// Based Ape Chemistry Clun - generated with HeyMint.xyz Launchpad - https://nft-launchpad.heymint.xyz
//
import {StorageSlot} from "@openzeppelin/contracts/utils/StorageSlot.sol";
import {IAddressRelay} from "./interfaces/IAddressRelay.sol";
import {BaseConfig, TokenConfig} from "./libraries/HeyMintStorage.sol";
contract BasedApeChemistryClun {
bytes32 internal constant _IMPLEMENTATION_SLOT =
0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;
bytes32 internal constant _ADDRESS_RELAY_SLOT =
keccak256("heymint.launchpad.1155.addressRelay");
/**
* @notice Initializes the child contract with the base implementation address and the configuration settings
* @param _name The name of the NFT
* @param _symbol The symbol of the NFT
* @param _baseConfig Base configuration settings
*/
constructor(
string memory _name,
string memory _symbol,
address _addressRelay,
address _implementation,
BaseConfig memory _baseConfig,
TokenConfig[] memory _tokenConfig
) {
StorageSlot
.getAddressSlot(_IMPLEMENTATION_SLOT)
.value = _implementation;
StorageSlot.getAddressSlot(_ADDRESS_RELAY_SLOT).value = _addressRelay;
IAddressRelay addressRelay = IAddressRelay(_addressRelay);
address implContract = addressRelay.fallbackImplAddress();
(bool success, ) = implContract.delegatecall(
abi.encodeWithSelector(
0x4efe6f3c,
_name,
_symbol,
_baseConfig,
_tokenConfig
)
);
require(success);
}
/**
* @dev Delegates the current call to nftImplementation
*
* This function does not return to its internal call site - it will return directly to the external caller.
*/
fallback() external payable {
IAddressRelay addressRelay = IAddressRelay(
StorageSlot.getAddressSlot(_ADDRESS_RELAY_SLOT).value
);
address implContract = addressRelay.getImplAddress(msg.sig);
assembly {
calldatacopy(0, 0, calldatasize())
let result := delegatecall(
gas(),
implContract,
0,
calldatasize(),
0,
0
)
returndatacopy(0, 0, returndatasize())
switch result
case 0 {
revert(0, returndatasize())
}
default {
return(0, returndatasize())
}
}
}
receive() external payable {}
}
// SPDX-License-Identifier: MIT
pragma solidity 0.8.18;
struct BaseConfig {
// Used to create a default HeyMint Launchpad URI for token metadata to save gas over setting a custom URI and increase fetch reliability
uint24 projectId;
// If true, the default CORI subscription address will be used to enforce royalties with the Operator Filter Registry
bool enforceRoyalties;
// The royalty payout percentage in basis points
uint16 royaltyBps;
// If true, HeyMint fees will be charged for minting tokens
bool heyMintFeeActive;
// The address used to sign and validate presale mints
address presaleSignerAddress;
// If enabled, tokens can be minted using an affiliate during presale.
bool presaleAffiliateMintEnabled;
// If enabled, tokens can be minted using an affiliate during public sale.
bool publicSaleAffiliateMintEnabled;
// The percentage of the sale price to be paid to an affiliate in basis points.
uint16 affiliateBasisPoints;
// The base URI for all token metadata
string uriBase;
}
struct TokenConfig {
uint16 tokenId;
// Maximum supply of tokens that can be minted
uint16 maxSupply;
// If true tokens can be minted in the public sale
bool publicSaleActive;
// The price of a token in the public sale in 1/100,000 ETH - e.g. 1 = 0.00001 ETH, 100,000 = 1 ETH - multiply by 10^13 to get correct wei amount
uint32 publicPrice;
// The number of tokens that can be minted in the public sale per address
uint8 publicMintsAllowedPerAddress;
// If enabled, automatic start and stop times for the public sale will be enforced, otherwise ignored
bool usePublicSaleTimes;
// The automatic start time for the public sale (if usePublicSaleTimes is true and publicSaleActive is true)
uint32 publicSaleStartTime;
// The automatic end time for the public sale (if usePublicSaleTimes is true and publicSaleActive is true)
uint32 publicSaleEndTime;
// If true tokens can be minted in the presale
bool presaleActive;
// The price of a token in the presale in 1/100,000 ETH
uint32 presalePrice;
// Total number of tokens available for minting in the presale
uint16 presaleMaxSupply;
// The number of tokens that can be minted in the presale per address
uint8 presaleMintsAllowedPerAddress;
// The uri for this token (defaults to using uriBase if not set).
string tokenUri;
// If enabled, automatic start and stop times for the presale will be enforced, otherwise ignored
bool usePresaleTimes;
// The automatic start time for the presale (if usePresaleTimes is true and presaleActive is true)
uint32 presaleStartTime;
// The automatic end time for the presale (if usePresaleTimes is true and presaleActive is true)
uint32 presaleEndTime;
// Free claim
address freeClaimContractAddress;
uint16 mintsPerFreeClaim;
bool freeClaimActive;
// Burn to mint
uint32 burnPayment;
uint16 mintsPerBurn;
bool burnClaimActive;
// Soulbinding
bool soulbindingActive;
// If set, the UTC timestamp in seconds until which tokens are refundable for refundPrice
uint32 refundEndsAt;
// The amount returned to a user in a token refund in 1/100,000 ETH
uint32 refundPrice;
}
struct AdvancedConfig {
// Optional address where royalties are paid out. If not set, royalties are paid to the contract owner.
address royaltyPayoutAddress;
// The respective share of funds to be sent to each address in payoutAddresses in basis points
uint16[] payoutBasisPoints;
// The addresses to which funds are sent when a token is sold. If empty, funds are sent to the contract owner.
address[] payoutAddresses;
// Permanenetly disables the ability to change payout addresses or basis points.
bool payoutAddressesFrozen;
// Custom addresses that are allowed to call the credit card minting functions.
address[] creditCardMintAddresses;
// Soulbinding
bool soulbindAdminTransfersPermanentlyDisabled;
address soulboundAdminAddress;
// The address where refunded tokens are returned. If not set, refunded tokens are sent to the contract owner.
address refundAddress;
}
struct Data {
// All token ids on the contract
uint16[] tokenIds;
// HeyMint fee to be paid per minted token (if not set, defaults to defaultHeymintFeePerToken)
uint256 heymintFeePerToken;
// Keeps track of if advanced config settings have been initialized to prevent setting multiple times
bool advancedConfigInitialized;
// Keeps track of how many of each token have been minted.
mapping(uint16 => uint16) totalSupply;
// Keeps track of how many tokens each address has minted.
mapping(address => mapping(uint16 => uint16)) tokensMintedByAddress;
// Keeps track of the number of tokens minted per email address (via credit card) during presale
mapping(bytes32 => mapping(uint256 => uint256)) tokensMintedByEmailAddress;
// If minting a token has been permanently disabled.
mapping(uint16 => bool) tokenMintingPermanentlyDisabled;
// Keeps track of token ids that have been used for free claim.
mapping(uint16 => mapping(uint256 => bool)) tokenFreeClaimUsed;
// Used to allow an admin to transfer soulbound tokens when necessary
bool soulboundAdminTransferInProgress;
mapping(uint16 => bool) tokenMetadataFrozen;
bool allMetadataFrozen;
}
struct BurnToken {
// The contract address of the token to be burned
address contractAddress;
// The type of contract - 1 = ERC-721, 2 = ERC-1155
uint8 tokenType;
// The number of tokens to burn per mint
uint8 tokensPerBurn;
// The ID of the token on an ERC-1155 contract eligible for burn; unused for ERC-721
uint16 tokenId;
}
library HeyMintStorage {
struct State {
string name;
string symbol;
BaseConfig cfg;
mapping(uint16 => TokenConfig) tokens;
mapping(uint16 => BurnToken[]) burnTokens;
AdvancedConfig advCfg;
Data data;
}
bytes32 internal constant STORAGE_SLOT =
keccak256("heymint.launchpad.storage.erc1155");
function state() internal pure returns (State storage s) {
bytes32 slot = STORAGE_SLOT;
assembly {
s.slot := slot
}
}
}
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.18;
struct Implementation {
address implAddress;
bytes4[] selectors;
}
interface IAddressRelay {
/**
* @notice Returns the fallback implementation address
*/
function fallbackImplAddress() external returns (address);
/**
* @notice Adds or updates selectors and their implementation addresses
* @param _selectors The selectors to add or update
* @param _implAddress The implementation address the selectors will point to
*/
function addOrUpdateSelectors(
bytes4[] memory _selectors,
address _implAddress
) external;
/**
* @notice Removes selectors
* @param _selectors The selectors to remove
*/
function removeSelectors(bytes4[] memory _selectors) external;
/**
* @notice Removes an implementation address and all the selectors that point to it
* @param _implAddress The implementation address to remove
*/
function removeImplAddressAndAllSelectors(address _implAddress) external;
/**
* @notice Returns the implementation address for a given function selector
* @param _functionSelector The function selector to get the implementation address for
*/
function getImplAddress(
bytes4 _functionSelector
) external view returns (address implAddress_);
/**
* @notice Returns all the implementation addresses and the selectors they support
* @return impls_ An array of Implementation structs
*/
function getAllImplAddressesAndSelectors()
external
view
returns (Implementation[] memory impls_);
/**
* @notice Return all the fucntion selectors associated with an implementation address
* @param _implAddress The implementation address to get the selectors for
*/
function getSelectorsForImplAddress(
address _implAddress
) external view returns (bytes4[] memory selectors_);
/**
* @notice Sets the fallback implementation address to use when a function selector is not found
* @param _fallbackAddress The fallback implementation address
*/
function setFallbackImplAddress(address _fallbackAddress) external;
/**
* @notice Updates the supported interfaces
* @param _interfaceId The interface ID to update
* @param _supported Whether the interface is supported or not
*/
function updateSupportedInterfaces(
bytes4 _interfaceId,
bool _supported
) external;
/**
* @notice Returns whether the interface is supported or not
* @param _interfaceId The interface ID to check
*/
function supportsInterface(
bytes4 _interfaceId
) external view returns (bool);
}
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.7.0) (utils/StorageSlot.sol)
pragma solidity ^0.8.0;
/**
* @dev Library for reading and writing primitive types to specific storage slots.
*
* Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts.
* This library helps with reading and writing to such slots without the need for inline assembly.
*
* The functions in this library return Slot structs that contain a `value` member that can be used to read or write.
*
* Example usage to set ERC1967 implementation slot:
* ```
* contract ERC1967 {
* bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;
*
* function _getImplementation() internal view returns (address) {
* return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;
* }
*
* function _setImplementation(address newImplementation) internal {
* require(Address.isContract(newImplementation), "ERC1967: new implementation is not a contract");
* StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;
* }
* }
* ```
*
* _Available since v4.1 for `address`, `bool`, `bytes32`, and `uint256`._
*/
library StorageSlot {
struct AddressSlot {
address value;
}
struct BooleanSlot {
bool value;
}
struct Bytes32Slot {
bytes32 value;
}
struct Uint256Slot {
uint256 value;
}
/**
* @dev Returns an `AddressSlot` with member `value` located at `slot`.
*/
function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) {
/// @solidity memory-safe-assembly
assembly {
r.slot := slot
}
}
/**
* @dev Returns an `BooleanSlot` with member `value` located at `slot`.
*/
function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) {
/// @solidity memory-safe-assembly
assembly {
r.slot := slot
}
}
/**
* @dev Returns an `Bytes32Slot` with member `value` located at `slot`.
*/
function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) {
/// @solidity memory-safe-assembly
assembly {
r.slot := slot
}
}
/**
* @dev Returns an `Uint256Slot` with member `value` located at `slot`.
*/
function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) {
/// @solidity memory-safe-assembly
assembly {
r.slot := slot
}
}
}
{
"compilationTarget": {
"contracts/BasedApeChemistryClun.sol": "BasedApeChemistryClun"
},
"evmVersion": "paris",
"libraries": {},
"metadata": {
"bytecodeHash": "ipfs"
},
"optimizer": {
"enabled": true,
"runs": 10000
},
"remappings": []
}
[{"inputs":[{"internalType":"string","name":"_name","type":"string"},{"internalType":"string","name":"_symbol","type":"string"},{"internalType":"address","name":"_addressRelay","type":"address"},{"internalType":"address","name":"_implementation","type":"address"},{"components":[{"internalType":"uint24","name":"projectId","type":"uint24"},{"internalType":"bool","name":"enforceRoyalties","type":"bool"},{"internalType":"uint16","name":"royaltyBps","type":"uint16"},{"internalType":"bool","name":"heyMintFeeActive","type":"bool"},{"internalType":"address","name":"presaleSignerAddress","type":"address"},{"internalType":"bool","name":"presaleAffiliateMintEnabled","type":"bool"},{"internalType":"bool","name":"publicSaleAffiliateMintEnabled","type":"bool"},{"internalType":"uint16","name":"affiliateBasisPoints","type":"uint16"},{"internalType":"string","name":"uriBase","type":"string"}],"internalType":"struct BaseConfig","name":"_baseConfig","type":"tuple"},{"components":[{"internalType":"uint16","name":"tokenId","type":"uint16"},{"internalType":"uint16","name":"maxSupply","type":"uint16"},{"internalType":"bool","name":"publicSaleActive","type":"bool"},{"internalType":"uint32","name":"publicPrice","type":"uint32"},{"internalType":"uint8","name":"publicMintsAllowedPerAddress","type":"uint8"},{"internalType":"bool","name":"usePublicSaleTimes","type":"bool"},{"internalType":"uint32","name":"publicSaleStartTime","type":"uint32"},{"internalType":"uint32","name":"publicSaleEndTime","type":"uint32"},{"internalType":"bool","name":"presaleActive","type":"bool"},{"internalType":"uint32","name":"presalePrice","type":"uint32"},{"internalType":"uint16","name":"presaleMaxSupply","type":"uint16"},{"internalType":"uint8","name":"presaleMintsAllowedPerAddress","type":"uint8"},{"internalType":"string","name":"tokenUri","type":"string"},{"internalType":"bool","name":"usePresaleTimes","type":"bool"},{"internalType":"uint32","name":"presaleStartTime","type":"uint32"},{"internalType":"uint32","name":"presaleEndTime","type":"uint32"},{"internalType":"address","name":"freeClaimContractAddress","type":"address"},{"internalType":"uint16","name":"mintsPerFreeClaim","type":"uint16"},{"internalType":"bool","name":"freeClaimActive","type":"bool"},{"internalType":"uint32","name":"burnPayment","type":"uint32"},{"internalType":"uint16","name":"mintsPerBurn","type":"uint16"},{"internalType":"bool","name":"burnClaimActive","type":"bool"},{"internalType":"bool","name":"soulbindingActive","type":"bool"},{"internalType":"uint32","name":"refundEndsAt","type":"uint32"},{"internalType":"uint32","name":"refundPrice","type":"uint32"}],"internalType":"struct TokenConfig[]","name":"_tokenConfig","type":"tuple[]"}],"stateMutability":"nonpayable","type":"constructor"},{"stateMutability":"payable","type":"fallback"},{"stateMutability":"payable","type":"receive"}]