Skip to content

Commit

Permalink
qualified multichain (had to eat the reduced opt runs for now)
Browse files Browse the repository at this point in the history
  • Loading branch information
0age committed Oct 17, 2024
1 parent ad3cb91 commit 582375f
Show file tree
Hide file tree
Showing 5 changed files with 539 additions and 61 deletions.
3 changes: 2 additions & 1 deletion foundry.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@
solc = '0.8.28'
evm_version='cancun'
via_ir = true
optimizer_runs = 4_294_967_295
# optimizer_runs = 4_294_967_295
optimizer_runs = 80_000
bytecode_hash = 'none'
src = "src"
out = "out"
Expand Down
103 changes: 102 additions & 1 deletion src/TheCompact.sol
Original file line number Diff line number Diff line change
Expand Up @@ -590,8 +590,36 @@ contract TheCompact is ITheCompact, ERC6909, Extsload {
return _processExogenousMultichainClaim(claimPayload, _release);
}

function claim(QualifiedMultichainClaim calldata claimPayload) external returns (bool) {
return _processQualifiedMultichainClaim(claimPayload, _release);
}

function claimAndWithdraw(QualifiedMultichainClaim calldata claimPayload)
external
returns (bool)
{
return _processQualifiedMultichainClaim(claimPayload, _release);
}

function claim(ExogenousQualifiedMultichainClaim calldata claimPayload)
external
returns (bool)
{
return _processExogenousQualifiedMultichainClaim(claimPayload, _release);
}

function claimAndWithdraw(ExogenousQualifiedMultichainClaim calldata claimPayload)
external
returns (bool)
{
return _processExogenousQualifiedMultichainClaim(claimPayload, _release);
}

function enableForcedWithdrawal(uint256 id) external returns (uint256 withdrawableAt) {
withdrawableAt = block.timestamp + id.toResetPeriod().toSeconds();
// overflow check not necessary as reset period is capped
unchecked {
withdrawableAt = block.timestamp + id.toResetPeriod().toSeconds();
}

_cutoffTime[msg.sender][id] = withdrawableAt;

Expand Down Expand Up @@ -812,6 +840,24 @@ contract TheCompact is ITheCompact, ERC6909, Extsload {
);
}

function _notExpiredAndWithValidSignaturesQualifiedExogenous(
bytes32 messageHash,
bytes32 qualificationMessageHash,
ExogenousQualifiedMultichainClaim calldata claimPayload,
address allocator
) internal view {
_notExpiredAndSignedByBoth(
claimPayload.expires,
claimPayload.notarizedChainId.toNotarizedDomainSeparator(),
messageHash,
claimPayload.sponsor,
claimPayload.sponsorSignature,
qualificationMessageHash,
allocator,
claimPayload.allocatorSignature
);
}

// NOTE: this function expects that there's at least one array element
function _notExpiredAndWithValidSignaturesBatch(BatchClaim calldata claimPayload)
internal
Expand Down Expand Up @@ -1016,6 +1062,30 @@ contract TheCompact is ITheCompact, ERC6909, Extsload {
);
}

function _processQualifiedMultichainClaim(
QualifiedMultichainClaim calldata claimPayload,
function(address, address, uint256, uint256) internal returns (bool) operation
) internal returns (bool) {
(bytes32 messageHash, bytes32 qualificationMessageHash) = claimPayload.toMessageHash();
address allocator = claimPayload.id.toRegisteredAllocatorWithConsumed(claimPayload.nonce);

_notExpiredAndWithValidQualifiedSignatures.usingQualifiedMultichainClaim()(
messageHash, qualificationMessageHash, claimPayload, allocator
);

claimPayload.amount.withinAllocated(claimPayload.allocatedAmount);

return _emitAndOperate(
claimPayload.sponsor,
claimPayload.claimant,
claimPayload.id,
messageHash,
claimPayload.amount,
allocator,
operation
);
}

function _processExogenousMultichainClaim(
ExogenousMultichainClaim calldata claimPayload,
function(address, address, uint256, uint256) internal returns (bool) operation
Expand Down Expand Up @@ -1045,6 +1115,37 @@ contract TheCompact is ITheCompact, ERC6909, Extsload {
);
}

function _processExogenousQualifiedMultichainClaim(
ExogenousQualifiedMultichainClaim calldata claimPayload,
function(address, address, uint256, uint256) internal returns (bool) operation
) internal returns (bool) {
(bytes32 messageHash, bytes32 qualificationMessageHash) = claimPayload.toMessageHash();

uint256 id = claimPayload.id;
uint256 amount = claimPayload.amount;
address allocator = id.toRegisteredAllocatorWithConsumed(claimPayload.nonce);

_notExpiredAndWithValidSignaturesQualifiedExogenous(
messageHash, qualificationMessageHash, claimPayload, allocator
);

if (id.toScope() != Scope.Multichain) {
revert InvalidScope(id);
}

amount.withinAllocated(claimPayload.allocatedAmount);

return _emitAndOperate(
claimPayload.sponsor,
claimPayload.claimant,
id,
messageHash,
amount,
allocator,
operation
);
}

function _verifyAndProcessSplitComponents(
address sponsor,
bytes32 messageHash,
Expand Down
21 changes: 20 additions & 1 deletion src/lib/FunctionCastLib.sol
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,12 @@ import {
QualifiedSplitBatchClaimWithWitness
} from "../types/BatchClaims.sol";

import { MultichainClaim } from "../types/MultichainClaims.sol";
import {
MultichainClaim,
QualifiedMultichainClaim,
ExogenousMultichainClaim,
ExogenousQualifiedMultichainClaim
} from "../types/MultichainClaims.sol";

import {
TransferComponent,
Expand Down Expand Up @@ -507,4 +512,18 @@ library FunctionCastLib {
fnOut := fnIn
}
}

function usingQualifiedMultichainClaim(
function(bytes32, bytes32, QualifiedClaim calldata, address) internal view fnIn
)
internal
pure
returns (
function(bytes32, bytes32, QualifiedMultichainClaim calldata, address) internal view fnOut
)
{
assembly ("memory-safe") {
fnOut := fnIn
}
}
}
Loading

0 comments on commit 582375f

Please sign in to comment.