Contract Source Code:
File 1 of 1 : GobPepe
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
contract GobPepe {
// Token metadata
string private _name = "Gob Pepe";
string private _symbol = "GOBPEPE";
string private _baseTokenURI;
uint256 public totalSupply = 0;
uint256 public maxSupply = 2222;
uint256 public maxMintAmountPerTx = 30;
uint256 public cost = 1 ether; // Mint cost in native currency
bool public paused = false;
// Owner of the contract
address public owner;
// Mappings for token data
mapping(uint256 => address) private _owners;
mapping(address => uint256) private _balances;
mapping(uint256 => address) private _tokenApprovals;
mapping(address => mapping(address => bool)) private _operatorApprovals;
// Royalties
address private _royaltyReceiver;
uint96 private constant _royaltyFeeNumerator = 500; // 5% royalties
// Reentrancy protection
uint256 private constant _NOT_ENTERED = 1;
uint256 private constant _ENTERED = 2;
uint256 private _status;
// Events
event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);
event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);
event ApprovalForAll(address indexed owner, address indexed operator, bool approved);
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
// Modifiers
modifier onlyOwner() {
require(msg.sender == owner, "Caller is not the owner");
_;
}
modifier whenNotPaused() {
require(!paused, "Contract is paused");
_;
}
modifier nonReentrant() {
require(_status != _ENTERED, "ReentrancyGuard: reentrant call");
_status = _ENTERED;
_;
_status = _NOT_ENTERED;
}
constructor(string memory baseURI) {
owner = msg.sender; // Set the deployer as the owner
_baseTokenURI = baseURI; // Set the base URI
_royaltyReceiver = owner; // Set the default royalty receiver as the owner
_status = _NOT_ENTERED; // Initialize reentrancy guard
}
// Public mint function
function mint(uint256 _mintAmount) public payable whenNotPaused nonReentrant {
require(_mintAmount > 0, "Invalid mint amount");
require(_mintAmount <= maxMintAmountPerTx, "Exceeds max mint amount per transaction");
require(totalSupply + _mintAmount <= maxSupply, "Max supply exceeded");
require(msg.value >= cost * _mintAmount, "Insufficient funds");
for (uint256 i = 0; i < _mintAmount; i++) {
_mint(msg.sender, totalSupply + 1);
}
}
// Admin mint function
function mintForAddress(uint256 _mintAmount, address _receiver) public onlyOwner {
require(totalSupply + _mintAmount <= maxSupply, "Max supply exceeded");
for (uint256 i = 0; i < _mintAmount; i++) {
_mint(_receiver, totalSupply + 1);
}
}
// Internal mint function
function _mint(address to, uint256 tokenId) internal {
require(to != address(0), "Mint to the zero address");
require(_owners[tokenId] == address(0), "Token already minted");
_balances[to] += 1;
_owners[tokenId] = to;
totalSupply += 1;
emit Transfer(address(0), to, tokenId);
}
// Token metadata
function name() public view returns (string memory) {
return _name;
}
function symbol() public view returns (string memory) {
return _symbol;
}
function tokenURI(uint256 tokenId) public view returns (string memory) {
require(_owners[tokenId] != address(0), "Token does not exist");
return string(abi.encodePacked(_baseTokenURI, uint256ToString(tokenId), ".json"));
}
// Pause/unpause minting
function setPaused(bool _state) public onlyOwner {
paused = _state;
}
// Approve a token for transfer
function approve(address to, uint256 tokenId) public {
address tokenOwner = _owners[tokenId];
require(msg.sender == tokenOwner || isApprovedForAll(tokenOwner, msg.sender), "Not authorized");
_tokenApprovals[tokenId] = to;
emit Approval(tokenOwner, to, tokenId);
}
// Get approved address for a token
function getApproved(uint256 tokenId) public view returns (address) {
return _tokenApprovals[tokenId];
}
// Set operator approval for all tokens
function setApprovalForAll(address operator, bool approved) public {
_operatorApprovals[msg.sender][operator] = approved;
emit ApprovalForAll(msg.sender, operator, approved);
}
// Check if operator is approved for all tokens
function isApprovedForAll(address tokenOwner, address operator) public view returns (bool) {
return _operatorApprovals[tokenOwner][operator];
}
// Withdraw contract balance
function withdraw() public onlyOwner nonReentrant {
(bool success, ) = owner.call{value: address(this).balance}("");
require(success, "Withdraw failed");
}
// Ownership transfer
function transferOwnership(address newOwner) public onlyOwner {
require(newOwner != address(0), "New owner is the zero address");
emit OwnershipTransferred(owner, newOwner);
owner = newOwner;
}
// ERC-2981 Royalties
function setRoyaltyReceiver(address receiver) public onlyOwner {
require(receiver != address(0), "Receiver cannot be the zero address");
_royaltyReceiver = receiver;
}
function royaltyInfo(uint256 /* tokenId */, uint256 salePrice)
external
view
returns (address, uint256)
{
uint256 royaltyAmount = (salePrice * _royaltyFeeNumerator) / 10000; //
return (_royaltyReceiver, royaltyAmount);
}
// ERC-721 interface support
function supportsInterface(bytes4 interfaceId) public pure returns (bool) {
return
interfaceId == 0x80ac58cd || // ERC-721
interfaceId == 0x5b5e139f || // ERC-721 Metadata
interfaceId == 0x2a55205a; // ERC-2981 (Royalties)
}
// Utility functions
function uint256ToString(uint256 value) internal pure returns (string memory) {
if (value == 0) {
return "0";
}
uint256 temp = value;
uint256 digits;
while (temp != 0) {
digits++;
temp /= 10;
}
bytes memory buffer = new bytes(digits);
while (value != 0) {
digits -= 1;
buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));
value /= 10;
}
return string(buffer);
}
}