Skip to content

Commit 01f863d

Browse files
committed
support for native tokens in depositAndRegister
1 parent e38e273 commit 01f863d

File tree

3 files changed

+78
-4
lines changed

3 files changed

+78
-4
lines changed

src/allocators/OnChainAllocator.sol

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -86,13 +86,28 @@ contract OnChainAllocator is IOnChainAllocator {
8686
uint32 expires,
8787
bytes32 typehash,
8888
bytes32 witness
89-
) public returns (bytes32 claimHash, uint256[] memory registeredAmounts, uint256 nonce) {
89+
) public payable returns (bytes32 claimHash, uint256[] memory registeredAmounts, uint256 nonce) {
9090
nonce = _getAndUpdateNonce(msg.sender, recipient);
9191

92+
if (commitments.length == 0) {
93+
revert InvalidCommitments();
94+
}
95+
9296
uint256[2][] memory idsAndAmounts = new uint256[2][](commitments.length);
9397

9498
uint256 minResetPeriod = type(uint256).max;
95-
for (uint256 i = 0; i < commitments.length; i++) {
99+
uint256 i = 0;
100+
if (commitments[i].token == address(0)) {
101+
minResetPeriod = _checkInput(commitments[i], recipient, expires, minResetPeriod);
102+
idsAndAmounts[i][0] = AL.toId(commitments[i].lockTag, commitments[i].token);
103+
104+
if (commitments[i].amount != 0 && commitments[i].amount != msg.value) {
105+
revert InvalidAmount(commitments[i].amount);
106+
}
107+
idsAndAmounts[i][1] = msg.value;
108+
i++;
109+
}
110+
for (; i < commitments.length; i++) {
96111
minResetPeriod = _checkInput(commitments[i], recipient, expires, minResetPeriod);
97112
idsAndAmounts[i][0] = AL.toId(commitments[i].lockTag, commitments[i].token);
98113
uint224 amount = uint224(commitments[i].amount);
@@ -114,7 +129,7 @@ contract OnChainAllocator is IOnChainAllocator {
114129
}
115130

116131
// Deposit the tokens and register the claim in the compact
117-
(claimHash, registeredAmounts) = ITheCompact(COMPACT_CONTRACT).batchDepositAndRegisterFor(
132+
(claimHash, registeredAmounts) = ITheCompact(COMPACT_CONTRACT).batchDepositAndRegisterFor{value: msg.value}(
118133
recipient, idsAndAmounts, arbiter, nonce, expires, typehash, witness
119134
);
120135

src/interfaces/IOnChainAllocator.sol

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,9 @@ interface IOnChainAllocator is IOnChainAllocation {
4646
/// @notice Thrown if the provided signature is invalid
4747
error InvalidSignature(address signer, address expectedSigner);
4848

49+
/// @notice Thrown if the provided commitments are empty
50+
error InvalidCommitments();
51+
4952
/// @notice Registers an allocation for a set of tokens
5053
/// @param commitments The commitments of the allocations
5154
/// @param arbiter The arbiter of the allocation
@@ -89,5 +92,5 @@ interface IOnChainAllocator is IOnChainAllocation {
8992
uint32 expires,
9093
bytes32 typehash,
9194
bytes32 witness
92-
) external returns (bytes32 claimHash, uint256[] memory registeredAmounts, uint256 nonce);
95+
) external payable returns (bytes32 claimHash, uint256[] memory registeredAmounts, uint256 nonce);
9396
}

test/OnChainAllocator.t.sol

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1128,6 +1128,25 @@ contract OnChainAllocatorTest is Test, TestHelper {
11281128
);
11291129
}
11301130

1131+
function test_allocateAndRegister_revert_InvalidCommitments() public {
1132+
Lock[] memory commitments = new Lock[](0);
1133+
1134+
vm.expectRevert(abi.encodeWithSelector(IOnChainAllocator.InvalidCommitments.selector));
1135+
allocator.allocateAndRegister(
1136+
recipient, commitments, arbiter, defaultExpiration, BATCH_COMPACT_TYPEHASH, bytes32(0)
1137+
);
1138+
}
1139+
1140+
function test_allocateAndRegister_revert_InvalidAmount_native() public {
1141+
Lock[] memory commitments = new Lock[](1);
1142+
commitments[0] = _makeLock(address(0), 1 ether);
1143+
1144+
vm.expectRevert(abi.encodeWithSelector(IOnChainAllocator.InvalidAmount.selector, commitments[0].amount));
1145+
allocator.allocateAndRegister{value: commitments[0].amount + 1}(
1146+
recipient, commitments, arbiter, defaultExpiration, BATCH_COMPACT_TYPEHASH, bytes32(0)
1147+
);
1148+
}
1149+
11311150
function test_allocateAndRegister_revert_InvalidAmount() public {
11321151
Lock[] memory commitments = new Lock[](1);
11331152
commitments[0] = _makeLock(address(usdc), uint256(type(uint224).max) + 1);
@@ -1274,6 +1293,43 @@ contract OnChainAllocatorTest is Test, TestHelper {
12741293
);
12751294
}
12761295

1296+
function test_allocateAndRegister_success_multiple() public {
1297+
uint256 amount1 = 1 ether;
1298+
uint256 amount2 = 2 ether;
1299+
1300+
usdc.mint(address(allocator), amount2);
1301+
1302+
Lock[] memory commitments = new Lock[](2);
1303+
commitments[0] = _makeLock(address(0), amount1);
1304+
commitments[1] = _makeLock(address(usdc), amount2);
1305+
1306+
vm.deal(caller, amount1);
1307+
vm.prank(caller);
1308+
(bytes32 claimHash, uint256[] memory registeredAmounts, uint256 nonce) = allocator.allocateAndRegister{
1309+
value: amount1
1310+
}(recipient, commitments, arbiter, defaultExpiration, BATCH_COMPACT_TYPEHASH, bytes32(0));
1311+
1312+
uint256 id1 = _toId(Scope.Multichain, ResetPeriod.TenMinutes, address(allocator), address(0));
1313+
uint256 id2 = _toId(Scope.Multichain, ResetPeriod.TenMinutes, address(allocator), address(usdc));
1314+
1315+
assertEq(registeredAmounts.length, 2);
1316+
assertEq(registeredAmounts[0], amount1);
1317+
assertEq(registeredAmounts[1], amount2);
1318+
1319+
assertEq(ERC6909(address(compact)).balanceOf(recipient, id1), amount1);
1320+
assertEq(ERC6909(address(compact)).balanceOf(recipient, id2), amount2);
1321+
1322+
uint256[2][] memory idsAndAmounts = new uint256[2][](2);
1323+
idsAndAmounts[0][0] = id1;
1324+
idsAndAmounts[0][1] = amount1;
1325+
idsAndAmounts[1][0] = id2;
1326+
idsAndAmounts[1][1] = amount2;
1327+
1328+
assertTrue(
1329+
allocator.isClaimAuthorized(claimHash, arbiter, recipient, nonce, defaultExpiration, idsAndAmounts, '')
1330+
);
1331+
}
1332+
12771333
function test_allocateAndRegister_tokensImmediatelyAllocated() public {
12781334
uint256 amount1 = 1 ether;
12791335
uint256 amount2 = 2 ether;

0 commit comments

Comments
 (0)