Skip to content

Save gas by packing total and expiresAt into the same 256-bit word in the Offer struct #45

Open
@ghost

Description

Description

The Offer struct is composed of two 256-bit words. Since the function .updateOffer() only updates a portion of this struct (the total and the expiresAt portions), we can pack these two properties together to save gas.

Scenario

If the total and the expiresAt properties are placed in the same word, we can save gas by only having to update one 256-bit word rather than two 256-bit words.

As they are currently structured:

The first 256-bit word is:
64 bits of expiresAt
160 bits of bidder
16 bits of offerCut
The first 16 bits of total

The second 256-bit word is:
The remaining 112 bits of total
128 bits of unsuccessfulFee

So total and expiresAt are not in the same word.

According to my suggestion, it would be structured as:

The first 256-bit word would be:
64 bits of expiresAt
128 bits of total
The first 64 bits of bidder

The second 256-bit word would be:
The remaining 96 bits of bidder
16 bits of offerCut
128 bits of unsuccessfulFee

Impact

Gas Savings: We can save gas by only paying 5000 gas to update one 256-bit word rather than 10,000 gas to update 256-bit words.

Reproduction

Observe that the expiresAt property is in the first 256-bit word of the Offer struct, whereas the total property is in the second 256-bit word:

struct Offer {
        // Time when offer expires
        uint64 expiresAt;
        // Bidder The creator of the offer
        address bidder;
        // Offer cut in basis points, which ranges from 0-10000.
        // It's the cut that CFO takes when the offer is successfully accepted by the owner.
        // This is stored in the offer struct so that it won't be changed if COO updates
        // the `offerCut` for new offers.
        uint16 offerCut;
        // Total value (in wei) a bidder sent in msg.value to create the offer
        uint128 total;
        // Fee (in wei) that CFO takes when the offer is expired or overbid.
        // This is stored in the offer struct so that it won't be changed if COO updates
        // the `unsuccessfulFee` for new offers.
        uint128 unsuccessfulFee;
    }

Fix

Reorder the struct to have the expiresAt property and the total property in the same half of the struct:

struct Offer {
        // Time when offer expires
        uint64 expiresAt;
        // Total value (in wei) a bidder sent in msg.value to create the offer
        uint128 total;
        // Bidder The creator of the offer
        address bidder;
        // Offer cut in basis points, which ranges from 0-10000.
        // It's the cut that CFO takes when the offer is successfully accepted by the owner.
        // This is stored in the offer struct so that it won't be changed if COO updates
        // the `offerCut` for new offers.
        uint16 offerCut;
        // Fee (in wei) that CFO takes when the offer is expired or overbid.
        // This is stored in the offer struct so that it won't be changed if COO updates
        // the `unsuccessfulFee` for new offers.
        uint128 unsuccessfulFee;
    }

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions