Skip to content

Commit efd14f4

Browse files
committed
create WithdrawalLogic
1 parent 54d144b commit efd14f4

File tree

4 files changed

+258
-182
lines changed

4 files changed

+258
-182
lines changed

src/lib/ClaimProcessorLogic.sol

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,10 +56,10 @@ import { EfficiencyLib } from "./EfficiencyLib.sol";
5656
import { FunctionCastLib } from "./FunctionCastLib.sol";
5757
import { HashLib } from "./HashLib.sol";
5858
import { IdLib } from "./IdLib.sol";
59-
import { DepositLogic } from "./DepositLogic.sol";
59+
import { WithdrawalLogic } from "./WithdrawalLogic.sol";
6060
import { ValidityLib } from "./ValidityLib.sol";
6161

62-
contract ClaimProcessorLogic is DepositLogic {
62+
contract ClaimProcessorLogic is WithdrawalLogic {
6363
using HashLib for address;
6464
using HashLib for bytes32;
6565
using HashLib for uint256;
@@ -130,6 +130,9 @@ contract ClaimProcessorLogic is DepositLogic {
130130
using FunctionCastLib for function(bytes32, bytes32, uint256, uint256, bytes32, function(address, address, uint256, uint256) internal returns (bool)) internal returns (bool);
131131
using FunctionCastLib for function(bytes32, bytes32, uint256, uint256, bytes32, bytes32, function(address, address, uint256, uint256) internal returns (bool)) internal returns (bool);
132132

133+
/// @dev `keccak256(bytes("Claim(address,address,address,bytes32)"))`.
134+
uint256 private constant _CLAIM_EVENT_SIGNATURE = 0x770c32a2314b700d6239ee35ba23a9690f2fceb93a55d8c753e953059b3b18d4;
135+
133136
function _processSimpleClaim(bytes32 messageHash, uint256 calldataPointer, uint256 offsetToId, bytes32 typehash, function(address, address, uint256, uint256) internal returns (bool) operation)
134137
internal
135138
returns (bool)

src/lib/InternalLogic.sol

Lines changed: 7 additions & 180 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,13 @@ contract InternalLogic is Tstorish {
8484
_PERMIT2_INITIALLY_DEPLOYED = _checkPermit2Deployment();
8585
}
8686

87+
function _emitClaim(address sponsor, bytes32 messageHash, address allocator) internal {
88+
assembly ("memory-safe") {
89+
mstore(0, messageHash)
90+
log4(0, 0x20, _CLAIM_EVENT_SIGNATURE, shr(0x60, shl(0x60, sponsor)), shr(0x60, shl(0x60, allocator)), caller())
91+
}
92+
}
93+
8794
function _notExpiredAndSignedByAllocator(bytes32 messageHash, address allocator, BasicTransfer calldata transferPayload) internal {
8895
transferPayload.expires.later();
8996

@@ -100,71 +107,6 @@ contract InternalLogic is Tstorish {
100107
_clearTstorish(_REENTRANCY_GUARD_SLOT);
101108
}
102109

103-
function _deriveConsistentAllocatorAndConsumeNonce(TransferComponent[] calldata components, uint256 nonce) internal returns (address allocator) {
104-
uint256 totalComponents = components.length;
105-
106-
uint256 errorBuffer = (totalComponents == 0).asUint256();
107-
108-
// TODO: bounds checks on these array accesses can be skipped as an optimization
109-
uint96 allocatorId = components[0].id.toAllocatorId();
110-
111-
allocator = allocatorId.fromRegisteredAllocatorIdWithConsumed(nonce);
112-
113-
unchecked {
114-
for (uint256 i = 1; i < totalComponents; ++i) {
115-
errorBuffer |= (components[i].id.toAllocatorId() != allocatorId).asUint256();
116-
}
117-
}
118-
119-
assembly ("memory-safe") {
120-
if errorBuffer {
121-
// revert InvalidBatchAllocation()
122-
mstore(0, 0x3a03d3bb)
123-
revert(0x1c, 0x04)
124-
}
125-
}
126-
}
127-
128-
function _deriveConsistentAllocatorAndConsumeNonce(SplitByIdComponent[] calldata components, uint256 nonce) internal returns (address allocator) {
129-
uint256 totalComponents = components.length;
130-
131-
uint256 errorBuffer = (totalComponents == 0).asUint256();
132-
133-
// TODO: bounds checks on these array accesses can be skipped as an optimization
134-
uint96 allocatorId = components[0].id.toAllocatorId();
135-
136-
allocator = allocatorId.fromRegisteredAllocatorIdWithConsumed(nonce);
137-
138-
unchecked {
139-
for (uint256 i = 1; i < totalComponents; ++i) {
140-
errorBuffer |= (components[i].id.toAllocatorId() != allocatorId).asUint256();
141-
}
142-
}
143-
144-
assembly ("memory-safe") {
145-
if errorBuffer {
146-
// revert InvalidBatchAllocation()
147-
mstore(0, 0x3a03d3bb)
148-
revert(0x1c, 0x04)
149-
}
150-
}
151-
}
152-
153-
function _emitClaim(address sponsor, bytes32 messageHash, address allocator) internal {
154-
assembly ("memory-safe") {
155-
mstore(0, messageHash)
156-
log4(0, 0x20, _CLAIM_EVENT_SIGNATURE, shr(0x60, shl(0x60, sponsor)), shr(0x60, shl(0x60, allocator)), caller())
157-
}
158-
}
159-
160-
function _emitForcedWithdrawalStatusUpdatedEvent(uint256 id, uint256 withdrawableAt) internal {
161-
assembly ("memory-safe") {
162-
mstore(0, iszero(iszero(withdrawableAt)))
163-
mstore(0x20, withdrawableAt)
164-
log3(0, 0x40, _FORCED_WITHDRAWAL_STATUS_UPDATED_SIGNATURE, caller(), id)
165-
}
166-
}
167-
168110
function _register(address sponsor, bytes32 claimHash, bytes32 typehash, uint256 duration) internal {
169111
assembly ("memory-safe") {
170112
let m := mload(0x40)
@@ -204,56 +146,6 @@ contract InternalLogic is Tstorish {
204146
return true;
205147
}
206148

207-
function _enableForcedWithdrawal(uint256 id) internal returns (uint256 withdrawableAt) {
208-
// overflow check not necessary as reset period is capped
209-
unchecked {
210-
withdrawableAt = block.timestamp + id.toResetPeriod().toSeconds();
211-
}
212-
213-
uint256 cutoffTimeSlotLocation = _getCutoffTimeSlot(msg.sender, id);
214-
assembly ("memory-safe") {
215-
sstore(cutoffTimeSlotLocation, withdrawableAt)
216-
}
217-
218-
_emitForcedWithdrawalStatusUpdatedEvent(id, withdrawableAt);
219-
}
220-
221-
function _disableForcedWithdrawal(uint256 id) internal returns (bool) {
222-
uint256 cutoffTimeSlotLocation = _getCutoffTimeSlot(msg.sender, id);
223-
224-
assembly ("memory-safe") {
225-
if iszero(sload(cutoffTimeSlotLocation)) {
226-
// revert ForcedWithdrawalAlreadyDisabled(msg.sender, id)
227-
mstore(0, 0xe632dbad)
228-
mstore(0x20, caller())
229-
mstore(0x40, id)
230-
revert(0x1c, 0x44)
231-
}
232-
233-
sstore(cutoffTimeSlotLocation, 0)
234-
}
235-
236-
_emitForcedWithdrawalStatusUpdatedEvent(id, uint256(0).asStubborn());
237-
238-
return true;
239-
}
240-
241-
function _processForcedWithdrawal(uint256 id, address recipient, uint256 amount) internal returns (bool) {
242-
uint256 cutoffTimeSlotLocation = _getCutoffTimeSlot(msg.sender, id);
243-
244-
assembly ("memory-safe") {
245-
let withdrawableAt := sload(cutoffTimeSlotLocation)
246-
if or(iszero(withdrawableAt), gt(withdrawableAt, timestamp())) {
247-
// revert PrematureWithdrawal(id)
248-
mstore(0, 0x9287bcb0)
249-
mstore(0x20, id)
250-
revert(0x1c, 0x24)
251-
}
252-
}
253-
254-
return _withdraw(msg.sender, recipient, id, amount);
255-
}
256-
257149
function _consume(uint256[] calldata nonces) internal returns (bool) {
258150
// NOTE: this may not be necessary, consider removing
259151
msg.sender.usingAllocatorId().mustHaveARegisteredAllocator();
@@ -292,60 +184,6 @@ contract InternalLogic is Tstorish {
292184
allocatorId = allocator.register();
293185
}
294186

295-
function _getForcedWithdrawalStatus(address account, uint256 id) internal view returns (ForcedWithdrawalStatus status, uint256 forcedWithdrawalAvailableAt) {
296-
uint256 cutoffTimeSlotLocation = _getCutoffTimeSlot(account, id);
297-
assembly ("memory-safe") {
298-
forcedWithdrawalAvailableAt := sload(cutoffTimeSlotLocation)
299-
status := mul(iszero(iszero(forcedWithdrawalAvailableAt)), sub(2, gt(forcedWithdrawalAvailableAt, timestamp())))
300-
}
301-
}
302-
303-
/// @dev Burns `amount` token `id` from `from` without checking transfer hooks and sends
304-
/// the corresponding underlying tokens to `to`. Emits a {Transfer} event.
305-
function _withdraw(address from, address to, uint256 id, uint256 amount) internal returns (bool) {
306-
_setReentrancyGuard();
307-
address token = id.toToken();
308-
309-
if (token == address(0)) {
310-
to.safeTransferETH(amount);
311-
} else {
312-
uint256 initialBalance = token.balanceOf(address(this));
313-
token.safeTransfer(to, amount);
314-
// NOTE: if the balance increased, this will underflow to a massive number causing
315-
// the burn to fail; furthermore, this scenario would indicate a very broken token
316-
unchecked {
317-
amount = initialBalance - token.balanceOf(address(this));
318-
}
319-
}
320-
321-
assembly ("memory-safe") {
322-
// Compute the balance slot.
323-
mstore(0x20, _ERC6909_MASTER_SLOT_SEED)
324-
mstore(0x14, from)
325-
mstore(0x00, id)
326-
let fromBalanceSlot := keccak256(0x00, 0x40)
327-
let fromBalance := sload(fromBalanceSlot)
328-
// Revert if insufficient balance.
329-
if gt(amount, fromBalance) {
330-
mstore(0x00, 0xf4d678b8) // `InsufficientBalance()`.
331-
revert(0x1c, 0x04)
332-
}
333-
// Subtract and store the updated balance.
334-
sstore(fromBalanceSlot, sub(fromBalance, amount))
335-
336-
let account := shr(0x60, shl(0x60, from))
337-
338-
// Emit the {Transfer} and {Withdrawal} events.
339-
mstore(0x00, caller())
340-
mstore(0x20, amount)
341-
log4(0x00, 0x40, _TRANSFER_EVENT_SIGNATURE, account, 0, id)
342-
}
343-
344-
_clearReentrancyGuard();
345-
346-
return true;
347-
}
348-
349187
function _getLockDetails(uint256 id) internal view returns (address token, address allocator, ResetPeriod resetPeriod, Scope scope) {
350188
token = id.toToken();
351189
allocator = id.toAllocatorId().toRegisteredAllocator();
@@ -400,15 +238,4 @@ contract InternalLogic is Tstorish {
400238
function _tokenURI(uint256 id) internal view returns (string memory) {
401239
return _METADATA_RENDERER.uri(id.toLock(), id);
402240
}
403-
404-
function _getCutoffTimeSlot(address account, uint256 id) internal pure returns (uint256 cutoffTimeSlotLocation) {
405-
assembly ("memory-safe") {
406-
let m := mload(0x40)
407-
mstore(0x14, account)
408-
mstore(0, _FORCED_WITHDRAWAL_ACTIVATIONS_SCOPE)
409-
mstore(0x34, id)
410-
cutoffTimeSlotLocation := keccak256(0x1c, 0x38)
411-
mstore(0x40, m)
412-
}
413-
}
414241
}

src/lib/TransferLogic.sol

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -184,4 +184,54 @@ contract TransferLogic is InternalLogic {
184184
}
185185
}
186186
}
187+
188+
function _deriveConsistentAllocatorAndConsumeNonce(TransferComponent[] calldata components, uint256 nonce) internal returns (address allocator) {
189+
uint256 totalComponents = components.length;
190+
191+
uint256 errorBuffer = (totalComponents == 0).asUint256();
192+
193+
// TODO: bounds checks on these array accesses can be skipped as an optimization
194+
uint96 allocatorId = components[0].id.toAllocatorId();
195+
196+
allocator = allocatorId.fromRegisteredAllocatorIdWithConsumed(nonce);
197+
198+
unchecked {
199+
for (uint256 i = 1; i < totalComponents; ++i) {
200+
errorBuffer |= (components[i].id.toAllocatorId() != allocatorId).asUint256();
201+
}
202+
}
203+
204+
assembly ("memory-safe") {
205+
if errorBuffer {
206+
// revert InvalidBatchAllocation()
207+
mstore(0, 0x3a03d3bb)
208+
revert(0x1c, 0x04)
209+
}
210+
}
211+
}
212+
213+
function _deriveConsistentAllocatorAndConsumeNonce(SplitByIdComponent[] calldata components, uint256 nonce) internal returns (address allocator) {
214+
uint256 totalComponents = components.length;
215+
216+
uint256 errorBuffer = (totalComponents == 0).asUint256();
217+
218+
// TODO: bounds checks on these array accesses can be skipped as an optimization
219+
uint96 allocatorId = components[0].id.toAllocatorId();
220+
221+
allocator = allocatorId.fromRegisteredAllocatorIdWithConsumed(nonce);
222+
223+
unchecked {
224+
for (uint256 i = 1; i < totalComponents; ++i) {
225+
errorBuffer |= (components[i].id.toAllocatorId() != allocatorId).asUint256();
226+
}
227+
}
228+
229+
assembly ("memory-safe") {
230+
if errorBuffer {
231+
// revert InvalidBatchAllocation()
232+
mstore(0, 0x3a03d3bb)
233+
revert(0x1c, 0x04)
234+
}
235+
}
236+
}
187237
}

0 commit comments

Comments
 (0)