Okay, first things first...I'm kind of an idiot. I'm a self-taught solidity dev and probably a bad one at that...so please don't judge me
I am working on this contract and my objective at this point is to make the contract scan the wallet address of the caller to see how much they own of another contract address, the contract does this already. However I am trying to make the amount the wallet owner has be the max amount they can mint for free off this contract.
As an example, if wallet owner 1 has 5 NFTs from A contract, they should be able to mint 5 NFTs from B contract but no more than 5 for free. If wallet owner 2 has 3 NFTs from A contract, they should only be able to mint 3 NFTs from contract B at a maximum.
Below is the code, you can see here I tried to make maxgiveawayamount = otherTokenAmount however it is an undeclared variable, so this will not work. However there is a function later called walletofOwnerofOtherContract that does produce the variable I'm looking for, "otherTokenAmount" and I want that variable to be the variable that governs maxgiveaway. Maybe its a pipe dream, I feel like I'm the verge of something but due to my lack of experience its hard for me to connect the dots.
Thanks to anyone who can assist.
pragma solidity >=0.7.0 <0.9.0;
contract NFT is ERC721, Ownable {
using Strings for uint256;
using Counters for Counters.Counter;
Counters.Counter private supply;
//other token nft contract
address public contract1;
address public contract2;
uint256 public criteria1 = 1;
string public baseURI;
string public baseExtension = ".json";
string public notRevealedUri;
uint256 public cost = 1 ether;
uint256 public maxSupply = 500;
uint256 public maxMintAmountPerTx = 10;
uint256 public MaxgiveawayAmountperTx = otherTokenAmount;
uint256 public giveawaylimit = 500;
uint256 public givedAway = 0;
bool public paused = false;
bool public revealed = true;
struct GivedAwayFree {
bool claimedFree;
}
mapping(address => GivedAwayFree) public givedAwayFree;
constructor(
string memory _name,
string memory _symbol,
string memory _initBaseURI,
string memory _initNotRevealedUri
) ERC721(_name, _symbol) {
setBaseURI(_initBaseURI);
setNotRevealedURI(_initNotRevealedUri);
}
// internal
function _baseURI() internal view virtual override returns (string memory) {
return baseURI;
}
modifier mintCompliance(uint256 _mintAmount) {
require(
_mintAmount > 0 && _mintAmount <= maxMintAmountPerTx,
"Invalid mint amount!"
);
require(
supply.current() + _mintAmount <= maxSupply,
"Max supply exceeded!"
);
_;
}
modifier giveawayCompliance(uint256 _giveawayAmount) {
require(
_giveawayAmount > 0 && _giveawayAmount <= MaxgiveawayAmountperTx,
"Invalid giveaway amount!"
);
require(
supply.current() + _giveawayAmount <= maxSupply,
"Max supply exceeded!"
);
_;
}
function totalSupply() public view returns (uint256) {
return supply.current();
}
function giveaway(uint256 _giveawayAmount)
public
payable
giveawayCompliance(_giveawayAmount)
{
require(!paused, "The contract is paused!");
// check if other user owns token from different contract
uint256 _contract1 = walletOfOwnerOfOtherContract(
msg.sender,
contract1
);
uint256 _contract2 = walletOfOwnerOfOtherContract(
msg.sender,
contract2
);
//if user owns any token from different contract
if (givedAway >= 500) {
require(msg.value >= cost * _giveawayAmount, "Insufficient funds!");
_mintLoop(msg.sender, _giveawayAmount);
} else {
if (
_contract1 >= criteria1 &&
_contract2 >= criteria1
) {
//check if user has already claimed free token
if (givedAwayFree[msg.sender].claimedFree == true) {
// if user has already claimed free token, then he can't mint for free, and has to pay
require(
msg.value >= cost * _giveawayAmount,
"Insufficient funds!"
);
_giveawayLoop(msg.sender, _giveawayAmount);
} else {
// if user has not claimed free token, then he can mint for free
_giveawayLoop(msg.sender, _giveawayAmount);
givedAwayFree[msg.sender].claimedFree = true;
givedAway++;
}
} else {
// if user does not own any token from different contract, then he cannot mint for free
require(msg.value >= cost * _giveawayAmount, "Insufficient funds!");
_giveawayLoop(msg.sender, _giveawayAmount);
}
}
}
function mint(uint256 _mintAmount)
public
payable
mintCompliance(_mintAmount)
{
require(!paused, "The contract is paused!");
require(msg.value >= cost * _mintAmount, "Insufficient funds!");
_mintLoop(msg.sender, _mintAmount);
}
function mintForAddress(uint256 _mintAmount, address _receiver)
public
mintCompliance(_mintAmount)
onlyOwner
{
_mintLoop(_receiver, _mintAmount);
}
function walletOfOwnerOfOtherContract(
address _owner,
address contractAddress
) public view returns (uint256 otherTokenAmount) {
uint256 ownerTokenCount = ERC721(contractAddress).balanceOf(_owner);
return ownerTokenCount;
}
function walletOfOwner(address _owner)
public
view
returns (uint256[] memory)
{
uint256 ownerTokenCount = balanceOf(_owner);
uint256[] memory ownedTokenIds = new uint256[](ownerTokenCount);
uint256 currentTokenId = 1;
uint256 ownedTokenIndex = 0;
while (
ownedTokenIndex < ownerTokenCount && currentTokenId <= maxSupply
) {
address currentTokenOwner = ownerOf(currentTokenId);
if (currentTokenOwner == _owner) {
ownedTokenIds[ownedTokenIndex] = currentTokenId;
ownedTokenIndex++;
}
currentTokenId++;
}
return ownedTokenIds;
}
function tokenURI(uint256 tokenId)
public
view
virtual
override
returns (string memory)
{
require(
_exists(tokenId),
"ERC721Metadata: URI query for nonexistent token"
);
if(revealed == false) {
return notRevealedUri;
}
string memory currentBaseURI = _baseURI();
return bytes(currentBaseURI).length > 0
? string(abi.encodePacked(currentBaseURI, tokenId.toString(), baseExtension))
: "";
}
function setcontract1(address _contract1) public onlyOwner returns(address){
return contract1 = _contract1;
}
function setcontract2(address _contract2) public onlyOwner returns(address){
return contract2 = _contract2;
}
function setcriteria1(uint256 _criteria1) public onlyOwner {
criteria1 = _criteria1;
}
function setRevealed(bool _state) public onlyOwner {
revealed = _state;
}
function setCost(uint256 _cost) public onlyOwner {
cost = _cost;
}
function setMaxMintAmountPerTx(uint256 _maxMintAmountPerTx)
public
onlyOwner
{
maxMintAmountPerTx = _maxMintAmountPerTx;
}
function setMaxgiveawayAmountPerTx(uint256 _maxgiveawayAmountPerTx)
public
onlyOwner
{
MaxgiveawayAmountperTx = _maxgiveawayAmountPerTx;
}
function setBaseURI(string memory _newBaseURI) public onlyOwner {
baseURI = _newBaseURI;
}
function setBaseExtension(string memory _newBaseExtension) public onlyOwner {
baseExtension = _newBaseExtension;
}
function setNotRevealedURI(string memory _notRevealedURI) public onlyOwner {
notRevealedUri = _notRevealedURI;
}
function setPaused(bool _state) public onlyOwner {
paused = _state;
}
function withdraw() public onlyOwner {
(bool os, ) = payable(owner()).call{value: address(this).balance}("");
require(os);
}
function _mintLoop(address _receiver, uint256 _mintAmount) internal {
for (uint256 i = 0; i < _mintAmount; i++) {
supply.increment();
_safeMint(_receiver, supply.current());
}
}
function _giveawayLoop(address _receiver, uint256 _giveawayAmount) internal {
for (uint256 i = 0; i < _giveawayAmount; i++) {
supply.increment();
_safeMint(_receiver, supply.current());
givedAway++;
}
}
}