Transfer ether to smart contract user SOLIDITY - solidity

I am coding a coin flip contract. I have an issue with the amount sent by the smart contract to a player who wins the game.
What I want to do is: when you loose the coin flip, you loose your bet and when you win, you get 2 x the bet amount - our royalty. Yet, when I deploy the contract on Remix and test the PayWinner() function, I do not get 2x what I bet - royalty.
Thanks for your help!
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.16;
contract CoinFlip {
uint roundId;
uint betAmount;
uint royalty;
address owner;
address payable[] players;
struct round {
address payable player;
uint betAmount;
bool playerChoice; // 0 = heads; 1 = tails
bool draw;
bool win;
uint winAmount;
}
round public myRound;
mapping (uint => round) public flipHistory; // map the roundId with the round data
constructor() {
owner = msg.sender;
betAmount = 0;
roundId = 0;
}
function setRoyalty(uint _royalty) public onlyOwner returns (uint) {
return royalty = _royalty / 100;
}
function getRandomNumber(uint _bet, bool _playerChoice) public payable {
// minimum amount to be bet
require(msg.value > .001 ether);
// update the array players with the latest player
players.push(payable(msg.sender));
// update roundId
roundId = roundId+1;
// update player in Struct
myRound.player = payable(msg.sender);
// update betAmount in Struct
myRound.betAmount = _bet;
// update playerChoice in Struct
myRound.playerChoice = _playerChoice;
myRound.draw = uint256(keccak256(abi.encodePacked(
msg.sender,
)
)
)
% 2 == 1;
payWinner();
}
function payWinner() private {
if (myRound.draw == myRound.playerChoice) { // if else statement
myRound.win = true;
// compute amount to be transferred to winner
myRound.winAmount = myRound.betAmount * (2 - royalty);
// update mapping
flipHistory[roundId] = myRound;
payable(myRound.player).transfer(myRound.winAmount);
}
else {
myRound.win = false;
// update mapping
flipHistory[roundId] = myRound;
}
}
modifier onlyOwner() {
require(msg.sender == owner);
_;
}
}

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

Solidity Chainlink keepers with PriceFeeds

I'm trying to integrate Pricefeeds in the chain keepers to automate a sell order when the price goes under certain value.
Separately both work but when adding the Price feed function inside the checkUpkeep() it doesn't trigger the performUpkeep().
Does checkUpkeep() function can call the priceFeed function or is not even praepared for this?
how should I implement it then?
Here is the code:
function checkUpkeep(bytes memory /* checkData */) public view override returns (//,bytes memory value
bool upkeepNeeded,
bytes memory num
){
uint256 EthPrice = 0;
// uint256 i = 2;
EthPrice = getPrice();
num = abi.encodePacked(EthPrice);
if (EthPrice > 0){
upkeepNeeded = true;
}
return (upkeepNeeded, num);//, value
}
function performUpkeep(bytes calldata num) external override {//, bytes calldata value
(bool upkeepNeeded, ) = checkUpkeep("");
if (!upkeepNeeded) {
revert Order__UpkeepNotNeeded(
address(this).balance,
s_Wallets.length
);
}
//Byte conversion to uint
uint256 number;
number = abi.decode(num, (uint256));
// for(uint i=0;i<num.length;i++){
// number = number + uint(uint8(num[i]))*(2**(8*(num.length-(i+1))));
// }
s_nombre = number;
}

Solidity ParseError: Expected primary expression

When I am compiling with truffle it is giving me this error
I got this error after adding payable
prior to that it was
winners[j].transfer(betwa*(10000+(LoserBet*10000/WinnerBet))/10000);
I had to add it because I was getting another error
Which was
TypeError: "send" and "transfer" are only available for objects of type "address payable", not "address".
My Complete Contract :
pragma solidity ^0.5.16;
contract Betting {
address public owner;
uint256 public minimumBet;
uint256 public totalBetsOne;
uint256 public totalBetsTwo;
address[] public players;
struct Player {
uint256 amountBet;
uint16 teamSelected;
}
// The address of the player and => the user info
mapping(address => Player) public playerInfo;
function() external payable {}
constructor() public {
owner = msg.sender;
minimumBet = 100000000000000;
}
function kill() public {
if(msg.sender == owner) selfdestruct(msg.sender);
}
function checkPlayerExists(address player) public view returns(bool){
for(uint256 i = 0; i < players.length; i++){
if(players[i] == player) return true;
}
return false;
}
function bet(uint8 _teamSelected) public payable {
//The first require is used to check if the player already exist
require(!checkPlayerExists(msg.sender));
//The second one is used to see if the value sended by the player is
//Higher than the minimum value
require(msg.value >= minimumBet);
//We set the player informations : amount of the bet and selected team
playerInfo[msg.sender].amountBet = msg.value;
playerInfo[msg.sender].teamSelected = _teamSelected;
//then we add the address of the player to the players array
players.push(msg.sender);
//at the end, we increment the stakes of the team selected with the player bet
if ( _teamSelected == 1){
totalBetsOne += msg.value;
}
else{
totalBetsTwo += msg.value;
}
}
// Generates a number between 1 and 10 that will be the winner
function distributePrizes(uint16 teamWinner) public {
address[1000] memory winners;
//We have to create a temporary in memory array with fixed size
//Let's choose 1000
uint256 count = 0; // This is the count for the array of winners
uint256 LoserBet = 0; //This will take the value of all losers bet
uint256 WinnerBet = 0; //This will take the value of all winners bet
address playerAddress;
//We loop through the player array to check who selected the winner team
for(uint256 i = 0; i < players.length; i++){
playerAddress = players[i];
//If the player selected the winner team
//We add his address to the winners array
if(playerInfo[playerAddress].teamSelected == teamWinner){
winners[count] = playerAddress;
count++;
}
}
//We define which bet sum is the Loser one and which one is the winner
if ( teamWinner == 1){
LoserBet = totalBetsTwo;
WinnerBet = totalBetsOne;
}
else{
LoserBet = totalBetsOne;
WinnerBet = totalBetsTwo;
}
//We loop through the array of winners, to give ethers to the winners
for(uint256 j = 0; j < count; j++){
// Check that the address in this fixed array is not empty
if(winners[j] != address(0)){
address add = winners[j];
uint256 betwa = playerInfo[add].amountBet;
//Transfer the money to the user
payable(winners[j]).transfer( (betwa*(10000+(LoserBet*10000/WinnerBet)))/10000 );
}
}
delete playerInfo[playerAddress]; // Delete all the players
players.length = 0; // Delete all the players array
LoserBet = 0; //reinitialize the bets
WinnerBet = 0;
totalBetsOne = 0;
totalBetsTwo = 0;
}
function AmountOne() public view returns(uint256){
return totalBetsOne;
}
function AmountTwo() public view returns(uint256){
return totalBetsTwo;
}
}
What I have tried is making the address payable in this function but It is not working I have tried to replace memory with payable but still it isn't working
My versions
Truffle v5.4.18 (core: 5.4.18)
Solidity v0.5.16 (solc-js)
Node v14.15.1
Web3.js v1.5.3
The payable() conversion from address to address payable was introduced in Solidity 0.6.
Source: https://docs.soliditylang.org/en/latest/060-breaking-changes.html#new-features
Since your contract is using (deprecated) version 0.5.16, it doesn't allow this conversion. So you need to define the winners array already as address payable:
// added `payable`
address payable[1000] memory winners;
Then you'll be able to use the .transfer() method of the address payable type:
// `winners[j]` is payable
winners[j].transfer(...);

Coding Question of Auction smart contract

This is Auction smart contract.
I want to make Auction like this. If someone registers his product for biding, anyone who want to buy can join on this bidding.
But When I test on Remix, it can't be complied even.
I think my coding is problem.
Please help me.
pragma solidity ^0.5.0;
contract Auction{
//product for auction
struct Product{
string name;
string description;
uint time;
}
//top bid
uint topMoney;
//presen owner of product
mapping (uint => address) productToOwner;
//owner of top bidder
mapping (uint => address) topMoneyOwner;
event Listed(uint id, string name, uint itme);
Product[] public products;
//register product
function listUp(string memory _name, string memory _description) public {
//time limit for bidding, 1 minutes;
uint time = now + 1 minutes;
//index of product
uint id = products.push(Product(_name, _description, time)) - 1;
//initial bid = 0
topMoney=0;
//initial owner of product
productToOwner[id] = msg.sender;
emit Listed(id, _name, time);
}
//bidding
function bidOn() payable public {
if ( topMoney < msg.value){
topMoney = msg.value;
topMoneyOwner[topMoney] = msg.sender;
} else {
msg.sender.transfer(msg.value);
}
}
//bidding end? return (bool)
function _end(uint _id) private view returns (bool) {
require(now >= products[_id].time);
return true;
}
//who is winner? Then, transfer money to owner of product.
function winner(uint _id) public {
require( true == _end(_id));
address(uint160(productToOwner[_id])).transfer(topMoney);
productToOwner[_id] = topMoneyOwner[topMoney];
}
}

Solidity smart contract for lottery, but I can only give the prize for the first one. I want it to give it to all winners

Can't make it gives the prize for all winners, just the first one person that putted the right combination. I think there is a problem with findWinners function but I can't find it. If I make address A the good combination, then B with a not good one, and finally C with also a good one, it only gives the prize to A.
pragma solidity ^0.5.1;
contract Lottery {
Game[] ListGames;
// uint public nbGames = ListGames.length;
uint price = 100000;
uint[6] winnerGame;
// winnerGame = [1,2,3,4,5,6];
address payable[] ListWinners;
uint winnersPayed = 0;
uint expiredGames = 0;
struct Game {
address payable gamer;
uint[6] numbers;
uint date;
bool valid;
}
function setWinner(uint[6] memory _winnerGame) public {
winnerGame = _winnerGame;
}
function findWinners() public returns (address payable[] memory) {
uint size = ListGames.length;
bool win = true;
for (uint j = 0; j < size; j++) {
for (uint i=0; i<6 ; i++) {
if ((ListGames[j].numbers[i] != winnerGame[i]) || !ListGames[j].valid) {
win = false;
}
}
if (win) {
ListGames[j].valid = false;
expiredGames ++;
ListWinners.push(ListGames[j].gamer);
}
}
return ListWinners;
}
function payer() public returns (uint) {
uint nbWinners = ListWinners.length;
uint prize;
if (nbWinners - winnersPayed != 0) {
prize = address(this).balance / (nbWinners- winnersPayed);
for (uint i = 0; i < nbWinners; i++) {
if(ListWinners[i] != address(0)) {
ListWinners[i].transfer(prize);
delete ListWinners[i];
winnersPayed++;
require(ListWinners[i] == address(0));
}
}
}
return nbWinners;
}
modifier costs(uint amount) {
require(msg.value >= amount);
_;
}
function postGame(uint[6] memory _numbers) public payable costs(price) {
Game memory newGame = Game(msg.sender, _numbers, block. timestamp, true);
ListGames.push(newGame);
}
function numberValidGames() public view returns (uint) {
return ListGames.length - expiredGames;
}
function getWinnersList() public view returns (address payable [] memory) {
return ListWinners;
}
function getTime() public view returns (uint) {
return block.timestamp;
}
function getBalance() public view returns (uint) {
return address(this).balance;
}
}