How to optimize gas cost of specific function on solidity

source code:https://testnet.bscscan.com/address/0x09850b9d949c71e1d9b7e9acaa3645ac5b63d6bb#code

This is a betting smart contract, I have a problem with the allocated prize. The gas cost is very high, it depends on the number of winners.

this is the function for allocating prize:

function allocatePrizes(uint _gameId, uint16 teamWinner) public onlyAgent {
        Game storage game = gameInfo[_gameId];
        require(bettingActive == false);
        address[1000] memory winners;
        address[1000] memory draw;
        //We have to create a temporary in memory array with fixed size
        //Let's choose 1000
       
        totalBets = 0;
        count = 0;
        
        //We loop through the player array to check who selected the winner team
        for( i = 0; i < players.length; i++){
            address 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++;
            }
            playerInfo[playerAddress]._state = PlayerStatus.Not_Joined;
        }


        //We define which bet sum is the Loser one and which one is the winner
        if ( teamWinner == 1){
            totalBets = totalBetsOne + totalBetsTwo;
        //We loop through the array of winners, to give ethers to the winners
        for(i = 0; i < count; i++){
            // Check that the address in this fixed array is not empty
            if(winners[i] != address(0)){
             add = winners[i];
             bets = playerInfo[add].amountBet;

            // token.transfer(winners[j],  (bets*(10000+(LoserBet*fee /WinnerBet)))/10000 );
             rewards = (bets*(10000-550 *(totalBets / totalBetsOne))) / 10000;
            _pendingBalance[add] += rewards;
            }
           
        }
        for(i=0; i < players.length; i++){
            add = players[i];
            if(players[i] != address(0)){
                delete playerInfo[add].amountBet;
                delete playerInfo[add].teamSelected;
                delete playerInfo[add];
            }
        }  
        bettingActive = true;
        gameInfo[_gameId] = Game(_gameId, State.Finished);
        game.state == State.Finished;
        players.length = 0; // Delete all the players array
        totalBets = 0;
        totalBetsOne = 0;
        totalBetsTwo = 0;  
        }
        else if(teamWinner == 2){
            totalBets = totalBetsOne + totalBetsTwo;  
        //We loop through the array of winners, to give ethers to the winners
        for( i = 0; i < count; i++){

            // Check that the address in this fixed array is not empty
            if(winners[i] != address(0)){
             add = winners[i];
             bets = playerInfo[add].amountBet;

            // token.transfer(winners[k],  (bets*(10000+(LoserBet*fee /WinnerBet)))/10000 );
            rewards = (bets*(10000-550 *(totalBets / totalBetsTwo))) / 10000; 
            _pendingBalance[add] += rewards;
            }
        }
    
        for(i=0; i < players.length; i++){
            add = players[i];
            if(players[i] != address(0)){
                delete playerInfo[add].amountBet;
                delete playerInfo[add].teamSelected;
                delete playerInfo[add];
            }
        }
        bettingActive = true;
        gameInfo[_gameId] = Game(_gameId, State.Finished);
        game.state == State.Finished;
        players.length = 0; // Delete all the players array
        totalBets = 0;
        totalBetsOne = 0;
        totalBetsTwo = 0;                
        }
        else if(teamWinner == 3){
            totalBets = totalBetsOne + totalBetsTwo;
            //We loop through the player array to check who selected the winner team
        num = 0;
        for( i = 0; i < players.length; i++){
            add = players[i];

            if(playerInfo[add].teamSelected == 1||playerInfo[add].teamSelected == 2){
                draw[num] = add;
                num++;
            }
        }
        //We loop through the array of winners, to give ethers to the winners
        for( i = 0; i < num; i++){
            // Check that the address in this fixed array is not empty
            if(draw[i] != address(0)){
             add = draw[i];
             bets = playerInfo[add].amountBet;

            // token.transfer(draw[m], (bets*(fee))/10000 );
            
            rewards = (bets*(10000-fee))/10000;
            _pendingBalance[add] += rewards;
        }
        bettingActive = true;
        gameInfo[_gameId] = Game(_gameId, State.Finished);
        game.state == State.Finished;
        delete playerInfo[add];
        delete playerInfo[add].amountBet;
        delete playerInfo[add].teamSelected;
        playerInfo[add]._state = PlayerStatus.Not_Joined;
        players.length = 0; // Delete all the players array
        totalBetsOne = 0;
        totalBetsTwo = 0;
        totalBets = 0;
        }
       
    }
       
    }

can anyone help me to optimize the function?

1 Like

you can Output Solidity contract sizes with Hardhat.

And Open optimizer in hardhat settings.

Just like this:


solidity:  {

    version: "0.8.2",

    settings: {

      optimizer: {

        enabled: true,

        runs: 200

      }

    }

  },

  contractSizer: { 

    alphaSort: true,

    runOnCompile: true,

    disambiguatePaths: false,

  }

Your business logic code can only be optimized by yourself. hope help you.

1 Like

A little complex for your function, I think you should simplify this function, maybe when a user get the prize, he can claim the reward by himself later.