7

I'm running into a YulException: Stack too deep when compiling inline assembly: Variable headStart is 1 slot(s) too deep inside the stack. using a smart contract that has this function. I took this function off and the error goes away, so I assume the error is within it. I searched a bit for this error, read this and this and this and concluded the EVM stack has a 16 limit of variables. Although my function has 12, I changed my string to bytes32 cause I read that string take 2 spaces. I also tried removing one of the function params, and it works great again. Although I need all these parameters to create a new struct. Any suggestions on how I should fix this situation?

pragma solidity ^0.6.2;
pragma experimental ABIEncoderV2;
...
        function addObservacaoPragas(
                bytes32 _unidadeProducao,
                bytes32 _parcela,
                bytes32 _subParcela,
                uint256 _estadoFenologico,
                bytes32 _armadilha,
                uint256 _tipo,
                bytes32 _praga,
                uint256 _leitura,
                uint256 _inicioOperacao,
                uint256 _fimOperacao,
                bytes32 _responsavel,
                bytes32 _nota
            ) public returns (...) {
              ...
            }
    ...

Here is a full example in case you want to try it in remix:

pragma solidity ^0.6.2; pragma experimental ABIEncoderV2;

contract Operacoes {
    All all;
    uint256 operacaoId;

    // All Operations inside All
    struct All {
        ObservacaoPragas[] observacoesPragas;
    }

    // Common to all operations
    struct CommonOperacao {
        uint256 id;
        uint256 inicioOperacao;
        uint256 fimOperacao;
        bytes32 responsavel;
        bytes32 nota;
    }


    struct ObservacaoPragas {
        bytes32 unidadeProducao;
        bytes32 parcela;
        bytes32 subParcela;
        EstadoFenologico estadoFenologico;
        bytes32 armadilha;
        ObservacaoPragasTipo tipo;
        bytes32 praga;
        uint256 leitura;
        CommonOperacao op;
    }
    // Enums
    enum EstadoFenologico {
        GOMO_DE_INVERNO,
        INICIO_DO_INCHAMENTO_DOS_GOMOS,
        FIM_DO_INCHAMENTO_DOS_GOMOS,
        ABROLHAMENTO,
        FOLHAS_LIVRES,
        CACHOS_VISIVEIS,
        CACHOS_SEPARADOS,
        BOTOES_FLORAIS_SEPARADOS,
        FLORACAO,
        PLENA_FLORACAO,
        BAGO_DE_ERVILHA,
        FECHO_DOS_CACHOS,
        PINTOR,
        MATURACAO
    }
    enum ObservacaoPragasTipo {LEITURA, INSTALACAO, REMOCAO, TROCAR_PLACA}

    constructor() public {
        operacaoId = 0;
    }


    /********************/
    /* Observação Pragas*/
    /********************/
    function addObservacaoPragas(
        bytes32 _unidadeProducao,
        bytes32 _parcela,
        bytes32 _subParcela,
        uint256 _estadoFenologico,
        bytes32 _armadilha,
        uint256 _tipo,
        bytes32 _praga,
        uint256 _leitura,
        uint256 _inicioOperacao,
        uint256 _fimOperacao,
        bytes32 _responsavel,
        bytes32 _nota
    ) public returns (ObservacaoPragas memory) {
        ObservacaoPragas memory obs = ObservacaoPragas(
            _unidadeProducao,
            _parcela,
            _subParcela,
            EstadoFenologico(_estadoFenologico),
            _armadilha,
            ObservacaoPragasTipo(_tipo),
            _praga,
            _leitura,
            CommonOperacao(
                operacaoId,
                _inicioOperacao,
                _fimOperacao,
                _responsavel,
                _nota
            )
        );

        all.observacoesPragas.push(obs);
        operacaoId++;
        return obs;
    }


    /*****************/
    /* Common to all */
    /*****************/
    function retrieveAllOperacoes() public view returns (All memory) {
        return all;
    } }
6
  • 1
    Since you are using ABIEncoderV2, should work if you enable optimization.
    – alberto
    Feb 10, 2020 at 17:28
  • 2
    Since you are using ABIEncoderV2 then you can pass the struct directly as parameter function addObservacaoPragas(ObservacaoPragas memory obs) public returns (ObservacaoPragas memory).
    – Ismael
    Feb 10, 2020 at 18:15
  • 1
    @alberto that indeed fixes the compilation error, thank you for the suggestion, although I think this solves a problem but later may make my contract extremely expensive and slow, am I right to assume that? Feb 11, 2020 at 10:26
  • 1
    So I will first try @Ismael approach and check if it is lighter/faster? Thank you bough, either way! Feb 11, 2020 at 10:26
  • @JoãoQuintanilha It is possible as you say, but also the use of ABIEncoderV2 could be risky as it may contain bugs.
    – alberto
    Feb 12, 2020 at 9:59

1 Answer 1

1

its because in function addObservacaoPragas(), you are getting 12 arguments. in solidity if you pass more than 7 arguments to a function it generates that error, solution for this is to pass these arguments as array of bytes and loop it thorough to assign the to global variable, or create a struct for these variables and in function signature take the type of that struct for example

struct Info{
uint256 id;
address user;
}

Info infos;

function getInfo(Info memory info) external{
 infos.id = info.id;
}

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.