1

I'm learning solidity language with Remix IDE using my phone then I encountered an error message like this:

CompilerError: Stack too deep. Try compiling with --via-ir (cli) or the equivalent viaIR: true (standard JSON) while enabling the optimizer. Otherwise, try removing local variables.
`principal,` code must be changed

enter image description here

This is the code I use:

    function _emit(uint256 loanId, LoanLibrary.Loan memory loan) private {
        emit LoanLibrary.LoanCreated(
            loanId,
            loan.offerId,
            loan.state,
            loan.principalToken,
            loan.collateralToken,
            loan.initialPrincipal,
            loan.currentPrincipal,
            loan.initialCollateral,
            loan.currentCollateral,
            loan.interestRate,
            loan.startDate,
            loan.maturityDate,
            loan.graceDays,
            loan.borrower,
            loan.lender
        );

Or you can see the code here: https://wtools.io/paste-code/bOUC

2 Answers 2

0

The stack-too-deep error is a commonly encountered error when writing smart contracts, especially those that deal with many different variables. See this excerpt from this article that explains what it is.

The reason is a limitation in how variables can be referenced in the EVM stack. While you can have more than 16 variables in it, once you try to reference a variable in slot 16 or higher, it will fail. It's therefore not always obvious why exactly some code is failing and then a few random changes just seem to fix it.

In your case, the error is being caused because you have too many variables inside your event's emit. You must either combine the variables into a struct and then emit that struct, or remove some of the variables.

For example this contract's function works correctly without any issue:

contract StackTooDeep {

event Stack(Too struc);


struct Too {
    uint num0;
    uint num1;
    uint num2;
    uint num3;
    uint num4;
    uint num5;
    uint num6;
    uint num7;
    address addr0;
    address addr1;
    address addr2;
    address addr3;
    address addr4;
    address addr5;
    address addr6;
    address addr7;
    bool bool0;
    bool bool1;
    bool bool2;
    bool bool3;
    bool bool4;
    bool bool5;
    bool bool6;
    bool bool7;
}

function deep(Too memory stu) public {
    emit Stack(stu);
}
}

When passed this as input to deep():

["0","1","2","3","4","5","6","7",
"0xd9145CCE52D386f254917e481eB44e9943F39138",
"0xd9145CCE52D386f254917e481eB44e9943F39138",
"0xd9145CCE52D386f254917e481eB44e9943F39138",
"0xd9145CCE52D386f254917e481eB44e9943F39138",
"0xd9145CCE52D386f254917e481eB44e9943F39138",
"0xd9145CCE52D386f254917e481eB44e9943F39138",
"0xd9145CCE52D386f254917e481eB44e9943F39138",
"0xd9145CCE52D386f254917e481eB44e9943F39138",
true,true,false,false,false,false,false,true]
0

Since you have a struct, are using events (indexed ones ?) and 15 variables in your function it is not surprising that you have the stack too deep error.

The EVM callstack can only handle properly the 16/17 elements. For instance the DUP opcode can only duplicate the 16 first elements of the stack while the SWAP opcode can swap from the first through the 17th element.

Possible solutions would be to:

  • lighten your variables in your struct.

  • split your variables in several structs.

  • pack your variables (learn about variable packing here).

  • Use internal functions to split the input & output.

There are couples of other solutions.

Here are two useful links that will provide you explanation and possible fixes.

https://soliditydeveloper.com/stacktoodeep

https://medium.com/aventus/stack-too-deep-error-in-solidity-5b8861891bae

Your Answer

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

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