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

Contract size raised by a riddicilous amount with one simple line of code #13377

Closed
migoldfinger opened this issue Aug 10, 2022 · 2 comments
Closed

Comments

@migoldfinger
Copy link

migoldfinger commented Aug 10, 2022

I have a library that helps with calculation of contract addresses created with CREATE2.

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import "../TokenPair.sol";

library Lib
{
	bytes private constant _PAIR_CREATION_CODE  = type(TokenPair).creationCode;

	function calculateAddress(address sender, address token0, address token1) internal pure returns (TokenPair) {
		return TokenPair(address(uint160(uint256(keccak256(abi.encodePacked(
				hex'ff',
				factory,
				keccak256(abi.encodePacked(token0, token1)),
				keccak256(abi.encodePacked(_PAIR_CREATION_CODE, abi.encode(token0, token1))) // init code hash
			))))));
	}
}

What really puzzled me for a while was that keccak256(abi.encodePacked(_PAIR_CREATION_CODE, abi.encode(tokenL, tokenR))) adds 13.034KiB to the contract size. -> Checked with hardhat-contract-sizer and comment in and out line by line.
The size jump also happens if I only call 'bytes32 creationCode = keccak256(abi.encodePacked(_PAIR_CREATION_CODE, abi.encode(token0, token1)));'
Same goes for bytes memory packed = abi.encodePacked(_PAIR_CREATION_CODE, abi.encode(token1, token0));

I now understand that the culprit is the _PAIR_CREATION_CODE that holds the creation code of the pair contract, which gets injected when used and adds it whole size to the contract. Is there a way to prehash that code and add the parameters later?
I would hate to switch back to a parameter less constructor since there is some logic depending on the parameters that can only be done at construction time and the use of immutable values for the tokens which safes gas all over the contract.

@hrkrshnn
Copy link
Member

hrkrshnn commented Aug 10, 2022

Is there a way to prehash that code and add the parameters later?

This wouldn't be feasible. Effectively, you want to compute the keccak256 hash of x + y + z but want to avoid or replace x. I don't think that is possible.

would hate to switch back to a parameter less constructor

Unfortunately, that is likely the best option here. You can see the trick that Uniswap-v3 uses for this: https://github.com/Uniswap/v3-core/blob/412d9b236a1e75a98568d49b1aeb21e3a1430544/contracts/UniswapV3PoolDeployer.sol#L34

Closing this, as it's not something that can be addressed at the language level. Feel free to reply if you have questions.

@migoldfinger
Copy link
Author

migoldfinger commented Aug 10, 2022

hm maybe an CREATE3 would be nice where the keccak256(abi.encodePacked(_PAIR_CREATION_CODE, abi.encode(token0, token1))) is calculated like keccak256(abi.encodePacked(keccak256(_PAIR_CREATION_CODE), abi.encode(token0, token1))) well maybe I dig into that kind of stuff and creating an EIP

Too late I see there is already an EIP with CREATE3 that would exactly cover my problem... ethereum/EIPs#3171 unfortunately it's stale

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants