I have a function, shown in its entirety below, that is getting the dreaded "stack too deep" compiler error. I have read several of the other posts on this forum about this error, but all of them attribute it to passing too many parameters to the function. As you can see below, I only have 5 method parameters. I have marked the line that the compiler via Remix flags with the "stack too deep" error.
Why am I getting this error and how can I fix it?:
/**
* @notice Make payments to the bands and players by calculating and then storing
* the amount due them in the claims map. For bands that we don't find an
* address for in the band addresses array, put the amount in escrow
* for them, using the owner ID associated with a given ID as the escrow
* key.
*
* NOTE: All the array must be of the same length and are to be greated as
* "columns" of a table where each array element at the same index is
* onefield value in the row.
*
* @param _aryVideoIds - An array of the video IDs that were used in the
* game.
* @param _aryOwnerIds - An array of the entities that own each of the
* videos. For example, a channel ID for a YouTube video if this game was
* played using YouTube videos, where the channel belongs to the band that
* owns or made the video.
* @param _aryWinnerAddr - an array of the winners from each round of
* game play. Each winner in a row won the round the video ID for the video
* in the same row of the table.
* @param _aryBandAddr - an array of the addresses for each band that
* was involved in the game. Each address corresponds to the band who the
* video belongs to.
*/
function makePayments(
uint256 _gameId,
bytes32[] _aryVideoIds,
bytes32[] _aryOwnerIds,
address[] _aryWinnerAddr,
address[] _aryBandAddr
)
public payable
onlyIfValidGameId(_gameId) onlyIfHouseAddr(_gameId) onlyIfPlayingState(_gameId) {
// The arrays all must have the same length and that length must be non-zero.
require(_aryVideoIds.length > 0, "(makePayments) The video ID array is empty.");
require(_aryVideoIds.length == _aryOwnerIds.length && _aryOwnerIds.length == _aryWinnerAddr.length && _aryWinnerAddr.length == _aryBandAddr.length,
"(makePayments) One or more of the given arrays is not the same length.");
// Change the game to the GAME OVER state or several of the payment function
// calls below will fail because they require the game to be in the game over
// state.
// --------->>>>>>>> STACK TOO DEEP ERROR OCCURS HERE.
s_mapGameIdToGame[_gameId].gameState = enGameState.GAME_OVER;
uint256 numVideos = _aryVideoIds.length;
// Calculate the amount due the house.
uint256 housePayment = s_mapGameIdToGame[_gameId].gameBalance.div(100).mul(pct_house);
// Calculate the remaining funds after removing the house percentage.
uint256 remainder = s_mapGameIdToGame[_gameId].gameBalance - housePayment;
require(remainder > 0, "(makePayments) The game balance after removing the house percentage is 0 or less.");
uint256 bandPaymentPool = 0;
uint256 perBandPayment = 0;
uint256 playerPaymentPool = 0;
uint256 perVideoPayment = 0;
// Calculate the amount of money to be distributed to the bands and the players.
if (s_mapGameIdToGame[_gameId].bandDonationPercent == 0)
{
// Everything goes to the players.
playerPaymentPool = remainder;
perVideoPayment = playerPaymentPool.div(numVideos);
}
else if (s_mapGameIdToGame[_gameId].bandDonationPercent == 100)
{
// Everything goes to the bands.
bandPaymentPool = remainder;
perBandPayment = bandPaymentPool.div(numVideos);
}
else
{
// Split the remainder between the players and the bands according to the
// band donation percentage.
bandPaymentPool = remainder.div(100).mul(s_mapGameIdToGame[_gameId].bandDonationPercent);
// The band payment pool is distributed evenly across the number of participating bands.
perBandPayment = bandPaymentPool.div(numVideos);
// Calculate the amount of funds to distributed across the players.
playerPaymentPool = remainder.sub(bandPaymentPool);
// The per player payment is based on the number of games each player won. However,
// the amount paid for each video is based on the number of videos in the game.
perVideoPayment = playerPaymentPool.div(numVideos);
}
// Watch out for having no payments at all to make.
require(perBandPayment == 0 && perVideoPayment == 0, "(makePayments) There are no payments to be made for this game, given the current amounts.");
// Process the band payments if we have any.
if (perBandPayment > 0)
{
processBandPayments(_gameId, _aryOwnerIds, _aryBandAddr, perBandPayment);
}
if (perVideoPayment > 0)
{
// Process the player payments.
processPlayerPayments(_gameId, _aryWinnerAddr, perVideoPayment);
}
}