0

i got stucked in it and i don't understand where the error is...

Is a Lottery Project and the problem comes in placeABid function in lottery.sol contract.

Below i attached my code:

LotteryToken.sol

//SPDX-License-Identifier: MIT

import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";


pragma solidity ^0.8.4;

contract LotteryToken is Ownable, ERC20{

    mapping(address=>uint)private _balances;


    constructor(string memory name, string memory symbol, uint totalSupply)ERC20(name, symbol){
        _mint(msg.sender, totalSupply);
        _balances[msg.sender] = totalSupply;

    }

    

    function increaseAllowance(address spender, uint256 addedValue) public virtual override returns (bool) {
        address owner = owner();
        _approve(owner, spender, allowance(owner, spender) + addedValue);
        return true;
    }



    function _transfer(
        address _from,
        address _to,
        uint _amount
        )internal virtual override{
            _balances[_from] -= _amount;
            _balances[_to] += _amount;
            super._transfer(_from, _to, _amount);
        }
    


    function balanceOf(address account)public view virtual override returns(uint){
        return _balances[account];
    }

}

Lottery.sol

//SPDX-License-Identifier: MIT

import "@openzeppelin/contracts/access/Ownable.sol";
import "./LotteryToken.sol";
import "./LotteryInfo.sol";

pragma solidity ^0.8.4;

contract Lottery is Ownable{

    LotteryInfo private lotteryInfo;
    LotteryToken private lotteryToken;

    event BidCorrect(address bidder, uint tokenId, uint defaultBid);

    constructor(){

    }


    function initLotteryTokenContract(address _lotteryTokenContract)public onlyOwner{
        lotteryToken = LotteryToken(_lotteryTokenContract);
        lotteryToken.increaseAllowance(address(this), lotteryToken.balanceOf(lotteryToken.owner()));
    }



    function initLotteryInfoContract(address _lotteryInfoContract)public onlyOwner{
        lotteryInfo = LotteryInfo(_lotteryInfoContract);
    }

    

    function setItemToWin(
        string memory _name,
        uint _defaultBid,
        uint _endingTimeLottery
        )public onlyOwner{
            require(_endingTimeLottery > block.timestamp, "Cannot set a date in the Past!");
            lotteryInfo.setItemToWin(_name, _defaultBid, _endingTimeLottery);
    }



    function buyTokens(uint _quantity)external payable{
        uint singleTokenPrice = 0.02 ether;
        uint finalPrice = singleTokenPrice * _quantity;
        require(msg.sender != owner() && msg.sender != lotteryToken.owner(), "Admin Cannot Buy Tokens!");
        require(msg.value == finalPrice, "Please set the right price!");
        payable(owner()).transfer(msg.value);
        address lotterytokenOwner = lotteryToken.owner();
        lotteryToken.transferFrom(lotterytokenOwner, msg.sender, _quantity);
    }



    function placeABid(uint _tokenIds)external{
        require(block.timestamp < lotteryInfo.getEndingTimeLottery(_tokenIds), "Lottery is closed!");
        require(msg.sender != owner() && msg.sender != lotteryToken.owner(), "Admin Cannot Place A Bid!");
        uint requiredTokenAmounts = lotteryInfo.getDefaultItemBid(_tokenIds);
        require(lotteryToken.balanceOf(msg.sender) >= requiredTokenAmounts, "No Necessary Funds To Partecipate!");
        address lotteryTokenOwner = lotteryToken.owner();
        lotteryToken.transferFrom(msg.sender, lotteryTokenOwner, requiredTokenAmounts);
        lotteryInfo.updateBid(_tokenIds, requiredTokenAmounts);
        lotteryInfo.updateAddress(_tokenIds, msg.sender);
        emit BidCorrect(msg.sender, _tokenIds, requiredTokenAmounts);
    }

There is another contract LotteryInfo but doesn't need to understand the problem.

What i want to do is to place a bid and send back the amount of bid to the lotteryToken.owner() but i receive error revert "ERC20 insufficient allowance". Can someone explain me why? Thanks a lot

  • Does this answer your question? [ERC20: insufficient allowance](https://stackoverflow.com/questions/71808619/erc20-insufficient-allowance) – Martijn Vissers Aug 24 '22 at 15:01
  • @MartijnVissers not really, because at the beginning (buyTokens function) it works, but it doesn't athe placeABid function. I tried the transfer function using parameter as msg.sender, requiredTokenAmounts but i got the error as well like.............. revert 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. Debug the transaction to get more information. – Matteo Gigli Aug 24 '22 at 16:42

2 Answers2

0

You have to call "approve" method from the caller of "placeABid" function. He/She has to approve your Lottery contract to spend (calling transferFrom) he/shes ERC20 tokens. Without increasing the allowance (approval) of ERC20, you wont be able to withdraw ERC20 tokens from msg.sender.

You can detaily check ERC20 standart contract from OpenZeppelin library aswell.

0

First you have to call approve method from the caller of placeABid function. Then person has to approve your Lottery contract to spend (calling transferFrom) the ERC20 tokens. Without increasing the allowance (approval) of ERC20, you wont be able to withdraw ERC20 tokens from msg.sender.

If amount is the maximum uint256, the allowance is not updated on * transferFrom. This is semantically equivalent to an infinite approval. * Requirements: - spender cannot be the zero address.

Here's a reference link

deaponn
  • 837
  • 2
  • 12