Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use calldata instead of memory for external functions where the function argument is read-only. #29

Open
code423n4 opened this issue Jan 4, 2022 · 3 comments
Labels
bug Something isn't working G (Gas Optimization) resolved Finding has been patched by sponsor (sponsor pls link to PR containing fix) sponsor confirmed Sponsor agrees this is a problem and intends to fix it (OK to use w/ "disagree with severity")

Comments

@code423n4
Copy link
Contributor

Handle

Dravee

Vulnerability details

Impact

On external functions, when using the memory keyword with a function argument, what's happening is that a memory acts as an intermediate.

Reading directly from calldata using calldataload instead of going via memory saves the gas from the intermediate memory operations that carry the values.

As an extract from https://ethereum.stackexchange.com/questions/74442/when-should-i-use-calldata-and-when-should-i-use-memory :

memory and calldata (as well as storage) are keywords that define the data area where a variable is stored. To answer your question directly, memory should be used when declaring variables (both function parameters as well as inside the logic of a function) that you want stored in memory (temporary), and calldata must be used when declaring an external function's dynamic parameters. The easiest way to think about the difference is that calldata is a non-modifiable, non-persistent area where function arguments are stored, and behaves mostly like memory.

Proof of Concept

interfaces\IXDEFIDistribution.sol:55:    function baseURI() external view returns (string memory baseURI_);
interfaces\IXDEFIDistribution.sol:74:    function setBaseURI(string memory baseURI_) external;
interfaces\IXDEFIDistribution.sol:77:    function setLockPeriods(uint256[] memory durations_, uint8[] memory multipliers) external;
interfaces\IXDEFIDistribution.sol:106:    function relockBatch(uint256[] memory tokenIds_, uint256 lockAmount_, uint256 duration_, address destination_) external returns (uint256 amountUnlocked_, uint256 
newTokenId_);
interfaces\IXDEFIDistribution.sol:109:    function unlockBatch(uint256[] memory tokenIds_, address destination_) external returns (uint256 amountUnlocked_);
interfaces\IXDEFIDistribution.sol:119:    function merge(uint256[] memory tokenIds_, address destination_) external returns (uint256 tokenId_);
interfaces\IXDEFIDistribution.sol:125:    function tokenURI(uint256 tokenId_) external view returns (string memory tokenURI_);
XDEFIDistribution.sol:73:    function setBaseURI(string memory baseURI_) external onlyOwner {
XDEFIDistribution.sol:77:    function setLockPeriods(uint256[] memory durations_, uint8[] memory multipliers) external onlyOwner {
XDEFIDistribution.sol:165:    function relockBatch(uint256[] memory tokenIds_, uint256 lockAmount_, uint256 duration_, address destination_) external noReenter returns (uint256 amountUnlocked_, uint256 
newTokenId_) {
XDEFIDistribution.sol:186:    function unlockBatch(uint256[] memory tokenIds_, address destination_) external noReenter returns (uint256 amountUnlocked_) {
XDEFIDistribution.sol:205:    function merge(uint256[] memory tokenIds_, address destination_) external returns (uint256 tokenId_) {

Tools Used

VS Code

Recommended Mitigation Steps

Use calldata instead of memory for external functions where the function argument is read-only.

@code423n4 code423n4 added bug Something isn't working G (Gas Optimization) labels Jan 4, 2022
code423n4 added a commit that referenced this issue Jan 4, 2022
@deluca-mike deluca-mike added the sponsor confirmed Sponsor agrees this is a problem and intends to fix it (OK to use w/ "disagree with severity") label Jan 5, 2022
@deluca-mike
Copy link
Collaborator

Yup, good catch. I'm usually a stickler for this, and I can't believe I didn't do it already.

@deluca-mike
Copy link
Collaborator

deluca-mike commented Jan 13, 2022

Fixed in release candidate:

@deluca-mike deluca-mike added the resolved Finding has been patched by sponsor (sponsor pls link to PR containing fix) label Jan 14, 2022
@Ivshti
Copy link
Member

Ivshti commented Jan 16, 2022

valid finding

@Ivshti Ivshti closed this as completed Jan 16, 2022
@CloudEllie CloudEllie reopened this Jan 22, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working G (Gas Optimization) resolved Finding has been patched by sponsor (sponsor pls link to PR containing fix) sponsor confirmed Sponsor agrees this is a problem and intends to fix it (OK to use w/ "disagree with severity")
Projects
None yet
Development

No branches or pull requests

4 participants