Skip to content
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

Merged
merged 24 commits into from
Jun 27, 2024

Conversation

elshan-eth
Copy link
Contributor

@elshan-eth elshan-eth commented Jun 18, 2024

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

  • Bug fix
  • New feature
  • Breaking change
  • Dependency changes
  • Code refactor / cleanup
  • Documentation or wording changes
  • Other

Checklist:

  • The diff is legible and has no extraneous changes
  • Complex code has been commented, including external interfaces
  • Tests have 100% code coverage
  • The base branch is either main, or there's a description of how to merge

Issue Resolution

Closes #656

@elshan-eth elshan-eth marked this pull request as ready for review June 20, 2024 16:07
Copy link
Collaborator

@EndymionJkb EndymionJkb left a 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.

pkg/solidity-utils/contracts/helpers/Cache.sol Outdated Show resolved Hide resolved
pkg/vault/contracts/VaultExtension.sol Show resolved Hide resolved
pkg/solidity-utils/contracts/helpers/Cache.sol Outdated Show resolved Hide resolved
pkg/solidity-utils/contracts/helpers/Cache.sol Outdated Show resolved Hide resolved
Copy link
Contributor

@joaobrunoah joaobrunoah left a 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)?

@elshan-eth
Copy link
Contributor Author

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

@elshan-eth elshan-eth closed this Jun 25, 2024
@elshan-eth elshan-eth reopened this Jun 25, 2024
Copy link
Contributor

@jubeira jubeira left a 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 have before and after 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.

pkg/vault/contracts/VaultExtension.sol Outdated Show resolved Hide resolved
pkg/vault/contracts/Vault.sol Outdated Show resolved Hide resolved
@elshan-eth elshan-eth requested a review from EndymionJkb June 25, 2024 18:34
Copy link
Collaborator

@EndymionJkb EndymionJkb left a 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.

pkg/vault/contracts/Vault.sol Outdated Show resolved Hide resolved
pkg/vault/contracts/lib/HooksConfigLib.sol Outdated Show resolved Hide resolved
pkg/vault/contracts/lib/HooksConfigLib.sol Outdated Show resolved Hide resolved
pkg/vault/contracts/lib/HooksConfigLib.sol Outdated Show resolved Hide resolved
Copy link
Contributor

@jubeira jubeira left a 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.

pkg/vault/contracts/Vault.sol Outdated Show resolved Hide resolved
Copy link
Contributor

@jubeira jubeira left a 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
);
}

Copy link
Contributor

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.

Copy link
Contributor Author

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

Copy link
Contributor Author

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

Copy link
Contributor

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?

Copy link
Contributor Author

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

Copy link
Collaborator

@EndymionJkb EndymionJkb left a 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!

Copy link
Contributor

@joaobrunoah joaobrunoah left a 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!

pkg/vault/contracts/lib/HooksConfigLib.sol Outdated Show resolved Hide resolved
pkg/vault/contracts/Vault.sol Show resolved Hide resolved
@elshan-eth elshan-eth merged commit 6371b85 into main Jun 27, 2024
12 checks passed
@elshan-eth elshan-eth deleted the merge-hooks-config-with-pool-config branch June 27, 2024 21:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Merge hooksConfig with poolConfig
4 participants