-
Notifications
You must be signed in to change notification settings - Fork 976
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
use custom storage for lockData #353
Conversation
c0686ad
to
ed5b1db
Compare
} | ||
} | ||
|
||
function update(LockData lockData, uint128 _length, uint128 _nonzeroDeltaCount) internal { |
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.
for readability/less footguns (there's certain parameter combinations here that are unacceptable), wonder if we can break this into 3 functions:
lockData.incrementNonzeroDeltaCount()
lockData.decrementNonzeroDeltaCount()
lockData.delete()
probably at the expense of some bytecode savings, but I think it would make a lot of the code nicer to look at, update(length, count)
feels vague and bug prone
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.
Ok i added these functions but they all use similar code paths.. which I separated into toLockData
and _update
which does the final write
contracts/types/LockData.sol
Outdated
// SPDX-License-Identifier: GPL-2.0-or-later | ||
pragma solidity ^0.8.20; | ||
|
||
import {LockDataLibrary} from "../libraries/LockDataLibrary.sol"; |
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.
keeping this in a separate file is breaking convention with types Currency + BalanceDelta. Wonder if it's worth migrating the library here
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.
moved it to types/LockData.sol to match
can rename PR to something like: use custom storage for LockData? |
@@ -138,14 +135,16 @@ contract PoolManager is IPoolManager, Fees, NoDelegateCall, ERC1155, IERC1155Rec | |||
|
|||
/// @inheritdoc IPoolManager | |||
function lock(bytes calldata data) external override returns (bytes memory result) { | |||
LockData lockData = LockDataLibrary.getLockData(); |
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.
something definitely feels a bit weird to me about using pop/push (write functionality) on a type memory uint256 that actually does storage writes. I wish there was a nice way to return a storage reference/pointer here instead of recaching below. Feels a bit off but can't think of any great solutions...this + update() feel a big "loosey goosey" if you will lol
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.
Yeah it is a bit wonky..let me know if you can think of another way, but I had to move away from a library for storage pointers because we don't yet have the transient
keyword.
We can rewrite the lib to use the transient keyword when there is solidity support.
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.
Wondering if we can tighten the library up by changing update to more opinionated functions otherwise library integrators can just input incoherent data right into storage.
Porbably not good the library performs storage writes using any arbitrary uint256 even if it doesn't match what's currently in storage. For push and pop, can we just call like this:
DataLockLibrary.push()
DataLockLibrary.pop()
then inline LockData lockData = getLockData();
as the first line of those functions instead of getting it outside?
The reason I didn't do that is because as its written right now it would be easy to replace the in-memory lockData variable with a transient storage variable I can change the |
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.
Left some thoughts about the setup of the library!
|
||
using LockDataLibrary for LockData global; | ||
|
||
function toLockData(uint128 _length, uint128 _nonzeroDeltaCount) pure returns (LockData lockData) { |
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.
Given its going to be transient storage, should we consider just putting these in different slots? Every function that writes to this slot, only updates 1 of the 2 values - they never both get updated. It feels like it would be easier to just separate them?
push
- only touches length
pull
- only touches length
incrementNonzeroDeltaCount
- only touches delta count
decrementNonzeroDeltaCount
- only touches delta count
Imo it might make more sense to have
NON_ZERO_DELTA_COUNT_SLOT = x
LOCKERS_SLOT = y
where
sload(LOCKERS_SLOT) => length
sload(LOCKERS_SLOT+1) => first locker
this is more like how actual arrays are encoded in storage
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.
interesting, yeah we could do that and compare gas. tload/tstore still 100 gas so its not crazy to pack though
Also - given the design of this library is currently a bit weird because it is designed with the |
closing in favor of separating the libs diff shown here #388 |
Related Issue
Which issue does this pull request resolve?
By changing the lockData structure to use custom storage, we are setting up the repository to leverage tstore/tload.
Description of changes
Changes the LockDataLibrary to account for the sentinel node in storage.