0
// SPDX-License-Identifier: MIT

pragma solidity 0.8.17;

contract LotteryApplication
{
    address public manager;
    address payable [] public participants;
    address public LotteryWinner;
    uint public _TotalTokens;
    uint8 decimal;
    string public _TokenName;
    string public _TokenSymbol;
    uint public TokenPrice;
    mapping(address => uint)TokenBalance;
   
    
    constructor(string memory TokenName, string memory Tokensymbol)
    {
        manager = msg.sender;
        _TotalTokens = 1000;
        _TokenName = TokenName;
        _TokenSymbol = Tokensymbol;
        decimal = 18;
        TokenPrice = 100 wei;
    }

    //This receive function will only receive ether when the require condition is satisfied.
    //Then it will store the address of whoever sends ether to this contract in the array participants.
    receive() external payable   
    {
        require(msg.value == 100 wei, "Ticket Cost is 1 ether");
        participants.push(payable(msg.sender)); 
        TokenBalance[msg.sender] += 1 ;
        _TotalTokens -= 1;
    }

    //This fucntion will only allow the manager to check balance of the contract.
    function CheckBalance() public view returns(uint)
    {
        require(msg.sender == manager, "!!! You are not authorized");
        return address(this).balance;
    }

    //This function allows the users to check their token balance.
    function CheckTokenBalance(address _account) public view returns(uint)
    {
        uint balanceofToken;
        balanceofToken = TokenBalance[_account];
        return balanceofToken;
        
    }

    // This function generates a random interger number which is then used to select the winner.
    function random() public view returns (uint)
    {
        return uint(keccak256(abi.encodePacked(block.difficulty,block.timestamp,participants.length)));
    }

    //This function is used to select a winner. It uses the modulo operator to generate the index of the winner.
    //All the funds of the contract are then send to this winner address.
    //Once the funds have been sent to the winner the lottery will reset making the participants array empty.
    function SelectWinner() public
    {
        require(msg.sender == manager, "!!! Access Denied, You are not the Manager");
        require(participants.length >= 3, "!!! Aborting, not enough participans");
        uint r = random();
        uint index = r % participants.length;
        address payable winner;
        winner = participants[index];
        winner.transfer(CheckBalance());
        LotteryWinner = winner;
        participants = new address payable[](0);
    }
    function Reset_tokens() public payable
    {
        require(msg.sender == manager, "Aborting, you are not the manager");
        uint length = participants.length;
        uint i;
        for(i = 0; i <= length;i++)
        {
            TokenBalance[payable(participants[i])] = 0;
        }
       _TotalTokens = 1000;
    }

}

The above is my Code, and if you see the last function, I am trying to reset the tokens that I gave to the participants after the lottery is completed.

All the token Balances of the participants are stored in a mapping. All the addresses of the participants are stored in an array. So, I was trying to delete all the tokens given to the participants using the functionality shown in the ResetToken function.

But I get the following error: "The called function should be payable if you send value and the value you send should be less than your current balance"

I have tried making the function payable as well. And I am not sure why the error.

1 Answer 1

2

The issue with the Reset_tokens() function is that the loop condition in line 64 includes the length of the participants array as well, which causes an index out of bounds error when the loop reaches the end of the array.

So to solve this issue you'll have to change the condition of the loop from <= to < as follow

function Reset_tokens() public {
    require(msg.sender == manager, "Aborting, you are not the manager");

    uint length = participants.length;
    for (uint i = 0; i < length; i++) {
        TokenBalance[participants[i]] = 0;
    }
    _TotalTokens = 1000;
}

This should work fine, lemme know if you face any issue

2
  • Thanks a lot, Sajid, the error told "called function should be payable if you send value and the value you send should be less than your current balance". So, I was thinking it was because of a payable modifier error. Never thought it was due to my loop condition. Thanks a lot man. Any tips on how i can find these kinds of errors in future? Apr 1 at 4:52
  • 1
    Welcome. Well there's no specific tool or anything for that but it comes with practice Apr 3 at 4:12

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.