Skip to content

Instantly share code, notes, and snippets.

@wcjohnson11
Last active June 17, 2022 06:26
Show Gist options
  • Save wcjohnson11/695fc68f312c1e43919b8020fba7d51f to your computer and use it in GitHub Desktop.
Save wcjohnson11/695fc68f312c1e43919b8020fba7d51f to your computer and use it in GitHub Desktop.
[
{
"inputs": [
{
"internalType": "address",
"name": "_openSeaProxyRegistryAddress",
"type": "address"
}
],
"stateMutability": "nonpayable",
"type": "constructor"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "owner",
"type": "address"
},
{
"indexed": true,
"internalType": "address",
"name": "approved",
"type": "address"
},
{
"indexed": true,
"internalType": "uint256",
"name": "tokenId",
"type": "uint256"
}
],
"name": "Approval",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "owner",
"type": "address"
},
{
"indexed": true,
"internalType": "address",
"name": "operator",
"type": "address"
},
{
"indexed": false,
"internalType": "bool",
"name": "approved",
"type": "bool"
}
],
"name": "ApprovalForAll",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "previousOwner",
"type": "address"
},
{
"indexed": true,
"internalType": "address",
"name": "newOwner",
"type": "address"
}
],
"name": "OwnershipTransferred",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "bytes32",
"name": "role",
"type": "bytes32"
},
{
"indexed": true,
"internalType": "bytes32",
"name": "previousAdminRole",
"type": "bytes32"
},
{
"indexed": true,
"internalType": "bytes32",
"name": "newAdminRole",
"type": "bytes32"
}
],
"name": "RoleAdminChanged",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "bytes32",
"name": "role",
"type": "bytes32"
},
{
"indexed": true,
"internalType": "address",
"name": "account",
"type": "address"
},
{
"indexed": true,
"internalType": "address",
"name": "sender",
"type": "address"
}
],
"name": "RoleGranted",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "bytes32",
"name": "role",
"type": "bytes32"
},
{
"indexed": true,
"internalType": "address",
"name": "account",
"type": "address"
},
{
"indexed": true,
"internalType": "address",
"name": "sender",
"type": "address"
}
],
"name": "RoleRevoked",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "from",
"type": "address"
},
{
"indexed": true,
"internalType": "address",
"name": "to",
"type": "address"
},
{
"indexed": true,
"internalType": "uint256",
"name": "tokenId",
"type": "uint256"
}
],
"name": "Transfer",
"type": "event"
},
{
"inputs": [],
"name": "DEFAULT_ADMIN_ROLE",
"outputs": [
{
"internalType": "bytes32",
"name": "",
"type": "bytes32"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "MANAGER_ROLE",
"outputs": [
{
"internalType": "bytes32",
"name": "",
"type": "bytes32"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "SALE_PRICE",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "to",
"type": "address"
},
{
"internalType": "uint256",
"name": "tokenId",
"type": "uint256"
}
],
"name": "approve",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "owner",
"type": "address"
}
],
"name": "balanceOf",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "claimAirdrops",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "tokenId",
"type": "uint256"
},
{
"internalType": "address",
"name": "_to",
"type": "address"
}
],
"name": "crossmint",
"outputs": [],
"stateMutability": "payable",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "tokenId",
"type": "uint256"
}
],
"name": "getApproved",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "getBaseURI",
"outputs": [
{
"internalType": "string",
"name": "",
"type": "string"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "bytes32",
"name": "role",
"type": "bytes32"
}
],
"name": "getRoleAdmin",
"outputs": [
{
"internalType": "bytes32",
"name": "",
"type": "bytes32"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "bytes32",
"name": "role",
"type": "bytes32"
},
{
"internalType": "address",
"name": "account",
"type": "address"
}
],
"name": "grantRole",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "bytes32",
"name": "role",
"type": "bytes32"
},
{
"internalType": "address",
"name": "account",
"type": "address"
}
],
"name": "hasRole",
"outputs": [
{
"internalType": "bool",
"name": "",
"type": "bool"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "owner",
"type": "address"
},
{
"internalType": "address",
"name": "operator",
"type": "address"
}
],
"name": "isApprovedForAll",
"outputs": [
{
"internalType": "bool",
"name": "",
"type": "bool"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "isPublicSaleActive",
"outputs": [
{
"internalType": "bool",
"name": "",
"type": "bool"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "maxChapters",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "tokenId",
"type": "uint256"
}
],
"name": "mint",
"outputs": [],
"stateMutability": "payable",
"type": "function"
},
{
"inputs": [],
"name": "name",
"outputs": [
{
"internalType": "string",
"name": "",
"type": "string"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "owner",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "tokenId",
"type": "uint256"
}
],
"name": "ownerOf",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "renounceOwnership",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "bytes32",
"name": "role",
"type": "bytes32"
},
{
"internalType": "address",
"name": "account",
"type": "address"
}
],
"name": "renounceRole",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "bytes32",
"name": "role",
"type": "bytes32"
},
{
"internalType": "address",
"name": "account",
"type": "address"
}
],
"name": "revokeRole",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "tokenId",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "salePrice",
"type": "uint256"
}
],
"name": "royaltyInfo",
"outputs": [
{
"internalType": "address",
"name": "receiver",
"type": "address"
},
{
"internalType": "uint256",
"name": "royaltyAmount",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "from",
"type": "address"
},
{
"internalType": "address",
"name": "to",
"type": "address"
},
{
"internalType": "uint256",
"name": "tokenId",
"type": "uint256"
}
],
"name": "safeTransferFrom",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "from",
"type": "address"
},
{
"internalType": "address",
"name": "to",
"type": "address"
},
{
"internalType": "uint256",
"name": "tokenId",
"type": "uint256"
},
{
"internalType": "bytes",
"name": "_data",
"type": "bytes"
}
],
"name": "safeTransferFrom",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "operator",
"type": "address"
},
{
"internalType": "bool",
"name": "approved",
"type": "bool"
}
],
"name": "setApprovalForAll",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "string",
"name": "_baseURI",
"type": "string"
}
],
"name": "setBaseURI",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "bool",
"name": "_isOpenSeaProxyActive",
"type": "bool"
}
],
"name": "setIsOpenSeaProxyActive",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "bool",
"name": "_isPublicSaleActive",
"type": "bool"
}
],
"name": "setIsPublicSaleActive",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "bytes4",
"name": "interfaceId",
"type": "bytes4"
}
],
"name": "supportsInterface",
"outputs": [
{
"internalType": "bool",
"name": "",
"type": "bool"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "symbol",
"outputs": [
{
"internalType": "string",
"name": "",
"type": "string"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "tokenId",
"type": "uint256"
}
],
"name": "tokenURI",
"outputs": [
{
"internalType": "string",
"name": "",
"type": "string"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "from",
"type": "address"
},
{
"internalType": "address",
"name": "to",
"type": "address"
},
{
"internalType": "uint256",
"name": "tokenId",
"type": "uint256"
}
],
"name": "transferFrom",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "newOwner",
"type": "address"
}
],
"name": "transferOwnership",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
}
]
// SPDX-License-Identifier: MIT
//Contract based on [https://docs.openzeppelin.com/contracts/3.x/erc721](https://docs.openzeppelin.com/contracts/3.x/erc721)
/*
The official genesis photography project by Gabriela Gabrielaa
,----,
,/ .`|
,` .' : ,---, ,--, .--.--.
; ; / ,--, .' .' `\ ,--.'| / / '.
.'___,/ ,',--.'| __ ,-. __ ,-. ,---.' \ | | : | : /`. / ,--, ,---, ,---.
| : | | |, ,' ,'/ /|,' ,'/ /| | | .`\ | : : ' ; | |--` ,'_ /| ,-+-. / | ' ,'\ .--.--.
; |.'; ; `--'_ ,---. ' | |' |' | |' | ,--.--. : : | ' | ,---. | ' | | : ;_ .--. | | : ,---. ,--.'|' | / / | / / '
`----' | | ,' ,'| / \ | | ,'| | ,'/ \ | ' ' ; : / \ ' | | \ \ `. ,'_ /| : . | / \| | ,"' |. ; ,. :| : /`./
' : ; ' | | / / |' : / ' : / .--. .-. | ' | ; . | / / || | : `----. \| ' | | . . / / | | / | |' | |: :| : ;_
| | ' | | : . ' / || | ' | | ' \__\/: . . | | : | '. ' / |' : |__ __ \ \ || | ' | | | . ' / | | | | |' | .; : \ \ `.
' : | ' : |__ ' ; /|; : | ; : | ," .--.; | ' : | / ; ' ; /|| | '.'| / /`--' /: | : ; ; | ' ; /| | | |/ | : | `----. \
; |.' | | '.'|' | / || , ; | , ; / / ,. | | | '` ,/ ' | / |; : ; '--'. / ' : `--' \' | / | | |--' \ \ / / /`--' /
'---' ; : ;| : | ---' ---' ; : .' \ ; : .' | : || , / `--'---' : , .-./| : | |/ `----' '--'. /
| , / \ \ / | , .-./ | ,.' \ \ / ---`-' `--`----' \ \ /'---' `--'---'
---`-' `----' `--`---' '---' `----' `----'
*/
pragma solidity ^0.8.4;
import "@openzeppelin/contracts/token/ERC721/extensions/ERC721URIStorage.sol";
import "@openzeppelin/contracts/interfaces/IERC2981.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/access/AccessControl.sol";
import "@openzeppelin/contracts/utils/Strings.sol";
import "@openzeppelin/contracts/utils/math/SafeMath.sol";
contract TierraDeSuenos is ERC721URIStorage, IERC2981, Ownable, AccessControl {
using Strings for uint256;
bytes32 public constant MANAGER_ROLE = keccak256("MANAGER_ROLE");
string private baseURI;
// OpenSea Proxy Variables
address private openSeaProxyRegistryAddress;
bool private isOpenSeaProxyActive = true;
// TODO: update Owner address
address private ownerAddress = 0xa7E458A1b32070387e7548063E1F5e7f3982E6D1;
address private managerAddress = 0xa7E458A1b32070387e7548063E1F5e7f3982E6D1;
// 13 chapters 1/1's
// 13 Airdropped full videos
uint256 public constant maxChapters = 13;
uint256 public constant SALE_PRICE = 1 ether;
bool public isPublicSaleActive;
// ============ ACCESS CONTROL/SANITY MODIFIERS ============
modifier publicSaleActive() {
require(
isPublicSaleActive,
"Public sale is not open"
);
_;
}
// Only mint chapters 1
modifier canMintChapter(uint256 tokenId) {
require(
!(_exists(tokenId)),
"NFT has already been minted."
);
_;
}
// Is crossmint address
modifier isCrossMint() {
require(
msg.sender == 0xdAb1a1854214684acE522439684a145E62505233,
"This function is for Crossmint only."
);
_;
}
modifier isCorrectPayment(uint256 price) {
require(
price == msg.value || msg.sender == ownerAddress,
"Incorrect ETH value sent"
);
_;
}
// TODO: Add openseaProxyRegistryAddress a la
// https://etherscan.io/address/0x5180db8f5c931aae63c74266b211f580155ecac8#code
constructor(
address _openSeaProxyRegistryAddress
) ERC721("TierraDeSuenos", "TIERRA") {
openSeaProxyRegistryAddress = _openSeaProxyRegistryAddress;
_setupRole(DEFAULT_ADMIN_ROLE, msg.sender);
grantRole(MANAGER_ROLE, msg.sender);
grantRole(MANAGER_ROLE, managerAddress);
}
// ============ PUBLIC FUNCTIONS FOR MINTING ============
function mint(uint256 tokenId)
external
payable
publicSaleActive
canMintChapter(tokenId)
isCorrectPayment(SALE_PRICE)
{
payable(address(ownerAddress)).transfer(msg.value);
_safeMint(msg.sender,tokenId);
}
function crossmint(uint256 tokenId, address _to)
external
payable
publicSaleActive
canMintChapter(tokenId)
isCrossMint()
isCorrectPayment(SALE_PRICE)
{
payable(address(ownerAddress)).transfer(msg.value);
_safeMint(_to, tokenId);
}
// ============ PUBLIC READ-ONLY FUNCTIONS ============
function getBaseURI() external view returns (string memory) {
return baseURI;
}
// ============ OWNER-ONLY ADMIN FUNCTIONS ============
function claimAirdrops()
external
onlyOwner
{
for (uint256 i = 0; i < maxChapters; i++) {
_safeMint(ownerAddress, i + maxChapters);
}
}
// ============ MANAGER-ONLY ADMIN FUNCTIONS ============
function setBaseURI(string memory _baseURI) public onlyRole(MANAGER_ROLE) {
baseURI = _baseURI;
}
// function to disable gasless listings for security in case
// opensea ever shuts down or is compromised
function setIsOpenSeaProxyActive(bool _isOpenSeaProxyActive)
external
onlyOwner
{
isOpenSeaProxyActive = _isOpenSeaProxyActive;
}
function setIsPublicSaleActive(bool _isPublicSaleActive)
external
onlyRole(MANAGER_ROLE)
{
isPublicSaleActive = _isPublicSaleActive;
}
// ============ FUNCTION OVERRIDES ============
function supportsInterface(bytes4 interfaceId)
public
view
virtual
override(ERC721, IERC165, AccessControl)
returns (bool)
{
return
interfaceId == type(IERC2981).interfaceId ||
super.supportsInterface(interfaceId);
}
/**
* @dev Override isApprovedForAll to allowlist user's OpenSea proxy accounts to enable gas-less listings.
*/
function isApprovedForAll(address owner, address operator)
public
view
override
returns (bool)
{
// Get a reference to OpenSea's proxy registry contract by instantiating
// the contract using the already existing address.
ProxyRegistry proxyRegistry = ProxyRegistry(
openSeaProxyRegistryAddress
);
if (
isOpenSeaProxyActive &&
address(proxyRegistry.proxies(owner)) == operator
) {
return true;
}
return super.isApprovedForAll(owner, operator);
}
/**
* @dev See {IERC721Metadata-tokenURI}.
*/
function tokenURI(uint256 tokenId)
public
view
virtual
override
returns (string memory)
{
require(_exists(tokenId), "Nonexistent token");
return
string(abi.encodePacked(baseURI, "/", tokenId.toString(), ".json"));
}
/**
* @dev See {IERC165-royaltyInfo}.
*/
// TODO: Update this with Gabriela's royalty info
// Check out royalty registry as alternative
function royaltyInfo(uint256 tokenId, uint256 salePrice)
external
view
override
returns (address receiver, uint256 royaltyAmount)
{
require(_exists(tokenId), "Nonexistent token");
return (address(ownerAddress), SafeMath.div(SafeMath.mul(salePrice, 10), 100));
}
}
// These contract definitions are used to create a reference to the OpenSea
// ProxyRegistry contract by using the registry's address (see isApprovedForAll).
contract OwnableDelegateProxy {
}
contract ProxyRegistry {
mapping(address => OwnableDelegateProxy) public proxies;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment