You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
CorporateActionStorage.totalSupplyBootstrapped is a bool that tracks whether LibTotalSupply.fold() has performed the one-time bootstrap (copying OZ's _totalSupply into unmigrated[0]). It guards onMint / onBurn from writing to the pot pre-bootstrap and drives effectiveTotalSupply's fallback-to-OZ branch.
The bool is derivable from totalSupplyLatestSplit:
Post-bootstrap: bootstrapped = true, totalSupplyLatestSplit > 0 (the walk inside fold() always advances past the triggering first-completed-split before returning).
At every _update boundary, totalSupplyBootstrapped <=> (totalSupplyLatestSplit != 0). The bool adds no information the uint256 doesn't already encode.
Costs:
One struct slot dedicated to holding a 1-byte bool. Any future struct field change has to account for its position.
One one-time SSTORE (20k gas) on first bootstrap.
Three SLOAD sites (onMint, onBurn, effectiveTotalSupply) that could read totalSupplyLatestSplit instead.
Related: proper sentinels
This is a specific instance of the broader pattern in #79: the corporate-actions storage relies on positional / convention-based disambiguation (0-means-unset) rather than value-level sentinels. If #79 is adopted and type(uint256).max becomes the "not set" value for pointer-like fields, totalSupplyLatestSplit would carry the same "bootstrap fired?" signal unambiguously with no separate bool.
Options
Drop the bool, replace every if (bootstrapped) with if (totalSupplyLatestSplit != 0). Zero storage footprint, same semantics.
CorporateActionStorage.totalSupplyBootstrappedis aboolthat tracks whetherLibTotalSupply.fold()has performed the one-time bootstrap (copying OZ's_totalSupplyintounmigrated[0]). It guardsonMint/onBurnfrom writing to the pot pre-bootstrap and driveseffectiveTotalSupply's fallback-to-OZ branch.The bool is derivable from
totalSupplyLatestSplit:bootstrapped = false,totalSupplyLatestSplit = 0(no split tracked yet).bootstrapped = true,totalSupplyLatestSplit > 0(the walk insidefold()always advances past the triggering first-completed-split before returning).At every
_updateboundary,totalSupplyBootstrapped <=> (totalSupplyLatestSplit != 0). The bool adds no information theuint256doesn't already encode.Costs:
onMint,onBurn,effectiveTotalSupply) that could readtotalSupplyLatestSplitinstead.Related: proper sentinels
This is a specific instance of the broader pattern in #79: the corporate-actions storage relies on positional / convention-based disambiguation (0-means-unset) rather than value-level sentinels. If #79 is adopted and
type(uint256).maxbecomes the "not set" value for pointer-like fields,totalSupplyLatestSplitwould carry the same "bootstrap fired?" signal unambiguously with no separate bool.Options
if (bootstrapped)withif (totalSupplyLatestSplit != 0). Zero storage footprint, same semantics.No runtime behaviour change in either option.