Infinite gas warning in Remix for a function - ethereum

Can anyone tell why the above warning is generated when putting this function into Remix?
function doFlip() public{
uint256 blockValue = uint256(blockhash(block.number - 1));
uint256 coinFlip = uint256(uint256(blockValue)/FACTOR);
side = coinFlip == 1 ? true : false;
flipper.flip(side);
}
The full contract looks like follows:
//SPDX-License-Identifier: Unlicensed
pragma solidity ^0.6.0;
import "#openzeppelin/contracts-ethereum-package/contracts/math/SafeMath.sol";
interface CoinFlip {
function flip(bool guess) external returns (bool);
}
contract Flipper {
using SafeMath for uint256;
uint256 FACTOR = 57896044618658097711785492504343953926634992332820282019728792003956564819968;
bool public side;
CoinFlip public flipper;
constructor() public {
flipper = CoinFlip(xxxxxxxxxx);
}
function doFlip() public{
uint256 blockValue = uint256(blockhash(block.number - 1));
uint256 coinFlip = uint256(uint256(blockValue)/FACTOR);
side = coinFlip == 1 ? true : false;
flipper.flip(side);
}
}
The CoinFlip contract looks as follows:
/ SPDX-License-Identifier: MIT
pragma solidity ^0.6.0;
import '#openzeppelin/contracts/math/SafeMath.sol';
contract CoinFlip {
using SafeMath for uint256;
uint256 public consecutiveWins;
uint256 lastHash;
uint256 FACTOR = 57896044618658097711785492504343953926634992332820282019728792003956564819968;
constructor() public {
consecutiveWins = 0;
}
function flip(bool _guess) public returns (bool) {
uint256 blockValue = uint256(blockhash(block.number.sub(1)));
if (lastHash == blockValue) {
revert();
}
lastHash = blockValue;
uint256 coinFlip = blockValue.div(FACTOR);
bool side = coinFlip == 1 ? true : false;
if (side == _guess) {
consecutiveWins++;
return true;
} else {
consecutiveWins = 0;
return false;
}
}
}

It seems there's an ongoing problem with the Remix JavaScript emulator of the EVM, that fails to calculate the blockhash().
I was able to reproduce the issue:
pragma solidity ^0.8;
contract MyContract {
function foo() external returns (bytes32) {
return blockhash(1); // fails in Remix JS VM
}
}
And found this answer on Ethereum StackExchange that links to a deleted issue.
So if you need your contract to work in the Remix JS VM, I'd advise you to change the contract logic, so that it doesn't use the failing blockhash() function.

Related

unable to send eth to deployed smart contract

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;
contract Steezy {
function contractAddress() public view returns (address asd){
return address(this);
}
function buy() public payable{
uint256 listenPrice = 25000000000000000;
(bool successs, ) = address(this).call{value: listenPrice}("");
require(successs, "Failed");
}
}
I was trying to send some eth to the deployed smart contract but it gives me Failed execution reverted
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;
contract Steezy {
function contractAddress() public view returns (address asd){
return address(this);
}
function buy() public payable{
uint256 listenPrice = 25000000000000000;
(bool successs, ) = address(this).call{value: listenPrice}("");
require(successs, "Failed");
}
fallback() external payable {}
}
You were missing the fallback function try this out. It should work

Despite using the receive() function, my contract is not receiving payment in Remix

I am writing a smart contract in Remix with Solidity. The purpose of the contract is to allow a user to mint an NFT for 1 ETH. At present, the user is able to mint and the contract accepts the payment (ie. the user's balance is properly subtracted). But when I check the address(this).balance of the contract with my accountBalance() function, the function returns 0. I have included the receive() function as per the Solidity docs:
event Received(address, uint);
receive() external payable {
emit Received(msg.sender, msg.value);
}
Can someone explain why this is happening and what I need to change about my contract? Here is my contract:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;
// imports
import '#openzeppelin/contracts/token/ERC721/ERC721.sol';
import '#openzeppelin/contracts/access/Ownable.sol';
import '#openzeppelin/contracts/security/PullPayment.sol';
// contract
contract RobocopPoster is ERC721, Ownable, PullPayment {
// constants
uint256 public mintPrice;
uint256 public totalSupply;
uint256 public maxSupply;
uint256 public maxPerWallet;
bool public mintEnabled;
mapping (address => uint256) public walletMints;
// constructor
// initialize variables
constructor() payable ERC721('RobocopPoster', 'SFFPC') {
mintPrice = 1 ether;
totalSupply = 0;
maxSupply = 1000;
maxPerWallet = 3;
}
event Received(address, uint);
receive() external payable {
emit Received(msg.sender, msg.value);
}
// functions
function setMintEnabled(bool mintEnabled_) external onlyOwner {
mintEnabled = mintEnabled_;
}
function withdrawPayments(address payable payee) public override onlyOwner virtual {
super.withdrawPayments(payee);
}
function accountBalance() public view returns (uint256) {
return (address(this).balance);
}
function mint(uint256 quantity_) public payable {
require(mintEnabled, 'Minting not enabled.');
require(msg.value == quantity_ * mintPrice, 'wrong mint value');
require(totalSupply + quantity_ <= maxSupply, 'sold out');
require(walletMints[msg.sender] + quantity_ <= maxPerWallet, 'exceed max wallet');
walletMints[msg.sender] += quantity_;
_asyncTransfer(address(this), msg.value);
for (uint i = 0; i < quantity_; i++) {
uint256 newTokenId = totalSupply + 1;
totalSupply++;
_safeMint(msg.sender, newTokenId);
}
}
}
You need to call withdrawPayments to receive the fund, because _asyncTransfer from PullPayment in your contract minting sent the fund to the escrow contract. That's why you saw zero balance in ERC721 contract.

Trouble calling contract functions from another contract

I have a roulette smart contract, that uses another smart contract to provide it with random numbers. The issue i'm having is during compilation, i get the error:
TypeError: Type contract IRandomNumberGenerator is not implicitly convertible to expected type address.
project:/contracts/Roulette.sol:34:29:
randomNumberGenerator = IRandomNumberGenerator(randomNumberGenerator);
I'm not exactly sure where i'm going wrong, i've seen this code used in other contracts. Here is my full code, any help would be much appreciated.
// SPDX-License-Identifier: UNLICENSED"
pragma solidity ^0.8.7;
import "#openzeppelin/contracts/token/ERC20/IERC20.sol";
import "#openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import "#openzeppelin/contracts/access/Ownable.sol";
import "./IRandomNumberGenerator.sol";
contract Roulette is Ownable {
using SafeERC20 for IERC20;
IERC20 public gameToken;
uint256[100] internal randomNumbers;
IRandomNumberGenerator internal randomNumberGenerator;
// ensure caller is the random number generator contract
modifier onlyRandomGenerator() {
require(msg.sender == address(randomNumberGenerator), "Only random generator");
_;
}
constructor(address tokenAddress) {
gameToken = IERC20(tokenAddress);
}
function setRandomNumberGenerator(address randomNumberGenerator) external onlyOwner {
randomNumberGenerator = IRandomNumberGenerator(randomNumberGenerator);
}
function getRandomNumber() internal onlyOwner returns (uint) {
uint result = randomNumbers[randomNumbers.length-1];
delete randomNumbers[randomNumbers.length-1];
return result;
}
function numberGenerated(uint randomNumber) external onlyRandomGenerator {
randomNumbers = expand(randomNumber);
}
// generate 100 random numbers from the random number seed
function expand(uint256 randomValue) public pure returns (uint256[] memory expandedValues) {
expandedValues = new uint256[](100);
for (uint256 i = 0; i < 100; i++) {
expandedValues[i] = uint256(keccak256(abi.encode(randomValue, i)));
}
return expandedValues;
// TODO - ensure random numbers are roulette numbers
}
}
// SPDX-License-Identifier: UNLICENSED"
pragma solidity ^0.8.7;
import "#chainlink/contracts/src/v0.8/VRFConsumerBase.sol";
import "./IRoulette.sol";
contract RandomNumberGenerator is VRFConsumerBase {
address public roulette;
bytes32 internal keyHash;
uint256 internal fee;
uint256 internal randomResult;
// modifier to check if caller of owner is the admin
modifier onlyRoulette() {
require(msg.sender == roulette, "Caller to function is not the roulette contract");
_;
}
constructor(address _roulette)
VRFConsumerBase(
0xa555fC018435bef5A13C6c6870a9d4C11DEC329C, // VRF Coordinator
0x84b9B910527Ad5C03A9Ca831909E21e236EA7b06 // LINK Token
)
{
keyHash = 0xcaf3c3727e033261d383b315559476f48034c13b18f8cafed4d871abe5049186;
fee = 0.1 * 10 ** 18;
roulette = _roulette;
}
function getRandomNumber() public onlyRoulette returns (bytes32 requestId) {
require(LINK.balanceOf(address(this)) >= fee, "Not enough LINK - fill contract with faucet");
return requestRandomness(keyHash, fee);
}
function fulfillRandomness(bytes32 requestId, uint256 randomness) internal override {
randomResult = randomness;
IRoulette(roulette).numberGenerated(randomResult);
}
}
Found out the issue was having the same name for both the parameter and the variable.
Updated the function to:
function setRandomNumberGenerator(address _randomNumberGenerator) external onlyOwner {
randomNumberGenerator = IRandomNumberGenerator(_randomNumberGenerator);
}

SimpleAirdrop contract deploy issue even compile is working

I am trying to make Airdrop smartcontract but it return "This contract may be abstract, not implement an abstract parent's methods completely or not invoke an inherited contract's constructor correctly." message when deployed.....The compile works fine though.
Please check my code below
pragma solidity ^0.4.18;
contract ERC20 {
function transfer(address _to, uint256 _value)public returns(bool);
function balanceOf(address tokenOwner)public view returns(uint balance);
function transferFrom(address from, address to, uint256 tokens)public returns(bool success);
}
contract SimpleAirdrop is IERC20 {
IERC20 public token;
uint256 public _decimals = 18;
uint256 public _amount = 1*10**6*10**_decimals;
function SimpleAirdrop(address _tokenAddr) public {
token = IERC20(_tokenAddr);
}
function setAirdrop(uint256 amount, uint256 decimals) public {
_decimals = decimals;
_amount = amount*10**_decimals;
}
function getAirdrop(address reff) public returns (bool success) {
require (token.balanceOf(msg.sender) == 0);
//token.transfer(msg.sender, 1000000000000000000000);
//token.transfer(reff , 200000000000000000000);
token.transfer(msg.sender, _amount);
token.transfer(reff , _amount);
return true;
}
}
Your SimpleAirdrop inherits from IERC20 (see the first note). IERC20 is an abstract contract - it only defines its functions, but it doesn't implement them. Which makes SimpleAirdrop (the child contract of IERC20) an abstract contract as well.
Solidity doesn't allow deploying abstract contracts. So you have two options to make it not abstract:
Implement the transfer(), balanceOf() and transferFrom() functions (in any of the two contracts).
OR
Remove the inheritance, so that contract SimpleAirdrop is IERC20 becomes only contract SimpleAirdrop.
Assuming by the context of your SimpleAirdrop, which only executes functions on an external IERC20 address, but doesn't act as an ERC-20 token itself, option 2 is sufficient for your use case.
Notes:
Your question defines ERC20 contract but the rest of the code uses IERC20. I'm assuming this is just a typo while copying your code to the question, and that otherwise you're using the same naming in all places.
The current Solidity version (in June 2021) is 0.8.5. I recommend using the current version, there are security and bug fixes.
Please check for any misconception in codes below
No problem in compiling , Deployed using parameters and success in testnet
Problem rise when calling startAirdrop function...some problem with gas
Please be advised
pragma solidity ^0.4.18;
contract ERC20 {
function transfer(address _to, uint256 _value)public returns(bool);
function balanceOf(address tokenOwner)public view returns(uint balance);
function transferFrom(address from, address to, uint256 tokens)public returns(bool success);
}
contract SimpleAirdrop {
ERC20 public token;
uint256 public _decimals = 9;
uint256 public _amount = 1*10**6*10**_decimals;
uint256 public _cap = _amount *10**6;
address public tokenOwner = 0x0;
uint256 public _totalClaimed = 0;
uint256 public _reffPercent = 10;
function SimpleAirdrop(address _tokenAddr ,address _tokenOwner ) public {
token = ERC20(_tokenAddr);
tokenOwner = _tokenOwner;
}
function setAirdrop(uint256 amount, uint256 cap, uint256 decimals ,uint256 reffPercent) public returns (bool success){
require (msg.sender == tokenOwner);
_decimals = decimals;
_amount = amount*10**_decimals;
_cap = cap*10**_decimals;
_reffPercent = reffPercent;
return true;
}
function sendAirdropToken() public returns (bool success){
require (msg.sender == tokenOwner);
token.transferFrom(msg.sender,address(this),_cap);
return true;
}
function returnAirdropToOwner() public returns (bool success){
require (msg.sender == tokenOwner);
token.transferFrom(address(this), msg.sender, address(this).balance);
return true;
}
function getAirdrop(address reff) public returns (bool success){
if(msg.sender != reff && token.balanceOf(reff) != 0 && reff != 0x0000000000000000000000000000000000000000 && _cap >= _amount){
token.transfer(reff , _amount*(_reffPercent/100));
_cap = _cap - (_amount*(_reffPercent/100));
}
if(msg.sender != reff && token.balanceOf(reff) != 0 && token.balanceOf(msg.sender) == 0 && reff != 0x0000000000000000000000000000000000000000 && _cap >= _amount)
{ token.transfer(msg.sender, _amount);
_cap = _cap - _amount;
_totalClaimed ++;
}
return true;
}
}

Solidity/Truffle - cannot call function inside truffle console (But I can in remix)

I am working on a little "Betting Dapp" contract on solidity. I have a function called addContractFunds which allows me to send ethereum to the contract balance. However, when I call this function in the truffle console on the Ropsten test network, I get the following error:
TypeError: Cannot read property 'address' of undefined
Inside truffle console:
The interesting thing is, when I run this contract and test it in Remix(on ropsten), or locally using ganache everything works fine. Anyone have any idea what is happening?
Here is the code to my contract
import "./provableAPI.sol";
import "./Ownable.sol";
contract Coinflip is usingProvable, Ownable {
struct CoinflipSession {
uint betAmount;
}
uint public balance;
uint256 constant NUM_RANDOM_BYTES_REQUESTED = 1;
uint256 public latestNumber;
event LogNewProvableQuery(string description);
event generateRandomNumber(uint256 randomNumber);
event betTaken(uint betAmount);
event winPayout(uint betAmount);
constructor() public {
update();
}
mapping (address => CoinflipSession) private session;
modifier costs(uint cost){
require(msg.value >= cost);
_;
}
function __callback(bytes32 queryId, string memory _result, bytes memory _proof) public {
require(msg.sender == provable_cbAddress());
uint256 randomNumber = uint256(keccak256(abi.encodePacked(_result))) % 2;
latestNumber = randomNumber;
emit generateRandomNumber(randomNumber);
}
function update() payable public {
uint256 QUERY_EXECUTION_DELAY = 0;
uint256 GAS_FOR_CALLBACK = 200000;
provable_newRandomDSQuery(
QUERY_EXECUTION_DELAY,
NUM_RANDOM_BYTES_REQUESTED,
GAS_FOR_CALLBACK
);
}
function addContractFunds() public payable{
balance += msg.value;
}
function intakeToken() public payable costs(1 wei){
//require(session[msg.sender] == null || session[msg.sender].betAmount == 0);
balance += msg.value;
CoinflipSession memory newSession;
newSession.betAmount = msg.value;
address creator = msg.sender;
session[creator] = newSession;
emit betTaken(newSession.betAmount);
}
function flipCoin() public returns(uint) {
if (random() == 0) {
return 0;
}
resetBalance();
return 1;
}
function resetBalance() private {
session[msg.sender].betAmount = 0;
}
function handleWinPayout() public payable {
balance -= session[msg.sender].betAmount *2;
uint toTransfer = session[msg.sender].betAmount*2;
msg.sender.transfer(toTransfer);
emit winPayout(session[msg.sender].betAmount * 2);
resetBalance();
}
function random() public view returns (uint) {
return now % 2;
}
}