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
- Token tracker
- Rise Companion (RISENFT)
- 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)));
}
}