APE Price: $0.73 (+1.93%)

Contract Diff Checker

Contract Name:
MintpadFactory

Contract Source Code:

// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (proxy/Clones.sol)

pragma solidity ^0.8.0;

/**
 * @dev https://eips.ethereum.org/EIPS/eip-1167[EIP 1167] is a standard for
 * deploying minimal proxy contracts, also known as "clones".
 *
 * > To simply and cheaply clone contract functionality in an immutable way, this standard specifies
 * > a minimal bytecode implementation that delegates all calls to a known, fixed address.
 *
 * The library includes functions to deploy a proxy using either `create` (traditional deployment) or `create2`
 * (salted deterministic deployment). It also includes functions to predict the addresses of clones deployed using the
 * deterministic method.
 *
 * _Available since v3.4._
 */
library Clones {
    /**
     * @dev Deploys and returns the address of a clone that mimics the behaviour of `implementation`.
     *
     * This function uses the create opcode, which should never revert.
     */
    function clone(address implementation) internal returns (address instance) {
        /// @solidity memory-safe-assembly
        assembly {
            // Cleans the upper 96 bits of the `implementation` word, then packs the first 3 bytes
            // of the `implementation` address with the bytecode before the address.
            mstore(0x00, or(shr(0xe8, shl(0x60, implementation)), 0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000))
            // Packs the remaining 17 bytes of `implementation` with the bytecode after the address.
            mstore(0x20, or(shl(0x78, implementation), 0x5af43d82803e903d91602b57fd5bf3))
            instance := create(0, 0x09, 0x37)
        }
        require(instance != address(0), "ERC1167: create failed");
    }

    /**
     * @dev Deploys and returns the address of a clone that mimics the behaviour of `implementation`.
     *
     * This function uses the create2 opcode and a `salt` to deterministically deploy
     * the clone. Using the same `implementation` and `salt` multiple time will revert, since
     * the clones cannot be deployed twice at the same address.
     */
    function cloneDeterministic(address implementation, bytes32 salt) internal returns (address instance) {
        /// @solidity memory-safe-assembly
        assembly {
            // Cleans the upper 96 bits of the `implementation` word, then packs the first 3 bytes
            // of the `implementation` address with the bytecode before the address.
            mstore(0x00, or(shr(0xe8, shl(0x60, implementation)), 0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000))
            // Packs the remaining 17 bytes of `implementation` with the bytecode after the address.
            mstore(0x20, or(shl(0x78, implementation), 0x5af43d82803e903d91602b57fd5bf3))
            instance := create2(0, 0x09, 0x37, salt)
        }
        require(instance != address(0), "ERC1167: create2 failed");
    }

    /**
     * @dev Computes the address of a clone deployed using {Clones-cloneDeterministic}.
     */
    function predictDeterministicAddress(
        address implementation,
        bytes32 salt,
        address deployer
    ) internal pure returns (address predicted) {
        /// @solidity memory-safe-assembly
        assembly {
            let ptr := mload(0x40)
            mstore(add(ptr, 0x38), deployer)
            mstore(add(ptr, 0x24), 0x5af43d82803e903d91602b57fd5bf3ff)
            mstore(add(ptr, 0x14), implementation)
            mstore(ptr, 0x3d602d80600a3d3981f3363d3d373d3d3d363d73)
            mstore(add(ptr, 0x58), salt)
            mstore(add(ptr, 0x78), keccak256(add(ptr, 0x0c), 0x37))
            predicted := keccak256(add(ptr, 0x43), 0x55)
        }
    }

    /**
     * @dev Computes the address of a clone deployed using {Clones-cloneDeterministic}.
     */
    function predictDeterministicAddress(
        address implementation,
        bytes32 salt
    ) internal view returns (address predicted) {
        return predictDeterministicAddress(implementation, salt, address(this));
    }
}

// SPDX-License-Identifier: MIT

pragma solidity 0.8.28;

import "@openzeppelin/contracts/proxy/Clones.sol";
import "../utils/Versioning.sol";

contract MintpadFactory is Versioning {
    // Event emitted when a clone is created
    event CloneCreated(address indexed cloneAddress, address indexed creator);

    // Platform address to receive the transaction fee
    address public platformAddress;

    // Fee in wei (equivalent to $1 in ETH at a fixed rate, e.g., 1 ETH = $2000)
    uint256 public constant TRANSACTION_FEE = 0.00030 ether;

    // Set the platform address of the contract
    constructor(address _platformAddress) {
        require(_platformAddress != address(0), "MintpadFactory: Invalid platform address");
        platformAddress = _platformAddress;
        _setVersion("1.0.0");
    }

    /**
     * @dev Creates a clone of the implementation contract and transfers the transaction fee.
     * @param _implementation The address of the implementation contract to clone.
     * @param _initData Initialization data for the cloned contract.
     * @return cloneAddress The address of the newly created clone.
     */
    function clone(
        address _implementation,
        bytes memory _initData
    ) external payable returns (address cloneAddress) {
        require(_implementation != address(0), "MintpadFactory: Invalid implementation address");
        require(msg.value >= TRANSACTION_FEE, "MintpadFactory: Insufficient transaction fee");

        // Transfer the transaction fee to the platform address
        payable(platformAddress).transfer(TRANSACTION_FEE);

        // Clone the implementation contract
        cloneAddress = Clones.clone(_implementation);

        // Initialize the clone
        (bool success, ) = cloneAddress.call(_initData);
        require(success, "MintpadFactory: Failed to initialize clone");

        // Emit an event for the new clone
        emit CloneCreated(cloneAddress, msg.sender);

        // Refund any excess ETH sent
        if (msg.value > TRANSACTION_FEE) {
            payable(msg.sender).transfer(msg.value - TRANSACTION_FEE);
        }
    }

    /**
     * @dev Updates the platform address to receive the transaction fee.
     * @param _platformAddress The new platform address.
     */
    function setPlatformAddress(address _platformAddress) external {
        require(_platformAddress != address(0), "MintpadFactory: Invalid platform address");
        require(msg.sender == platformAddress, "MintpadFactory: Only current platform can update address");
        platformAddress = _platformAddress;
    }
}

// SPDX-License-Identifier: MIT

pragma solidity 0.8.28;

abstract contract Versioning {
    // The version of the contract
    string public version;

    constructor() {}

    // Set the version of the contract
    function _setVersion(string memory _version) internal {
        version = _version;
    }
}

Please enter a contract address above to load the contract details and source code.

Context size (optional):