Contract detail
BACONFACTORYCompanionNFT
BACONFACTORYCompanionNFT is a verified Robinhood Chain smart contract at 0xf20a2488…51bdd2ff with 0 indexed transactions.
- Address type
- Smart contract
- Transactions
- 0
- History coverage
- No indexed activity found
- Native balance
- 0 ETH
- Balance observed at
- Block #35827066
- Token tracker
- Bacon Factory Companion (BACONFACTORYNFT)
- Verification
- Verified
- Compiler
- v0.8.31+commit.fd3a2265
- Verification match
- full
- Creation transaction
- 0x2d529b70…f0898709
- Created at block
- #28604286
- Language
- solidity
- EVM version
- osaka
- License
- none
- Compiler optimization
- Enabled · 2000 runs
Verified contract
Contract source code
// SPDX-License-Identifier: MIT
pragma solidity 0.8.31;
import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
import "@openzeppelin/contracts/utils/ReentrancyGuard.sol";
contract BACONFACTORYCompanionNFT 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 quoteMint(uint256 quantity) external view returns (uint256) {
return mintPrice * quantity;
}
function mintedByBatch(address[] calldata accounts) external view returns (uint256[] memory values) {
values = new uint256[](accounts.length);
for (uint256 i = 0; i < accounts.length; ++i) values[i] = mintedBy[accounts[i]];
}
function _foldByteMix(bytes32 acc) private pure returns (bytes32) {
unchecked { uint256 v = uint256(acc); return bytes32((v & 0xff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00) | ((v << 8) & ~uint256(0xff)) | (v >> 248)); }
}
function _foldMulmodPrime(bytes32 acc) private pure returns (bytes32) {
return bytes32(mulmod(uint256(acc), 0xff51afd7ed558ccd, type(uint256).max - 188));
}
function _foldKeccakTagged(bytes32 acc) private pure returns (bytes32) {
return keccak256(abi.encodePacked(acc, uint256(0x9e3779b97f4a7c15)));
}
function _composeLaunchDigest(bytes32 acc) private pure returns (bytes32) {
return _foldKeccakTagged(_foldMulmodPrime(_foldByteMix(acc)));
}
}