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

feat(Permit3): unlock account message type #2

Merged
merged 4 commits into from
Feb 27, 2025

Conversation

re1ro
Copy link
Collaborator

@re1ro re1ro commented Feb 27, 2025

No description provided.

@re1ro re1ro self-assigned this Feb 27, 2025
@re1ro re1ro requested a review from nknavkal February 27, 2025 01:06
usedNonces[owner][nonce] = 1;
function _useNonce(address owner, bytes32 salt) internal {
require(usedNonces[owner][salt] == 0, NonceAlreadyUsed());
usedNonces[owner][salt] = 1;

Choose a reason for hiding this comment

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

using both salt and nonce in these methods is confusing

Copy link
Collaborator Author

@re1ro re1ro Feb 27, 2025

Choose a reason for hiding this comment

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

salt is what user passes, but salt is userAddress + salt

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

but I agree it's not elegant

Choose a reason for hiding this comment

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

lol even in that response it is confusing

Copy link
Contributor

Choose a reason for hiding this comment

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

We should unify into a single name — I see the conflict because it is kind of a salt and definitely a nonce. We can probably go with salt or something like snonce? Also could make the name descriptive like asyncNonce

pepper is taken...

@@ -83,6 +85,7 @@ contract Permit3 is IPermit3, PermitBase, NonceManager {
*/
function permit(
address owner,
bytes32 salt,

Choose a reason for hiding this comment

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

no natspec for this

src/Permit3.sol Outdated
@@ -114,32 +117,40 @@ contract Permit3 is IPermit3, PermitBase, NonceManager {
* 1. Immediate transfers (transferOrExpiration = 1)
* 2. Allowance updates (transferOrExpiration = future timestamp)

Choose a reason for hiding this comment

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

update these to be modeOrExpiration

if (allowed.expiration == LOCKED_ALLOWANCE && timestamp < allowed.timestamp) {
if (
allowed.expiration == LOCKED_ALLOWANCE
&& (p.modeOrExpiration != uint48(PermitType.Unlock) || timestamp <= allowed.timestamp)

Choose a reason for hiding this comment

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

What if i wanted to increase the timestamp of the lock?

usedNonces[msg.sender][noncesToInvalidate[i]] = 1;
uint256 length = salts.length;

for (uint256 i = 0; i < length; i++) {

Choose a reason for hiding this comment

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

++i

Copy link
Contributor

Choose a reason for hiding this comment

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

i don't think this matters here

Copy link
Contributor

Choose a reason for hiding this comment

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

oh wait

Copy link
Contributor

Choose a reason for hiding this comment

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

5 gas saved 🙏

allowed.timestamp = timestamp;
}
}

emit Permit(owner, p.token, p.spender, allowed.amount, allowed.expiration, chain.nonce);
emit Permit(owner, p.token, p.account, allowed.amount, allowed.expiration, timestamp);

Choose a reason for hiding this comment

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

this timestamp is...a nonce?

@@ -80,15 +80,15 @@ interface IPermit {
* @param spender The approved spender
* @param amount The approved amount
* @param expiration When the approval expires
* @param nonce The nonce used in the permit signature
* @param timestamp The nonce used in the permit signature

Choose a reason for hiding this comment

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

nonce?

bytes32 chainedInvalidationHashes = proof.preHash;
chainedInvalidationHashes =
keccak256(abi.encodePacked(chainedInvalidationHashes, hashNoncesToInvalidate(proof.invalidations)));
bytes32 unbalancedInvalidationRoot = proof.preHash;

Choose a reason for hiding this comment

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

having trouble wrapping my head around this, but i think i just need to think about it more

Copy link

@nknavkal nknavkal left a comment

Choose a reason for hiding this comment

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

Most of my comments are questions


4. **Increase Mode** (`transferOrExpiration > 2`)
4. **Unlock Mode** (`transferOrExpiration = 3`)
Copy link
Contributor

Choose a reason for hiding this comment

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

glad we added this explicitly

@@ -101,9 +105,9 @@ struct Allowance {
### Account Locking

Locked accounts have special restrictions:
- Cannot increase allowances
- Cannot increase/decrease allowances
Copy link
Contributor

Choose a reason for hiding this comment

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

we want to keep the ability to decrease allowances in this state — if a user has approvals out for N tokens they might want to be able to decrease them all to zero while in this state

I guess you could pass in an array with an unlock step first and set all the approvals to zero in the operations that follow, but I like the idea that you can ensure the allowances are decreased in lock state + its more friendly to non-dev users

Copy link
Contributor

Choose a reason for hiding this comment

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

disregard: I now see that lockdown is per token and therefore this is not needed

Copy link
Contributor

Choose a reason for hiding this comment

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

maybe add a comment here that lockdown is per token and sets allowances to zero — that was why I was confused at first

bytes32 chainedInvalidationHashes = proof.preHash;
chainedInvalidationHashes =
keccak256(abi.encodePacked(chainedInvalidationHashes, hashNoncesToInvalidate(proof.invalidations)));
bytes32 unbalancedInvalidationRoot = proof.preHash;
Copy link
Contributor

Choose a reason for hiding this comment

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

unbalancedInvalidationRoot --> unhingedInvalidationRoot 🥇

usedNonces[owner][nonce] = 1;
function _useNonce(address owner, bytes32 salt) internal {
require(usedNonces[owner][salt] == 0, NonceAlreadyUsed());
usedNonces[owner][salt] = 1;
Copy link
Contributor

Choose a reason for hiding this comment

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

We should unify into a single name — I see the conflict because it is kind of a salt and definitely a nonce. We can probably go with salt or something like snonce? Also could make the name descriptive like asyncNonce

pepper is taken...

src/Permit3.sol Outdated
@@ -27,15 +27,16 @@ contract Permit3 is IPermit3, PermitBase, NonceManager {
* Used in cross-chain signature verification
*/
bytes32 public constant CHAIN_PERMITS_TYPEHASH = keccak256(
"ChainPermits(uint64 chainId,uint48 nonce,AllowanceOrTransfer[] permits)AllowanceOrTransfer(uint48 transferOrExpiration,address token,address spender,uint160 amountDelta)"
"ChainPermits(uint64 chainId,AllowanceOrTransfer[] permits)AllowanceOrTransfer(uint48 transferOrExpiration,address token,address spender,uint160 amountDelta)"
Copy link
Contributor

Choose a reason for hiding this comment

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

transferOrExpiration --> modeOrExpiration

Copy link
Contributor

Choose a reason for hiding this comment

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

also spender should be account

@christianangelopoulos
Copy link
Contributor

I noticed some of the variable names are different in the EIP.md still — so will want to rectify those

@christianangelopoulos christianangelopoulos merged commit f21e649 into main Feb 27, 2025
0 of 2 checks passed
@christianangelopoulos christianangelopoulos deleted the feat/unlock-acoount-message branch February 27, 2025 03:41
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.

3 participants