How variable length arguments are encoded in calldata
// Example: dynamic length data type sandwiched between two fixed length data types functionthreeArgs(uint256 a,uint256[] calldata b,uint256 c ) external {}
calldata for input values of 5, [1,2,3], 7
0xc6f922d00000000000000000000000000000000000000000000000000000000000000005// first input argument 0000000000000000000000000000000000000000000000000000000000000060// 60 - pointer to location of dynamic array data0000000000000000000000000000000000000000000000000000000000000007// third input argument 0000000000000000000000000000000000000000000000000000000000000003// length of array data to look at 0000000000000000000000000000000000000000000000000000000000000001// array values 0000000000000000000000000000000000000000000000000000000000000002// ..... 0000000000000000000000000000000000000000000000000000000000000003// .....
Using a struct instead of an array will encode the variables directly into memory in order, since it knows in advance how big the struct is