Search code examples
ethereumsoliditynftremix

How to create a timer and reset list after timer is up in Solidity?


I'm trying to create smart contract that would do 3 types of check before minting a NFT to a user. First i would like to check if user is in whitelist then check if user is VIP but VIP list i wanna to reset and add manually after timer is up (5 weeks). I got some parts of my code working fine but i couldn't reset VIP list.

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;

import '@openzeppelin/contracts/token/ERC721/ERC721.sol';
import '@openzeppelin/contracts/access/Ownable.sol';

contract TestContractV1 is ERC721, Ownable{
    uint256 public mintPrice = 0.00000000000000001 ether;
    uint256 public totalSupply;
    uint256 public maxSupply;
    bool public isMintEnabled;
    uint start;
    uint end;
    mapping(address => uint256) public mintedWalletes;
    mapping(address => bool) public whitelist;
    mapping(address => bool) public monthlyVIP;
    address [] public  vip;
    constructor() payable ERC721('Test V1', 'TV1'){
        maxSupply = 2;
    }

    modifier timeIsOver{
            require(block.timestamp>=end,"Time is up");
            callThisWhenTimeIsUp();
            _;
        } 

    function toggleIsMintEnabled() external onlyOwner{
        isMintEnabled = !isMintEnabled;
        whitelist[msg.sender] = true;
        startTimer();
    }

    function setMaxSupply(uint256 maxSupply_) external onlyOwner{
        maxSupply = maxSupply_;
    }

      function addToWhitelist(address[] calldata toAddAddresses) external onlyOwner
    {
        for (uint i = 0; i < toAddAddresses.length; i++) {
            whitelist[toAddAddresses[i]] = true;
        }
    }

    function addToVIP(address[] calldata toAddAddresses) external onlyOwner
    {
        for (uint i = 0; i < toAddAddresses.length; i++) {
            monthlyVIP[toAddAddresses[i]] = true;
            
        }
    }


    function removeFromWhitelist(address[] calldata toRemoveAddresses) external onlyOwner
    {
        for (uint i = 0; i < toRemoveAddresses.length; i++) {
            delete whitelist[toRemoveAddresses[i]];
        }
    }

    function resetVIPs() public {
        for (uint i=0; i< vip.length ; i++) {
            monthlyVIP[vip[i]] = false;
        }
    }

    function whitelistFunc() public view 
    {
        require(whitelist[msg.sender], "NOT_IN_WHITELIST");
    }

   
    function startTimer() public{
        start = block.timestamp;
    }

    function endTimer() public {
        end = 60 + start;
    }

    function timeLefts() public view returns(uint){
        return( block.timestamp - end);
    }

    function callThisWhenTimeIsUp() public {
            startTimer();
            endTimer();
            resetVIPs();
            
    }


    function mint() external payable {
        require(isMintEnabled, 'MINTING_NOT_ENABLED');
        require(whitelist[msg.sender], 'NOT_IN_WHITELIST');
        require(mintedWalletes[msg.sender] < 100, 'REARD_BEEN_CLAIMED_ALREADY');
        require(monthlyVIP[msg.sender] , 'YOU_NOT_MONTHLY_VIP');
        //require(msg.value == mintPrice, 'WRONG_PRICE_VOULE');
        require(maxSupply > totalSupply, 'SOLD_OUT');
        mintedWalletes[msg.sender]++;
        totalSupply++;
        uint256 tokenId = totalSupply; 
        _safeMint(msg.sender, tokenId);   
    }
}

Solution

  • You are forgetting to populate the vip array within this function since it's used to reset the monthlyVIP mapping.

    function addToVIP(address[] calldata toAddAddresses) external onlyOwner
        {
            for (uint i = 0; i < toAddAddresses.length; i++) {
                monthlyVIP[toAddAddresses[i]] = true;
                
            }
        }
    

    Please add the following line:

    function addToVIP(address[] calldata toAddAddresses) external onlyOwner
        {
            for (uint i = 0; i < toAddAddresses.length; i++) {
                monthlyVIP[toAddAddresses[i]] = true;
                vip.push(toAddAddresses[i]);
            }
        }