-
Notifications
You must be signed in to change notification settings - Fork 4
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
Save gas by writing to storage once rather than twice in .updateOffer() #46
Comments
Not sure if you saw my comment here: #39 (comment), but it is related. Initially, I thought the same as you. However, I am doubtful now that you can indeed save 5k gas by just updating 1 word in the 2 word struct due to the solidity compiler. I think the problem is--at least compiled with solidity-- you are rewriting both of the words in the struct even if one word stays the same (i.e. the code calls SSTORE twice) by setting it equal to an Offer type variable. I just tried this with remix and it costs 10k gas to update according to your fix, so it does not save any gas. The only fix I can think of to save gas is to create two mappings. One that contains the expiry time of an offer and one that contains the Offer struct except with the expiry time removed (so it is a struct with one 256 word). Then, you will only need to update the second mapping when someone updates their bid and it will only cost 5k gas even though you are changing two variables in the struct. |
This issue still stands even if it's the case that we can only ever write the entire struct to storage. The following lines are two separate writes to storage:
It still would save gas to write to storage once rather than twice by using the temporary variable |
Thanks @michaelKim4736 for the feedback! We will take this into consideration. |
Ah I see. Right. I guess another way to even save on top of that is two create two mappings as I’ve suggested. Then it would only cost 5k instead of the current 20k. |
Thanks for your participation, @michaelKim4736! Our team has reviewed your submission, and we are pleased to reward you for your report. Severity: Note |
Description
.updateOffer()
updates both theoffer.total
property and theoffer.expiresAt
property of anoffer
struct.However, it writes each of these changes in two separate writes to storage.
We can save gas by making a single write to storage, rather than two.
Scenario
Every time that
.updateOffer()
is called to raise the price of an offer, we waste gas by writing to storage twice rather than once.Impact
Medium: It costs 5,000 gas for each write to storage. If we do a single write to storage (and pack the properties more efficiently as mentioned in Issue #45), we can save 5,000 gas every single time the function is run.
Reproduction
(1) In
.updateOffer()
, we retrieve a pointer to the offer struct that we will update:(2) If msg.value is greater than zero, we update
offer.total
. Since this is a pointer to storage that we are updating, this costs 5,000 gas, a very expensive operation gas-wise:(3) Only after that do we update a different property of the same struct in storage, again costing us another 5,000 gas:
Fix
Instead, we can make both changes locally, and then do a single write to storage. If we combine this with the better struct-packing from Issue #45, we will save 5,000 gas on every write. Change this:
to this:
We would also need to reorder the properties of the Offer struct, as outlined in Issue #45.
The text was updated successfully, but these errors were encountered: