Skip to content

Commit

Permalink
add qualified batch claim (still unoptimized)
Browse files Browse the repository at this point in the history
  • Loading branch information
0age committed Oct 14, 2024
1 parent 02fd11e commit 69f0c3d
Show file tree
Hide file tree
Showing 5 changed files with 244 additions and 84 deletions.
46 changes: 45 additions & 1 deletion src/TheCompact.sol
Original file line number Diff line number Diff line change
Expand Up @@ -470,6 +470,14 @@ contract TheCompact is ITheCompact, ERC6909, Extsload {
return _processBatchClaim(claimPayload, _release);
}

function claim(QualifiedBatchClaim calldata claimPayload) external returns (bool) {
return _processQualifiedBatchClaim(claimPayload, _release);
}

function claimAndWithdraw(QualifiedBatchClaim calldata claimPayload) external returns (bool) {
return _processQualifiedBatchClaim(claimPayload, _release);
}

function enableForcedWithdrawal(uint256 id) external returns (uint256 withdrawableAt) {
withdrawableAt = block.timestamp + id.toResetPeriod().toSeconds();

Expand Down Expand Up @@ -629,7 +637,7 @@ contract TheCompact is ITheCompact, ERC6909, Extsload {
);
}

// NOTE: this function assumes that there's at least one array element
// NOTE: this function expects that there's at least one array element
function _notExpiredAndWithValidSignaturesBatch(BatchClaim calldata claimPayload)
internal
returns (bytes32 messageHash, uint96 allocatorId)
Expand All @@ -648,6 +656,25 @@ contract TheCompact is ITheCompact, ERC6909, Extsload {
);
}

// NOTE: this function expects that there's at least one array element
function _notExpiredAndWithValidSignaturesQualifiedBatch(
QualifiedBatchClaim calldata claimPayload
) internal returns (bytes32 messageHash, uint96 allocatorId) {
bytes32 qualificationMessageHash;
claimPayload.expires.later();

allocatorId = claimPayload.claims[0].id.toAllocatorId();

(messageHash, qualificationMessageHash) = claimPayload.toMessageHash();
bytes32 domainSeparator = _INITIAL_DOMAIN_SEPARATOR.toLatest(_INITIAL_CHAIN_ID);
messageHash.signedBy(claimPayload.sponsor, claimPayload.sponsorSignature, domainSeparator);
qualificationMessageHash.signedBy(
allocatorId.fromRegisteredAllocatorIdWithConsumed(claimPayload.nonce),
claimPayload.allocatorSignature,
domainSeparator
);
}

function _notExpiredAndWithValidSignaturesQualified(QualifiedClaim calldata claimPayload)
internal
returns (bytes32 messageHash)
Expand Down Expand Up @@ -1077,6 +1104,23 @@ contract TheCompact is ITheCompact, ERC6909, Extsload {
);
}

function _processQualifiedBatchClaim(
QualifiedBatchClaim calldata batchClaim,
function(address, address, uint256, uint256) internal returns (bool) operation
) internal returns (bool) {
(bytes32 messageHash, uint96 allocatorId) =
_notExpiredAndWithValidSignaturesQualifiedBatch(batchClaim);

return _verifyAndProcessBatchComponents(
allocatorId,
batchClaim.sponsor,
batchClaim.claimant,
messageHash,
batchClaim.claims,
operation
);
}

function _processBatchPermit2Deposits(
bool firstUnderlyingTokenIsNative,
address recipient,
Expand Down
16 changes: 3 additions & 13 deletions src/lib/HashLib.sol
Original file line number Diff line number Diff line change
Expand Up @@ -366,7 +366,7 @@ library HashLib {
}
}

function toMessageHash(QualifiedBatchClaim memory claim)
function toMessageHash(QualifiedBatchClaim calldata claim)
internal
view
returns (bytes32 messageHash, bytes32 qualificationMessageHash)
Expand All @@ -381,19 +381,9 @@ library HashLib {
assembly ("memory-safe") {
let m := mload(0x40) // Grab the free memory pointer; memory will be left dirtied.

// TODO: calldatacopy this whole chunk at once as part of calldata implementation
let sponsor := mload(claim)
let expires := mload(add(claim, 0x20))
let nonce := mload(add(claim, 0x40))

let id := mload(add(claim, 0x60))
let amount := mload(add(claim, 0x80))

mstore(m, BATCH_COMPACT_TYPEHASH)
mstore(add(m, 0x20), sponsor)
mstore(add(m, 0x40), expires)
mstore(add(m, 0x60), nonce)
mstore(add(m, 0x80), caller()) // arbiter: msg.sender
mstore(add(m, 0x20), caller()) // arbiter: msg.sender
calldatacopy(add(m, 0x40), add(claim, 0x40), 0x60) // sponsor, nonce, expires
mstore(add(m, 0xa0), idsAndAmountsHash)
messageHash := keccak256(m, 0xc0)
}
Expand Down
42 changes: 21 additions & 21 deletions src/types/BatchClaims.sol
Original file line number Diff line number Diff line change
Expand Up @@ -34,35 +34,35 @@ struct BatchClaim {
}

struct QualifiedBatchClaim {
uint256 nonce; // A parameter to enforce replay protection, scoped to allocator.
uint256 expires; // The time at which the claim expires.
bytes allocatorSignature; // Authorization from the allocator.
address sponsor; // The account to source the tokens from.
bytes sponsorSignature; // Authorization from the sponsor.
address sponsor; // The account to source the tokens from.
uint256 nonce; // A parameter to enforce replay protection, scoped to allocator.
uint256 expires; // The time at which the claim expires.
bytes32 qualificationTypehash; // Typehash of the qualification payload.
bytes qualificationPayload; // Data used to derive qualification hash.
BatchClaimComponent[] claims; // IDs and amounts.
address claimant; // The claim recipient; specified by the arbiter.
}

struct BatchClaimWithWitness {
uint256 nonce; // A parameter to enforce replay protection, scoped to allocator.
uint256 expires; // The time at which the claim expires.
bytes allocatorSignature; // Authorization from the allocator.
address sponsor; // The account to source the tokens from.
bytes sponsorSignature; // Authorization from the sponsor.
address sponsor; // The account to source the tokens from.
uint256 nonce; // A parameter to enforce replay protection, scoped to allocator.
uint256 expires; // The time at which the claim expires.
bytes32 witness; // Hash of the witness data.
string witnessTypestring; // Witness typestring appended to existing typestring.
BatchClaimComponent[] claims; // IDs and amounts.
address claimant; // The claim recipient; specified by the arbiter.
}

struct QualifiedBatchClaimWithWitness {
uint256 nonce; // A parameter to enforce replay protection, scoped to allocator.
uint256 expires; // The time at which the claim expires.
bytes allocatorSignature; // Authorization from the allocator.
address sponsor; // The account to source the tokens from.
bytes sponsorSignature; // Authorization from the sponsor.
address sponsor; // The account to source the tokens from.
uint256 nonce; // A parameter to enforce replay protection, scoped to allocator.
uint256 expires; // The time at which the claim expires.
bytes32 witness; // Hash of the witness data.
string witnessTypestring; // Witness typestring appended to existing typestring.
bytes32 qualificationTypehash; // Typehash of the qualification payload.
Expand All @@ -72,42 +72,42 @@ struct QualifiedBatchClaimWithWitness {
}

struct SplitBatchClaim {
uint256 nonce; // A parameter to enforce replay protection, scoped to allocator.
uint256 expires; // The time at which the claim expires.
bytes allocatorSignature; // Authorization from the allocator.
address sponsor; // The account to source the tokens from.
bytes sponsorSignature; // Authorization from the sponsor.
address sponsor; // The account to source the tokens from.
uint256 nonce; // A parameter to enforce replay protection, scoped to allocator.
uint256 expires; // The time at which the claim expires.
SplitBatchClaimComponent[] claims; // The claim token IDs, recipients and amounts.
}

struct SplitBatchClaimWithWitness {
uint256 nonce; // A parameter to enforce replay protection, scoped to allocator.
uint256 expires; // The time at which the claim expires.
bytes allocatorSignature; // Authorization from the allocator.
address sponsor; // The account to source the tokens from.
bytes sponsorSignature; // Authorization from the sponsor.
address sponsor; // The account to source the tokens from.
uint256 nonce; // A parameter to enforce replay protection, scoped to allocator.
uint256 expires; // The time at which the claim expires.
bytes32 witness; // Hash of the witness data.
string witnessTypestring; // Witness typestring appended to existing typestring.
SplitBatchClaimComponent[] claims; // The claim token IDs, recipients and amounts.
}

struct QualifiedSplitBatchClaim {
uint256 nonce; // A parameter to enforce replay protection, scoped to allocator.
uint256 expires; // The time at which the claim expires.
bytes allocatorSignature; // Authorization from the allocator.
address sponsor; // The account to source the tokens from.
bytes sponsorSignature; // Authorization from the sponsor.
address sponsor; // The account to source the tokens from.
uint256 nonce; // A parameter to enforce replay protection, scoped to allocator.
uint256 expires; // The time at which the claim expires.
bytes32 qualificationTypehash; // Typehash of the qualification payload.
bytes qualificationPayload; // Data used to derive qualification hash.
SplitBatchClaimComponent[] claims; // The claim token IDs, recipients and amounts.
}

struct QualifiedSplitBatchClaimWithWitness {
uint256 nonce; // A parameter to enforce replay protection, scoped to allocator.
uint256 expires; // The time at which the claim expires.
bytes allocatorSignature; // Authorization from the allocator.
address sponsor; // The account to source the tokens from.
bytes sponsorSignature; // Authorization from the sponsor.
address sponsor; // The account to source the tokens from.
uint256 nonce; // A parameter to enforce replay protection, scoped to allocator.
uint256 expires; // The time at which the claim expires.
bytes32 witness; // Hash of the witness data.
string witnessTypestring; // Witness typestring appended to existing typestring.
bytes32 qualificationTypehash; // Typehash of the qualification payload.
Expand Down
Loading

0 comments on commit 69f0c3d

Please sign in to comment.