More Deployment Gas with Variable Packeting
- Dominant language
- C++
- Stars
- 25.7k
- Forks
- 6.2k
- Avg merge
- 1d 11h
- Merged PRs (30d)
- 21
Description
Hello,
I have a question. (i reopen it as an bug because i do not know why is this happening).
If we have a contract that the state variables look like that (random):
``` contract TSCT is Context, IERC20, Ownable {
using SafeMath for uint256;
uint128 b; // 16 bytes
uint256 private constant _tTotal = 420690000000 * 10**_decimals;
uint256 private _transferTax = 0;
uint256 public _maxTxAmount = 2 * (_tTotal/100);
mapping (address => mapping (address => uint256)) private _tPermits;
uint256 public _maxTaxSwap = 1 * (_tTotal/100);
uint256 private _reduceBuyTaxAt = 12;
uint256 public _maxWalletSize = 2 * (_tTotal/100);
bool private inSwap = false;
uint256 c; // 32 bytes
uint256 private _initialSellTax = 15;
string private constant _name = unicode"The Shopping Cart Theory";
address payable private ecoRebond = payable(0x844471Cc96A7463Ab647C00514C50fdF09d873fF);
string private constant _symbol = unicode"TSCT";
address private uniPair;
uint256 private _finalBuyTax = 0;
mapping (address => uint256) private _tOwned;
uint8 private constant _decimals = 9;
bool private swapEnabled = false;
uint256 public _taxSwapThreshold = 1 * (_tTotal/100);
uint256 private _finalSellTax = 0;
bool private tradingOpen;
uint256 private _preventSwapBefore = 15;
mapping (address => bool) private _isExcludedFromFee;
uint256 private _reduceSellTaxAt = 12;
uint256 private _initialBuyTax = 15;
uint16 a; // 2 bytes
uint256 private _buyCount = 0;
IUniswapV2Router02 private uniRouter;
…
```
and then i make a reorder of them and look like that (ordered):
``` contract TSCT is Context, IERC20, Ownable {
using SafeMath for uint256;
uint128 b; // 16 bytes
uint16 a; // 2 bytes
bool private inSwap = false;
bool private swapEnabled = false;
bool private tradingOpen;
uint8 private constant _decimals = 9;
uint256 c; // 32 bytes
uint256 private _finalSellTax = 0;
uint256 private _finalBuyTax = 0;
uint256 private _initialSellTax = 15;
uint256 private constant _tTotal = 420690000000 * 10**_decimals;
uint256 public _maxTxAmount = 2 * (_tTotal/100);
uint256 public _maxWalletSize = 2 * (_tTotal/100);
uint256 private _transferTax = 0;
address payable private ecoRebond = payable(0x844471Cc96A7463Ab647C00514C50fdF09d873fF);
uint256 private _reduceBuyTaxAt = 12;
address private uniPair;
uint256 private _buyCount = 0;
uint256 private _reduceSellTaxAt = 12;
uint256 public _maxTaxSwap = 1 * (_tTotal/100);
uint256 private _initialBuyTax = 15;
uint256 public _taxSwapThreshold = 1 * (_tTotal/100);
uint256 private _preventSwapBefore = 15;
mapping (address => bool) private _isExcludedFromFee;
string private constant _name = unicode"The Shopping Cart Theory";
mapping (address => uint256) private _tOwned;
mapping (address => mapping (address => uint256)) private _tPermits;
string private constant _symbol = unicode"TSCT";
...
```
Then i use forge to get the deployment gas, as well as the EVMBytecode for the random and the ordered version. And i observe that both, deployment gas and EVMBytecode in the ordered version are bigger, despite the fact that from what i see from the storage layout the random version of the contaract get 23 slots for storing the state variables, while in the ordered state variables get 21 slots in storage.
(packeting these together in slot 1 :
uint128 b; // 16 bytes
uint16 a; // 2 bytes
bool private inSwap = false;
bool private swapEnabled = false;
bool private tradingOpen;
uint8 private constant _decimals = 9;)
Contributor guide
Research direction
Reproduce both variable orderings with forge and compare their deployment gas, EVM bytecode, and reported storage layouts. Start by isolating the smallest contract that preserves the difference; done means documenting which compiler or code-generation behavior accounts for the discrepancy and adding a focused regression case if the repository’s test structure is identified.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- solidity
- Domain
- blockchain, compilers
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Needs clarification
- Newbie friendliness
- 25/100