Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion snapshots/HybridAllocatorTest.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,5 @@
"allocateAndRegister_nativeToken_emptyAmountInput": "139067",
"allocateAndRegister_second_erc20Token": "114886",
"allocateAndRegister_second_nativeToken": "104867",
"hybrid_execute_single": "171479"
"hybrid_execute_single": "171524"
}
4 changes: 2 additions & 2 deletions snapshots/OnChainAllocatorTest.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,6 @@
"allocate_erc20": "127841",
"allocate_native": "127601",
"allocate_second_erc20": "95853",
"onchain_execute_double": "343074",
"onchain_execute_single": "216727"
"onchain_execute_double": "343161",
"onchain_execute_single": "216772"
}
4 changes: 3 additions & 1 deletion src/allocators/HybridAllocator.sol
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,9 @@ contract HybridAllocator is IHybridAllocator {
bytes calldata /* orderData */
) external returns (uint256 nonce) {
nonce = nonces + 1;
AL.prepareAllocation(address(_COMPACT), nonce, recipient, idsAndAmounts, arbiter, expires, typehash, witness);
AL.prepareAllocation(
address(_COMPACT), nonce, recipient, idsAndAmounts, arbiter, expires, typehash, witness, ALLOCATOR_ID
);
}

/// @inheritdoc IOnChainAllocation
Expand Down
4 changes: 3 additions & 1 deletion src/allocators/OnChainAllocator.sol
Original file line number Diff line number Diff line change
Expand Up @@ -257,7 +257,9 @@ contract OnChainAllocator is IOnChainAllocator {
}
uint32 expiration = uint32(expires);
nonce = _getNonce(msg.sender, recipient);
AL.prepareAllocation(COMPACT_CONTRACT, nonce, recipient, idsAndAmounts, arbiter, expiration, typehash, witness);
AL.prepareAllocation(
COMPACT_CONTRACT, nonce, recipient, idsAndAmounts, arbiter, expiration, typehash, witness, ALLOCATOR_ID
);

return nonce;
}
Expand Down
12 changes: 11 additions & 1 deletion src/allocators/lib/AllocatorLib.sol
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ library AllocatorLib {

error InvalidBalanceChange(uint256 newBalance, uint256 oldBalance);
error InvalidPreparation();
error InvalidAllocatorId(uint96 providedId, uint96 allocatorId);
error InvalidRegistration(address recipient, bytes32 claimHash, bytes32 typehash);

function prepareAllocation(
Expand All @@ -27,7 +28,8 @@ library AllocatorLib {
address arbiter,
uint256 expires,
bytes32 typehash,
bytes32 witness
bytes32 witness,
uint96 allocatorId
) internal {
assembly ("memory-safe") {
// identifier = keccak256(abi.encode(PREPARE_ALLOCATION_SELECTOR, recipient, ids, arbiter, expires, typehash, witness));
Expand All @@ -45,6 +47,14 @@ library AllocatorLib {
for { let i := 0 } lt(i, idsAndAmounts.length) { i := add(i, 1) } {
let id := calldataload(add(idsAndAmounts.offset, mul(i, 0x40)))

// Verify the id fits the allocator
if iszero(eq(shr(164, shl(4, id)), allocatorId)) {
mstore(0x00, 0x8bbfd798) // InvalidAllocatorId()
mstore(0x20, shr(164, shl(4, id)))
mstore(0x40, allocatorId)
revert(0x1c, 0x44)
}

// Retrieve and store the current balance of the recipient in transient storage
mstore(0x14, recipient) // Store the `owner` argument.
mstore(0x34, id)
Expand Down
15 changes: 15 additions & 0 deletions test/HybridAllocator.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,21 @@ contract HybridAllocatorTest is Test, TestHelper {
assertFalse(allocator.signers(attacker));
}

function test_prepareAllocation_revert_InvalidAllocatorId() public {
uint256[2][] memory idsAndAmounts = new uint256[2][](1);
idsAndAmounts[0][0] = _toId(Scope.Multichain, ResetPeriod.TenMinutes, address(this), address(usdc));
idsAndAmounts[0][1] = defaultAmount;

uint96 allocatorId = _toAllocatorId(address(this));

vm.expectRevert(
abi.encodeWithSelector(AllocatorLib.InvalidAllocatorId.selector, allocatorId, allocator.ALLOCATOR_ID())
);
allocator.prepareAllocation(
user, idsAndAmounts, arbiter, defaultExpiration, BATCH_COMPACT_TYPEHASH, bytes32(0), ''
);
}

function test_prepareAllocation_returnsNonce_andDoesNotIncrement() public {
uint256[2][] memory idsAndAmounts = _idsAndAmounts(address(usdc), defaultAmount);
uint96 beforeNonces = allocator.nonces();
Expand Down
15 changes: 15 additions & 0 deletions test/OnChainAllocator.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -967,6 +967,21 @@ contract OnChainAllocatorTest is Test, TestHelper {
idsAndAmounts[1][1] = amountB;
}

function test_prepareAllocation_revert_InvalidAllocatorId() public {
uint256[2][] memory idsAndAmounts = new uint256[2][](1);
idsAndAmounts[0][0] = _toId(Scope.Multichain, ResetPeriod.TenMinutes, address(this), address(usdc));
idsAndAmounts[0][1] = defaultAmount;

uint96 allocatorId = _toAllocatorId(address(this));

vm.expectRevert(
abi.encodeWithSelector(AllocatorLib.InvalidAllocatorId.selector, allocatorId, allocator.ALLOCATOR_ID())
);
allocator.prepareAllocation(
recipient, idsAndAmounts, arbiter, defaultExpiration, BATCH_COMPACT_TYPEHASH, bytes32(0), ''
);
}

function test_prepareAllocation_returnsNonce_and_doesNotIncrementStorage() public {
uint256[2][] memory idsAndAmounts = _idsAndAmountsFor(address(usdc), defaultAmount);

Expand Down