Skip to content

Commit

Permalink
implement (totally untested) typehash derivation for deposit + register
Browse files Browse the repository at this point in the history
  • Loading branch information
0age committed Oct 27, 2024
1 parent 37ba683 commit 153101c
Show file tree
Hide file tree
Showing 4 changed files with 98 additions and 13 deletions.
90 changes: 86 additions & 4 deletions src/lib/HashLib.sol
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ import {
PERMIT2_ACTIVATION_MULTICHAIN_COMPACT_TYPESTRING_FRAGMENT_THREE,
PERMIT2_ACTIVATION_MULTICHAIN_COMPACT_TYPESTRING_FRAGMENT_FOUR,
PERMIT2_ACTIVATION_MULTICHAIN_COMPACT_TYPESTRING_FRAGMENT_FIVE,
PERMIT2_ACTIVATION_BATCH_COMPACT_TYPESTRING_FRAGMENT_SIX
PERMIT2_ACTIVATION_MULTICHAIN_COMPACT_TYPESTRING_FRAGMENT_SIX
} from "../types/EIP712Types.sol";

import {
Expand Down Expand Up @@ -122,7 +122,7 @@ import {

import { TransferComponent, SplitComponent, SplitByIdComponent, BatchClaimComponent, SplitBatchClaimComponent } from "../types/Components.sol";

import { CompactCategory } from "../types/CompactCategory.sol";
import { ActivatedCompactCategory } from "../types/ActivatedCompactCategory.sol";
import { ResetPeriod } from "../types/ResetPeriod.sol";
import { Scope } from "../types/Scope.sol";

Expand Down Expand Up @@ -922,7 +922,89 @@ library HashLib {
}
}

function toPermit2ActivatedCompactTypehash(CompactCategory category, string calldata witness) internal pure returns (bytes32 typehash) {
// ...
function toPermit2ActivatedCompactTypehash(ActivatedCompactCategory category, string calldata witness) internal pure returns (bytes32 typehash) {
assembly ("memory-safe") {
function toTypehash(c, witnessOffset, witnessLength) -> t {
let m := mload(0x40) // Grab the free memory pointer; memory will be left dirtied

let isBatch := gt(c, 2)
c := sub(c, mul(isBatch, 3))

// 1. handle no-witness cases or prepare first witness fragment based on deposit vs batch deposit
let fragmentTwoStart
if iszero(isBatch) {
if iszero(witnessLength) {
mstore(0, PERMIT2_DEPOSIT_WITH_COMPACT_ACTIVATION_TYPEHASH)
mstore(0x20, PERMIT2_DEPOSIT_WITH_BATCH_COMPACT_ACTIVATION_TYPEHASH)
mstore(0x40, PERMIT2_DEPOSIT_WITH_MULTICHAIN_COMPACT_ACTIVATION_TYPEHASH)
t := mload(shl(5, c))
mstore(0x40, m)
leave
}

mstore(m, PERMIT2_DEPOSIT_WITH_ACTIVATION_TYPESTRING_FRAGMENT_ONE)
mstore(add(m, 0x20), PERMIT2_DEPOSIT_WITH_ACTIVATION_TYPESTRING_FRAGMENT_TWO)
mstore(add(m, 0x40), PERMIT2_DEPOSIT_WITH_ACTIVATION_TYPESTRING_FRAGMENT_THREE)
mstore(add(m, 0x6d), PERMIT2_DEPOSIT_WITH_ACTIVATION_TYPESTRING_FRAGMENT_FIVE)
mstore(add(m, 0x60), PERMIT2_DEPOSIT_WITH_ACTIVATION_TYPESTRING_FRAGMENT_FOUR)
fragmentTwoStart := add(m, 0x8d)
}

if iszero(fragmentTwoStart) {
if iszero(witnessLength) {
mstore(0, PERMIT2_BATCH_DEPOSIT_WITH_COMPACT_ACTIVATION_TYPEHASH)
mstore(0x20, PERMIT2_BATCH_DEPOSIT_WITH_BATCH_COMPACT_ACTIVATION_TYPEHASH)
mstore(0x40, PERMIT2_BATCH_DEPOSIT_WITH_MULTICHAIN_COMPACT_ACTIVATION_TYPEHASH)
t := mload(shl(5, c))
mstore(0x40, m)
leave
}

mstore(m, PERMIT2_DEPOSIT_WITH_ACTIVATION_TYPESTRING_FRAGMENT_ONE)
mstore(add(m, 0x20), PERMIT2_BATCH_DEPOSIT_WITH_ACTIVATION_TYPESTRING_FRAGMENT_TWO)
mstore(add(m, 0x40), PERMIT2_BATCH_DEPOSIT_WITH_ACTIVATION_TYPESTRING_FRAGMENT_THREE)
mstore(add(m, 0x60), PERMIT2_BATCH_DEPOSIT_WITH_ACTIVATION_TYPESTRING_FRAGMENT_FOUR)
mstore(add(m, 0x80), PERMIT2_BATCH_DEPOSIT_WITH_ACTIVATION_TYPESTRING_FRAGMENT_FIVE)
mstore8(add(m, 0xa0), PERMIT2_BATCH_DEPOSIT_WITH_ACTIVATION_TYPESTRING_FRAGMENT_SIX)
fragmentTwoStart := add(m, 0xa1)
}

// 2. prepare second witness fragment based on compact category
let fragmentThreeStart
if iszero(c) {
mstore(fragmentTwoStart, PERMIT2_ACTIVATION_COMPACT_TYPESTRING_FRAGMENT_ONE)
mstore(add(fragmentTwoStart, 0x20), PERMIT2_ACTIVATION_COMPACT_TYPESTRING_FRAGMENT_TWO)
mstore(add(fragmentTwoStart, 0x50), PERMIT2_ACTIVATION_COMPACT_TYPESTRING_FRAGMENT_FOUR)
mstore(add(fragmentTwoStart, 0x40), PERMIT2_ACTIVATION_COMPACT_TYPESTRING_FRAGMENT_THREE)
fragmentThreeStart := add(fragmentTwoStart, 0x70)
}

if iszero(sub(c, 1)) {
mstore(fragmentTwoStart, PERMIT2_ACTIVATION_BATCH_COMPACT_TYPESTRING_FRAGMENT_ONE)
mstore(add(fragmentTwoStart, 0x20), PERMIT2_ACTIVATION_BATCH_COMPACT_TYPESTRING_FRAGMENT_TWO)
mstore(add(fragmentTwoStart, 0x5b), PERMIT2_ACTIVATION_BATCH_COMPACT_TYPESTRING_FRAGMENT_FOUR)
mstore(add(fragmentTwoStart, 0x40), PERMIT2_ACTIVATION_BATCH_COMPACT_TYPESTRING_FRAGMENT_THREE)
fragmentThreeStart := add(fragmentTwoStart, 0x7b)
}

if iszero(fragmentThreeStart) {
mstore(fragmentTwoStart, PERMIT2_ACTIVATION_MULTICHAIN_COMPACT_TYPESTRING_FRAGMENT_ONE)
mstore(add(fragmentTwoStart, 0x20), PERMIT2_ACTIVATION_MULTICHAIN_COMPACT_TYPESTRING_FRAGMENT_TWO)
mstore(add(fragmentTwoStart, 0x40), PERMIT2_ACTIVATION_MULTICHAIN_COMPACT_TYPESTRING_FRAGMENT_THREE)
mstore(add(fragmentTwoStart, 0x60), PERMIT2_ACTIVATION_MULTICHAIN_COMPACT_TYPESTRING_FRAGMENT_FOUR)
mstore(add(fragmentTwoStart, 0x90), PERMIT2_ACTIVATION_MULTICHAIN_COMPACT_TYPESTRING_FRAGMENT_SIX)
mstore(add(fragmentTwoStart, 0x80), PERMIT2_ACTIVATION_MULTICHAIN_COMPACT_TYPESTRING_FRAGMENT_FIVE)
fragmentThreeStart := add(fragmentTwoStart, 0xb0)
}

// 3. insert the supplied witness (must also include TokenPermissions)
calldatacopy(fragmentThreeStart, witnessOffset, witnessLength)

// 4. derive the typehash
t := keccak256(m, add(sub(fragmentThreeStart, m), witnessLength))
}

typehash := toTypehash(category, witness.offset, witness.length)
}
}
}
11 changes: 11 additions & 0 deletions src/types/ActivatedCompactCategory.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.27;

enum ActivatedCompactCategory {
Compact,
BatchCompact,
MultichainCompact,
BatchDepositCompact,
BatchDepositBatchCompact,
BatchDepositMultichainCompact
}
8 changes: 0 additions & 8 deletions src/types/CompactCategory.sol

This file was deleted.

2 changes: 1 addition & 1 deletion src/types/EIP712Types.sol
Original file line number Diff line number Diff line change
Expand Up @@ -212,4 +212,4 @@ bytes32 constant PERMIT2_ACTIVATION_MULTICHAIN_COMPACT_TYPESTRING_FRAGMENT_FOUR
bytes32 constant PERMIT2_ACTIVATION_MULTICHAIN_COMPACT_TYPESTRING_FRAGMENT_FIVE = 0x697465722c75696e7432353620636861696e49642c75696e743235365b325d5b;

// uint128(abi.decode(bytes("] idsAndAmounts,"), (bytes16)))
uint128 constant PERMIT2_ACTIVATION_BATCH_COMPACT_TYPESTRING_FRAGMENT_SIX = 0x5d20696473416e64416d6f756e74732c;
uint128 constant PERMIT2_ACTIVATION_MULTICHAIN_COMPACT_TYPESTRING_FRAGMENT_SIX = 0x5d20696473416e64416d6f756e74732c;

0 comments on commit 153101c

Please sign in to comment.