'Solidity dynamic arrays in memory: overflow bug

I was trying to create a lottery smart contract that stores every tickets (ticket = address) that someone buys into into an array to later on select winners from it. Unfortunately I stumbled into an overflow error at line 16, I have looked up at the debugger but I can't understand why it goes into overflow. The first piece of code is a solution that I come up to after seeing many people using fixed arrays instead of dynamic ones but still it doesn't work. I just want to understand why it throws that error and how I can solve it. Thank you in advance for your help!

the error:

"error": "Failed to decode output: Error: overflow (fault="overflow", operation="toNumber", value="35408467139433450592217433187231851964531694900788300625387963629091585785856", code=NUMERIC_FAULT, version=bignumber/5.5.0)"

//SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

contract Lottery{

    address[] public s_players; //storage

    function enterLottery(uint _tickets) public payable returns (address[] memory) {
        uint lotteryCost = _tickets*250000000000000000;
        address sender = msg.sender;
        require(msg.value >= lotteryCost, 'Ticket cant be purchased');
        address[] memory _players = new address[](1000);
        _players = s_players;
        uint index = _players.length;
        for (uint x = 0; x < _tickets; x++){
            _players[index] = payable(sender); //.push() only storage arrays = use index
            index += 1;
        }
        s_players = _players;
        // Tickets as input, return players
        return s_players;
    }
}
//SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

contract Lottery {

    address payable[] public s_players; //storage

    function enterLottery(uint _tickets) public payable returns (address payable[] memory) {
        uint lotteryCost = _tickets*500000000 gwei;
        require(msg.value >= lotteryCost, 'Ticket cant be purchased');
        address payable[] memory _players = s_players;
        uint length = _players.length;
        for (uint x = 0; x < _tickets; x = unsafe_inc(x)){
            _players[length] = payable(msg.sender); //.push() only storage arrays = use index
            length += 1;
        }
        s_players = _players;
        // Tickets as input, return players
        return s_players;
    }
}


Solution 1:[1]

Here is the code. The overflow came from the fact that your dynamic array was set to a static array value, and it lead to a number with 77 digits. In solidity the biggest possible number is 2^255 - 1, as that is how much 256 bits of information can store. (5.7896045e76)

//SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

contract Lottery {

    // dynamic array that stores all players
    address[] public s_players;

    // use _tickets when its a private function, it is a convention
    function enterLottery(uint tickets) public payable returns (address[] memory) {

        // we can use ether to represent 10**18 to make code clearer
        uint lotteryCost = _tickets * 25 ether / 100;
        address sender = msg.sender;
        require(msg.value >= lotteryCost, 'Ticket cant be purchased');

        // we use the for loop to push to the s_players array each iteration        
        for (uint x = 0; x < _tickets; x++){
            s_players.push(payable(sender));
            /*
            instead of creating a new length variable in this code,
            we could have instead just used x, because each time it
            loops, it is incremented (x++) */
        }
        
        // we then return the storage array
        return s_players;
    }

}

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 NikolaiSch