-
Notifications
You must be signed in to change notification settings - Fork 40
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
Merge hooks config with pool config #659
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great savings, and I think dropping to a single PoolConfig library (vs. PoolConfig and HooksConfig) is also a win.
Somebody else should verify the tests (my eyes were glazing over), but looks good to me.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To be honest, I think hooks config lib and pool config lib in the same file is a bit too messy. I wonder if we kept the "call" hook functions in HookConfigLib, would the gas saving be the same (around 2k)?
I agree with you. I will split it. By the gas and bytecode size, it will be the same |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for pushing this @elshan-eth, great job.
Some general comments:
- I think I prefer this approach, even if the other one saves a bit more gas. The reason is that having the
anyHook
flag is kinda duplicating the information that we have in the other flags, which adds some extra complexity to the reader. - About this approach: if I'm not mistaken, in the current
main
we are forced to do 2 storage reads for pool config and hook config, even if we don't need to call any hooks. By merging the flags, we can have only one storage read, and defer reading the hook address only in case we actually need it. I think this optimization is good enough (i.e. have all flags in one slot, and hook address in another one). If we have to read the hook address from storage twice because we havebefore
andafter
hooks that's fine; the second one will be warm (100 gas).
Personally I'd remove the cache, and just read the hook address from storage only when needed. That should help us keep the hook logic pretty well self-contained.
Anyways, I really welcome the effort in this exploration. There are no clear good answers to this; just a big pile of trade-offs to choose from.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Definitely like this approach better, and it's clearer without the Cache (probably too much optimization there, as Juani points out). Just had one question about whether we should revisit an earlier decision, given how the interfaces have evolved since then.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Second quick pass done.
I have a comment that may help keeping the logic of the hooks a bit more localized, without needing to deal with address slots in this case. Other than that I think it looks mostly good! Will do one more thorough pass after this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Side comment: let's try to minimize the diff a bit, and if necessary split some of these changes to separate PRs so as to make the review easier.
hookFlags.shouldCallAfterRemoveLiquidity | ||
); | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this refactor needed for this PR? If not, I'd suggest opening a separate PR just with the refactor. Let's try to keep this one minimal, with changes related only to the optimization itself.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, I don’t quite understand what you mean. here, I changed variable witch we set (hooksConfig->poolConfigBits) + moved these to the zone where poolConfigBits set other parameters
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, I don’t quite understand what you mean. here, I changed the variable which we set (hooksConfig->poolConfigBits) + moved these to the zone where poolConfigBits set other parameters
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same as above. This doesn't seem to be strictly related with the optimization; it can be a PR in it's own right, which will make it easier to review.
Hooks config lib needs to depend on pool config lib anyways right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you mean to move all constants to Pool ConfigLib? And do it in a different PR? Sounds a little strange to me, but I can do it
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've looked at this so many times I might be too familiar - but looks great now. The main thing I wanted to see was moving the "shouldCall" checks outside of the library, to save loading all the parameters up and making the call, just to immediately return. Looks much cleaner now!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Minor comments, but LGTM!
Description
This PR is about merging hooks config and pool config. To preserve the functions onComputeDynamicSwapFee, onBeforeSwap, and others in PoolConfigLib, I decided to create a Cache library. These functions use hooksContract, and Cache allows loading variables from storage once and subsequently using them from memory. Another approach would be to remove these functions from PoolConfigLib and implement all the logic directly in the places where they are used.
Also, I made a mistake with PoolConfigLib.t.sol in the previous PR, and this PR also fixes these tests.
Alternative approach #671.
Type of change
Checklist:
main
, or there's a description of how to mergeIssue Resolution
Closes #656