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

ERC721Permit #210

Merged
merged 47 commits into from
Aug 3, 2024
Merged

ERC721Permit #210

merged 47 commits into from
Aug 3, 2024

Conversation

saucepoint
Copy link
Collaborator

Related Issue

Closes #167 and replaces #205

Description of changes

Adds ERC721Permit with

  • Solmate ERC721
  • OZ EIP712.sol
  • Unordered Nonces

@saucepoint saucepoint added the posm position manager label Jul 26, 2024
src/base/ERC721Permit.sol Outdated Show resolved Hide resolved
@saucepoint saucepoint marked this pull request as ready for review July 26, 2024 04:25
Copy link
Contributor

@hensha256 hensha256 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks great! Mostly just want more testing!

src/PositionManager.sol Outdated Show resolved Hide resolved
src/base/ERC721Permit.sol Show resolved Hide resolved
src/base/ERC721Permit.sol Outdated Show resolved Hide resolved
src/base/UnorderedNonce.sol Show resolved Hide resolved
test/shared/LiquidityOperations.sol Outdated Show resolved Hide resolved
test/shared/LiquidityOperations.sol Outdated Show resolved Hide resolved
test/position-managers/PositionManager.multicall.t.sol Outdated Show resolved Hide resolved
test/position-managers/Permit.t.sol Outdated Show resolved Hide resolved
test/position-managers/Permit.t.sol Show resolved Hide resolved
src/base/UnorderedNonce.sol Show resolved Hide resolved
src/base/UnorderedNonce.sol Show resolved Hide resolved
src/base/ERC721Permit.sol Outdated Show resolved Hide resolved
src/base/UnorderedNonce.sol Show resolved Hide resolved

import {PosmTestSetup} from "../shared/PosmTestSetup.sol";

contract PermitTest is Test, PosmTestSetup {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we call this PermitERC721 ? Cause we will also have a permit for permit2 exposed

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

will rename this at the end before merge to preserve reviews / diffs

test/position-managers/Permit.t.sol Show resolved Hide resolved
Copy link
Contributor

@hensha256 hensha256 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lots of really nice testing in here 👯

src/base/ERC721Permit.sol Outdated Show resolved Hide resolved
src/base/UnorderedNonce.sol Show resolved Hide resolved
test/mocks/MockUnorderedNonce.sol Outdated Show resolved Hide resolved
src/libraries/ERC721PermitHash.sol Show resolved Hide resolved
test/ERC721Permit.t.sol Outdated Show resolved Hide resolved
test/UnorderedNonce.t.sol Outdated Show resolved Hide resolved
test/mocks/MockUnorderedNonce.sol Outdated Show resolved Hide resolved
src/interfaces/IERC721Permit.sol Show resolved Hide resolved
Comment on lines 45 to 46
mstore(0, 0x1fb09b80) // 4 bytes of NonceAlreadyUsed.selector
revert(0x1c, 0x04)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if we're going to use .revertWith lib from core this will need to be changed

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

are we doing that? lol

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we can put that in the error pr just a call out tho

function bitmapPositions(uint256 nonce) private pure returns (uint256 wordPos, uint256 bitPos) {
wordPos = uint248(nonce >> 8);
bitPos = uint8(nonce);
function _flipBit(mapping(uint256 => uint256) storage bitmap, uint256 nonce) private {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

imo this does more than flip the bit so we should maybe split out this code.

1 - use the nonce to extract the wordPos/the bitmap to operate on
2- flip bit

flipBit(nonce) makes it seem like the nonce thats being passed in is the bit thats being flipped which is not really how the data is used

src/base/UnorderedNonce.sol Outdated Show resolved Hide resolved
@saucepoint saucepoint requested a review from snreynolds August 2, 2024 19:22
sstore(slot, or(previousBits, bit))
}
(uint256 wordPos, uint256 bitPos) = nonce.getBitmapPositions();
nonces[owner].flipBit(wordPos, bitPos);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is it more expensive if we did nonces[owner][wordPos].flipBit(bitPos)? can you see? i think i just like that abstraction a little better

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

its not as friendly since flipBit would calculate the new bitmap and return it so the caller can set it in storage

the alternative/cleaner syntax might be nonces[owner].spendNonce(nonce) where spendNonce does the wordPos/bitPos logic

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hmmm

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok i misunderstood - now i see it lol
i agree that doing it on the word would be messy becaus eyou have to write

nonces[owner][wordPos] = nonces[owner][wordPos].flipBit(x)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i think i still prefer the abstraction where we were to change it to

nonces[owner][wordPos].flipTick bc the functions become more reusable (to extract bitPos and wordPos) from nonce, then to get the new bitmap...

buttt i get it if its too expensive

maybe we could still have nonces[owner].spendNonce() that still use other helpers for those two things? im just noticing that we have to rewrite helpers in tests to do the same thing weve written here/ I could see those functions being helpful generally in a library

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you see how much gas is saved not doing it this way? @saucepoint

like is it significantly more expsenive to do

nonces[owner][wordPos] = nonces[owner][wordPos].flipTick(bitPos) ?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i will also say tho.. this is not a super heavily used codepath so we could just go back to the solidity version and be done w it, theres no need to hyper optimize this path

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah im happy with that 🤷 no strong opinions

contract UnorderedNonce {
error NonceAlreadyUsed();

mapping(address owner => mapping(uint256 word => uint256 bitmap)) public nonces;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

natspec that the word is actually max type(uint248).max

);
}

function test_permit_increaseLiquidity() public {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you dont actually need permissions to increase, so can probably remove this?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

or you can leave it to show you dont need a permit

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

removing

the test test_increaseLiquidity_withUnapprovedCaller shows that users can increase without approval

vm.prank(alice);
mint(config, liquidityAlice, alice, ZERO_BYTES);
uint256 tokenIdAlice = lpm.nextTokenId() - 1;

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can you add an expect revert bob trying to adjust alices position before the permit

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tested in test_noPermit_decreaseLiquidityRevert

@snreynolds snreynolds dismissed hensha256’s stale review August 3, 2024 01:06

alice has reviewed, will flag for another look Sunday

@saucepoint saucepoint merged commit 1f28ac2 into main Aug 3, 2024
3 checks passed
@saucepoint saucepoint deleted the posm-erc721permit-signed branch August 3, 2024 01:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
posm position manager
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[posm]: Add Permit functionality to ERC721
3 participants