4

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;
    } }
  • 1
    Since you are using ABIEncoderV2, should work if you enable optimization. – alberto Feb 10 at 17:28
  • 1
    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 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? – João Quintanilha Feb 11 at 10:26
  • 1
    So I will first try @Ismael approach and check if it is lighter/faster? Thank you bough, either way! – João Quintanilha Feb 11 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 at 9:59

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.