tldr; we should be able to shave off a total of 4 SSTOREs in buyName without getting too hardcore.
_clusterNames
How many entries do you see per clusterId in _clusterNames?
EnumerableSet does 3 cold SSTOREs for the very first write. If it's low (< 4), we can consider using a flat enumerable set, using 0x00... as the terminator. And if the number of values is more than 4, we will fill up the enumerable set as per normal.
Another alternative is to avoid storing the defaultClusterName in _clusterNames. This can help first-time registrations pay less gas.
This change can be quite involved, so let's consider other lower hanging fruits first.
Bid struct can be packed
Use a single word to store bidder (160 bits), createdTimestamp (32 bits), ethAmount (64 bits).
If these values can't be packed, write to the full slots.
https://github.com/delegatexyz/clusters/blob/bdae06ba7f6ae065e46d1347dcc0f4a546b48579/src/IClusters.sol#L14
PriceIntegral struct can be packed
Use a single word to store name (160 bits), lastUpdatedTimestamp (32 bits), lastUpdatedPrice (64 bits).
While the name is 32 bytes, it is unlikely that people will have a name that is more than 20 bytes long.
This should save 2 SSTOREs from buyName.
If these values can't be packed, write to the full slots.
https://github.com/delegatexyz/clusters/blob/bdae06ba7f6ae065e46d1347dcc0f4a546b48579/src/IClusters.sol#L7
Use Solady's lnWad and expWad
Differentially fuzzed against solmate's. Contains a few minor optimizations.
Pricing contract logic may be inlined
Or make the variable immutable.
https://github.com/delegatexyz/clusters/blob/bdae06ba7f6ae065e46d1347dcc0f4a546b48579/src/NameManager.sol#L23
Use constant value for wadLn(0.5e18)
Replace wadLn(0.5e18) with -693147180559945310.
Pack protocolRevenue, totalBidBacking, totalNameBacking, nextClusterId
Change all of them to uint96.
totalNameBacking should be next to nextClusterId, since they are modifed together in buyName.
This should save 1 SSTORE in buyName.
Pack nameToClusterId and nameBacking
In practice, clusterId and amount won't exceed 96 bits.
Consider using a mapping(bytes32 name => NameData data) mapping.
This should save 1 SSTORE in buyName.
Normalize names
Make sure that all bytes after the first zero byte are zeroized.
Consider using small strings throughout
Shaves two words off calldata: string's offset, string's length. Good for L2.
Use Solady's new fromSmallString
Prior to v0.0.148, LibString.fromSmallString(0x00ff000000000000000000000000000000000000000000000000000000000000) returns hex"00ff" instead of hex"00".
tldr; we should be able to shave off a total of 4 SSTOREs in
buyNamewithout getting too hardcore._clusterNames
How many entries do you see per
clusterIdin_clusterNames?EnumerableSet does 3 cold SSTOREs for the very first write. If it's low (< 4), we can consider using a flat enumerable set, using 0x00... as the terminator. And if the number of values is more than 4, we will fill up the enumerable set as per normal.
Another alternative is to avoid storing the
defaultClusterNamein_clusterNames. This can help first-time registrations pay less gas.This change can be quite involved, so let's consider other lower hanging fruits first.
Bid struct can be packed
Use a single word to store
bidder(160 bits),createdTimestamp(32 bits),ethAmount(64 bits).If these values can't be packed, write to the full slots.
https://github.com/delegatexyz/clusters/blob/bdae06ba7f6ae065e46d1347dcc0f4a546b48579/src/IClusters.sol#L14
PriceIntegral struct can be packed
Use a single word to store
name(160 bits),lastUpdatedTimestamp(32 bits),lastUpdatedPrice(64 bits).While the
nameis 32 bytes, it is unlikely that people will have a name that is more than 20 bytes long.This should save 2 SSTOREs from
buyName.If these values can't be packed, write to the full slots.
https://github.com/delegatexyz/clusters/blob/bdae06ba7f6ae065e46d1347dcc0f4a546b48579/src/IClusters.sol#L7
Use Solady's lnWad and expWad
Differentially fuzzed against solmate's. Contains a few minor optimizations.
Pricing contract logic may be inlined
Or make the variable immutable.
https://github.com/delegatexyz/clusters/blob/bdae06ba7f6ae065e46d1347dcc0f4a546b48579/src/NameManager.sol#L23
Use constant value for wadLn(0.5e18)
Replace
wadLn(0.5e18)with-693147180559945310.Pack protocolRevenue, totalBidBacking, totalNameBacking, nextClusterId
Change all of them to
uint96.totalNameBackingshould be next tonextClusterId, since they are modifed together inbuyName.This should save 1 SSTORE in
buyName.Pack nameToClusterId and nameBacking
In practice,
clusterIdandamountwon't exceed 96 bits.Consider using a
mapping(bytes32 name => NameData data)mapping.This should save 1 SSTORE in
buyName.Normalize names
Make sure that all bytes after the first zero byte are zeroized.
Consider using small strings throughout
Shaves two words off calldata: string's offset, string's length. Good for L2.
Use Solady's new fromSmallString
Prior to v0.0.148,
LibString.fromSmallString(0x00ff000000000000000000000000000000000000000000000000000000000000)returnshex"00ff"instead ofhex"00".