diff --git a/src/TheCompact.sol b/src/TheCompact.sol index 7771ef0..4c7f987 100644 --- a/src/TheCompact.sol +++ b/src/TheCompact.sol @@ -1044,7 +1044,7 @@ contract TheCompact is ITheCompact, ERC6909, Extsload { uint256 nonce; uint256 expires; - assembly { + assembly ("memory-safe") { let allocatorSignaturePtr := add(calldataPointer, calldataload(calldataPointer)) allocatorSignature.offset := add(0x20, allocatorSignaturePtr) allocatorSignature.length := calldataload(allocatorSignaturePtr) @@ -1063,7 +1063,7 @@ contract TheCompact is ITheCompact, ERC6909, Extsload { address allocator = allocatorId.fromRegisteredAllocatorIdWithConsumed(nonce); bytes32 domainSeparator = _INITIAL_DOMAIN_SEPARATOR.toLatest(_INITIAL_CHAIN_ID); - assembly { + assembly ("memory-safe") { sponsorDomainSeparator := add(sponsorDomainSeparator, mul(iszero(sponsorDomainSeparator), domainSeparator)) } @@ -1116,7 +1116,7 @@ contract TheCompact is ITheCompact, ERC6909, Extsload { address claimant; uint256 amount; - assembly { + assembly ("memory-safe") { let calldataPointerWithOffset := add(calldataPointer, offsetToId) id := calldataload(calldataPointerWithOffset) allocatedAmount := calldataload(add(calldataPointerWithOffset, 0x20)) @@ -1143,7 +1143,7 @@ contract TheCompact is ITheCompact, ERC6909, Extsload { uint256 allocatedAmount; SplitComponent[] calldata claimants; - assembly { + assembly ("memory-safe") { let calldataPointerWithOffset := add(calldataPointer, offsetToId) id := calldataload(calldataPointerWithOffset) allocatedAmount := calldataload(add(calldataPointerWithOffset, 0x20)) @@ -1161,7 +1161,7 @@ contract TheCompact is ITheCompact, ERC6909, Extsload { } function _ensureValidScope(bytes32 sponsorDomainSeparator, uint256 id) internal pure { - assembly { + assembly ("memory-safe") { if iszero(or(iszero(sponsorDomainSeparator), iszero(shr(255, id)))) { // revert InvalidScope(id) mstore(0, 0xa06356f5) @@ -1181,7 +1181,7 @@ contract TheCompact is ITheCompact, ERC6909, Extsload { ) internal returns (bool) { BatchClaimComponent[] calldata claims; address claimant; - assembly { + assembly ("memory-safe") { let calldataPointerWithOffset := add(calldataPointer, offsetToId) let claimsPtr := add(calldataPointer, calldataload(calldataPointerWithOffset)) claims.offset := add(0x20, claimsPtr) @@ -1196,7 +1196,7 @@ contract TheCompact is ITheCompact, ERC6909, Extsload { uint256 totalClaims = claims.length; - assembly { + assembly ("memory-safe") { if iszero(totalClaims) { // revert InvalidBatchAllocation() mstore(0, 0x3a03d3bb) @@ -1231,7 +1231,7 @@ contract TheCompact is ITheCompact, ERC6909, Extsload { _ensureValidScope(sponsorDomainSeparator, component.id); } - assembly { + assembly ("memory-safe") { // revert InvalidBatchAllocation() mstore(0, 0x3a03d3bb) revert(0x1c, 0x04) @@ -1251,7 +1251,7 @@ contract TheCompact is ITheCompact, ERC6909, Extsload { function(address, address, uint256, uint256) internal returns (bool) operation ) internal returns (bool) { SplitBatchClaimComponent[] calldata claims; - assembly { + assembly ("memory-safe") { let claimsPtr := add(calldataPointer, calldataload(add(calldataPointer, offsetToId))) claims.offset := add(0x20, claimsPtr) claims.length := calldataload(claimsPtr) @@ -1279,7 +1279,7 @@ contract TheCompact is ITheCompact, ERC6909, Extsload { _ensureValidScope(sponsorDomainSeparator, claims[i].id); } - assembly { + assembly ("memory-safe") { // revert InvalidBatchAllocation() mstore(0, 0x3a03d3bb) revert(0x1c, 0x04) @@ -1394,14 +1394,14 @@ contract TheCompact is ITheCompact, ERC6909, Extsload { returns (bool) { (bytes32 messageHash, bytes32 qualificationMessageHash) = claimPayload.toMessageHash(); - return _processBatchClaimWithQualification.usingQualifiedBatchMultichainClaim()(messageHash, qualificationMessageHash, claimPayload, 0xe0, operation); + return _processBatchClaimWithQualification.usingQualifiedBatchMultichainClaim()(messageHash, qualificationMessageHash, claimPayload, 0x100, operation); } function _processBatchMultichainClaimWithWitness(BatchMultichainClaimWithWitness calldata claimPayload, function(address, address, uint256, uint256) internal returns (bool) operation) internal returns (bool) { - return _processSimpleBatchClaim.usingBatchMultichainClaimWithWitness()(claimPayload.toMessageHash(), claimPayload, 0xe0, operation); + return _processSimpleBatchClaim.usingBatchMultichainClaimWithWitness()(claimPayload.toMessageHash(), claimPayload, 0x100, operation); } function _processQualifiedBatchMultichainClaimWithWitness( @@ -1409,7 +1409,7 @@ contract TheCompact is ITheCompact, ERC6909, Extsload { function(address, address, uint256, uint256) internal returns (bool) operation ) internal returns (bool) { (bytes32 messageHash, bytes32 qualificationMessageHash) = claimPayload.toMessageHash(); - return _processBatchClaimWithQualification.usingQualifiedBatchMultichainClaimWithWitness()(messageHash, qualificationMessageHash, claimPayload, 0x120, operation); + return _processBatchClaimWithQualification.usingQualifiedBatchMultichainClaimWithWitness()(messageHash, qualificationMessageHash, claimPayload, 0x140, operation); } function _processExogenousQualifiedBatchMultichainClaim( @@ -1418,7 +1418,7 @@ contract TheCompact is ITheCompact, ERC6909, Extsload { ) internal returns (bool) { (bytes32 messageHash, bytes32 qualificationMessageHash) = claimPayload.toMessageHash(); return _processBatchClaimWithQualificationAndSponsorDomain.usingExogenousQualifiedBatchMultichainClaim()( - messageHash, qualificationMessageHash, claimPayload, 0x120, claimPayload.notarizedChainId.toNotarizedDomainSeparator(), operation + messageHash, qualificationMessageHash, claimPayload, 0x140, claimPayload.notarizedChainId.toNotarizedDomainSeparator(), operation ); } @@ -1427,7 +1427,7 @@ contract TheCompact is ITheCompact, ERC6909, Extsload { function(address, address, uint256, uint256) internal returns (bool) operation ) internal returns (bool) { return _processBatchClaimWithSponsorDomain.usingExogenousBatchMultichainClaimWithWitness()( - claimPayload.toMessageHash(), claimPayload, 0x120, claimPayload.notarizedChainId.toNotarizedDomainSeparator(), operation + claimPayload.toMessageHash(), claimPayload, 0x140, claimPayload.notarizedChainId.toNotarizedDomainSeparator(), operation ); } @@ -1437,7 +1437,7 @@ contract TheCompact is ITheCompact, ERC6909, Extsload { ) internal returns (bool) { (bytes32 messageHash, bytes32 qualificationMessageHash) = claimPayload.toMessageHash(); return _processBatchClaimWithQualificationAndSponsorDomain.usingExogenousQualifiedBatchMultichainClaimWithWitness()( - messageHash, qualificationMessageHash, claimPayload, 0x160, claimPayload.notarizedChainId.toNotarizedDomainSeparator(), operation + messageHash, qualificationMessageHash, claimPayload, 0x180, claimPayload.notarizedChainId.toNotarizedDomainSeparator(), operation ); } @@ -1761,7 +1761,7 @@ contract TheCompact is ITheCompact, ERC6909, Extsload { } } - assembly { + assembly ("memory-safe") { if errorBuffer { // revert InvalidBatchAllocation() mstore(0, 0x3a03d3bb) diff --git a/src/lib/ConsumerLib.sol b/src/lib/ConsumerLib.sol index 385f30a..1651170 100644 --- a/src/lib/ConsumerLib.sol +++ b/src/lib/ConsumerLib.sol @@ -11,7 +11,7 @@ library ConsumerLib { // specific nonces are consumed for each account and can only be used once. // NOTE: this function temporarily overwrites the free memory pointer, but // restores it before returning. - assembly { + assembly ("memory-safe") { let freeMemoryPointer := mload(0x40) // slot: keccak256(_CONSUMER_NONCE_SCOPE ++ account ++ nonce[0:31]) @@ -35,7 +35,7 @@ library ConsumerLib { } function isConsumedBy(uint256 nonceToCheck, address account) internal view returns (bool consumed) { - assembly { + assembly ("memory-safe") { let freeMemoryPointer := mload(0x40) // slot: keccak256(_CONSUMER_NONCE_SCOPE ++ account ++ nonce[0:31]) diff --git a/src/lib/EfficiencyLib.sol b/src/lib/EfficiencyLib.sol index 80117f1..1836120 100644 --- a/src/lib/EfficiencyLib.sol +++ b/src/lib/EfficiencyLib.sol @@ -10,7 +10,7 @@ library EfficiencyLib { // around the fact that solidity only evaluates both expressions in an && if // the first expression evaluates to true, which requires a conditional jump. function and(bool a, bool b) internal pure returns (bool c) { - assembly { + assembly ("memory-safe") { c := and(a, b) } } @@ -20,7 +20,7 @@ library EfficiencyLib { // around the fact that solidity only evaluates both expressions in an || if // the first expression evaluates to false, which requires a conditional jump. function or(bool a, bool b) internal pure returns (bool c) { - assembly { + assembly ("memory-safe") { c := or(a, b) } } @@ -28,56 +28,56 @@ library EfficiencyLib { // NOTE: this function is only safe if the supplied uint256 is known to not // have any dirty bits set (i.e. it is either 0 or 1). function asBool(uint256 a) internal pure returns (bool b) { - assembly { + assembly ("memory-safe") { b := a } } function asSanitizedAddress(uint256 accountValue) internal pure returns (address account) { // extract last 160 bits (can also just use a mask if contract size permits) - assembly { + assembly ("memory-safe") { account := shr(96, shl(96, accountValue)) } } function isNullAddress(address account) internal pure returns (bool isNull) { - assembly { + assembly ("memory-safe") { isNull := iszero(shl(96, account)) } } function asUint256(bool a) internal pure returns (uint256 b) { - assembly { + assembly ("memory-safe") { b := a } } function asUint256(uint8 a) internal pure returns (uint256 b) { - assembly { + assembly ("memory-safe") { b := a } } function asUint256(uint96 a) internal pure returns (uint256 b) { - assembly { + assembly ("memory-safe") { b := a } } function asUint256(Scope a) internal pure returns (uint256 b) { - assembly { + assembly ("memory-safe") { b := a } } function asUint256(address a) internal pure returns (uint256 b) { - assembly { + assembly ("memory-safe") { b := a } } function asUint256(ResetPeriod a) internal pure returns (uint256 b) { - assembly { + assembly ("memory-safe") { b := a } } diff --git a/src/lib/FunctionCastLib.sol b/src/lib/FunctionCastLib.sol index bfb7cbf..ddd901b 100644 --- a/src/lib/FunctionCastLib.sol +++ b/src/lib/FunctionCastLib.sol @@ -119,7 +119,7 @@ library FunctionCastLib { ) internal returns (bool) fnOut ) { - assembly { + assembly ("memory-safe") { fnOut := fnIn } } @@ -145,7 +145,7 @@ library FunctionCastLib { ) internal returns (bool) fnOut ) { - assembly { + assembly ("memory-safe") { fnOut := fnIn } } @@ -169,7 +169,7 @@ library FunctionCastLib { ) internal returns (bool) fnOut ) { - assembly { + assembly ("memory-safe") { fnOut := fnIn } } @@ -195,7 +195,7 @@ library FunctionCastLib { ) internal returns (bool) fnOut ) { - assembly { + assembly ("memory-safe") { fnOut := fnIn } } @@ -219,7 +219,7 @@ library FunctionCastLib { ) internal returns (bool) fnOut ) { - assembly { + assembly ("memory-safe") { fnOut := fnIn } } @@ -245,7 +245,7 @@ library FunctionCastLib { ) internal returns (bool) fnOut ) { - assembly { + assembly ("memory-safe") { fnOut := fnIn } } @@ -269,7 +269,7 @@ library FunctionCastLib { ) internal returns (bool) fnOut ) { - assembly { + assembly ("memory-safe") { fnOut := fnIn } } @@ -295,7 +295,7 @@ library FunctionCastLib { ) internal returns (bool) fnOut ) { - assembly { + assembly ("memory-safe") { fnOut := fnIn } } @@ -319,7 +319,7 @@ library FunctionCastLib { ) internal returns (bool) fnOut ) { - assembly { + assembly ("memory-safe") { fnOut := fnIn } } @@ -345,7 +345,7 @@ library FunctionCastLib { ) internal returns (bool) fnOut ) { - assembly { + assembly ("memory-safe") { fnOut := fnIn } } @@ -369,7 +369,7 @@ library FunctionCastLib { ) internal returns (bool) fnOut ) { - assembly { + assembly ("memory-safe") { fnOut := fnIn } } @@ -395,7 +395,7 @@ library FunctionCastLib { ) internal returns (bool) fnOut ) { - assembly { + assembly ("memory-safe") { fnOut := fnIn } } @@ -419,7 +419,7 @@ library FunctionCastLib { ) internal returns (bool) fnOut ) { - assembly { + assembly ("memory-safe") { fnOut := fnIn } } @@ -445,7 +445,7 @@ library FunctionCastLib { ) internal returns (bool) fnOut ) { - assembly { + assembly ("memory-safe") { fnOut := fnIn } } @@ -469,7 +469,7 @@ library FunctionCastLib { ) internal returns (bool) fnOut ) { - assembly { + assembly ("memory-safe") { fnOut := fnIn } } @@ -495,7 +495,7 @@ library FunctionCastLib { ) internal returns (bool) fnOut ) { - assembly { + assembly ("memory-safe") { fnOut := fnIn } } @@ -519,7 +519,7 @@ library FunctionCastLib { ) internal returns (bool) fnOut ) { - assembly { + assembly ("memory-safe") { fnOut := fnIn } } @@ -545,7 +545,7 @@ library FunctionCastLib { ) internal returns (bool) fnOut ) { - assembly { + assembly ("memory-safe") { fnOut := fnIn } } @@ -569,7 +569,7 @@ library FunctionCastLib { ) internal returns (bool) fnOut ) { - assembly { + assembly ("memory-safe") { fnOut := fnIn } } @@ -595,7 +595,7 @@ library FunctionCastLib { ) internal returns (bool) fnOut ) { - assembly { + assembly ("memory-safe") { fnOut := fnIn } } @@ -619,7 +619,7 @@ library FunctionCastLib { ) internal returns (bool) fnOut ) { - assembly { + assembly ("memory-safe") { fnOut := fnIn } } @@ -645,7 +645,7 @@ library FunctionCastLib { ) internal returns (bool) fnOut ) { - assembly { + assembly ("memory-safe") { fnOut := fnIn } } @@ -669,7 +669,7 @@ library FunctionCastLib { ) internal returns (bool) fnOut ) { - assembly { + assembly ("memory-safe") { fnOut := fnIn } } @@ -695,7 +695,7 @@ library FunctionCastLib { ) internal returns (bool) fnOut ) { - assembly { + assembly ("memory-safe") { fnOut := fnIn } } @@ -719,7 +719,7 @@ library FunctionCastLib { ) internal returns (bool) fnOut ) { - assembly { + assembly ("memory-safe") { fnOut := fnIn } } @@ -745,7 +745,7 @@ library FunctionCastLib { ) internal returns (bool) fnOut ) { - assembly { + assembly ("memory-safe") { fnOut := fnIn } } @@ -769,7 +769,7 @@ library FunctionCastLib { ) internal returns (bool) fnOut ) { - assembly { + assembly ("memory-safe") { fnOut := fnIn } } @@ -795,7 +795,7 @@ library FunctionCastLib { ) internal returns (bool) fnOut ) { - assembly { + assembly ("memory-safe") { fnOut := fnIn } } @@ -819,7 +819,7 @@ library FunctionCastLib { ) internal returns (bool) fnOut ) { - assembly { + assembly ("memory-safe") { fnOut := fnIn } } @@ -845,7 +845,7 @@ library FunctionCastLib { ) internal returns (bool) fnOut ) { - assembly { + assembly ("memory-safe") { fnOut := fnIn } } @@ -869,7 +869,7 @@ library FunctionCastLib { ) internal returns (bool) fnOut ) { - assembly { + assembly ("memory-safe") { fnOut := fnIn } } @@ -895,7 +895,7 @@ library FunctionCastLib { ) internal returns (bool) fnOut ) { - assembly { + assembly ("memory-safe") { fnOut := fnIn } } @@ -921,7 +921,7 @@ library FunctionCastLib { ) internal returns (bool) fnOut ) { - assembly { + assembly ("memory-safe") { fnOut := fnIn } } @@ -949,7 +949,7 @@ library FunctionCastLib { ) internal returns (bool) fnOut ) { - assembly { + assembly ("memory-safe") { fnOut := fnIn } } @@ -975,7 +975,7 @@ library FunctionCastLib { ) internal returns (bool) fnOut ) { - assembly { + assembly ("memory-safe") { fnOut := fnIn } } @@ -1003,7 +1003,7 @@ library FunctionCastLib { ) internal returns (bool) fnOut ) { - assembly { + assembly ("memory-safe") { fnOut := fnIn } } @@ -1029,7 +1029,7 @@ library FunctionCastLib { ) internal returns (bool) fnOut ) { - assembly { + assembly ("memory-safe") { fnOut := fnIn } } @@ -1057,7 +1057,7 @@ library FunctionCastLib { ) internal returns (bool) fnOut ) { - assembly { + assembly ("memory-safe") { fnOut := fnIn } } @@ -1083,7 +1083,7 @@ library FunctionCastLib { ) internal returns (bool) fnOut ) { - assembly { + assembly ("memory-safe") { fnOut := fnIn } } @@ -1111,7 +1111,7 @@ library FunctionCastLib { ) internal returns (bool) fnOut ) { - assembly { + assembly ("memory-safe") { fnOut := fnIn } } @@ -1137,7 +1137,7 @@ library FunctionCastLib { ) internal returns (bool) fnOut ) { - assembly { + assembly ("memory-safe") { fnOut := fnIn } } @@ -1165,7 +1165,7 @@ library FunctionCastLib { ) internal returns (bool) fnOut ) { - assembly { + assembly ("memory-safe") { fnOut := fnIn } } @@ -1191,7 +1191,7 @@ library FunctionCastLib { ) internal returns (bool) fnOut ) { - assembly { + assembly ("memory-safe") { fnOut := fnIn } } @@ -1219,7 +1219,7 @@ library FunctionCastLib { ) internal returns (bool) fnOut ) { - assembly { + assembly ("memory-safe") { fnOut := fnIn } } @@ -1245,7 +1245,7 @@ library FunctionCastLib { ) internal returns (bool) fnOut ) { - assembly { + assembly ("memory-safe") { fnOut := fnIn } } @@ -1273,7 +1273,7 @@ library FunctionCastLib { ) internal returns (bool) fnOut ) { - assembly { + assembly ("memory-safe") { fnOut := fnIn } } @@ -1299,7 +1299,7 @@ library FunctionCastLib { ) internal returns (bool) fnOut ) { - assembly { + assembly ("memory-safe") { fnOut := fnIn } } @@ -1327,7 +1327,7 @@ library FunctionCastLib { ) internal returns (bool) fnOut ) { - assembly { + assembly ("memory-safe") { fnOut := fnIn } } diff --git a/src/lib/HashLib.sol b/src/lib/HashLib.sol index 701ec50..1c5ada1 100644 --- a/src/lib/HashLib.sol +++ b/src/lib/HashLib.sol @@ -310,7 +310,7 @@ library HashLib { errorBuffer |= (amount < singleAmount).asUint256(); } - assembly { + assembly ("memory-safe") { let extraOffset := add(add(idsAndAmounts, 0x20), mul(i, 0x40)) mstore(extraOffset, id) mstore(add(extraOffset, 0x20), amount) @@ -319,7 +319,7 @@ library HashLib { } bytes32 idsAndAmountsHash; - assembly { + assembly ("memory-safe") { if errorBuffer { // Revert Panic(0x11) (arithmetic overflow) mstore(0, 0x4e487b71) @@ -339,7 +339,7 @@ library HashLib { unchecked { for (uint256 i = 0; i < totalIds; ++i) { BatchClaimComponent calldata claimComponent = claims[i]; - assembly { + assembly ("memory-safe") { let extraOffset := add(add(idsAndAmounts, 0x20), mul(i, 0x40)) mstore(extraOffset, calldataload(claimComponent)) // id mstore(add(extraOffset, 0x20), calldataload(add(claimComponent, 0x20))) // amount @@ -347,7 +347,7 @@ library HashLib { } } - assembly { + assembly ("memory-safe") { idsAndAmountsHash := keccak256(add(idsAndAmounts, 0x20), mload(idsAndAmounts)) } } @@ -359,7 +359,7 @@ library HashLib { unchecked { for (uint256 i = 0; i < totalIds; ++i) { SplitBatchClaimComponent calldata claimComponent = claims[i]; - assembly { + assembly ("memory-safe") { let extraOffset := add(add(idsAndAmounts, 0x20), mul(i, 0x40)) mstore(extraOffset, calldataload(claimComponent)) // id mstore(add(extraOffset, 0x20), calldataload(add(claimComponent, 0x20))) // amount @@ -367,7 +367,7 @@ library HashLib { } } - assembly { + assembly ("memory-safe") { idsAndAmountsHash := keccak256(add(idsAndAmounts, 0x20), mload(idsAndAmounts)) } } diff --git a/src/lib/ValidityLib.sol b/src/lib/ValidityLib.sol index c97962a..811cafb 100644 --- a/src/lib/ValidityLib.sol +++ b/src/lib/ValidityLib.sol @@ -53,7 +53,7 @@ library ValidityLib { } function excludingNative(address token) internal pure returns (address) { - assembly { + assembly ("memory-safe") { if iszero(shl(96, token)) { // revert InvalidToken(0); mstore(0x40, 0x961c9a4f) diff --git a/test/TheCompact.t.sol b/test/TheCompact.t.sol index 49c0583..885184b 100644 --- a/test/TheCompact.t.sol +++ b/test/TheCompact.t.sol @@ -100,7 +100,7 @@ contract TheCompactTest is Test { hex"604580600e600039806000f350fe7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe03601600081602082378035828234f58015156039578182fd5b8082525050506014600cf3"; vm.deal(permit2DeployerDeployer, 1e18); vm.prank(permit2DeployerDeployer); - assembly { + assembly ("memory-safe") { deployedPermit2Deployer := create(0, add(permit2DeployerCreationCode, 0x20), mload(permit2DeployerCreationCode)) } @@ -3228,6 +3228,459 @@ contract TheCompactTest is Test { assertEq(block.chainid, notarizedChainId); } + function test_qualifiedBatchMultichainClaim() public { + uint256 amount = 1e18; + uint256 anotherAmount = 1e18; + uint256 aThirdAmount = 1e18; + uint256 nonce = 0; + uint256 expires = block.timestamp + 1000; + address claimant = 0x1111111111111111111111111111111111111111; + address arbiter = 0x2222222222222222222222222222222222222222; + + vm.prank(allocator); + theCompact.__register(allocator, ""); + + vm.startPrank(swapper); + uint256 id = theCompact.deposit{ value: amount }(allocator, ResetPeriod.TenMinutes, Scope.Multichain, swapper); + + uint256 anotherId = theCompact.deposit(address(token), allocator, ResetPeriod.TenMinutes, Scope.Multichain, anotherAmount, swapper); + assertEq(theCompact.balanceOf(swapper, anotherId), anotherAmount); + + uint256 aThirdId = theCompact.deposit(address(anotherToken), allocator, ResetPeriod.TenMinutes, Scope.Multichain, aThirdAmount, swapper); + assertEq(theCompact.balanceOf(swapper, aThirdId), aThirdAmount); + + vm.stopPrank(); + + assertEq(theCompact.balanceOf(swapper, id), amount); + assertEq(theCompact.balanceOf(swapper, anotherId), anotherAmount); + assertEq(theCompact.balanceOf(swapper, aThirdId), aThirdAmount); + + uint256[2][] memory idsAndAmounts = new uint256[2][](3); + idsAndAmounts[0] = [id, amount]; + idsAndAmounts[1] = [anotherId, anotherAmount]; + idsAndAmounts[2] = [aThirdId, aThirdAmount]; + + uint256 anotherChainId = 7171717; + + uint256[2][] memory idsAndAmountsOne = new uint256[2][](1); + idsAndAmountsOne[0] = [id, amount]; + + uint256[2][] memory idsAndAmountsTwo = new uint256[2][](2); + idsAndAmountsTwo[0] = [anotherId, anotherAmount]; + idsAndAmountsTwo[1] = [aThirdId, aThirdAmount]; + + bytes32 allocationHashOne = + keccak256(abi.encode(keccak256("Allocation(address arbiter,uint256 chainId,uint256[2][] idsAndAmounts)"), arbiter, block.chainid, keccak256(abi.encodePacked(idsAndAmountsOne)))); + + bytes32 allocationHashTwo = + keccak256(abi.encode(keccak256("Allocation(address arbiter,uint256 chainId,uint256[2][] idsAndAmounts)"), arbiter, anotherChainId, keccak256(abi.encodePacked(idsAndAmountsTwo)))); + + bytes32 claimHash = keccak256( + abi.encode( + keccak256("MultichainCompact(address sponsor,uint256 nonce,uint256 expires,Allocation[] allocations)Allocation(address arbiter,uint256 chainId,uint256[2][] idsAndAmounts)"), + swapper, + nonce, + expires, + keccak256(abi.encodePacked(allocationHashOne, allocationHashTwo)) + ) + ); + + bytes32 initialDomainSeparator = theCompact.DOMAIN_SEPARATOR(); + + bytes32 digest = keccak256(abi.encodePacked(bytes2(0x1901), initialDomainSeparator, claimHash)); + + (bytes32 r, bytes32 vs) = vm.signCompact(swapperPrivateKey, digest); + bytes memory sponsorSignature = abi.encodePacked(r, vs); + + bytes32 qualificationTypehash = keccak256("ExampleQualifiedClaim(bytes32 claimHash,uint256 qualifiedClaimArgument)"); + + uint256 qualifiedClaimArgument = 123; + bytes memory qualificationPayload = abi.encode(qualifiedClaimArgument); + + bytes32 qualifiedClaimHash = keccak256(abi.encode(qualificationTypehash, claimHash, qualifiedClaimArgument)); + + digest = keccak256(abi.encodePacked(bytes2(0x1901), initialDomainSeparator, qualifiedClaimHash)); + + (r, vs) = vm.signCompact(allocatorPrivateKey, digest); + bytes memory allocatorSignature = abi.encodePacked(r, vs); + + bytes32[] memory additionalChains = new bytes32[](1); + additionalChains[0] = allocationHashTwo; + + BatchClaimComponent[] memory claims = new BatchClaimComponent[](1); + claims[0] = BatchClaimComponent({ id: id, allocatedAmount: amount, amount: amount }); + + QualifiedBatchMultichainClaim memory claim = + QualifiedBatchMultichainClaim(allocatorSignature, sponsorSignature, swapper, nonce, expires, qualificationTypehash, qualificationPayload, additionalChains, claims, claimant); + + uint256 snapshotId = vm.snapshot(); + vm.prank(arbiter); + (bool status) = theCompact.claim(claim); + assert(status); + + assertEq(address(theCompact).balance, amount); + assertEq(claimant.balance, 0); + assertEq(theCompact.balanceOf(swapper, id), 0); + assertEq(theCompact.balanceOf(claimant, id), amount); + vm.revertToAndDelete(snapshotId); + + // change to "new chain" (this hack is so the original one gets stored) + uint256 notarizedChainId = abi.decode(abi.encode(block.chainid), (uint256)); + assert(notarizedChainId != anotherChainId); + vm.chainId(anotherChainId); + assertEq(block.chainid, anotherChainId); + assert(notarizedChainId != anotherChainId); + + bytes32 anotherDomainSeparator = theCompact.DOMAIN_SEPARATOR(); + + assert(initialDomainSeparator != anotherDomainSeparator); + + digest = keccak256(abi.encodePacked(bytes2(0x1901), anotherDomainSeparator, qualifiedClaimHash)); + + (r, vs) = vm.signCompact(allocatorPrivateKey, digest); + bytes memory exogenousAllocatorSignature = abi.encodePacked(r, vs); + + additionalChains[0] = allocationHashOne; + uint256 chainIndex = 0; + + claims = new BatchClaimComponent[](2); + claims[0] = BatchClaimComponent({ id: anotherId, allocatedAmount: anotherAmount, amount: anotherAmount }); + claims[1] = BatchClaimComponent({ id: aThirdId, allocatedAmount: aThirdAmount, amount: aThirdAmount }); + + ExogenousQualifiedBatchMultichainClaim memory anotherClaim = ExogenousQualifiedBatchMultichainClaim( + exogenousAllocatorSignature, sponsorSignature, swapper, nonce, expires, qualificationTypehash, qualificationPayload, additionalChains, chainIndex, notarizedChainId, claims, claimant + ); + + vm.prank(arbiter); + (bool exogenousStatus) = theCompact.claim(anotherClaim); + assert(exogenousStatus); + + assertEq(theCompact.balanceOf(swapper, anotherId), 0); + assertEq(theCompact.balanceOf(claimant, anotherId), anotherAmount); + assertEq(theCompact.balanceOf(claimant, aThirdId), aThirdAmount); + + // change back + vm.chainId(notarizedChainId); + assertEq(block.chainid, notarizedChainId); + } + + function test_batchMultichainClaimWithWitness() public { + uint256 amount = 1e18; + uint256 anotherAmount = 1e18; + uint256 aThirdAmount = 1e18; + uint256 nonce = 0; + uint256 expires = block.timestamp + 1000; + address claimant = 0x1111111111111111111111111111111111111111; + address arbiter = 0x2222222222222222222222222222222222222222; + + vm.prank(allocator); + theCompact.__register(allocator, ""); + + vm.startPrank(swapper); + uint256 id = theCompact.deposit{ value: amount }(allocator, ResetPeriod.TenMinutes, Scope.Multichain, swapper); + + uint256 anotherId = theCompact.deposit(address(token), allocator, ResetPeriod.TenMinutes, Scope.Multichain, anotherAmount, swapper); + assertEq(theCompact.balanceOf(swapper, anotherId), anotherAmount); + + uint256 aThirdId = theCompact.deposit(address(anotherToken), allocator, ResetPeriod.TenMinutes, Scope.Multichain, aThirdAmount, swapper); + assertEq(theCompact.balanceOf(swapper, aThirdId), aThirdAmount); + + vm.stopPrank(); + + assertEq(theCompact.balanceOf(swapper, id), amount); + assertEq(theCompact.balanceOf(swapper, anotherId), anotherAmount); + assertEq(theCompact.balanceOf(swapper, aThirdId), aThirdAmount); + + uint256[2][] memory idsAndAmounts = new uint256[2][](3); + idsAndAmounts[0] = [id, amount]; + idsAndAmounts[1] = [anotherId, anotherAmount]; + idsAndAmounts[2] = [aThirdId, aThirdAmount]; + + uint256 anotherChainId = 7171717; + + uint256[2][] memory idsAndAmountsOne = new uint256[2][](1); + idsAndAmountsOne[0] = [id, amount]; + + uint256[2][] memory idsAndAmountsTwo = new uint256[2][](2); + idsAndAmountsTwo[0] = [anotherId, anotherAmount]; + idsAndAmountsTwo[1] = [aThirdId, aThirdAmount]; + + string memory witnessTypestring = "Witness witness)Witness(uint256 witnessArgument)"; + uint256 witnessArgument = 234; + bytes32 witness = keccak256(abi.encode(witnessArgument)); + + bytes32 allocationHashOne = keccak256( + abi.encode( + keccak256("Allocation(address arbiter,uint256 chainId,uint256[2][] idsAndAmounts,Witness witness)Witness(uint256 witnessArgument)"), + arbiter, + block.chainid, + keccak256(abi.encodePacked(idsAndAmountsOne)), + witness + ) + ); + + bytes32 allocationHashTwo = keccak256( + abi.encode( + keccak256("Allocation(address arbiter,uint256 chainId,uint256[2][] idsAndAmounts,Witness witness)Witness(uint256 witnessArgument)"), + arbiter, + anotherChainId, + keccak256(abi.encodePacked(idsAndAmountsTwo)), + witness + ) + ); + + bytes32 claimHash = keccak256( + abi.encode( + keccak256( + "MultichainCompact(address sponsor,uint256 nonce,uint256 expires,Allocation[] allocations)Allocation(address arbiter,uint256 chainId,uint256[2][] idsAndAmounts,Witness witness)Witness(uint256 witnessArgument)" + ), + swapper, + nonce, + expires, + keccak256(abi.encodePacked(allocationHashOne, allocationHashTwo)) + ) + ); + + bytes32 initialDomainSeparator = theCompact.DOMAIN_SEPARATOR(); + + bytes32 digest = keccak256(abi.encodePacked(bytes2(0x1901), initialDomainSeparator, claimHash)); + + (bytes32 r, bytes32 vs) = vm.signCompact(swapperPrivateKey, digest); + bytes memory sponsorSignature = abi.encodePacked(r, vs); + + (r, vs) = vm.signCompact(allocatorPrivateKey, digest); + bytes memory allocatorSignature = abi.encodePacked(r, vs); + + bytes32[] memory additionalChains = new bytes32[](1); + additionalChains[0] = allocationHashTwo; + + BatchClaimComponent[] memory claims = new BatchClaimComponent[](1); + claims[0] = BatchClaimComponent({ id: id, allocatedAmount: amount, amount: amount }); + + BatchMultichainClaimWithWitness memory claim = + BatchMultichainClaimWithWitness(allocatorSignature, sponsorSignature, swapper, nonce, expires, witness, witnessTypestring, additionalChains, claims, claimant); + + uint256 snapshotId = vm.snapshot(); + vm.prank(arbiter); + (bool status) = theCompact.claim(claim); + assert(status); + + assertEq(address(theCompact).balance, amount); + assertEq(claimant.balance, 0); + assertEq(theCompact.balanceOf(swapper, id), 0); + assertEq(theCompact.balanceOf(claimant, id), amount); + vm.revertToAndDelete(snapshotId); + + // change to "new chain" (this hack is so the original one gets stored) + uint256 notarizedChainId = abi.decode(abi.encode(block.chainid), (uint256)); + assert(notarizedChainId != anotherChainId); + vm.chainId(anotherChainId); + assertEq(block.chainid, anotherChainId); + assert(notarizedChainId != anotherChainId); + + bytes32 anotherDomainSeparator = theCompact.DOMAIN_SEPARATOR(); + + assert(initialDomainSeparator != anotherDomainSeparator); + + digest = keccak256(abi.encodePacked(bytes2(0x1901), anotherDomainSeparator, claimHash)); + + (r, vs) = vm.signCompact(allocatorPrivateKey, digest); + bytes memory exogenousAllocatorSignature = abi.encodePacked(r, vs); + + additionalChains[0] = allocationHashOne; + uint256 chainIndex = 0; + + claims = new BatchClaimComponent[](2); + claims[0] = BatchClaimComponent({ id: anotherId, allocatedAmount: anotherAmount, amount: anotherAmount }); + claims[1] = BatchClaimComponent({ id: aThirdId, allocatedAmount: aThirdAmount, amount: aThirdAmount }); + + ExogenousBatchMultichainClaimWithWitness memory anotherClaim = ExogenousBatchMultichainClaimWithWitness( + exogenousAllocatorSignature, sponsorSignature, swapper, nonce, expires, witness, witnessTypestring, additionalChains, chainIndex, notarizedChainId, claims, claimant + ); + + vm.prank(arbiter); + (bool exogenousStatus) = theCompact.claim(anotherClaim); + assert(exogenousStatus); + + assertEq(theCompact.balanceOf(swapper, anotherId), 0); + assertEq(theCompact.balanceOf(claimant, anotherId), anotherAmount); + assertEq(theCompact.balanceOf(claimant, aThirdId), aThirdAmount); + + // change back + vm.chainId(notarizedChainId); + assertEq(block.chainid, notarizedChainId); + } + + function test_qualifiedBatchMultichainClaimWithWitness() public { + uint256 amount = 1e18; + uint256 anotherAmount = 1e18; + uint256 aThirdAmount = 1e18; + uint256 nonce = 0; + uint256 expires = block.timestamp + 1000; + address claimant = 0x1111111111111111111111111111111111111111; + address arbiter = 0x2222222222222222222222222222222222222222; + + vm.prank(allocator); + theCompact.__register(allocator, ""); + + vm.startPrank(swapper); + uint256 id = theCompact.deposit{ value: amount }(allocator, ResetPeriod.TenMinutes, Scope.Multichain, swapper); + + uint256 anotherId = theCompact.deposit(address(token), allocator, ResetPeriod.TenMinutes, Scope.Multichain, anotherAmount, swapper); + assertEq(theCompact.balanceOf(swapper, anotherId), anotherAmount); + + uint256 aThirdId = theCompact.deposit(address(anotherToken), allocator, ResetPeriod.TenMinutes, Scope.Multichain, aThirdAmount, swapper); + assertEq(theCompact.balanceOf(swapper, aThirdId), aThirdAmount); + + vm.stopPrank(); + + assertEq(theCompact.balanceOf(swapper, id), amount); + assertEq(theCompact.balanceOf(swapper, anotherId), anotherAmount); + assertEq(theCompact.balanceOf(swapper, aThirdId), aThirdAmount); + + uint256[2][] memory idsAndAmounts = new uint256[2][](3); + idsAndAmounts[0] = [id, amount]; + idsAndAmounts[1] = [anotherId, anotherAmount]; + idsAndAmounts[2] = [aThirdId, aThirdAmount]; + + uint256 anotherChainId = 7171717; + + uint256[2][] memory idsAndAmountsOne = new uint256[2][](1); + idsAndAmountsOne[0] = [id, amount]; + + uint256[2][] memory idsAndAmountsTwo = new uint256[2][](2); + idsAndAmountsTwo[0] = [anotherId, anotherAmount]; + idsAndAmountsTwo[1] = [aThirdId, aThirdAmount]; + + string memory witnessTypestring = "Witness witness)Witness(uint256 witnessArgument)"; + uint256 witnessArgument = 234; + bytes32 witness = keccak256(abi.encode(witnessArgument)); + + bytes32 allocationHashOne = keccak256( + abi.encode( + keccak256("Allocation(address arbiter,uint256 chainId,uint256[2][] idsAndAmounts,Witness witness)Witness(uint256 witnessArgument)"), + arbiter, + block.chainid, + keccak256(abi.encodePacked(idsAndAmountsOne)), + witness + ) + ); + + bytes32 allocationHashTwo = keccak256( + abi.encode( + keccak256("Allocation(address arbiter,uint256 chainId,uint256[2][] idsAndAmounts,Witness witness)Witness(uint256 witnessArgument)"), + arbiter, + anotherChainId, + keccak256(abi.encodePacked(idsAndAmountsTwo)), + witness + ) + ); + + bytes32 claimHash = keccak256( + abi.encode( + keccak256( + "MultichainCompact(address sponsor,uint256 nonce,uint256 expires,Allocation[] allocations)Allocation(address arbiter,uint256 chainId,uint256[2][] idsAndAmounts,Witness witness)Witness(uint256 witnessArgument)" + ), + swapper, + nonce, + expires, + keccak256(abi.encodePacked(allocationHashOne, allocationHashTwo)) + ) + ); + + bytes32 initialDomainSeparator = theCompact.DOMAIN_SEPARATOR(); + + bytes32 digest = keccak256(abi.encodePacked(bytes2(0x1901), initialDomainSeparator, claimHash)); + + (bytes32 r, bytes32 vs) = vm.signCompact(swapperPrivateKey, digest); + bytes memory sponsorSignature = abi.encodePacked(r, vs); + + bytes32 qualificationTypehash = keccak256("ExampleQualifiedClaim(bytes32 claimHash,uint256 qualifiedClaimArgument)"); + + uint256 qualifiedClaimArgument = 123; + bytes memory qualificationPayload = abi.encode(qualifiedClaimArgument); + + bytes32 qualifiedClaimHash = keccak256(abi.encode(qualificationTypehash, claimHash, qualifiedClaimArgument)); + + digest = keccak256(abi.encodePacked(bytes2(0x1901), initialDomainSeparator, qualifiedClaimHash)); + + (r, vs) = vm.signCompact(allocatorPrivateKey, digest); + bytes memory allocatorSignature = abi.encodePacked(r, vs); + + bytes32[] memory additionalChains = new bytes32[](1); + additionalChains[0] = allocationHashTwo; + + BatchClaimComponent[] memory claims = new BatchClaimComponent[](1); + claims[0] = BatchClaimComponent({ id: id, allocatedAmount: amount, amount: amount }); + + QualifiedBatchMultichainClaimWithWitness memory claim = QualifiedBatchMultichainClaimWithWitness( + allocatorSignature, sponsorSignature, swapper, nonce, expires, witness, witnessTypestring, qualificationTypehash, qualificationPayload, additionalChains, claims, claimant + ); + + uint256 snapshotId = vm.snapshot(); + vm.prank(arbiter); + (bool status) = theCompact.claim(claim); + assert(status); + + assertEq(address(theCompact).balance, amount); + assertEq(claimant.balance, 0); + assertEq(theCompact.balanceOf(swapper, id), 0); + assertEq(theCompact.balanceOf(claimant, id), amount); + vm.revertToAndDelete(snapshotId); + + // change to "new chain" (this hack is so the original one gets stored) + uint256 notarizedChainId = abi.decode(abi.encode(block.chainid), (uint256)); + assert(notarizedChainId != anotherChainId); + vm.chainId(anotherChainId); + assertEq(block.chainid, anotherChainId); + assert(notarizedChainId != anotherChainId); + + bytes32 anotherDomainSeparator = theCompact.DOMAIN_SEPARATOR(); + + assert(initialDomainSeparator != anotherDomainSeparator); + + digest = keccak256(abi.encodePacked(bytes2(0x1901), anotherDomainSeparator, qualifiedClaimHash)); + + (r, vs) = vm.signCompact(allocatorPrivateKey, digest); + bytes memory exogenousAllocatorSignature = abi.encodePacked(r, vs); + + additionalChains[0] = allocationHashOne; + uint256 chainIndex = 0; + + claims = new BatchClaimComponent[](2); + claims[0] = BatchClaimComponent({ id: anotherId, allocatedAmount: anotherAmount, amount: anotherAmount }); + claims[1] = BatchClaimComponent({ id: aThirdId, allocatedAmount: aThirdAmount, amount: aThirdAmount }); + + ExogenousQualifiedBatchMultichainClaimWithWitness memory anotherClaim = ExogenousQualifiedBatchMultichainClaimWithWitness( + exogenousAllocatorSignature, + sponsorSignature, + swapper, + nonce, + expires, + witness, + witnessTypestring, + qualificationTypehash, + qualificationPayload, + additionalChains, + chainIndex, + notarizedChainId, + claims, + claimant + ); + + vm.prank(arbiter); + (bool exogenousStatus) = theCompact.claim(anotherClaim); + assert(exogenousStatus); + + assertEq(theCompact.balanceOf(swapper, anotherId), 0); + assertEq(theCompact.balanceOf(claimant, anotherId), anotherAmount); + assertEq(theCompact.balanceOf(claimant, aThirdId), aThirdAmount); + + // change back + vm.chainId(notarizedChainId); + assertEq(block.chainid, notarizedChainId); + } + function test_splitBatchMultichainClaim() public { uint256 amount = 1e18; uint256 anotherAmount = 1e18; @@ -3526,7 +3979,6 @@ contract TheCompactTest is Test { claims[1] = SplitBatchClaimComponent({ id: aThirdId, allocatedAmount: aThirdAmount, portions: recipients }); } - // TODO: work out encoding stack-too-deep issues! ExogenousQualifiedSplitBatchMultichainClaim memory anotherClaim; { anotherClaim.allocatorSignature = abi.encodePacked(r, vs); @@ -3603,7 +4055,6 @@ contract TheCompactTest is Test { idsAndAmountsTwo[0] = [anotherId, anotherAmount]; idsAndAmountsTwo[1] = [aThirdId, aThirdAmount]; - string memory witnessTypestring = "Witness witness)Witness(uint256 witnessArgument)"; uint256 witnessArgument = 234; bytes32 witness = keccak256(abi.encode(witnessArgument)); @@ -3665,32 +4116,33 @@ contract TheCompactTest is Test { claims[0] = SplitBatchClaimComponent({ id: id, allocatedAmount: amount, portions: recipients }); } - // TODO: stack-too-deep!! - // { - // uint256 snapshotId = vm.snapshot(); - // SplitBatchMultichainClaimWithWitness memory claim; - // claim.allocatorSignature = abi.encodePacked(r, vs); - // claim.sponsorSignature = sponsorSignature; - // claim.sponsor = swapper; - // claim.nonce = 0; - // claim.expires = expires; - // claim.witness = witness; - // claim.witnessTypestring = witnessTypestring; - // claim.additionalChains = additionalChains; - // claim.claims = claims; + SplitBatchMultichainClaimWithWitness memory claim; + claim.sponsorSignature = sponsorSignature; - // vm.prank(arbiter); - // (bool status) = theCompact.claim(claim); - // assert(status); - - // assertEq(address(theCompact).balance, amount); - // assertEq(recipientOne.balance, 0); - // assertEq(recipientTwo.balance, 0); - // assertEq(theCompact.balanceOf(swapper, id), 0); - // assertEq(theCompact.balanceOf(recipientOne, id), amountOne); - // assertEq(theCompact.balanceOf(recipientTwo, id), amountTwo); - // vm.revertToAndDelete(snapshotId); - // } + { + uint256 snapshotId = vm.snapshot(); + + claim.allocatorSignature = abi.encodePacked(r, vs); + claim.sponsor = swapper; + claim.nonce = 0; + claim.expires = expires; + claim.witness = witness; + claim.witnessTypestring = "Witness witness)Witness(uint256 witnessArgument)"; + claim.additionalChains = additionalChains; + claim.claims = claims; + + vm.prank(arbiter); + (bool status) = theCompact.claim(claim); + assert(status); + + assertEq(address(theCompact).balance, amount); + assertEq(recipientOne.balance, 0); + assertEq(recipientTwo.balance, 0); + assertEq(theCompact.balanceOf(swapper, id), 0); + assertEq(theCompact.balanceOf(recipientOne, id), amountOne); + assertEq(theCompact.balanceOf(recipientTwo, id), amountTwo); + vm.revertToAndDelete(snapshotId); + } // change to "new chain" (this hack is so the original one gets stored) uint256 notarizedChainId = abi.decode(abi.encode(block.chainid), (uint256)); @@ -3718,21 +4170,21 @@ contract TheCompactTest is Test { claims[1] = SplitBatchClaimComponent({ id: aThirdId, allocatedAmount: aThirdAmount, portions: recipients }); } - // TODO: work out encoding stack-too-deep issues! - // ExogenousSplitBatchMultichainClaimWithWitness memory anotherClaim; - // { - // anotherClaim.allocatorSignature = abi.encodePacked(r, vs); - // anotherClaim.sponsorSignature = sponsorSignature; - // anotherClaim.sponsor = swapper; - // anotherClaim.nonce = 0; - // anotherClaim.expires = expires; - // anotherClaim.witness = witness; - // anotherClaim.witnessTypestring = witnessTypestring; - // anotherClaim.additionalChains = additionalChains; - // anotherClaim.chainIndex = 0; - // anotherClaim.notarizedChainId = notarizedChainId; - // anotherClaim.claims = claims; - // } + ExogenousSplitBatchMultichainClaimWithWitness memory anotherClaim; + anotherClaim.allocatorSignature = abi.encodePacked(r, vs); + anotherClaim.sponsorSignature = sponsorSignature; + anotherClaim.witnessTypestring = "Witness witness)Witness(uint256 witnessArgument)"; + anotherClaim.additionalChains = additionalChains; + + { + anotherClaim.sponsor = swapper; + anotherClaim.nonce = 0; + anotherClaim.expires = expires; + anotherClaim.witness = witness; + anotherClaim.chainIndex = 0; + anotherClaim.notarizedChainId = notarizedChainId; + anotherClaim.claims = claims; + } // { // vm.prank(arbiter); @@ -3924,7 +4376,6 @@ contract TheCompactTest is Test { claims[1] = SplitBatchClaimComponent({ id: aThirdId, allocatedAmount: aThirdAmount, portions: recipients }); } - // TODO: work out encoding stack-too-deep issues! ExogenousQualifiedSplitBatchMultichainClaimWithWitness memory anotherClaim; { anotherClaim.allocatorSignature = abi.encodePacked(r, vs); @@ -3935,37 +4386,26 @@ contract TheCompactTest is Test { anotherClaim.witness = witness; anotherClaim.witnessTypestring = witnessTypestring; anotherClaim.qualificationTypehash = qualificationTypehash; - //anotherClaim.qualificationPayload = qualificationPayload; + anotherClaim.qualificationPayload = qualificationPayload; anotherClaim.additionalChains = additionalChains; anotherClaim.chainIndex = 0; anotherClaim.notarizedChainId = notarizedChainId; anotherClaim.claims = claims; } - //_encodeQualificationPayload(anotherClaim, qualificationPayload, msg.data.length); - - // NOTE: this actually encodes fine unless the qualification payload is added... *** - // { - // vm.prank(arbiter); - // (bool exogenousStatus) = theCompact.claim(anotherClaim); - // assert(exogenousStatus); - // } + { + vm.prank(arbiter); + (bool exogenousStatus) = theCompact.claim(anotherClaim); + assert(exogenousStatus); + } - // assertEq(theCompact.balanceOf(swapper, anotherId), 0); - // assertEq(theCompact.balanceOf(recipientOne, anotherId), anotherAmount); - // assertEq(theCompact.balanceOf(recipientOne, aThirdId), amountOne); - // assertEq(theCompact.balanceOf(recipientTwo, aThirdId), amountTwo); + assertEq(theCompact.balanceOf(swapper, anotherId), 0); + assertEq(theCompact.balanceOf(recipientOne, anotherId), anotherAmount); + assertEq(theCompact.balanceOf(recipientOne, aThirdId), amountOne); + assertEq(theCompact.balanceOf(recipientTwo, aThirdId), amountTwo); // change back vm.chainId(notarizedChainId); assertEq(block.chainid, notarizedChainId); } - - /// ??? - function _encodeQualificationPayload(ExogenousQualifiedSplitBatchMultichainClaimWithWitness memory anotherClaim, bytes memory qualificationPayload, uint256 doNotInline) internal pure { - assert(doNotInline != 0); - assembly { - mstore(add(mload(anotherClaim), 0x100), qualificationPayload) - } - } }