Solidity - ParserError: Expected ';' but got '[' - ethereum

** I'm getting an error on the below mentioned line. ParserError: Expected ';' but got '[' . I'm using solidity version 0.8.7 in remix editor. Please help me regarding this problem **
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.7; //version
contract Lottery
{
address public manager;
address [] public players;
constructor()
{
manager = msg.sender;
}
function enter() public payable
{
require(msg.value > .01 ether);
players.push(msg.sender);
}
function random() private view returns(uint)
{
return uint(keccak256(abi.encodePacked(block.difficulty, block.timestamp, players)));
}
function pickWinner() public
{
uint index = random() % players.length;
address payable players[].transfer(); // error on this line
}
}

You're using incorrect syntax on this line:
address payable players[].transfer();
I'm assuming that you want to transfer some amount to the indexth player.
uint index = random() % players.length;
uint amount = address(this).balance; // whole ETH balance of this contract
payable(players[index]).transfer(amount);
You can also use the ether unit to specify an absolute value.
uint amount = 0.01 ether;
Note that your random() function could be theoretically exploited by a dishonest miner if they have a big enough incentive. See the second half of this answer for more into.

Related

Error message while executing solidity contract

I am learning solidity. The code i have written compiles correctly and the same solution is given in the solutions of the question but it keeps reverting without any output. Please check the code once and let me know the mistake.
The question is to transfer the given amount from the amount array to the to array from the same position, i.e., from ith position of amount to ith position of to.
It shows the error message : "The transaction has been reverted to the initial state.
Note: The called function should be payable if you send value and the value you send should be less than your current balance."
//SPDX-License-Identifier: UNLICENSED
pragma solidity >=0.5.0 <0.9.0;
contract Day4 {
address owner;
constructor() {
owner = msg.sender;
}
function send(address payable[] memory to, uint256[] memory amount)
public
payable
ownerOnly
{
require(to.length == amount.length, "to must be same length as amount");
for (uint256 i = 0; i < to.length; i++) {
to[i].transfer(amount[i]); //to array - 0x00 0x01 0x02
//amount array - 10 20 30
}
}
modifier ownerOnly() {
require(msg.sender == owner,"You are not the owner");
_;
}
}
Your issue depends from transfer() function. In details, this function allow you to transfer a specific amount from the smart contract balance to another address.
In your case, when you call directly send() function the smart contract balance is 0 because I think (since I don't see a deposit method) that you didn't deposit an amount to it.
For this reason, when you call send() function it reverts and doesn't works.
To solve this issue before call send() method, try to deposit a specific amount of ether to smart contract and then call send() method.
REMEMBER: The sum of array amount must be less to smart contract balance, otherwise it reverts.
I adjusted your smart contract in this way:
//SPDX-License-Identifier: UNLICENSED
pragma solidity >=0.5.0 <0.9.0;
contract Day4 {
address owner;
constructor() {
owner = msg.sender;
}
function send(address payable[] memory to, uint256[] memory amount)
public
payable
ownerOnly
{
require(to.length == amount.length, "to must be same length as amount");
for (uint256 i = 0; i < to.length; i++) {
to[i].transfer(amount[i]);
}
}
modifier ownerOnly() {
require(msg.sender == owner,"You are not the owner");
_;
}
// NOTE: Call this function for first, and before this operation set the values inside msg.value textbox in
// Remix IDE (if you're using it)
function deposit() public payable {
}
}

Large amount of wei not being processed by Solidity on Remix

U am trying to implement liquidity pools with Solidity, and had written two functions : addLiquidity() and withdraw() for it. However, the withdraw function doesn't seem to work with Remix when I try to withdraw large sums (like 0.001 ether), but works with sums like 150000 wei or something.
It doesn't seem to be an issue with Remix's IDE (i read somehere it has a problem working with large numbers), because even when I pass the 149999998499999985165 wei in double quotes (e.g. "149999998499999985165") the same error appears.
The error states: "Gas estimation errored with the following message (see below). The transaction execution will likely fail. Do you want to force sending?
execution reverted { "originalError": { "code": 3, "data": "0x4e487b710000000000000000000000000000000000000000000000000000000000000011", "message": "execution reverted" } }"
Code:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
interface linkStandardToken {
function transferFrom(address _from, address _to, uint256 _value) external returns (bool) ;
function balanceOf(address _owner) external returns (uint256) ;
function transfer(address to, uint tokens) external returns (bool success);
}
contract Uniswap
{
using SafeMath for uint256;
uint public totalLiquidity;
uint public balance;
address public owner;
address public tokenAddress = 0xaFF4481D10270F50f203E0763e2597776068CBc5; // REPLACE WITH ACTUAL TOKEN
linkStandardToken token;
bool public poolInit = false;
uint public protocolFees = 30; //in basis points i.e. divide by 10,000
uint public tempTokenPrice = 0;
mapping(address => uint) public liquidityBalances;
constructor()
{
owner = msg.sender;
token = linkStandardToken(tokenAddress);
}
function init(uint _tokenAmount) public payable
{
require(totalLiquidity == 0, "Already initialized");
require(_tokenAmount > 0, "Token amount must be > 0");
require(msg.value > 0, "Eth amount must be > 0");
totalLiquidity = totalLiquidity.add(_tokenAmount);
balance = balance.add(msg.value);
poolInit = true;
require(token.transferFrom(msg.sender, address(this), _tokenAmount), "Can't transfer tokens to contract");
setTokenToEthPrice();
}
fallback() payable external{}
receive() payable external{}
// _amount - input token amount, X - input token reserve, Y- output token reserve
function _swap(uint _amount, uint X , uint Y) public view returns (uint)
{
// code omitted
}
function swapEthToToken(/*uint _inputEthAmount*/) public payable
{
// code omitted
}
function swapTokenToEth(uint _tokenAmount) public payable
{
// code omitted
}
function setTokenToEthPrice() public // set to internal later
{
tempTokenPrice = _swap(1, balance , token.balanceOf(address(this))) ;
}
function addLiquidity(uint maxTokens) payable public returns (uint)
{
require(msg.value > 0, "msg.val <= 0");
require(totalLiquidity > 0, "totalLiquidity <= 0");
uint tokensBalance = getTokenBalance(address(this));
uint tokensToAdd = msg.value.mul(tokensBalance)/balance;
require(tokensToAdd <= maxTokens , "tokensToAdd > maxTokens");
balance= balance.add(msg.value);
uint mintedLiquidity = msg.value.mul(totalLiquidity)/balance;
liquidityBalances[msg.sender] = liquidityBalances[msg.sender].add(mintedLiquidity);
totalLiquidity = totalLiquidity.add(mintedLiquidity);
require(linkStandardToken(
0xaFF4481D10270F50f203E0763e2597776068CBc5)
.transferFrom(msg.sender, address(this), tokensToAdd));
return mintedLiquidity;
}
function withdraw9(uint256 amount, uint minimumEth, uint minimumTokens) public
{
require(liquidityBalances[msg.sender] >= amount, "Liquidity Balance of msg send < amount");
require(totalLiquidity > 0, "totalLiquidity <= 0");
uint tokenBalance = getTokenBalance(address(this));
uint temp = amount.mul(totalLiquidity);
uint etherToTransfer = temp.div(balance);
uint temp1 = amount.mul(totalLiquidity);
uint tokensToTransfer = temp1.div(tokenBalance);
require(minimumEth < etherToTransfer, "minimumEth >= etherToTransfer");
require(minimumTokens < tokensToTransfer, "minimumTokens >= tokensToTransfer");
balance = balance - etherToTransfer;
totalLiquidity = totalLiquidity.sub(amount);
liquidityBalances[msg.sender] = liquidityBalances[msg.sender].sub(amount);
address payable addr = payable(msg.sender);
addr.transfer(etherToTransfer);
require(linkStandardToken(
0xaFF4481D10270F50f203E0763e2597776068CBc5)
.transfer(msg.sender, tokensToTransfer), "Token transfer unsuccesful");
}
}
library SafeMath {
....// code emitted for compactness
}
As i can see in the last line of widthdraw9 function you use .transfer in order to send ether to some contract. I guess this contract have some code in receive function, so .transfer is not your choose. This function has a gas limitation and any code in receive can break it. If i correctly saw the problem then you should use .call function with enough amount of gas. More about these functions.
The "Gas estimation errored" message doesn't necessarily mean that the problem is with the amount of gas given, just that it hit some error while estimating the amount of gas needed.
The originalError.data has "0x4e487b71...". Looking up those high order 4 bytes on 4byte.directory shows that it's the signature for Panic(uint256), and the code in the low order bytes is "...00011" so the error code is 0x11 (17 decimal). The Solidity doc lists these codes, indicating:
0x11: If an arithmetic operation results in underflow or overflow outside of an unchecked { ... } block.
In the code, balance is not declared in uint etherToTransfer = temp.div(balance). If it's a state variable, could it be 0? Or is there a missing uint256 balance = liquidityBalances[msg.sender]?

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);
}

ParseError: Source file requires different compiler , when using chainlink-brownie-contracts

I'm trying to implement PatrickAlpha NFT implementation Github. When I followed readme instructions, collectibles are minted correctly. But If I tried to change anything in the code , it gives me error like this.
Compiling contracts...
Solc version: 0.6.6
Optimizer: Enabled Runs: 200
EVM Version: Istanbul
CompilerError: solc returned the following errors:
/Users/batuhansesli/.brownie/packages/smartcontractkit/chainlink-brownie-contracts#1.0.2/contracts/src/v0.6/VRFConsumerBase.sol:2:1: ParserError: Source file requires different compiler version (current compiler is 0.6.6+commit.6c089d02.Darwin.appleclang - note that nightly builds are considered to be strictly less than the released version
pragma solidity 0.6.0;
^--------------------^
For debug, I tried to change only ERC721 constructor parameters, but error occured again.
Original Code:
pragma solidity 0.6.6;
import "#openzeppelin/contracts/token/ERC721/ERC721.sol";
import "#chainlink/contracts/src/v0.6/VRFConsumerBase.sol";
contract AdvancedCollectible is ERC721, VRFConsumerBase {
uint256 public tokenCounter;
enum Breed{PUG, SHIBA_INU, ST_BERNARD}
// add other things
mapping(bytes32 => address) public requestIdToSender;
mapping(bytes32 => string) public requestIdToTokenURI;
mapping(uint256 => Breed) public tokenIdToBreed;
mapping(bytes32 => uint256) public requestIdToTokenId;
event requestedCollectible(bytes32 indexed requestId);
bytes32 internal keyHash;
uint256 internal fee;
constructor(address _VRFCoordinator, address _LinkToken, bytes32 _keyhash)
public
VRFConsumerBase(_VRFCoordinator, _LinkToken)
ERC721("Dogie", "DOG")
{
tokenCounter = 0;
keyHash = _keyhash;
fee = 0.1 * 10 ** 18;
}
function createCollectible(string memory tokenURI, uint256 userProvidedSeed)
public returns (bytes32){
bytes32 requestId = requestRandomness(keyHash, fee, userProvidedSeed);
requestIdToSender[requestId] = msg.sender;
requestIdToTokenURI[requestId] = tokenURI;
emit requestedCollectible(requestId);
}
function fulfillRandomness(bytes32 requestId, uint256 randomNumber) internal override {
address dogOwner = requestIdToSender[requestId];
string memory tokenURI = requestIdToTokenURI[requestId];
uint256 newItemId = tokenCounter;
_safeMint(dogOwner, newItemId);
_setTokenURI(newItemId, tokenURI);
Breed breed = Breed(randomNumber % 3);
tokenIdToBreed[newItemId] = breed;
requestIdToTokenId[requestId] = newItemId;
tokenCounter = tokenCounter + 1;
}
function setTokenURI(uint256 tokenId, string memory _tokenURI) public {
require(
_isApprovedOrOwner(_msgSender(), tokenId),
"ERC721: transfer caller is not owner nor approved"
);
_setTokenURI(tokenId, _tokenURI);
}
}
My Code :
pragma solidity 0.6.6;
import "#openzeppelin/contracts/token/ERC721/ERC721.sol";
import "#chainlink/contracts/src/v0.6/VRFConsumerBase.sol";
contract FootballerCollectible is ERC721, VRFConsumerBase {
bytes32 internal keyHash;
uint256 public fee;
uint256 public tokenCounter;
enum Player{MBAPPE, NEYMAR, MESSI, RONALDO}
mapping (bytes32 => address) public requestIdToSender;
mapping (bytes32 => string) public requestIdToTokenURI;
mapping (uint256 => Player) public tokenIdToPlayer;
event requestedCollectible(bytes32 indexed requestId);
constructor(address _VRFCoordinator, address _LinkToken, bytes32 _keyhash) public
VRFConsumer(_VRFCoordinator, _LinkToken)
ERC721("Footballer", "FTC")
{
keyHash = _keyhash;
fee = 0.1 * 10 ** 18;
tokenCounter = 0;
}
function createCollectible(uint256 userProvidedSeed, string memory tokenURI)
public returns (bytes32) {
bytes32 requestId = requestRandomness(keyHash, fee, userProvidedSeed);
requestIdToSender[requestId] = msg.sender;
requestIdToTokenURI[requestId] = tokenURI;
emit requestedCollectible(requestId);
}
function fulfillRandomness(bytes32 requestId, uint256 randomNumber) internal override{
address cardOwner = requestIdToSender[requestId];
string memory tokenURI = requestIdToTokenURI[requestId];
uint256 newItemId = tokenCounter;
_safeMint(cardOwner, newItemId);
_setTokenURI(newItemId, tokenURI);
Player player = Player(randomNumber % 4);
tokenIdToPlayer[newItemId] = player;
requestIdToTokenId[requestId] = newItemId;
tokenCounter = tokenCounter + 1;
}
function setTokenURI(uint256 tokenId, string memory _tokenURI) public {
require(
_isApprovedOrOwner(_msgSender(), tokenId),
"ERC721: transfer caller is not owner nor approved"
);
_setTokenURI(tokenId, _tokenURI);
}
}
Hi :) In the Error message that you received
Blockquote ParserError: Source file requires different compiler version (current compiler is 0.6.6+commit.6c089d02.Darwin.appleclang - note that nightly builds are considered to be strictly less than the released version
pragma solidity 0.6.0;
it says that you are trying to compile your contract with a different version of pragma solidity. The smart contract in question is:
[https://github.com/smartcontractkit/chainlink-brownie-contracts/blob/main/contracts/src/v0.6/VRFConsumerBase.sol]
which is using
pragma solidity ^0.6.0;
You are specifying to use version 0.6.6 in your contract which is later than the selected compiler. To get around this, you can either drop down to ^0.6.0 or you can change your pragma to
pragma solidity ^0.6.0;
For more information, you can read this ticket

How to declare constants in Solidity

I am really new to Solidity and smart contracts and would really appreciate some help. I am following a tutorial and this is the exact code they use. But when I compile the code I get this error:
ParserError: Expected primary expression.
address public constant approver = ;
pragma solidity ^0.6.0;
contract ApprovalContract {
address public sender;
address public receiver;
address public constant approver = ;
function deposit(address _receiver) external payable {
require(msg.value > 0);
sender = msg.sender;
receiver = _receiver;
}
function viewApprover() external pure returns(address) {
return(approver);
}
function approve() external {
require(msg.sender == approver);
receiver.transfer(address(this).balance);
}
}
The constant needs to be initialized
address public constant approver = YOURADDRESS;
There are 2 types of constant variables in Solidity:
Constants: a variable that is hardcoded in the smart contract and that you cannot change the value
Immutables: variables you can only define the value in the constructor and that cannot be updated afterwards
Here is an example:
uint256 public constant EXAMPLE_NUMBER = 123;
unit256 public immutable EXAMPLE_NUMBER_2;
constructor(uint256 _number) {
EXAMPLE_NUMBER_2 = _number;
}
You can read more about it here.