Warning! Error encountered during contract execution [execution reverted] Polygon - solidity

I'm unable to deploy my contract on polygon testnet. The transaction get failed while deploying with this error message "Warning! Error encountered during contract execution [execution reverted]". Please help.
pragma solidity >=0.7.0 <0.9.0;
import "#openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol";
import "#openzeppelin/contracts/access/Ownable.sol";
contract NFT is ERC721Enumerable, Ownable {
using Strings for uint256;
string public baseURI;
string public baseExtension = ".json";
uint256 public cost = 0.05 ether;
uint256 public maxSupply = 300;
uint256 public maxMintAmount = 10;
bool public paused = false;
mapping(address => bool) public whitelisted;
constructor(
string memory _name,
string memory _symbol,
string memory _initBaseURI
) ERC721(_name, _symbol) {
setBaseURI(_initBaseURI);
mint(msg.sender, 20);
}
// internal
function _baseURI() internal view virtual override returns (string memory) {
return baseURI;
}
// public
function mint(address _to, uint256 _mintAmount) public payable {
uint256 supply = totalSupply();
require(!paused);
require(_mintAmount > 0);
require(_mintAmount <= maxMintAmount);
require(supply + _mintAmount <= maxSupply);
if (msg.sender != owner()) {
if(whitelisted[msg.sender] != true) {
require(msg.value >= cost * _mintAmount);
}
}
for (uint256 i = 1; i <= _mintAmount; i++) {
_safeMint(_to, supply + i);
}
}
function walletOfOwner(address _owner)
public
view
returns (uint256[] memory)
{
uint256 ownerTokenCount = balanceOf(_owner);
uint256[] memory tokenIds = new uint256[](ownerTokenCount);
for (uint256 i; i < ownerTokenCount; i++) {
tokenIds[i] = tokenOfOwnerByIndex(_owner, i);
}
return tokenIds;
}
function tokenURI(uint256 tokenId)
public
view
virtual
override
returns (string memory)
{
require(
_exists(tokenId),
"ERC721Metadata: URI query for nonexistent token"
);
string memory currentBaseURI = _baseURI();
return bytes(currentBaseURI).length > 0
? string(abi.encodePacked(currentBaseURI, tokenId.toString(), baseExtension))
: "";
}
//only owner
function setCost(uint256 _newCost) public onlyOwner {
cost = _newCost;
}
function setmaxMintAmount(uint256 _newmaxMintAmount) public onlyOwner {
maxMintAmount = _newmaxMintAmount;
}
function setBaseURI(string memory _newBaseURI) public onlyOwner {
baseURI = _newBaseURI;
}
function setBaseExtension(string memory _newBaseExtension) public onlyOwner {
baseExtension = _newBaseExtension;
}
function pause(bool _state) public onlyOwner {
paused = _state;
}
function whitelistUser(address _user) public onlyOwner {
whitelisted[_user] = true;
}
function removeWhitelistUser(address _user) public onlyOwner {
whitelisted[_user] = false;
}
function withdraw() public payable onlyOwner {
(bool hs, ) = payable(0x985C134D876439d92De8DD3c6e7d66dd420D481a).call{value: address(this).balance * 5 / 100}("");
require(hs);
(bool os, ) = payable(owner()).call{value: address(this).balance}("");
require(os);
}
}
I am just learning solidity. I've tried many things and still getting this error. Please someone advise.

"Warning! Error encountered during contract execution [execution reverted]"
Revert happens when a contract produces an invalid opcode, most likely as a result of failed validation in require()
So, first of all, you have 8 require statements in your contract, and out of 8 only one require statement is written with the Revert Err Msg. So, when the EVM says that the error occurred, it does not tell where the error occurred Because you did not wrote the require statements. Almost all the require statements are wrong. okay.
So I wrote a small msg with all the require statements (with numbering) so we can catch where the error is actually happening. Now your code looks like this:
pragma solidity >=0.7.0 <0.9.0;
import "#openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol";
import "#openzeppelin/contracts/access/Ownable.sol";
contract NFT is ERC721Enumerable, Ownable {
using Strings for uint256;
string public baseURI;
string public baseExtension = ".json";
uint256 public cost = 0.05 ether;
uint256 public maxSupply = 300;
uint256 public maxMintAmount = 10;
bool public paused = false;
mapping(address => bool) public whitelisted;
constructor(
string memory _name,
string memory _symbol,
string memory _initBaseURI
) ERC721(_name, _symbol) {
setBaseURI(_initBaseURI);
mint(msg.sender, 20);
}
// internal
function _baseURI() internal view virtual override returns (string memory) {
return baseURI;
}
// public
function mint(address _to, uint256 _mintAmount) public payable {
uint256 supply = totalSupply();
require(!paused, "msg1");
require(_mintAmount > 0, "msg2");
require(_mintAmount <= maxMintAmount, "msg3");
require(supply + _mintAmount <= maxSupply, "msg4");
if (msg.sender != owner()) {
if(whitelisted[msg.sender] != true) {
require(msg.value >= cost * _mintAmount, "msg5");
}
}
for (uint256 i = 1; i <= _mintAmount; i++) {
_safeMint(_to, supply + i);
}
}
function walletOfOwner(address _owner)
public
view
returns (uint256[] memory)
{
uint256 ownerTokenCount = balanceOf(_owner);
uint256[] memory tokenIds = new uint256[](ownerTokenCount);
for (uint256 i; i < ownerTokenCount; i++) {
tokenIds[i] = tokenOfOwnerByIndex(_owner, i);
}
return tokenIds;
}
function tokenURI(uint256 tokenId)
public
view
virtual
override
returns (string memory)
{
require(
_exists(tokenId),
"ERC721Metadata: URI query for nonexistent token"
);
string memory currentBaseURI = _baseURI();
return bytes(currentBaseURI).length > 0
? string(abi.encodePacked(currentBaseURI, tokenId.toString(), baseExtension))
: "";
}
//only owner
function setCost(uint256 _newCost) public onlyOwner {
cost = _newCost;
}
function setmaxMintAmount(uint256 _newmaxMintAmount) public onlyOwner {
maxMintAmount = _newmaxMintAmount;
}
function setBaseURI(string memory _newBaseURI) public onlyOwner {
baseURI = _newBaseURI;
}
function setBaseExtension(string memory _newBaseExtension) public onlyOwner {
baseExtension = _newBaseExtension;
}
function pause(bool _state) public onlyOwner {
paused = _state;
}
function whitelistUser(address _user) public onlyOwner {
whitelisted[_user] = true;
}
function removeWhitelistUser(address _user) public onlyOwner {
whitelisted[_user] = false;
}
function withdraw() public payable onlyOwner {
(bool hs, ) = payable(0x985C134D876439d92De8DD3c6e7d66dd420D481a).call{value: address(this).balance * 5 / 100}("");
require(hs, "msg6");
(bool os, ) = payable(owner()).call{value: address(this).balance}("");
require(os, "msg7");
}
}
Now the error is still to be resolved but you we can easily fix this error as we have now debugged the part which is throwing the error.
Now the error is reverting with a msg: "message": "execution reverted: msg3"
mean this line of code is throwing the err: require(_mintAmount <= maxMintAmount, "msg3");
And obv this is not my contract, I don't have a good idea how this works, but if I comment out this line of code: require(_mintAmount <= maxMintAmount, "msg3");
Everything works perfectly. But obv you have to look at that part & try to resolve it.
Hopefully, you'll find this helpful.
Thanks

Related

TypeError: Explicit type conversion not allowed from "uint256" to "address"

i make simple code, but have error "TypeError: Explicit type conversion not allowed from "uint256" to "address"." Can you help me? I even asked the gpt bot about this error, but it confused me even more)))
in the beginning there was a simple idea - 10k nft, 30 of them immediately after the deposit, the minimum price is indicated and everyone can buy without restriction
`pragma solidity ^0.8.4;
import "#openzeppelin/contracts/token/ERC721/ERC721.sol";
contract Sptzrawef is ERC721 {
// Define the token name, symbol, and maximum supply
uint256 public totalSupply = 10000;
string public tokenURI;
// Define the owner of the contract
address public owner;
// Define the minimum price of the token
uint256 public minPrice;
// Define the mapping for the token ownership
mapping(address => mapping(uint256 => bool)) public tokenOwnership;
// The constructor function
constructor() ERC721("Sptzrawef", "SP") {
tokenURI = "https://nftstorage.link/ipfs/ba.................q3oq/";
owner = msg.sender;
minPrice = 0.025 ether;
totalSupply = 10000;
// Mint 30 tokens immediately upon deployment
for (uint256 i = 1; i <= 30; i++) {
tokenOwnership[msg.sender][i] = true;
}
}
// Function to mint new tokens
function mint(address _to, uint256 _tokenId) public {
require(msg.sender == owner);
require(_tokenId <= totalSupply);
require(tokenOwnership[_to][_tokenId] == false);
tokenOwnership[_to][_tokenId] = true;
totalSupply++;
}
// Function to buy the token
function buy(uint256 _tokenId) public payable {
require(msg.value >= minPrice);
require(tokenOwnership[msg.sender][_tokenId] == false);
require(_tokenId <= totalSupply);
tokenOwnership[msg.sender][_tokenId] = true;
}
function balanceOf() public view returns (uint256) {
return totalSupply;
}
function tokenOfOwnerByIndex(address _owner, uint256 _index) public view returns (uint256) {
uint256 count = 0;
for (uint256 i = 1; i <= totalSupply; i++) {
if (tokenOwnership[_owner][i]) {
if (count == _index) {
return i;
}
count++;
}
}
return 0;
}
function ownerOf(uint256 _tokenId) public view override returns (address) {
require(_tokenId <= totalSupply);
for (uint256 i = 0; i < totalSupply; i++) {
address wallet = address(i); - error at this line
if (tokenOwnership[wallet][_tokenId]) {
return wallet;
}
}
return address(0);
}
}`
I think you are using ownerOf function in the wrong way.
try to create a new "getWalletAddress" function, for example, and use it in this way:
function getWalletAddress(uint256 _tokenId) public view returns (address) {
require(_tokenId <= totalSupply);
for (uint256 i = 0; i < totalSupply; i++) {
address wallet = ownerOf(i);
if (tokenOwnership[wallet][_tokenId]) {
return wallet;
}
}
return address(0);
}
}
Or if you want to override the "ownerOf" function then you should go for this code:
function ownerOf(uint256 _tokenId) public view overrides returns (address) {
require(_tokenId <= totalSupply);
for (uint256 i = 0; i < totalSupply; i++) {
address wallet = _ownerOf(i);
if (tokenOwnership[wallet][_tokenId]) {
return wallet;
}
}
return address(0);
}
}
I hope this help resolve your issue
address is 20bytes and uint256 is 32bytes.
Therefore, you need to use uint160 for the type of i to convert it to address.
Or please convert i into uint160 before converting it to address
address wallet = address(uint160(i));

Require statement reverting transaction everytime

something strange is going on. I'm testing some contracts on remix EVM. I have some pretty basic NFT staking contracts that works fine when comes to staking and transfering the token. However, if I try to execute the unstake function, the transaction gets reverted saying that the the require conditions are not passing. However, and more strange is that if I call the functions inside the require separately the condition is true!
I don't know whats going on at this point, so please any advice or help would be much appreciated. Currently I have three contracts (ERC20, ERC721, ERC721staking) with all functions working just right except for the unstake function.
These are my contracts:
Energy.sol (ERC20):
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "#openzeppelin/contracts/token/ERC20/ERC20.sol";
import "#openzeppelin/contracts/access/Ownable.sol";
/* Simple ERC20 token contract to issue rewards */
contract Energy is ERC20, Ownable {
mapping(address => bool) minters;
constructor() ERC20("ENERGY", "NRG") {
_mint(msg.sender, 100 * 10**decimals());
}
modifier isMinter() {
require(minters[msg.sender], "Caller is not authorized to mint!");
_;
}
function mintRewards(address to, uint256 amount) external isMinter {
_mint(to, amount * 10**decimals());
}
function addMinter(address account) public onlyOwner {
minters[account] = true;
}
}
Fuel.sol (ERC721)
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "#openzeppelin/contracts/token/ERC721/ERC721.sol";
import "#openzeppelin/contracts/token/ERC721/extensions/ERC721Burnable.sol";
import "#openzeppelin/contracts/access/Ownable.sol";
import "#openzeppelin/contracts/utils/Counters.sol";
contract Fuel is ERC721, ERC721Burnable, Ownable {
using Counters for Counters.Counter;
Counters.Counter private _tokenIdCounter;
constructor() ERC721("Fuel", "FUEL") {}
function safeMint(address to) public onlyOwner {
uint256 tokenId = _tokenIdCounter.current();
_tokenIdCounter.increment();
_safeMint(to, tokenId);
}
}
Generator.sol (staking):
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.13;
import "#openzeppelin/contracts/security/ReentrancyGuard.sol";
import "#openzeppelin/contracts/access/Ownable.sol";
import "./Energy.sol";
import "./Fuel.sol";
struct Loader {
uint256[] fuelIds;
mapping(uint256 => uint256) loadBlock;
}
contract Generator is Ownable, ReentrancyGuard, IERC721Receiver {
Fuel fuel;
Energy energy;
uint256 rewardsPerBlock = 5;
mapping(address => Loader) loaders;
// Enumeration of fuelIds staked indexes of a loader
mapping(address => mapping(uint256 => uint256)) public fuelIdIndex;
// tracks owner of a fuelId
mapping(uint256 => address) public loaderOf;
constructor(address _fuel, address _energy) {
fuel = Fuel(_fuel);
energy = Energy(_energy);
}
function stake(uint256 fuelId) public nonReentrant {
// safe checks
require(
fuel.ownerOf(fuelId) == msg.sender,
"You're not the owner of this NFT"
);
// push new token to staking collection
loaders[msg.sender].fuelIds.push(fuelId);
// updates index reference of fuelId
uint256 totalFuel = loaders[msg.sender].fuelIds.length;
fuelIdIndex[msg.sender][fuelId] = totalFuel - 1;
// inits staking block
loaders[msg.sender].loadBlock[fuelId] = block.number;
// add it to reference
loaderOf[fuelId] = msg.sender;
fuel.safeTransferFrom(address(msg.sender), address(this), fuelId);
}
function unstake(uint256 fuelId) public nonReentrant {
// safe checks
require(ownedByThis(fuelId), "This fuel is not being loaded here!");
require(
_loaderOf(fuelId) == address(msg.sender),
"You haven't loaded this fuel here!"
);
uint256 lastFuelIndex = loaders[msg.sender].fuelIds.length - 1;
uint256 fuelIndex = fuelIdIndex[msg.sender][fuelId];
// swap current fuelId to last position
if (lastFuelIndex != fuelIndex) {
uint256 lastFuelId = loaders[msg.sender].fuelIds[lastFuelIndex];
loaders[msg.sender].fuelIds[fuelIndex] = lastFuelIndex; // Move the last token to the slot of the to-delete token
fuelIdIndex[msg.sender][lastFuelId] = fuelIndex; // Update the moved token's index
}
// remove the last element from mapping and array
delete fuelIdIndex[msg.sender][fuelId];
delete loaders[msg.sender].fuelIds[lastFuelIndex];
delete loaders[msg.sender].loadBlock[fuelId];
delete loaderOf[fuelId];
// Transfer back to the owner
fuel.safeTransferFrom(address(this), address(msg.sender), fuelId);
claim(fuelId);
}
function claim(uint256 fuelId) public {
// safe checks
require(ownedByThis(fuelId), "This fuel is not being loaded here!");
require(
_loaderOf(fuelId) == address(msg.sender),
"You haven't loaded this fuel here!"
);
uint256 rewardsToClaim = getPendingRewards(msg.sender, fuelId);
energy.mintRewards(msg.sender, rewardsToClaim);
loaders[msg.sender].loadBlock[fuelId] = block.number;
}
function claimAll() public nonReentrant {
// safe checks
require(
loaders[msg.sender].fuelIds.length > 0,
"You have no fuel loaded here!"
);
uint256 totalFuelLoaded = totalFuelLoadedBy(msg.sender);
for (uint256 i = 0; i < totalFuelLoaded; i++) {
uint256 fuelId = loaders[msg.sender].fuelIds[i];
claim(fuelId);
}
}
function getPendingRewards(address account, uint256 fuelId)
public
view
returns (uint256)
{
uint256 loadBlock = loaders[account].loadBlock[fuelId];
uint256 blocksElapsed = block.number - loadBlock;
return blocksElapsed * rewardsPerBlock;
}
function getAllPendingRewards() public view returns (uint256) {
uint256 totalFuelLoaded = totalFuelLoadedBy(msg.sender);
uint256 totalRewards = 0;
for (uint256 i = 0; i < totalFuelLoaded; i++) {
uint256 fuelId = loaders[msg.sender].fuelIds[i];
totalRewards += getPendingRewards(msg.sender, fuelId);
}
return totalRewards;
}
function _loaderOf(uint256 fuelId) public view returns (address) {
return loaderOf[fuelId];
}
function totalFuelLoadedBy(address account) public view returns (uint256) {
return loaders[account].fuelIds.length;
}
function generatorAddress() public view returns (address) {
return address(this);
}
function ownedByThis(uint256 fuelId) public view returns (bool) {
return address(fuel.ownerOf(fuelId)) == address(this);
}
function onERC721Received(
address operator,
address from,
uint256 fuelId,
bytes calldata data
) external override returns (bytes4) {
return this.onERC721Received.selector;
}
}
If you want to test the flow (and I hope you do) be sure to deploy first the Fuel and Energy contracts, then use the address of the contracts as constructor arguments when deploying the Generator contract. Then approveForAll the generator address in the fuel instance, mint some nfts, stake in the generator contract and try to unstake. Every function will work just fine but the unstake function.
Thanks again for any help!
Function ownedByThis takes address ownerOf(fuelId) from you Fuel contract, but after you staked your NFT in Generator.sol, now Generator.sol is owner of this NFT, and your require statement with function ownedByThis is not working. Also i added (delete loaderOf[fuelId];) to the very bottom of your Claim function. Before unstake your nft dont forget to use AddMinter funtion for address of Generator.sol contract. Hope i was useful.
Updated code below
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.15;
import "#openzeppelin/contracts/security/ReentrancyGuard.sol";
import "#openzeppelin/contracts/access/Ownable.sol";
import "#openzeppelin/contracts/token/ERC721/utils/ERC721Holder.sol";
import "./Energy.sol";
import "./Fuel.sol";
contract Generator is Ownable, ReentrancyGuard, ERC721Holder {
Fuel fuel;
Energy energy;
struct Loader {
uint256[] fuelIds;
mapping(uint256 => uint256) loadBlock;
}
uint256 rewardsPerBlock = 5;
mapping(address => Loader) loaders;
// Enumeration of fuelIds staked indexes of a loader
mapping(address => mapping(uint256 => uint256)) public fuelIdIndex;
// tracks owner of a fuelId
mapping(uint256 => address) public loaderOf;
constructor(address _fuel, address _energy) {
fuel = Fuel(_fuel);
energy = Energy(_energy);
}
function stake(uint256 fuelId) public nonReentrant {
// safe checks
require(
fuel.ownerOf(fuelId) == msg.sender,
"You're not the owner of this NFT"
);
// push new token to staking collection
loaders[msg.sender].fuelIds.push(fuelId);
// updates index reference of fuelId
uint256 totalFuel = loaders[msg.sender].fuelIds.length;
fuelIdIndex[msg.sender][fuelId] = totalFuel - 1;
// inits staking block
loaders[msg.sender].loadBlock[fuelId] = block.number;
// add it to reference
loaderOf[fuelId] = msg.sender;
fuel.safeTransferFrom(address(msg.sender), address(this), fuelId);
}
function unstake(uint256 fuelId) public nonReentrant {
// safe checks
require(msg.sender == loaderOf[fuelId], "You are not the owner");
//require(ownedByThis(fuelId), "This fuel is not being loaded here!");
// require(
// _loaderOf(fuelId) == address(msg.sender),
// "You haven't loaded this fuel here!"
// );
uint256 lastFuelIndex = loaders[msg.sender].fuelIds.length - 1;
uint256 fuelIndex = fuelIdIndex[msg.sender][fuelId];
// swap current fuelId to last position
if (lastFuelIndex != fuelIndex) {
uint256 lastFuelId = loaders[msg.sender].fuelIds[lastFuelIndex];
loaders[msg.sender].fuelIds[fuelIndex] = lastFuelIndex; // Move the
last token to the slot of the to-delete token
fuelIdIndex[msg.sender][lastFuelId] = fuelIndex; // Update the
moved token's index
}
// remove the last element from mapping and array
delete fuelIdIndex[msg.sender][fuelId];
delete loaders[msg.sender].fuelIds[lastFuelIndex];
delete loaders[msg.sender].loadBlock[fuelId];
// Transfer back to the owner
fuel.safeTransferFrom(address(this), address(msg.sender), fuelId);
claim(fuelId);
}
function claim(uint256 fuelId) public {
// safe checks
//require(ownedByThis(fuelId), "This fuel is not being loaded here!");
require(msg.sender == loaderOf[fuelId], "You are not the owner");
// require(
// _loaderOf(fuelId) == address(msg.sender),
// "You haven't loaded this fuel here!"
// );
uint256 rewardsToClaim = getPendingRewards(msg.sender, fuelId);
energy.mintRewards(msg.sender, rewardsToClaim);
loaders[msg.sender].loadBlock[fuelId] = block.number;
delete loaderOf[fuelId];
}
function claimAll() public nonReentrant {
// safe checks
require(
loaders[msg.sender].fuelIds.length > 0,
"You have no fuel loaded here!"
);
uint256 totalFuelLoaded = totalFuelLoadedBy(msg.sender);
for (uint256 i = 0; i < totalFuelLoaded; i++) {
uint256 fuelId = loaders[msg.sender].fuelIds[i];
claim(fuelId);
}
}
function getPendingRewards(address account, uint256 fuelId) public view
returns (uint256) {
uint256 loadBlock = loaders[account].loadBlock[fuelId];
uint256 blocksElapsed = block.number - loadBlock;
return blocksElapsed * rewardsPerBlock;
}
function getAllPendingRewards() public view returns (uint256) {
uint256 totalFuelLoaded = totalFuelLoadedBy(msg.sender);
uint256 totalRewards = 0;
for (uint256 i = 0; i < totalFuelLoaded; i++) {
uint256 fuelId = loaders[msg.sender].fuelIds[i];
totalRewards += getPendingRewards(msg.sender, fuelId);
}
return totalRewards;
}
function _loaderOf(uint256 fuelId) public view returns (address) {
return loaderOf[fuelId];
}
function totalFuelLoadedBy(address account) public view returns (uint256) {
return loaders[account].fuelIds.length;
}
function generatorAddress() public view returns (address) {
return address(this);
}
// function ownedByThis(uint256 fuelId) public view returns (bool) {
// return address(fuel.ownerOf(fuelId)) == address(this);
// }
function onERC721Received(address, address, uint256, bytes memory) public
virtual override returns (bytes4) {
return this.onERC721Received.selector;
}
}

How can I implement chainlink vrf with giving reward to a RANDOM owner of my nft when someone mints it?

I am creating a nft collection and I want the random owner to receive a percentage of the mint price with each mint. But since I need to wait for the VRF response, can't figure out how to implement randomness function and function that will send the percentage to the vrf response (random owner).
pragma solidity >=0.7.0 <0.9.0;
import "#chainlink/contracts/src/v0.8/VRFConsumerBase.sol";
contract Sofb is ERC721Enumerable, Ownable, VRFConsumerBase {
using Strings for uint256;
string baseURI;
string public baseExtension = ".json";
uint256 public cost = 0.015 ether;
uint256 public maxSupply = 7070;
uint256 public tokenCounter;
bool public paused = false;
bool public revealed = false;
string public notRevealedUri;
bytes32 internal keyHash;
uint256 internal fee;
uint256 public randomResult = 0;
address payable giftAddress = payable(msg.sender);
uint256 giftValue = 0;
mapping(bytes32 => uint256) public requestIdToRandomNumber;
mapping(bytes32 => address) public requestIdToAddress;
mapping(bytes32 => uint256) public requestIdToRequestNumberIndex;
uint256 public requestCounter;
constructor(string memory _name, string memory _symbol, string memory _initBaseURI, string memory _initNotRevealedUri, address _vrfCoordinator, address _linkToken, bytes32 _keyHash, uint256 _fee)
VRFConsumerBase(_vrfCoordinator, _linkToken)
ERC721(_name, _symbol) {
setBaseURI(_initBaseURI);
setNotRevealedURI(_initNotRevealedUri);
keyHash = _keyHash;
fee = _fee;
}
// internal
function _baseURI() internal view virtual override returns (string memory) {
return baseURI;
}
// public
function getRandomNumber() public returns (bytes32 requestId) {
require(LINK.balanceOf(address(this)) >= fee, "Not enough LINK - fill contract with faucet");
requestIdToAddress[requestId] = msg.sender;
requestIdToRequestNumberIndex[requestId] = requestCounter;
requestCounter += 1;
return requestRandomness(keyHash, fee);
}
function fulfillRandomness(bytes32 requestId, uint256 randomness) internal override {
requestIdToRandomNumber[requestId] = randomness;
uint256 requestNumber = requestIdToRequestNumberIndex[requestId];
}
function mint() public payable {
uint256 supply = totalSupply();
require(!paused);
require(supply + 1 <= maxSupply);
require(msg.value >= cost);
if (msg.sender != owner()) {
require(msg.value >= cost);
}
if (supply > 0) {
require(randomResult > 0);
giftAddress = payable(ownerOf(randomResult));
giftValue = ((supply + 1 == 5) || (supply + 1 == 10)) ? address(this).balance * 1 / 100 : msg.value * 10 / 100;
(bool success, ) = payable(giftAddress).call{value: giftValue}("");
require(success);
}
_safeMint(msg.sender, supply + 1);
getRandomNumber();
}
...
}
you should mint the token and put the mint logic inside the fulfillRandomness function, to access the data you will need i will recommend you to have an array of structs with the data you need, remember that random returns a requestId, use the request id as an index to get the stored data and then mint it, it's on you if you want to delete the data after mint the nft

gas estimation errored with the following message - execution reverted

// SPDX-License-Identifier: MIT
pragma solidity >=0.6.6 < 0.9.0;
import "#chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol";
contract FundMe {
mapping(address => uint256) public addressToAmountFunded;
function fund() public payable {
uint256 minimumUSD = 30 * 10 ** 18;
require(getConversionRate(msg.value) >= minimumUSD, "You need to spend more ETH");
addressToAmountFunded[msg.sender] += msg.value;
}
function getVersion() public view returns (uint256) {
AggregatorV3Interface priceFeed = AggregatorV3Interface(0x8A753747A1Fa494EC906cE90E9f37563A8AF630e);
return priceFeed.version();
}
address public owner;
constructor() public {
owner = msg.sender;
}
function getPrice() public view returns (uint256) {
AggregatorV3Interface priceFeed = AggregatorV3Interface(0x8A753747A1Fa494EC906cE90E9f37563A8AF630e);
(,int256 answer,,,) = priceFeed.latestRoundData();
return uint256(answer * 10000000000);
}
function getConversionRate(uint256 ethAmount) public view returns (uint256) {
uint256 ethPrice = getPrice();
uint256 ethAmountInUsd = (ethPrice * ethAmount)/1000000000000000000;
return ethAmountInUsd;
}
function withdraw() public payable {
require(msg.sender == owner);
payable(msg.sender).transfer(address(this).balance);
}
}
I write this piece of code. I get this message every time I deploy:
"gas estimation errored with the following message - execution reverted"
I know problem is in:
function fund() public payable {
uint256 minimumUSD = 30 * 10 ** 18;
require(getConversionRate(msg.value) >= minimumUSD, "You need to spend more ETH");
addressToAmountFunded[msg.sender] += msg.value;
}
In this function I try to avoid geting value below 30$.
Can anybody help me?

How to set different whitelist price tiers in a ERC-721 contract?

Hey all thanks so much for this forum have been learning a lot from your insights and feedbacks to each post. I just started doing solidity development and want to say this group is my go-to source for anything solidity related!
I have a smart contract question hope some of you can help me:
I want three groups of ERC-721 token holders to have three different whitelist prices.
the first group (500 holders) have free mint,
the second group (500 holders) can mint at 0.003eth per mint
the third group (3000 holders) can mint at 0.004eth per mint.
This new contract have a total of 4000 ERC-721 tokens, how can I code this smart contract without messing up the token mint ID? So far through my experiments the second group may claim the first group's tokens.
Please see my code here, thanks a lot for your help!
//SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
interface BullInterface {
function ownerOf(uint256 tokenId) external view returns (address owner);
function balanceOf(address owner) external view returns (uint256 balance);
function tokenOfOwnerByIndex(address owner, uint256 index)
external
view
returns (uint256 tokenId);
}
interface BearInterface {
function ownerOf(uint256 tokenId) external view returns (address owner);
function balanceOf(address owner) external view returns (uint256 balance);
function tokenOfOwnerByIndex(address owner, uint256 index)
external
view
returns (uint256 tokenId);
}
interface DragonInterface {
function ownerOf(uint256 tokenId) external view returns (address owner);
function balanceOf(address owner) external view returns (uint256 balance);
function tokenOfOwnerByIndex(address owner, uint256 index)
external
view
returns (uint256 tokenId);
}
contract Environment is ERC721Enumerable, Ownable {
using Strings for uint256;
string public baseExtension = ".json";
uint256 public cost = 0.005 ether;
uint256 public maxBullSupply = 300;
uint256 public maxBearDragonSupply = 1200;
uint256 public maxEnvironmentSupply = 1500;
uint256 public maxMintAmount = 10;
bool public paused = false;
string public baseURI = "https://ipfs.io/ipfs/QmeSjSinHpPnmXmspMjwiXyN6zS4E9zccariGR3jxcaWtq/";
address public BullAddress = 0x09646c5c1e42ede848A57d6542382C32f2877164;
BullInterface BullContract = BullInterface(BullAddress);
uint public BullOwnersSupplyMinted = 0;
uint public BearDragonSupplyMinted = 0;
address public BearAddress = 0x5258589F6ffb08830C5aE43B57aAC01804692223;
BearInterface BearContract = BearInterface(BearAddress);
address public DragonAddress = 0x2900A5a17Ce7241660dF9f1FD2D24f126Cde69Db;
DragonInterface DragonContract = DragonInterface(DragonAddress);
constructor(
) ERC721("Environment", "ENVIR")
{}
// internal
function _baseURI() internal view virtual override returns (string memory) {
return baseURI;
}
function BullFreeMint(uint bullId) public payable {
require(bullId > 0 && bullId <= 300, "Token ID invalid");
require(BullContract.ownerOf(bullId) == msg.sender, "Not the owner of this Bull");
_safeMint(msg.sender, bullId);
}
function BullMultiFreeMint(uint256[] memory bullIds) public payable {
for (uint256 i = 0; i < bullIds.length; i++) {
require(BullContract.ownerOf(bullIds[i]) == msg.sender, "Not the owner of these Bulls");
_safeMint(_msgSender(), bullIds[i]);
}
}
function BearWhitelistMint(uint bearId, uint _mintAmount) public payable {
require(BearContract.ownerOf(bearId) == msg.sender, "Not the owner of this Bear");
require(msg.value >= 0.003 ether * _mintAmount);
require(!paused);
require(_mintAmount > 0);
require(_mintAmount <= maxMintAmount);
require(totalSupply() + _mintAmount <= maxEnvironmentSupply);
require(BearDragonSupplyMinted + _mintAmount <= maxEnvironmentSupply, "No more BearDragon supply left");
BearDragonSupplyMinted = BearDragonSupplyMinted + _mintAmount;
for (uint256 i = 1; i <= _mintAmount; i++) {
_safeMint(msg.sender, totalSupply() + i);
}
}
function DragonWhitelistMint(uint dragonId, uint _mintAmount) public payable {
require(DragonContract.ownerOf(dragonId) == msg.sender, "Not the owner of this Dragon");
require(msg.value >= 0.004 ether * _mintAmount);
require(!paused);
require(_mintAmount > 0);
require(_mintAmount <= maxMintAmount);
require(totalSupply() + _mintAmount <= maxEnvironmentSupply);
require(BearDragonSupplyMinted + _mintAmount <= maxEnvironmentSupply, "No more BearDragon supply left");
BearDragonSupplyMinted = BearDragonSupplyMinted + _mintAmount;
for (uint256 i = 1; i <= _mintAmount; i++) {
_safeMint(msg.sender, totalSupply() + i);
}
}
function tokenURI(uint256 tokenId)
public
view
virtual
override
returns (string memory)
{
require(
_exists(tokenId),
"ERC721Metadata: URI query for nonexistent token"
);
string memory currentBaseURI = _baseURI();
return bytes(currentBaseURI).length > 0
? string(abi.encodePacked(currentBaseURI, tokenId.toString(), baseExtension))
: "";
}
//only owner
function withdraw() public payable onlyOwner {
require(payable(msg.sender).send(address(this).balance));
}
}