TSender

Cyfrin
DeFiFoundry
15,000 USDC
View results
Submission Details
Severity: medium
Invalid

Using `memory` instead of `calldata` results in a more optimized version of the codebase

Summary

The current implementation of the airdropERC20 function uses calldata for passing arrays, which was expected to be more gas efficient. However, tests show that using memory instead of calldata is approximately 0.26% more gas optimized. This undermines the project's goal of creating a huff version that is more gas efficient than the Solidity/Yul implementation.

Vulnerability Details

In the airdropERC20 function, arrays are passed as calldata to leverage the expected gas efficiency. However, the actual gas usage reveals that using memory for passing arrays results in lower gas consumption.

Here is the result of the test testAirDropErc20OneThousand for the contract TSenderReference using both calldata and memory for passing arrays :

  • calldata :

Ran 1 test for test/unit/hasChecks/TSenderReferenceTest.t.sol:TSenderReferenceTest
[PASS] testAirDropErc20OneThousand() (gas: 28436430)
Logs:
Gas used 26490540
  • memory :

Ran 1 test for test/unit/hasChecks/TSenderReferenceTest.t.sol:TSenderReferenceTest
[PASS] testAirDropErc20OneThousand() (gas: 28368501)
Logs:
Gas used 26422611

So about a 0,256% improved gas costs. Which is a lot. Knowing that solidity is just a less optimized version of it's Yul counterpart the TSender.sol contract, if we apply the same percentage improvement, we get an improved gas costs of about 25495734 for the TSender contract, which is less than the TSender_NoCheck.huff !

It is well known that calldata is cheaper gas-wise than memory, and that it should be used when passing large arrays. Here's my understanding, I believe calldata is more useful because it doesn't invole copying data into memory. Had the function only worked with the stack and calldata, it would have been more gas efficient. But since we are manipulating memory by storing values into it, memory costs less in this case.

Impact

It is arguable that this is only a gas improvement and not a security related issue. However, the goal of the Huff implementation is to be more gas efficient than the Solidity/Yul version. If someone creates a Yul version using memory, it would be more gas efficient, easier to use, and easier to read, defeating the purpose of the huff version. It's like saying a product that is marketed entirely for this purpose is not doing it's job.
So I believe medium severity is suited.

Tools Used

Manual review + foundry test suite

Recommendations

Rewrite the contracts (both yul and huff) to load data from memory instead of calldata.

Updates

Lead Judging Commences

patrickalphac Auditor
12 months ago
inallhonesty Lead Judge 12 months ago
Submission Judgement Published
Invalidated
Reason: Non-acceptable severity

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.