TransWikia.com

How to Fix "Stack Too Deep" Error?

Ethereum Asked by Jeffrey Liang on December 29, 2020

I know that this has been covered in other questions here but I’m not sure what’s happening in my case. My code is returning a compiler error “Stack too deep, try removing local variables.” But I only have around five function arguments and a few more local variables. The function in question is given below:

function sell(bool limit, uint256 whichquery, uint8 whichoutcome, uint256 amount, uint16 price) {
        uint cumulativeamountgained;
        uint numorderstobedeleted;
        uint amountnotfilled = amount;
        if(tokenHoldings[msg.sender][whichquery][whichoutcome] < amount) throw;
        if(limit){
            for (uint i=orderbook[whichquery][whichoutcome][0].length-1;i>=0;i--){
                if(orderbook[whichquery][whichoutcome][0][i][0] >= price) {
                    if(orderbook[whichquery][whichoutcome][0][i][1] > amountnotfilled){
                        orderbook[whichquery][whichoutcome][0][i][1] -= amountnotfilled;
                        tokenHoldings[address(orderbook[whichquery][whichoutcome][0][i][2])][whichquery][whichoutcome] += amountnotfilled;

The error is triggered on the last line of this code snippet under the first “whichquery”.

4 Answers

You can also scope variables like this

uint var1;
{
    (uint varA, uint varB) = getVars();
    var1 = varA + varB;
}

// now use var1

Inspired by Uniswap.

Answered by Markus - soliditydeveloper.com on December 29, 2020

Found nice trick to avoid "Stack too deep" issue:

function swapWithReferral(
    IERC20 fromToken,
    IERC20 destToken,
    uint256 amount,
    uint256 minReturn,
    uint256[] calldata distribution,
    uint256 flags,
    address referral,
    uint256 feePercent
) external makeGasDiscount(flags) returns(uint256 returnAmount) {
    ...
    fromToken.transferFrom(address(this), amount); // <-- Stack too deep
    ...
    destToken.transfer(msg.sender, returnAmount);  // <-- Stack too deep
    ...
}

Just define few additional internal functions like _fromToken() and _destToken() to decode args:

// Helps to avoid "Stack too deep" in swap() method
function _fromToken(bytes memory data) internal pure returns(IERC20 token) {
    assembly {
        token := mload(add(data, 36))
    }
}

// Helps to avoid "Stack too deep" in swap() method
function _destToken(bytes memory data) internal pure returns(IERC20 token) {
    assembly {
        token := mload(add(data, 68))
    }
}

And use these functions instead of access to those vars:

function swapWithReferral(
    IERC20 /*fromToken*/,
    IERC20 /*destToken*/,
    uint256 amount,
    uint256 minReturn,
    uint256[] calldata distribution,
    uint256 flags,
    address referral,
    uint256 feePercent
) external makeGasDiscount(flags) returns(uint256 returnAmount) {
    ...
    _fromToken(msg.sender).transferFrom(address(this), amount); // Works great!
    ...
    _destToken(msg.sender).transfer(msg.sender, returnAmount);  // Works great!
    ...
}

Notice: Be careful with internal and public functions, since msg.data is updated only on external calls. You can externally call public function with this.doSomething().

Answered by k06a on December 29, 2020

The limit of having not more than 16 local variables could be a problem here. You can try to refactor your code and probably break this function into two parts. That should fix the issue I hope.

Please read the article Solidity stack too deep by James Carlyle to understand more about this issue.

Answered by Sanchit on December 29, 2020

there is limited amount of local variables you are allowed to declare in your function(arguments and return types inclusive), i think it is 16, but as it seems you have exceeded that limit.

Answered by coderwithattitude on December 29, 2020

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP