Closed code423n4 closed 3 years ago
The reason that external
modifier can sometimes be cheaper than public
is that Solidity keeps function parameters in calldata in external
but copies them to memory in public
. If there are no function parameters in a function or they are explicitly set to be kept in calldata, there is no potential gas saving. This is the case in our contracts and hence, changing public to external won't do anything.
Agree with sponsor
Handle
defsec
Vulnerability details
Impact
In a nutshell, public and external differs in terms of gas usage. The former use more than the latter when used with large arrays of data. This is due to the fact that Solidity copies arguments to memory on a public function while external read from calldata which a cheaper than memory allocation. public functions are called internally and externally. internal calls are executed via jumps in the code because array arguments are passed internally by pointers to memory. When the compiler generates the code for an internal function, that function expects its arguments to be located in memory. That is why public functions are allocated to memory. The optimization that happens with external is that is does not care for the internal calls. So if you know the function you create only allows for external calls, go for it. It provides performance benefits and you will save on gas. In the Sushi Trident contracts, some of the methods are marked as public. The public function should be replaced with the external ones.
Proof of Concept
The following functions are marked as a public.
The following functions are marked as a public.
The following functions are marked as a public.
POC
Calling each function, we can see that the public function uses 496 gas, while the external function uses only 261.
Tools Used
None
Recommended Mitigation Steps
Overrided function should be marked as an external for the gas optimization.