Robinhood MainnetChain ID: 4663
Contract detail

RISECompanionNFT

RISECompanionNFT is a verified Robinhood Chain smart contract at 0xadbbb76e…979bf371 with 0 indexed transactions.

Address type
Smart contract
Transactions
0
History coverage
No indexed activity found
Verification
Verified
Compiler
v0.8.34+commit.80d5c536
Verification match
full
Creation transaction
0x2dcc8d9e…033040af
Created at block
#28540660
Language
solidity
EVM version
osaka
License
none
Compiler optimization
Enabled · 5000 runs
Verified contract

Contract source code

// SPDX-License-Identifier: MIT
pragma solidity 0.8.34;
import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
import "@openzeppelin/contracts/utils/ReentrancyGuard.sol";
contract RISECompanionNFT is ERC721, ReentrancyGuard {
    error InvalidConfiguration();
    error SaleClosed();
    error InvalidQuantity();
    error SupplyExceeded();
    error WalletLimitExceeded();
    error IncorrectPayment();
    error NothingToWithdraw();
    error NativeTransferFailed();
    error ZeroLaunchFingerprint();
    error ScheduleOverflow();
    string private _baseTokenUri;
    uint256 public immutable mintPrice;
    uint256 public immutable maxSupply;
    uint256 public immutable maxPerWallet;
    uint256 public immutable saleStart;
    uint256 public immutable saleEnd;
    address payable public immutable proceedsRecipient;
    bytes32 public immutable launchFingerprint;
    uint256 public totalMinted;
    mapping(address => uint256) public mintedBy;
    event Minted(address indexed buyer, uint256 indexed firstTokenId, uint256 quantity, uint256 paid);
    event ProceedsWithdrawn(address indexed recipient, uint256 amount);
    constructor(
        string memory name_,
        string memory symbol_,
        string memory baseTokenUri_,
        uint256 mintPrice_,
        uint256 maxSupply_,
        uint256 maxPerWallet_,
        uint256 mintStartDelay_,
        uint256 mintDuration_,
        address payable proceedsRecipient_,
        bytes32 launchFingerprint_
    ) ERC721(name_, symbol_) {
        if (bytes(name_).length == 0 || bytes(symbol_).length == 0) revert InvalidConfiguration();
        if (maxSupply_ == 0 || maxPerWallet_ == 0 || maxPerWallet_ > maxSupply_) revert InvalidConfiguration();
        if (mintDuration_ == 0 || proceedsRecipient_ == address(0)) revert InvalidConfiguration();
        if (mintStartDelay_ > type(uint256).max - block.timestamp) revert ScheduleOverflow();
        uint256 computedSaleStart = block.timestamp + mintStartDelay_;
        if (mintDuration_ > type(uint256).max - computedSaleStart) revert ScheduleOverflow();
        if (launchFingerprint_ == bytes32(0)) revert ZeroLaunchFingerprint();
        if (_composeLaunchDigest(launchFingerprint_) == bytes32(0)) revert ZeroLaunchFingerprint();
        _baseTokenUri = baseTokenUri_;
        mintPrice = mintPrice_;
        maxSupply = maxSupply_;
        maxPerWallet = maxPerWallet_;
        saleStart = computedSaleStart;
        saleEnd = computedSaleStart + mintDuration_;
        proceedsRecipient = proceedsRecipient_;
        launchFingerprint = launchFingerprint_;
    }
    function mint(uint256 quantity) external payable nonReentrant returns (uint256 firstTokenId) {
        if (block.timestamp < saleStart || block.timestamp > saleEnd) revert SaleClosed();
        if (quantity == 0) revert InvalidQuantity();
        if (totalMinted + quantity > maxSupply) revert SupplyExceeded();
        if (mintedBy[msg.sender] + quantity > maxPerWallet) revert WalletLimitExceeded();
        if (msg.value != mintPrice * quantity) revert IncorrectPayment();
        firstTokenId = totalMinted + 1;
        totalMinted += quantity;
        mintedBy[msg.sender] += quantity;
        for (uint256 i = 0; i < quantity; ++i) _safeMint(msg.sender, firstTokenId + i);
        emit Minted(msg.sender, firstTokenId, quantity, msg.value);
    }
    function withdrawProceeds() external nonReentrant {
        uint256 amount = address(this).balance;
        if (amount == 0) revert NothingToWithdraw();
        (bool sent, ) = proceedsRecipient.call{value: amount}("");
        if (!sent) revert NativeTransferFailed();
        emit ProceedsWithdrawn(proceedsRecipient, amount);
    }
    function launchId() external view returns (bytes32) {
        if (_composeLaunchDigest(launchFingerprint) == bytes32(0)) revert ZeroLaunchFingerprint();
        return launchFingerprint;
    }
    function _baseURI() internal view override returns (string memory) {
        return _baseTokenUri;
    }

    function remainingSupply() external view returns (uint256) {
        return maxSupply - totalMinted;
    }
    function _foldKeccakPacked(bytes32 acc) private pure returns (bytes32) {
        return keccak256(abi.encodePacked(acc));
    }

    function _foldSwapHalves(bytes32 acc) private pure returns (bytes32) {
        unchecked { uint256 v = uint256(acc); return bytes32((v << 128) | (v >> 128)); }
    }

    function _foldRotateRight11(bytes32 acc) private pure returns (bytes32) {
        unchecked { uint256 v = uint256(acc); return bytes32((v >> 11) | (v << 245)); }
    }

    function _composeLaunchDigest(bytes32 acc) private pure returns (bytes32) {
        return _foldRotateRight11(_foldSwapHalves(_foldKeccakPacked(acc)));
    }
}