Here's my first ever smart contract. What exactly causes such a warning and how should I improve my code?
This is just one of many similar warnings
Warning:
Gas requirement of function Consensus.deployPmu(string) high: infinite. If the gas requirement of a function is higher than the block gas limit, it cannot be executed. Please avoid loops in your functions or actions that modify large areas of storage (this includes clearing or copying arrays in storage)
pragma solidity ^0.5.7;
contract Consensus {
struct PMU{
string name;
address pmu;
uint256[] data;
bool errorFlag;
uint256 errorCount;
}
mapping (address => PMU) PMUS;
address[] accounts;
uint256[] empty;
function deployPmu(string memory _name) public{
PMUS[msg.sender] = PMU(_name,msg.sender,empty,false,0);
accounts.push(msg.sender);
}
function print() public view returns(string memory name, uint256[] memory data,bool errorFlag,uint256 errorCount){
PMU memory instancePMU = PMUS[msg.sender];
return (instancePMU.name,instancePMU.data,instancePMU.errorFlag,instancePMU.errorCount);
}
function log(uint256[] memory roc) public{
for (uint i=0; i<roc.length;i++){
PMUS[msg.sender].data.push(roc[i]);
if(roc[i]<12){
PMUS[msg.sender].errorFlag = false;
errorFlags[msg.sender] = false;
PMUS[msg.sender].errorCount=0;
}
if(roc[i]>12){
PMUS[msg.sender].errorCount= PMUS[msg.sender].errorCount+1;
}
if( PMUS[msg.sender].errorCount >= 5){
PMUS[msg.sender].errorFlag = true;
errorFlags[msg.sender] = true;
PMUS[msg.sender].errorCount = 0;
}
}
}
mapping (address => bool) errorFlags;
bool GridFault=false;
bool PMUfault=false;
address[] tru;
address[] falz;
function faultStatus () public returns (address[] memory)
{
address[] memory empty;
tru = empty;
falz =empty;
GridFault = false;
PMUfault = false;
uint256 count =0;
for(uint256 i =0; i<accounts.length; i++){
if(errorFlags[accounts[i]] == true){
count = count + 1;
tru.push(accounts[i]);
}
else{
falz.push(accounts[i]);
}
}
if(count > (accounts.length-1)/2){
GridFault = true;
if(falz.length != 0){
PMUfault = true;
}
}
else if(count == 0){
GridFault = false;
PMUfault = false;
}
else{
PMUfault = true;
return tru;
}
}
function gridstatus() public view returns(address[] memory, bool, bool){
if(GridFault == true){
return (falz,GridFault, PMUfault);
}
else{
return(tru,GridFault, PMUfault);
}
}
}
Related
function _mintFee(uint112 _reserve0, uint112 _reserve1) private returns (bool feeOn) {
address feeTo = IUniswapV2Factory(factory).feeTo();
feeOn = feeTo != address(0);
uint _kLast = kLast; // gas savings
if (feeOn) {
if (_kLast != 0) {
uint rootK = Math.sqrt(uint(_reserve0).mul(_reserve1));
uint rootKLast = Math.sqrt(_kLast);
if (rootK > rootKLast) {
uint numerator = totalSupply.mul(rootK.sub(rootKLast));
uint denominator = rootK.mul(5).add(rootKLast);
uint liquidity = numerator / denominator;
if (liquidity > 0) _mint(feeTo, liquidity);
}
}
} else if (_kLast != 0) {
kLast = 0;
}
}
// this low-level function should be called from a contract which performs important safety checks
function mint(address to) external lock returns (uint liquidity) {
(uint112 _reserve0, uint112 _reserve1,) = getReserves(); // gas savings
uint balance0 = IERC20(token0).balanceOf(address(this));
uint balance1 = IERC20(token1).balanceOf(address(this));
uint amount0 = balance0.sub(_reserve0);
uint amount1 = balance1.sub(_reserve1);
bool feeOn = _mintFee(_reserve0, _reserve1);
uint _totalSupply = totalSupply; // gas savings, must be defined here since totalSupply can update in _mintFee
if (_totalSupply == 0) {
liquidity = Math.sqrt(amount0.mul(amount1)).sub(MINIMUM_LIQUIDITY);
_mint(address(0), MINIMUM_LIQUIDITY); // permanently lock the first MINIMUM_LIQUIDITY tokens
} else {
liquidity = Math.min(amount0.mul(_totalSupply) / _reserve0, amount1.mul(_totalSupply) / _reserve1);
}
require(liquidity > 0, 'UniswapV2: INSUFFICIENT_LIQUIDITY_MINTED');
_mint(to, liquidity);
_update(balance0, balance1, _reserve0, _reserve1);
if (feeOn) kLast = uint(reserve0).mul(reserve1); // reserve0 and reserve1 are up-to-date
emit Mint(msg.sender, amount0, amount1);
}
I've start to reading uniV2 codes and i faced this problem, imagine the feeTo has been set in factory contract, and the new pair has been created, for the first time we deposit the amount to the pair contract, now the feeOn is true and kLast is zero that mean
if (feeOn) {
if (_kLast != 0) {
this condition doesn't meet, so my question is for the first time that we create a pair and feeOn is true, Does protocol take its fee?
I've tried to test it, but the protocol didn't take its portion Lp tokens at the first addLiquidity.
I am trying to create a whitelist. I've used a for and if loop to check if the msg.sender already exists in the array. When the whitelist() function is run, no errors are returned, but when I run check(), it tells me the address doesn't exist in the array, same thing with directing fetching the array.
//SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
contract SelfWhitelist {
address[] public addressWhitelist;
function whitelist() public returns(string memory) {
for(uint i = 0; i < addressWhitelist.length; i++) {
if(addressWhitelist[i] != msg.sender) {
addressWhitelist.push(msg.sender);
return "Whitelisted!";
}
}
return "Already whitelisted!";
}
function check() public view returns (bool){
for(uint i = 0; i < addressWhitelist.length; i++){
if(addressWhitelist[i] == msg.sender)
return true;
}
return false;
}
}
I added this block of code to check for duplicate entries in the array.
for(uint i = 0; i < addressWhitelist.length; i++) {
if(addressWhitelist[i] != msg.sender) {
addressWhitelist.push(msg.sender);
return "Whitelisted!";
}
Expected for no errors and my address being pushed to the array.
The code ran without errors, but nothing was added to the array.
I would use mapping type to hold the whitelisted addresses, then you don't have to loop over the array
contract SelfWhitelist {
mapping(address => bool) public addressWhitelist;
function whitelist() public returns(string memory) {
if (check()) {
return "Already whitelisted!";
}
addressWhitelist[msg.sender] = true;
return "Whitelisted!";
}
function check() public view returns (bool) {
return addressWhitelist[msg.sender];
}
}
And in your code, seems you have logical issues:
for(uint i = 0; i < addressWhitelist.length; i++) {
if(addressWhitelist[i] != msg.sender) {
addressWhitelist.push(msg.sender);
return "Whitelisted!";
}
}
if the array is empty, the loop never executes, so nothing will be added
if the first item is not msg.sender, msg.sender will be whitelisted, even though it might be already whitelisted.
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);
}
}
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]);
}
}
Im following a youtube tutorial on smart contracts as i am still very new to solidity however when I compile I am getting this error.
ParserError: Expected '(' but got identifier
--> contracts/CryptoKids.sol:57:14:
|
57 | function availableToWithdraw(address walletAddress) public returns(bool)
| ^^^^^^^^^^^^^^^^^^^
// SPDX-License-Identifier: Unlicensed
pragma solidity ^0.8.7;
contract CryptoKids
{
//Define Dad
address owner;
constructor(){
owner = msg.sender;
}
//Define Kid
struct Kid{
address payable walletAddress;
string firstName;
string LastName;
uint releaseTime;
uint amount;
bool canWithdraw;
}
Kid[] public kids;
//add kid to contract
function addKids(address payable walletAddress,string memory firstName,string memory LastName,uint releaseTime,uint amount,bool canWithdraw) public{
kids.push(Kid(walletAddress,firstName,LastName,releaseTime,amount,canWithdraw));
}
//deposit funds to contract, specifically to kids contract
function deposit(address walletAddress) payable public {
addToKidsBalance(walletAddress);
}
function balanceOf() public view returns(uint){
return address(this).balance;
}
function addToKidsBalance(address walletAddress) private{
for (uint i = 0; i < kids.length; i++){
if(kids[i].walletAddress == walletAddress){
kids[i].amount += msg.value;
}
}
}
function getIndex(address walletAddress) view private returns(uint){
for (uint i = 0; i < kids.length; i++){
if(kids[i].walletAddress == walletAddress){{
return i;
}
}
return 999;
}
//kid checks if can withdraw
function availableToWithdraw(address walletAddress) public returns(bool)
{
uint i = getIndex(walletAddress);
if (block.timestamp > kids[1].releaseTime)
{
kids[i].canWithdraw = true;
return true;
}
else
{
return false;
}
}
//if can withdraw money
function withdraw(address payable walletAddress) payable public{
uint i = getIndex(walletAddress);
kids[i].walletAddress.transfer(kids[i].amount);
}
}
Im not sure what the issue is as ive checked my codes with against the video that im following and cant find anything wrong
Video Link: https://www.youtube.com/watch?v=s9MVkHKV2Vw
In your getIndex() function remove a curly bracket in the end of the following if condition:
function getIndex(address walletAddress) view private returns(uint){
for (uint i = 0; i < kids.length; i++){
if(kids[i].walletAddress == walletAddress){{ // <- This is the issue
return i;
}
}
return 999;
}
Replace it with:
function getIndex(address walletAddress) view private returns(uint){
for (uint i = 0; i < kids.length; i++){
if(kids[i].walletAddress == walletAddress) {
return i;
}
}
return 999;
}
I am working on dapp using hardhat and goerli testnet and when I run it using npx hardhat run scripts/deploy.js --network goerli, I receive this error, I do have goerli faucet eth on my wallet but still it will display that my account balance is 0:
Error: insufficient funds for intrinsic transaction cost [ See: https://links.ethers.org/v5-errors-INSUFFICIENT_FUNDS ] (error={"name":"ProviderError","_stack":"ProviderError: HttpProviderError\n at HttpProvider.request (C:\\Users\\SAIFUL\\RTW3-Week7-NFT-Marketplace\\node_modules\\hardhat\\src\\internal\\core\\providers\\http.ts:78:19)\n at LocalAccountsProvider.request (C:\\Users\\SAIFUL\\RTW3-Week7-NFT-Marketplace\\node_modules\\hardhat\\src\\internal\\core\\providers\\accounts.ts:181:36)\n at processTicksAndRejections (internal/process/task_queues.js:95:5)\n at EthersProviderWrapper.send (C:\\Users\\SAIFUL\\RTW3-Week7-NFT-Marketplace\\node_modules\\#nomiclabs\\hardhat-ethers\\src\\internal\\ethers-provider-wrapper.ts:13:20)","code":-32000,"_isProviderError":true}, method="sendTransaction", transaction=undefined, code=INSUFFICIENT_FUNDS, version=providers/5.7.2)
at Logger.makeError (C:\Users\SAIFUL\RTW3-Week7-NFT-Marketplace\node_modules\#ethersproject\logger\src.ts\index.ts:269:28)
at Logger.throwError (C:\Users\SAIFUL\RTW3-Week7-NFT-Marketplace\node_modules\#ethersproject\logger\src.ts\index.ts:281:20)
at checkError (C:\Users\SAIFUL\RTW3-Week7-NFT-Marketplace\node_modules\#ethersproject\providers\src.ts\json-rpc-provider.ts:98:16)
at C:\Users\SAIFUL\RTW3-Week7-NFT-Marketplace\node_modules\#ethersproject\providers\src.ts\json-rpc-provider.ts:265:24
at processTicksAndRejections (internal/process/task_queues.js:95:5) {
reason: 'insufficient funds for intrinsic transaction cost',
code: 'INSUFFICIENT_FUNDS',
error: ProviderError: HttpProviderError
at HttpProvider.request (C:\Users\SAIFUL\RTW3-Week7-NFT-Marketplace\node_modules\hardhat\src\internal\core\providers\http.ts:78:19)
at LocalAccountsProvider.request (C:\Users\SAIFUL\RTW3-Week7-NFT-Marketplace\node_modules\hardhat\src\internal\core\providers\accounts.ts:181:36)
at processTicksAndRejections (internal/process/task_queues.js:95:5)
at EthersProviderWrapper.send (C:\Users\SAIFUL\RTW3-Week7-NFT-Marketplace\node_modules\#nomiclabs\hardhat-ethers\src\internal\ethers-provider-wrapper.ts:13:20),
method: 'sendTransaction',
transaction: undefined
}
here is my deploy.js file everything is supposed to fine and working but error won't disappear
require("#nomiclabs/hardhat-waffle");
require("#nomiclabs/hardhat-ethers");
const fs = require('fs');
// const infuraId = fs.readFileSync(".infuraid").toString().trim() || "";
task("accounts", "Prints the list of accounts", async(taskArgs, hre) => {
const accounts = await hre.ethers.getSigners();
for (const account of accounts) {
console.log(account.address);
}
});
module.exports = {
defaultNetwork: "hardhat",
networks: {
hardhat: {
chainId: 1337
},
goerli: {
url: "https://eth-mainnet.g.alchemy.com/v2/2Hmp7mz6XEpw6Z47cCZx2vEIAYXFGYOL",
accounts: ["private key here"]
}
},
solidity: {
version: "0.8.4",
settings: {
optimizer: {
enabled: true,
runs: 200
}
}
}
};
here is my solidity contract:
//SPDX-License-Identifier: Unlicense
pragma solidity ^0.8.0;
import "hardhat/console.sol";
import "#openzeppelin/contracts/utils/Counters.sol";
import "#openzeppelin/contracts/token/ERC721/extensions/ERC721URIStorage.sol";
import "#openzeppelin/contracts/token/ERC721/ERC721.sol";
contract NFTMarketplace is ERC721URIStorage {
address payable owner;
using Counters for Counters.Counter;
Counters.Counter private _tokenIds;
Counters.Counter private _itemsSold;
uint256 listPrice = 0.01 ether;
constructor() ERC721("NFTMarketplace", "NFTM") {
owner = payable(msg.sender);
}
struct ListedToken {
uint256 tokenId;
address payable owner;
address payable seller;
uint256 price;
bool currentlyListed;
}
mapping(uint256 => ListedToken) private idToListedToken;
function updateListPrice(uint256 _listprice) public payable {
require(owner == msg.sender, "only owner can update listing price ");
listPrice = _listprice;
}
function getListPrice() public view returns (uint256) {
return listPrice;
}
function getLatestIdToListedtoken()
public
view
returns (ListedToken memory)
{
uint256 currentTokenId = _tokenIds.current();
return idToListedToken[currentTokenId];
}
function getListedForToken(uint256 tokenId) public view returns (ListedToken memory) {
return idToListedToken[tokenId];
}
function getCurrentToken() public view returns (uint256) {
return _tokenIds.current();
}
function createToken(string memory tokenURI, uint256 price) public payable returns (uint) {
require(msg.value == listPrice, "Send enough ether to list");
require(price > 0, "Make sure the price isn't negative");
_tokenIds.increment();
uint256 currentTokenId = _tokenIds.current();
_safeMint(msg.sender, currentTokenId);
_setTokenURI(currentTokenId, tokenURI);
createListedToken(currentTokenId, price);
return currentTokenId;
}
function createListedToken(uint256 tokenId, uint256 price) private {
idToListedToken[tokenId] = ListedToken(
tokenId,
payable(address(this)),
payable(msg.sender),
price,
true
);
_transfer(msg.sender, address(this), tokenId);
}
function getAllNFTs() public view returns(ListedToken[] memory) {
uint nftCount = _tokenIds.current();
ListedToken[] memory tokens = new ListedToken[](nftCount);
uint currentIndex = 0;
for(uint i=0; i<nftCount; i++) {
uint currentId = i+1;
ListedToken storage currentItem = idToListedToken[currentId];
tokens[currentIndex] = currentItem;
currentIndex += 1;
}
return tokens;
}
function getMyNFTs() public view returns (ListedToken[] memory) {
uint totalItemCount = _tokenIds.current();
uint itemCount = 0;
uint currentIndex = 0;
uint currentId;
for(uint i=0; i < totalItemCount; i++)
{
if(idToListedToken[i+1].owner == msg.sender || idToListedToken[i+1].seller == msg.sender){
itemCount += 1;
}
}
ListedToken[] memory items = new ListedToken[](itemCount);
for(uint i=0; i < totalItemCount; i++) {
if(idToListedToken[i+1].owner == msg.sender || idToListedToken[i+1].seller == msg.sender) {
currentId = i+1;
ListedToken storage currentItem = idToListedToken[currentId];
items[currentIndex] = currentItem;
currentIndex += 1;
}
}
return items;
}
function executeSale(uint256 tokenId) public payable {
uint price = idToListedToken[tokenId].price;
require(msg.value == price, "please submit the relevant NFT price in order to purchase");
address seller = idToListedToken[tokenId].seller;
idToListedToken[tokenId].currentlyListed = true;
idToListedToken[tokenId].seller = payable(msg.sender);
_itemsSold.increment();
_transfer(address(this), msg.sender, tokenId);
approve(address(this), tokenId);
payable(owner).transfer(listPrice);
payable(seller).transfer(msg.value);
}
}
I tried different networks, but I have no choice except goerli because I will use alchemy Api.
You still need to get more Goerli ETH from faucets or from your other peers.
Try that and see if it will work
Finally I switched from INFURA to ALCHEMY and following the instructions here:
https://hardhat.org/tutorial/deploying-to-a-live-network
it worked!