Tadej Vengust
Tadej Vengust

Reputation: 1401

What are limitations of Event arguments?

Are there any limitation on the amount of arguments that can be send in an event?

I have a function in which I want to trigger event that has 12 arguments of which 6 arguments are arrays. I get Stack too deep, try using less variables. Without the event the function works normally.

I am guessing event arguments have some limitations or count towards max arguments in a solidity function but I cannot find any documentation around it.

Can anyone clarify this?

Edit:

The contract looks something like this: I'm using safe math and the _getAddressSubArrayTo is an internal pure function that gets a sub array from index to index.

event LogTemp(address a,
             address b,
             address[] c,
             uint256[] d,
             address[] e,
             uint256[] f,
             address[] g,
             uint256[] h,
             uint256 i,
             uint256 j,
             uint256 k,
             bytes32 l);

function test(address[] _addresses,
           uint256[] _uints,
           uint8 _v,
           bytes32 _r,
           bytes32 _s,
           bool test)
  public
  returns (bool)
{

Temp memory temp = Temp({
  a: _addresses[0],
  b: _addresses[1],
  c: _getAddressSubArrayTo(_addresses, 2, _uints[3].add(2)),
  d: _getUintSubArrayTo(_uints, 5, _uints[3].add(5)),
  e: _getAddressSubArrayTo(_addresses, _uints[3].add(2), (_uints[3].add(2)).add(_uints[4])),
  f: _getUintSubArrayTo(_uints, _uints[3].add(5), (_uints[3].add(5)).add(_uints[4])),
  g: _getAddressSubArrayTo(_addresses, (_uints[3].add(2)).add(_uints[4]), _addresses.length),
  h: _getUintSubArrayTo(_uints,(_uints[3].add(5)).add(_uints[4]), _uints.length),
  i: _uints[0],
  j: _uints[1],
  k: _uints[2],
  l: hash(
    _addresses,
    _uints
  )
});


LogTemp(
  temp.a,
  temp.b,
  temp.c,
  temp.d,
  temp.e,
  temp.f,
  temp.g,
  temp.h,
  temp.i,
  temp.j,
  temp.k,
  temp.l
);
}

Upvotes: 5

Views: 5260

Answers (3)

Sr.PEDRO
Sr.PEDRO

Reputation: 2067

You have a limit of 16 variables in stack including arguments, local variables and returns. One way to overcome this error is using a struct instead of sending the variables one by one, as a struct counts as 1 variable.

So you could just declare the event with only the struct

event LogTemp(Temp tmp);

and then emit it like

LogTemp(temp);

This will emit all of the information inside the struct.

See Demystifying the “Stack too deep” Error in Solidity: Understanding its Causes and Solutions for this and other ways to solve it

Upvotes: 0

Tadej Vengust
Tadej Vengust

Reputation: 1401

I was able to find an answer:

If you look at the ContractCompiler.cpp where FunctionDefinition is declared, you see there is a limit of 17 elements on the stack ;

if (stackLayout.size() > 17)           
  BOOST_THROW_EXCEPTION(   
        CompilerError() <<     
    errinfo_sourceLocation(_function.location()) <<     
    errinfo_comment("Stack too deep, try removing local variables.")     
);      

Events are defined as functions, as can be seen in ExpressionCompiler.cpp.

Simply put Events are treated as functions so they have a limit of 17 arguments. Array counts as 2 so in my example where I have 6 arrays + 6 normal arguments this equals 18 and I'm breaking the stack by 1.

Upvotes: 5

Adam Kipnis
Adam Kipnis

Reputation: 10991

Yes, there are limits. You can have up to three indexed arguments in your event. Non-indexed arguments are less restrictive as it’s not limited by the event data structure itself, but is limited by the block gas size for storage (at a cost of 8 gas per byte of data stored in the log).

Solidity event documentation

Upvotes: 5

Related Questions