ETH Price: $1,965.18 (-0.78%)
 

Overview

ETH Balance

0 ETH

Eth Value

$0.00

More Info

Private Name Tags

ContractCreator

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To
Destroy244720802026-02-16 21:30:235 days ago1771277423IN
0x3d3D4e4F...b686d5D82
0 ETH0.000001330.04692894
Self Immolate244720722026-02-16 21:28:475 days ago1771277327IN
0x3d3D4e4F...b686d5D82
0 ETH0.000422320.04201181

Latest 2 internal transactions

Advanced mode:
Parent Transaction Hash Method Block
From
To
Transfer244720802026-02-16 21:30:235 days ago1771277423
0x3d3D4e4F...b686d5D82
0 ETH
0x60806040244720722026-02-16 21:28:475 days ago1771277327
0x3d3D4e4F...b686d5D82
 Contract Creation0 ETH
Loading...
Loading
Loading...
Loading
Cross-Chain Transactions

Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

Validator Index Block Amount
View All Withdrawals

Transaction Hash Block Value Eth2 PubKey Valid
View All Deposits
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
OnChainMonstersFaucet

Compiler Version
v0.8.30+commit.73712a01

Optimization Enabled:
Yes with 200 runs

Other Settings:
prague EvmVersion
// SPDX-License-Identifier: MIT
pragma solidity >=0.8.2 <0.9.0;

interface IOCM {
    function mintMonster() external;
    function transferFrom(address from, address to, uint256 tokenId) external;
    function balanceOf(address owner) external view returns (uint256);
    function tokenOfOwnerByIndex(
        address owner,
        uint256 index
    ) external view returns (uint256);
    function burnForMint(uint256 tokenId) external;
    function totalSupply() external view returns (uint256);
}

interface IOCMD {
    function approve(address spender, uint256 amount) external returns (bool);
    function transfer(address to, uint256 amount) external returns (bool);
    function transferFrom(
        address from,
        address to,
        uint256 amount
    ) external returns (bool);
    function balanceOf(address) external view returns (uint256);
    function allowance(
        address owner,
        address spender
    ) external view returns (uint256);
}

contract TempMinter {
    constructor(
        address _ocm,
        address _ocmd,
        address mintToAddr,
        address remainingBalanceToAddr,
        uint256 _amount,
        uint256 _doughPerToken
    ) {
        // All operations must happen in constructor because only the constructor is allowed to call mintMonster
        // Once the constructor finalizes, the contract cannot call mintMonster anymore

        IOCM ocm = IOCM(_ocm);
        IOCMD ocmd = IOCMD(_ocmd);

        // Calculate total tokens needed for all monsters
        uint256 totalTokens = _amount * _doughPerToken * 1 ether;

        // Approve OCM to spend all OCMD tokens at once
        ocmd.approve(address(ocm), totalTokens);

        // Mint and transfer
        for (uint256 i = 0; i < _amount; ) {
            ocm.mintMonster();

            uint256 tokenId = ocm.tokenOfOwnerByIndex(address(this), 0);
            ocm.transferFrom(address(this), mintToAddr, tokenId);

            unchecked {
                ++i;
            }
        }

        // Return any unused OCMD tokens back to the specified address
        uint256 remainingBalance = ocmd.balanceOf(address(this));
        if (remainingBalance > 0) {
            ocmd.transfer(remainingBalanceToAddr, remainingBalance);
        }
    }
}

contract TempImmolator {
    constructor(
        address _ocm,
        address _tokenOwner,
        uint256 _tokenId,
        uint256 _rounds
    ) {
        // All operations must happen in constructor because only the constructor is allowed to call burnForMint
        // Once the constructor finalizes, the contract cannot call burnForMint anymore

        IOCM ocm = IOCM(_ocm);

        uint256 currentTokenId = _tokenId;

        // Perform the immolation rounds
        for (uint256 i = 0; i < _rounds; ) {
            // Burn the current token (this will mint a new one)
            ocm.burnForMint(currentTokenId);

            // Get the newly minted token ID (it will be the latest one)
            currentTokenId = ocm.totalSupply() - 1;

            unchecked {
                ++i;
            }
        }

        // Transfer the final token back to the owner
        ocm.transferFrom(address(this), _tokenOwner, currentTokenId);
    }
}

contract OnChainMonstersFaucet {
    address public owner;
    bool public isClosed;
    IOCM public OCM = IOCM(0xaA5D0f2E6d008117B16674B0f00B6FCa46e3EFC4);
    IOCMD public OCMD = IOCMD(0x10971797FcB9925d01bA067e51A6F8333Ca000B1);

    // Track how many tokens each address has minted through publicMint
    mapping(address => uint256) public publicMintCount;
    uint256 public constant MAX_PUBLIC_MINT_PER_ADDRESS = 20;
    uint256 public constant MAX_PUBLIC_MINT_PER_CALL = 10;
    uint256 public constant PUBLIC_MINT_DOUGH_PER_TOKEN = 4;

    modifier onlyOwner() {
        require(msg.sender == owner, "Not the owner");
        _;
    }

    modifier notClosed() {
        require(!isClosed, "Faucet is closed");
        _;
    }

    constructor() {
        owner = msg.sender;
    }

    /*
    function mintWithMyOwnTokens(uint256 amount, uint256 doughPerToken) external notClosed {
        // Transfer tokens from the caller to this contract
        uint256 requiredTokens = amount * doughPerToken * 1 ether;
        OCMD.transferFrom(msg.sender, address(this), requiredTokens);
        
        // Call internal minting function
        _mintInternal(msg.sender, msg.sender, amount, doughPerToken);
    }

    function publicMint(uint256 amount) external notClosed {
        require(amount > 0, "Amount must be greater than 0");
        require(amount <= MAX_PUBLIC_MINT_PER_CALL, "Max mints per call exceeded");
        require(publicMintCount[msg.sender] + amount <= MAX_PUBLIC_MINT_PER_ADDRESS, "Exceeds maximum mint limit per address");
        
        publicMintCount[msg.sender] += amount;

        _mintInternal(msg.sender, address(this), amount, PUBLIC_MINT_DOUGH_PER_TOKEN);
    }

    function _mintInternal(address mintToAddr, address remainingBalanceToAddr, uint256 amount, uint256 doughPerToken) internal {
        // Use CREATE2 to predict the single TempMinter address
        bytes32 salt = keccak256(abi.encodePacked(msg.sender, block.timestamp, amount, doughPerToken));
        address predictedAddress = address(uint160(uint256(keccak256(abi.encodePacked(
            bytes1(0xff),
            address(this),
            salt,
            keccak256(abi.encodePacked(
                type(TempMinter).creationCode,
                abi.encode(address(OCM), address(OCMD), mintToAddr, remainingBalanceToAddr, amount, doughPerToken)
            ))
        )))));
        
        // Transfer all required tokens to the predicted address in one go
        uint256 requiredTokens = amount * doughPerToken * 1 ether;
        OCMD.transfer(predictedAddress, requiredTokens);
        
        // Create single TempMinter contract that will mint all monsters
        TempMinter tempMinter = new TempMinter{salt: salt}(address(OCM), address(OCMD), mintToAddr, remainingBalanceToAddr, amount, doughPerToken);

        // Validate that the actual deployed address matches our prediction
        require(address(tempMinter) == predictedAddress, "Address prediction mismatch");
    }

    function approveDough() external onlyOwner {
        OCMD.approve(address(OCM), 100000 ether);
    }
    */

    function selfImmolate(uint256 tokenId, uint256 rounds) external notClosed {
        // Use CREATE2 to predict the single TempImmolator address
        bytes32 salt = keccak256(
            abi.encodePacked(msg.sender, block.timestamp, tokenId, rounds)
        );
        address predictedAddress = address(
            uint160(
                uint256(
                    keccak256(
                        abi.encodePacked(
                            bytes1(0xff),
                            address(this),
                            salt,
                            keccak256(
                                abi.encodePacked(
                                    type(TempImmolator).creationCode,
                                    abi.encode(
                                        address(OCM),
                                        msg.sender,
                                        tokenId,
                                        rounds
                                    )
                                )
                            )
                        )
                    )
                )
            )
        );

        // Transfer the token to the predicted address
        OCM.transferFrom(msg.sender, predictedAddress, tokenId);

        // Create single TempImmolator contract that will handle the immolation
        TempImmolator tempImmolator = new TempImmolator{salt: salt}(
            address(OCM),
            msg.sender,
            tokenId,
            rounds
        );

        // Validate that the actual deployed address matches our prediction
        require(
            address(tempImmolator) == predictedAddress,
            "Address prediction mismatch"
        );
    }

    function close() external onlyOwner {
        isClosed = true;
    }

    function withdraw() external onlyOwner {
        payable(owner).transfer(address(this).balance);
    }

    function destroy() public onlyOwner {
        selfdestruct(payable(owner));
    }
}

Settings
{
  "remappings": [
    "forge-std/=lib/forge-std/src/"
  ],
  "optimizer": {
    "enabled": true,
    "runs": 200
  },
  "metadata": {
    "useLiteralContent": false,
    "bytecodeHash": "ipfs",
    "appendCBOR": true
  },
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "devdoc",
        "userdoc",
        "metadata",
        "abi"
      ]
    }
  },
  "evmVersion": "prague",
  "viaIR": false
}

Contract Security Audit

Contract ABI

API
[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"MAX_PUBLIC_MINT_PER_ADDRESS","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_PUBLIC_MINT_PER_CALL","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"OCM","outputs":[{"internalType":"contract IOCM","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"OCMD","outputs":[{"internalType":"contract IOCMD","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PUBLIC_MINT_DOUGH_PER_TOKEN","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"close","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"destroy","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"isClosed","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"publicMintCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"rounds","type":"uint256"}],"name":"selfImmolate","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"}]

6080604052600180546001600160a01b031990811673aa5d0f2e6d008117b16674b0f00b6fca46e3efc417909155600280549091167310971797fcb9925d01ba067e51a6f8333ca000b11790553480156056575f5ffd5b505f80546001600160a01b03191633179055610873806100755f395ff3fe608060405234801561000f575f5ffd5b50600436106100b1575f3560e01c806383197ef01161006e57806383197ef0146101285780638c2abb28146101305780638da5cb5b1461014357806396330b5f14610155578063c2b6b58c14610174578063d3b08fe014610197575f5ffd5b8063125eb42c146100b5578063270afaa1146100e55780633ccfd60b146100fb57806343d726d6146101055780635380afbb1461010d578063812dbb0414610115575b5f5ffd5b6001546100c8906001600160a01b031681565b6040516001600160a01b0390911681526020015b60405180910390f35b6100ed600481565b6040519081526020016100dc565b61010361019f565b005b61010361020b565b6100ed601481565b6002546100c8906001600160a01b031681565b610103610248565b61010361013e366004610541565b61027e565b5f546100c8906001600160a01b031681565b6100ed610163366004610561565b60036020525f908152604090205481565b5f5461018790600160a01b900460ff1681565b60405190151581526020016100dc565b6100ed600a81565b5f546001600160a01b031633146101d15760405162461bcd60e51b81526004016101c89061058e565b60405180910390fd5b5f80546040516001600160a01b03909116914780156108fc02929091818181858888f19350505050158015610208573d5f5f3e3d5ffd5b50565b5f546001600160a01b031633146102345760405162461bcd60e51b81526004016101c89061058e565b5f805460ff60a01b1916600160a01b179055565b5f546001600160a01b031633146102715760405162461bcd60e51b81526004016101c89061058e565b5f546001600160a01b0316ff5b5f54600160a01b900460ff16156102ca5760405162461bcd60e51b815260206004820152601060248201526f11985d58d95d081a5cc818db1bdcd95960821b60448201526064016101c8565b6040516bffffffffffffffffffffffff193360601b16602082015242603482015260548101839052607481018290525f906094016040516020818303038152906040528051906020012090505f60ff60f81b30836040518060200161032e90610534565b601f1982820381018352601f9091011660408181526001546001600160a01b031660208301523390820152606081018990526080810188905260a00160408051601f198184030181529082905261038892916020016105cc565b604051602081830303815290604052805190602001206040516020016103e594939291906001600160f81b031994909416845260609290921b6bffffffffffffffffffffffff191660018401526015830152603582015260550190565b60408051808303601f190181529082905280516020909101206001546323b872dd60e01b83523360048401526001600160a01b0380831660248501526044840188905291935016906323b872dd906064015f604051808303815f87803b15801561044d575f5ffd5b505af115801561045f573d5f5f3e3d5ffd5b505050505f8260015f9054906101000a90046001600160a01b031633878760405161048990610534565b6001600160a01b039485168152939092166020840152604083015260608201526080018190604051809103905ff59050801580156104c9573d5f5f3e3d5ffd5b509050816001600160a01b0316816001600160a01b03161461052d5760405162461bcd60e51b815260206004820152601b60248201527f416464726573732070726564696374696f6e206d69736d61746368000000000060448201526064016101c8565b5050505050565b610255806105e983390190565b5f5f60408385031215610552575f5ffd5b50508035926020909101359150565b5f60208284031215610571575f5ffd5b81356001600160a01b0381168114610587575f5ffd5b9392505050565b6020808252600d908201526c2737ba103a34329037bbb732b960991b604082015260600190565b5f81518060208401855e5f93019283525090919050565b5f6105e06105da83866105b5565b846105b5565b94935050505056fe608060405234801561000f575f5ffd5b5060405161025538038061025583398101604081905261002e9161018f565b83825f5b838110156101055760405163c4ef71c760e01b8152600481018390526001600160a01b0384169063c4ef71c7906024015f604051808303815f87803b158015610079575f5ffd5b505af115801561008b573d5f5f3e3d5ffd5b505050506001836001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156100cd573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906100f191906101cf565b6100fb91906101e6565b9150600101610032565b506040516323b872dd60e01b81523060048201526001600160a01b038681166024830152604482018390528316906323b872dd906064015f604051808303815f87803b158015610153575f5ffd5b505af1158015610165573d5f5f3e3d5ffd5b5050505050505050505061020b565b80516001600160a01b038116811461018a575f5ffd5b919050565b5f5f5f5f608085870312156101a2575f5ffd5b6101ab85610174565b93506101b960208601610174565b6040860151606090960151949790965092505050565b5f602082840312156101df575f5ffd5b5051919050565b8181038181111561020557634e487b7160e01b5f52601160045260245ffd5b92915050565b603e806102175f395ff3fe60806040525f5ffdfea2646970667358221220cfe1301d9f43590613fe96f78d028472ee87fd30e93622bf9ef6757c9d6593e364736f6c634300081e0033a2646970667358221220457944092765e261f77d6fb0251d1a6266f0ec5c8cacab819b48a467ecf9551764736f6c634300081e0033

Deployed Bytecode

0x608060405234801561000f575f5ffd5b50600436106100b1575f3560e01c806383197ef01161006e57806383197ef0146101285780638c2abb28146101305780638da5cb5b1461014357806396330b5f14610155578063c2b6b58c14610174578063d3b08fe014610197575f5ffd5b8063125eb42c146100b5578063270afaa1146100e55780633ccfd60b146100fb57806343d726d6146101055780635380afbb1461010d578063812dbb0414610115575b5f5ffd5b6001546100c8906001600160a01b031681565b6040516001600160a01b0390911681526020015b60405180910390f35b6100ed600481565b6040519081526020016100dc565b61010361019f565b005b61010361020b565b6100ed601481565b6002546100c8906001600160a01b031681565b610103610248565b61010361013e366004610541565b61027e565b5f546100c8906001600160a01b031681565b6100ed610163366004610561565b60036020525f908152604090205481565b5f5461018790600160a01b900460ff1681565b60405190151581526020016100dc565b6100ed600a81565b5f546001600160a01b031633146101d15760405162461bcd60e51b81526004016101c89061058e565b60405180910390fd5b5f80546040516001600160a01b03909116914780156108fc02929091818181858888f19350505050158015610208573d5f5f3e3d5ffd5b50565b5f546001600160a01b031633146102345760405162461bcd60e51b81526004016101c89061058e565b5f805460ff60a01b1916600160a01b179055565b5f546001600160a01b031633146102715760405162461bcd60e51b81526004016101c89061058e565b5f546001600160a01b0316ff5b5f54600160a01b900460ff16156102ca5760405162461bcd60e51b815260206004820152601060248201526f11985d58d95d081a5cc818db1bdcd95960821b60448201526064016101c8565b6040516bffffffffffffffffffffffff193360601b16602082015242603482015260548101839052607481018290525f906094016040516020818303038152906040528051906020012090505f60ff60f81b30836040518060200161032e90610534565b601f1982820381018352601f9091011660408181526001546001600160a01b031660208301523390820152606081018990526080810188905260a00160408051601f198184030181529082905261038892916020016105cc565b604051602081830303815290604052805190602001206040516020016103e594939291906001600160f81b031994909416845260609290921b6bffffffffffffffffffffffff191660018401526015830152603582015260550190565b60408051808303601f190181529082905280516020909101206001546323b872dd60e01b83523360048401526001600160a01b0380831660248501526044840188905291935016906323b872dd906064015f604051808303815f87803b15801561044d575f5ffd5b505af115801561045f573d5f5f3e3d5ffd5b505050505f8260015f9054906101000a90046001600160a01b031633878760405161048990610534565b6001600160a01b039485168152939092166020840152604083015260608201526080018190604051809103905ff59050801580156104c9573d5f5f3e3d5ffd5b509050816001600160a01b0316816001600160a01b03161461052d5760405162461bcd60e51b815260206004820152601b60248201527f416464726573732070726564696374696f6e206d69736d61746368000000000060448201526064016101c8565b5050505050565b610255806105e983390190565b5f5f60408385031215610552575f5ffd5b50508035926020909101359150565b5f60208284031215610571575f5ffd5b81356001600160a01b0381168114610587575f5ffd5b9392505050565b6020808252600d908201526c2737ba103a34329037bbb732b960991b604082015260600190565b5f81518060208401855e5f93019283525090919050565b5f6105e06105da83866105b5565b846105b5565b94935050505056fe608060405234801561000f575f5ffd5b5060405161025538038061025583398101604081905261002e9161018f565b83825f5b838110156101055760405163c4ef71c760e01b8152600481018390526001600160a01b0384169063c4ef71c7906024015f604051808303815f87803b158015610079575f5ffd5b505af115801561008b573d5f5f3e3d5ffd5b505050506001836001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156100cd573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906100f191906101cf565b6100fb91906101e6565b9150600101610032565b506040516323b872dd60e01b81523060048201526001600160a01b038681166024830152604482018390528316906323b872dd906064015f604051808303815f87803b158015610153575f5ffd5b505af1158015610165573d5f5f3e3d5ffd5b5050505050505050505061020b565b80516001600160a01b038116811461018a575f5ffd5b919050565b5f5f5f5f608085870312156101a2575f5ffd5b6101ab85610174565b93506101b960208601610174565b6040860151606090960151949790965092505050565b5f602082840312156101df575f5ffd5b5051919050565b8181038181111561020557634e487b7160e01b5f52601160045260245ffd5b92915050565b603e806102175f395ff3fe60806040525f5ffdfea2646970667358221220cfe1301d9f43590613fe96f78d028472ee87fd30e93622bf9ef6757c9d6593e364736f6c634300081e0033a2646970667358221220457944092765e261f77d6fb0251d1a6266f0ec5c8cacab819b48a467ecf9551764736f6c634300081e0033

Block Uncle Number Difficulty Gas Used Reward
View All Uncles
Loading...
Loading
Loading...
Loading
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.