// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
/// @author: @frankPoncelet
import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v4.2.0/contracts/utils/introspection/IERC165.sol";
interface IRoyalties is IERC165 {
// Royalty support for RaribleV1
// fees.recipient refers to either the item owner (By default) or an address where the Royalties will be received.
function getFeeRecipients(uint256 tokenId) external view returns (address payable[] memory);
// fees.value is the royalties percentage, by default this value is 1000 on Rarible which is a 10% royalties fee.
function getFeeBps(uint256 tokenId) external view returns (uint[] memory);
//
function getFees(uint256 tokenId) external view returns (address payable[] memory, uint256[] memory);
/** Called with the sale price to determine how much royalty
* is owed and to whom EIP2981
* @param tokenId - the NFT asset queried for royalty information
* @param salePrice - the sale price of the NFT asset specified by _tokenId
* @return receiver - address of who should be sent the royalty payment
* @return royaltyAmount - the royalty payment amount for _salePrice
*/
function royaltyInfo(uint256 tokenId, uint256 salePrice) external view returns (address, uint256);
}
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0 <0.9.0;
import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v4.2.0/contracts/token/ERC721/ERC721.sol";
import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v4.2.0/contracts/access/Ownable.sol";
import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v4.2.0/contracts/utils/math/SafeMath.sol";
import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v4.2.0/contracts/token/ERC721/extensions/ERC721Enumerable.sol";
import "./Royalties.sol";
/**
* @title LazySloths contract
* @dev Extends ERC721 Non-Fungible Token Standard basic implementation
*
*/
// Twitter @FrankPoncelet
//
contract LazySloths is Ownable, ERC721Enumerable, Royalties {
using SafeMath for uint256;
uint256 public tokenPrice = 50000000000000000; //0.05 ETH
uint256 public MAX_SLOTHS;
uint public constant MAX_PURCHASE = 20;
uint public constant MAX_RESERVE = 30;
bool public saleIsActive;
address payable[] private addr = new address payable[](1);
uint256[] private royalties = new uint256[](1);
// Base URI for Meta data
string private _baseTokenURI = "ipfs://QmetbFFTF51b78BADpgB4px18Bct25yjstRrsDH4wj7J4w/";
string public SLOTHS_PROVENANCE = "";
address private constant DAO = 0x8ef4268e320bAEfBF2499cF9cEfe67177e5D8649;
event priceChange(address _by, uint256 price);
event PaymentReleased(address to, uint256 amount);
constructor() ERC721("The Lazy Sloths", "SLOTHS") {
MAX_SLOTHS = 9973;
addr[0]=payable(owner());
royalties[0]=500; //5 % on Rarible
_safeMint( DAO, 0);
}
/**
* @dev See {IERC165-supportsInterface}.
*/
function supportsInterface(bytes4 interfaceId) public view override (ERC721Enumerable,Royalties) returns (bool){
return ERC721.supportsInterface(interfaceId) || Royalties.supportsInterface(interfaceId) || super.supportsInterface(interfaceId);
}
/**
* Set price
*/
function setPrice(uint256 price) public onlyOwner {
tokenPrice = price;
emit priceChange(msg.sender, tokenPrice);
}
function withdraw() public onlyOwner {
uint256 artists = address(this).balance / 5;
require(payable(DAO).send(artists*2));
require(payable(owner()).send(artists*3));
emit PaymentReleased(owner(), artists*3);
}
/**
* Set some Dorkis aside for giveaways.
*/
function reserveTokens() public onlyOwner {
require(totalSupply().add(MAX_RESERVE) <= MAX_SLOTHS, "Reserve would exceed max supply of Dorkis");
uint supply = totalSupply();
for (uint i = 0; i < MAX_RESERVE; i++) {
_safeMint(msg.sender, supply + i);
}
}
/*
* Set provenance once it's calculated
*/
function setProvenanceHash(string memory provenanceHash) public onlyOwner {
SLOTHS_PROVENANCE = provenanceHash;
}
/**
* @dev Base URI for computing {tokenURI}. If set, the resulting URI for each
* token will be the concatenation of the `baseURI` and the `tokenId`.
*/
function _baseURI() internal view virtual override returns (string memory) {
return _baseTokenURI;
}
/**
* @dev Set the base token URI
*/
function setBaseTokenURI(string memory baseURI) public onlyOwner {
_baseTokenURI = baseURI;
}
/*
* Pause sale if active, make active if paused
*/
function flipSaleState() public onlyOwner {
saleIsActive = !saleIsActive;
}
/**
* Mints Sloths
*/
function mintSloths(uint numberOfTokens) public payable {
require(numberOfTokens > 0, "numberOfNfts cannot be 0");
require(saleIsActive, "Sale must be active to mint tokens");
require(numberOfTokens <= MAX_PURCHASE, "Can only mint 20 tokens at a time");
require(totalSupply().add(numberOfTokens) <= MAX_SLOTHS, "Purchase would exceed max supply of tokens");
require(tokenPrice.mul(numberOfTokens) <= msg.value, "Ether value sent is not correct");
for(uint i = 0; i < numberOfTokens; i++) {
uint mintIndex = totalSupply();
if (totalSupply() < MAX_SLOTHS) {
_safeMint(msg.sender, mintIndex);
}
}
}
function preSale(address _to, uint256 numberOfTokens) external onlyOwner() {
require(totalSupply().add(numberOfTokens) <= MAX_SLOTHS, "Reserve would exceed max supply of tokens");
require(numberOfTokens <= MAX_PURCHASE, "Can only mint 20 tokens at a time");
uint256 supply = totalSupply();
for(uint256 i; i < numberOfTokens; i++){
_safeMint( _to, supply + i );
}
}
/**
* Get all tokens for a specific wallet
*
*/
function getTokensForAddress(address fromAddress) external view returns (uint256 [] memory){
uint tokenCount = balanceOf(fromAddress);
uint256[] memory tokensId = new uint256[](tokenCount);
for(uint i = 0; i < tokenCount; i++){
tokensId[i] = tokenOfOwnerByIndex(fromAddress, i);
}
return tokensId;
}
// contract can recieve Ether
fallback() external payable { }
receive() external payable { }
// Royalties implemetations
function getFeeRecipients(uint256 tokenId) external view override returns (address payable[] memory){
require(_exists(tokenId), "LazySloths: FeeRecipients query for nonexistent token");
return addr;
}
// fees.value is the royalties percentage, by default this value is 1000 on Rarible which is a 10% royalties fee.
function getFeeBps(uint256 tokenId) external view override returns (uint[] memory){
require(_exists(tokenId), "LazySloths: FeesBPS query for nonexistent token");
return royalties;
}
function getFees(uint256 tokenId) external view override returns (address payable[] memory, uint256[] memory){
require(_exists(tokenId), "LazySloths: Fees query for nonexistent token");
return (addr, royalties);
}
function royaltyInfo(uint256 tokenId, uint256 salePrice) external view override returns (address, uint256){
require(_exists(tokenId), "LazySloths: royaltyInfo query for nonexistent token");
return (address(this),(salePrice*royalties[0]/10000));
}
}
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
/// @author: @frankPoncelet
import "./IRoyalties.sol";
import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v4.2.0/contracts/utils/introspection/ERC165.sol";
abstract contract Royalties is IRoyalties, ERC165 {
/**
* @dev Rarible: RoyaltiesV1
*
* bytes4(keccak256('getFeeRecipients(uint256)')) == 0xb9c4d9fb
* bytes4(keccak256('getFeeBps(uint256)')) == 0x0ebd4c7f
*
* => 0xb9c4d9fb ^ 0x0ebd4c7f = 0xb7799584
*/
bytes4 private constant _INTERFACE_ID_ROYALTIES_RARIBLE = 0xb7799584;
/**
* @dev Foundation
*
* bytes4(keccak256('getFees(uint256)')) == 0xd5a06d4c
*
* => 0xd5a06d4c = 0xd5a06d4c
*/
bytes4 private constant _INTERFACE_ID_ROYALTIES_FOUNDATION = 0xd5a06d4c;
/**
* @dev EIP-2981
*
* bytes4(keccak256("royaltyInfo(uint256,uint256)")) == 0x2a55205a
*
* => 0x2a55205a = 0x2a55205a
*/
bytes4 private constant _INTERFACE_ID_ROYALTIES_EIP2981 = 0x2a55205a;
// Royalty mappings
/**
* @dev See {IERC165-supportsInterface}.
*/
function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {
return interfaceId == type(IRoyalties).interfaceId || super.supportsInterface(interfaceId)
|| interfaceId == _INTERFACE_ID_ROYALTIES_RARIBLE
|| interfaceId == _INTERFACE_ID_ROYALTIES_FOUNDATION
|| interfaceId == _INTERFACE_ID_ROYALTIES_EIP2981;
}
}
{
"compilationTarget": {
"contracts/LazySloths.sol": "LazySloths"
},
"evmVersion": "berlin",
"libraries": {},
"metadata": {
"bytecodeHash": "ipfs"
},
"optimizer": {
"enabled": true,
"runs": 200
},
"remappings": []
}
[{"inputs":[],"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":false,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"PaymentReleased","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"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_by","type":"address"},{"indexed":false,"internalType":"uint256","name":"price","type":"uint256"}],"name":"priceChange","type":"event"},{"stateMutability":"payable","type":"fallback"},{"inputs":[],"name":"MAX_PURCHASE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_RESERVE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_SLOTHS","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"SLOTHS_PROVENANCE","outputs":[{"internalType":"string","name":"","type":"string"}],"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":"flipSaleState","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getFeeBps","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getFeeRecipients","outputs":[{"internalType":"address payable[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getFees","outputs":[{"internalType":"address payable[]","name":"","type":"address[]"},{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"fromAddress","type":"address"}],"name":"getTokensForAddress","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"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":[{"internalType":"uint256","name":"numberOfTokens","type":"uint256"}],"name":"mintSloths","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":[{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256","name":"numberOfTokens","type":"uint256"}],"name":"preSale","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"reserveTokens","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"salePrice","type":"uint256"}],"name":"royaltyInfo","outputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","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":[],"name":"saleIsActive","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","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":"setBaseTokenURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"price","type":"uint256"}],"name":"setPrice","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"provenanceHash","type":"string"}],"name":"setProvenanceHash","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":"index","type":"uint256"}],"name":"tokenByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenOfOwnerByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"tokenPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","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":"transferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]