Skip to content

Commit bbea6e4

Browse files
authored
Merge pull request #12 from Uniswap/shuffle-city
improve inheritance graph
2 parents 9980d5b + 894012a commit bbea6e4

9 files changed

+254
-228
lines changed

src/TheCompact.sol

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,7 @@ import { Scope } from "./types/Scope.sol";
1111
import { ResetPeriod } from "./types/ResetPeriod.sol";
1212
import { ForcedWithdrawalStatus } from "./types/ForcedWithdrawalStatus.sol";
1313

14-
import { AllocatorLogic } from "./lib/AllocatorLogic.sol";
15-
import { ClaimProcessor } from "./lib/ClaimProcessor.sol";
16-
import { Extsload } from "./lib/Extsload.sol";
14+
import { TheCompactLogic } from "./lib/TheCompactLogic.sol";
1715

1816
import { ERC6909 } from "solady/tokens/ERC6909.sol";
1917
import { ISignatureTransfer } from "permit2/src/interfaces/ISignatureTransfer.sol";
@@ -26,7 +24,7 @@ import { ISignatureTransfer } from "permit2/src/interfaces/ISignatureTransfer.so
2624
* formation and mediation of reusable "resource locks."
2725
* This contract has not yet been properly tested, audited, or reviewed.
2826
*/
29-
contract TheCompact is ITheCompact, AllocatorLogic, ClaimProcessor, ERC6909, Extsload {
27+
contract TheCompact is ITheCompact, ERC6909, TheCompactLogic {
3028
function deposit(address allocator) external payable returns (uint256) {
3129
return _performBasicNativeTokenDeposit(allocator);
3230
}

src/lib/ClaimProcessorLogic.sol

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,10 +56,11 @@ 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 { RegistrationLogic } from "./RegistrationLogic.sol";
5960
import { ValidityLib } from "./ValidityLib.sol";
60-
import { WithdrawalLogic } from "./WithdrawalLogic.sol";
61+
import { SharedLogic } from "./SharedLogic.sol";
6162

62-
contract ClaimProcessorLogic is WithdrawalLogic {
63+
contract ClaimProcessorLogic is SharedLogic, RegistrationLogic {
6364
using HashLib for address;
6465
using HashLib for bytes32;
6566
using HashLib for uint256;

src/lib/DepositLogic.sol

Lines changed: 2 additions & 107 deletions
Original file line numberDiff line numberDiff line change
@@ -1,103 +1,18 @@
11
// SPDX-License-Identifier: MIT
22
pragma solidity ^0.8.27;
33

4-
import { ResetPeriod } from "../types/ResetPeriod.sol";
5-
import { Scope } from "../types/Scope.sol";
6-
7-
import { EfficiencyLib } from "./EfficiencyLib.sol";
8-
import { IdLib } from "./IdLib.sol";
9-
import { RegistrationLogic } from "./RegistrationLogic.sol";
10-
import { TransferLogic } from "./TransferLogic.sol";
11-
import { ValidityLib } from "./ValidityLib.sol";
4+
import { ConstructorLogic } from "./ConstructorLogic.sol";
125

136
import { SafeTransferLib } from "solady/utils/SafeTransferLib.sol";
14-
import { ISignatureTransfer } from "permit2/src/interfaces/ISignatureTransfer.sol";
157

16-
contract DepositLogic is TransferLogic, RegistrationLogic {
17-
using IdLib for uint96;
18-
using IdLib for uint256;
19-
using IdLib for address;
20-
using EfficiencyLib for bool;
21-
using ValidityLib for address;
8+
contract DepositLogic is ConstructorLogic {
229
using SafeTransferLib for address;
2310

2411
uint256 private constant _ERC6909_MASTER_SLOT_SEED = 0xedcaa89a82293940;
2512

2613
/// @dev `keccak256(bytes("Transfer(address,address,address,uint256,uint256)"))`.
2714
uint256 private constant _TRANSFER_EVENT_SIGNATURE = 0x1b3d7edb2e9c0b0e7c525b20aaaef0f5940d2ed71663c7d39266ecafac728859;
2815

29-
function _performBasicNativeTokenDeposit(address allocator) internal returns (uint256 id) {
30-
id = address(0).toIdIfRegistered(Scope.Multichain, ResetPeriod.TenMinutes, allocator);
31-
32-
_deposit(msg.sender, id, msg.value);
33-
}
34-
35-
function _processBatchDeposit(uint256[2][] calldata idsAndAmounts, address recipient) internal {
36-
_setReentrancyGuard();
37-
uint256 totalIds = idsAndAmounts.length;
38-
bool firstUnderlyingTokenIsNative;
39-
uint256 id;
40-
41-
assembly ("memory-safe") {
42-
let idsAndAmountsOffset := idsAndAmounts.offset
43-
id := calldataload(idsAndAmountsOffset)
44-
firstUnderlyingTokenIsNative := iszero(shr(96, shl(96, id)))
45-
// Revert if:
46-
// * the array is empty
47-
// * the callvalue is zero but the first token is native
48-
// * the callvalue is nonzero but the first token is non-native
49-
// * the first token is non-native and the callvalue doesn't equal the first amount
50-
if or(iszero(totalIds), or(eq(firstUnderlyingTokenIsNative, iszero(callvalue())), and(firstUnderlyingTokenIsNative, iszero(eq(callvalue(), calldataload(add(idsAndAmountsOffset, 0x20)))))))
51-
{
52-
// revert InvalidBatchDepositStructure()
53-
mstore(0, 0xca0fc08e)
54-
revert(0x1c, 0x04)
55-
}
56-
}
57-
58-
uint96 currentAllocatorId = id.toRegisteredAllocatorId();
59-
60-
if (firstUnderlyingTokenIsNative) {
61-
_deposit(recipient, id, msg.value);
62-
}
63-
64-
unchecked {
65-
for (uint256 i = firstUnderlyingTokenIsNative.asUint256(); i < totalIds; ++i) {
66-
uint256[2] calldata idAndAmount = idsAndAmounts[i];
67-
id = idAndAmount[0];
68-
uint256 amount = idAndAmount[1];
69-
70-
uint96 newAllocatorId = id.toAllocatorId();
71-
if (newAllocatorId != currentAllocatorId) {
72-
newAllocatorId.mustHaveARegisteredAllocator();
73-
currentAllocatorId = newAllocatorId;
74-
}
75-
76-
_transferAndDeposit(id.toToken(), recipient, id, amount);
77-
}
78-
}
79-
80-
_clearReentrancyGuard();
81-
}
82-
83-
function _performBasicERC20Deposit(address token, address allocator, uint256 amount) internal returns (uint256 id) {
84-
id = token.excludingNative().toIdIfRegistered(Scope.Multichain, ResetPeriod.TenMinutes, allocator);
85-
86-
_transferAndDepositWithReentrancyGuard(token, msg.sender, id, amount);
87-
}
88-
89-
function _performCustomNativeTokenDeposit(address allocator, ResetPeriod resetPeriod, Scope scope, address recipient) internal returns (uint256 id) {
90-
id = address(0).toIdIfRegistered(scope, resetPeriod, allocator);
91-
92-
_deposit(recipient, id, msg.value);
93-
}
94-
95-
function _performCustomERC20Deposit(address token, address allocator, ResetPeriod resetPeriod, Scope scope, uint256 amount, address recipient) internal returns (uint256 id) {
96-
id = token.excludingNative().toIdIfRegistered(scope, resetPeriod, allocator);
97-
98-
_transferAndDepositWithReentrancyGuard(token, recipient, id, amount);
99-
}
100-
10116
/// @dev Retrieves a token balance, compares against `initialBalance`, and mints the resulting balance
10217
/// change of `id` to `to`. Emits a {Transfer} event.
10318
function _checkBalanceAndDeposit(address token, address to, uint256 id, uint256 initialBalance) internal {
@@ -143,24 +58,4 @@ contract DepositLogic is TransferLogic, RegistrationLogic {
14358
log4(0, 0x40, _TRANSFER_EVENT_SIGNATURE, 0, recipient, id)
14459
}
14560
}
146-
147-
/// @dev Transfers `amount` of `token` and mints the resulting balance change of `id` to `to`.
148-
/// Emits a {Transfer} event.
149-
function _transferAndDeposit(address token, address to, uint256 id, uint256 amount) private {
150-
uint256 initialBalance = token.balanceOf(address(this));
151-
152-
token.safeTransferFrom(msg.sender, address(this), amount);
153-
154-
_checkBalanceAndDeposit(token, to, id, initialBalance);
155-
}
156-
157-
/// @dev Transfers `amount` of `token` and mints the resulting balance change of `id` to `to`.
158-
/// Emits a {Transfer} event.
159-
function _transferAndDepositWithReentrancyGuard(address token, address to, uint256 id, uint256 amount) private {
160-
_setReentrancyGuard();
161-
162-
_transferAndDeposit(token, to, id, amount);
163-
164-
_clearReentrancyGuard();
165-
}
16661
}

src/lib/DepositViaPermit2Logic.sol

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,14 +43,15 @@ import { ResetPeriod } from "../types/ResetPeriod.sol";
4343
import { Scope } from "../types/Scope.sol";
4444

4545
import { DepositLogic } from "./DepositLogic.sol";
46+
import { RegistrationLogic } from "./RegistrationLogic.sol";
4647
import { EfficiencyLib } from "./EfficiencyLib.sol";
4748
import { IdLib } from "./IdLib.sol";
4849
import { ValidityLib } from "./ValidityLib.sol";
4950

5051
import { SafeTransferLib } from "solady/utils/SafeTransferLib.sol";
5152
import { ISignatureTransfer } from "permit2/src/interfaces/ISignatureTransfer.sol";
5253

53-
contract DepositViaPermit2Logic is DepositLogic {
54+
contract DepositViaPermit2Logic is DepositLogic, RegistrationLogic {
5455
using IdLib for uint256;
5556
using IdLib for address;
5657
using IdLib for ResetPeriod;

src/lib/DirectDepositLogic.sol

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
// SPDX-License-Identifier: MIT
2+
pragma solidity ^0.8.27;
3+
4+
import { ResetPeriod } from "../types/ResetPeriod.sol";
5+
import { Scope } from "../types/Scope.sol";
6+
7+
import { EfficiencyLib } from "./EfficiencyLib.sol";
8+
import { IdLib } from "./IdLib.sol";
9+
import { DepositLogic } from "./DepositLogic.sol";
10+
import { ValidityLib } from "./ValidityLib.sol";
11+
12+
import { SafeTransferLib } from "solady/utils/SafeTransferLib.sol";
13+
import { ISignatureTransfer } from "permit2/src/interfaces/ISignatureTransfer.sol";
14+
15+
contract DirectDepositLogic is DepositLogic {
16+
using IdLib for uint96;
17+
using IdLib for uint256;
18+
using IdLib for address;
19+
using EfficiencyLib for bool;
20+
using ValidityLib for address;
21+
using SafeTransferLib for address;
22+
23+
function _performBasicNativeTokenDeposit(address allocator) internal returns (uint256 id) {
24+
id = address(0).toIdIfRegistered(Scope.Multichain, ResetPeriod.TenMinutes, allocator);
25+
26+
_deposit(msg.sender, id, msg.value);
27+
}
28+
29+
function _processBatchDeposit(uint256[2][] calldata idsAndAmounts, address recipient) internal {
30+
_setReentrancyGuard();
31+
uint256 totalIds = idsAndAmounts.length;
32+
bool firstUnderlyingTokenIsNative;
33+
uint256 id;
34+
35+
assembly ("memory-safe") {
36+
let idsAndAmountsOffset := idsAndAmounts.offset
37+
id := calldataload(idsAndAmountsOffset)
38+
firstUnderlyingTokenIsNative := iszero(shr(96, shl(96, id)))
39+
// Revert if:
40+
// * the array is empty
41+
// * the callvalue is zero but the first token is native
42+
// * the callvalue is nonzero but the first token is non-native
43+
// * the first token is non-native and the callvalue doesn't equal the first amount
44+
if or(iszero(totalIds), or(eq(firstUnderlyingTokenIsNative, iszero(callvalue())), and(firstUnderlyingTokenIsNative, iszero(eq(callvalue(), calldataload(add(idsAndAmountsOffset, 0x20)))))))
45+
{
46+
// revert InvalidBatchDepositStructure()
47+
mstore(0, 0xca0fc08e)
48+
revert(0x1c, 0x04)
49+
}
50+
}
51+
52+
uint96 currentAllocatorId = id.toRegisteredAllocatorId();
53+
54+
if (firstUnderlyingTokenIsNative) {
55+
_deposit(recipient, id, msg.value);
56+
}
57+
58+
unchecked {
59+
for (uint256 i = firstUnderlyingTokenIsNative.asUint256(); i < totalIds; ++i) {
60+
uint256[2] calldata idAndAmount = idsAndAmounts[i];
61+
id = idAndAmount[0];
62+
uint256 amount = idAndAmount[1];
63+
64+
uint96 newAllocatorId = id.toAllocatorId();
65+
if (newAllocatorId != currentAllocatorId) {
66+
newAllocatorId.mustHaveARegisteredAllocator();
67+
currentAllocatorId = newAllocatorId;
68+
}
69+
70+
_transferAndDeposit(id.toToken(), recipient, id, amount);
71+
}
72+
}
73+
74+
_clearReentrancyGuard();
75+
}
76+
77+
function _performBasicERC20Deposit(address token, address allocator, uint256 amount) internal returns (uint256 id) {
78+
id = token.excludingNative().toIdIfRegistered(Scope.Multichain, ResetPeriod.TenMinutes, allocator);
79+
80+
_transferAndDepositWithReentrancyGuard(token, msg.sender, id, amount);
81+
}
82+
83+
function _performCustomNativeTokenDeposit(address allocator, ResetPeriod resetPeriod, Scope scope, address recipient) internal returns (uint256 id) {
84+
id = address(0).toIdIfRegistered(scope, resetPeriod, allocator);
85+
86+
_deposit(recipient, id, msg.value);
87+
}
88+
89+
function _performCustomERC20Deposit(address token, address allocator, ResetPeriod resetPeriod, Scope scope, uint256 amount, address recipient) internal returns (uint256 id) {
90+
id = token.excludingNative().toIdIfRegistered(scope, resetPeriod, allocator);
91+
92+
_transferAndDepositWithReentrancyGuard(token, recipient, id, amount);
93+
}
94+
95+
/// @dev Transfers `amount` of `token` and mints the resulting balance change of `id` to `to`.
96+
/// Emits a {Transfer} event.
97+
function _transferAndDeposit(address token, address to, uint256 id, uint256 amount) private {
98+
uint256 initialBalance = token.balanceOf(address(this));
99+
100+
token.safeTransferFrom(msg.sender, address(this), amount);
101+
102+
_checkBalanceAndDeposit(token, to, id, initialBalance);
103+
}
104+
105+
/// @dev Transfers `amount` of `token` and mints the resulting balance change of `id` to `to`.
106+
/// Emits a {Transfer} event.
107+
function _transferAndDepositWithReentrancyGuard(address token, address to, uint256 id, uint256 amount) private {
108+
_setReentrancyGuard();
109+
110+
_transferAndDeposit(token, to, id, amount);
111+
112+
_clearReentrancyGuard();
113+
}
114+
}

0 commit comments

Comments
 (0)