Skip to content

Commit a4b3d52

Browse files
committed
refactor: optimize MSLV contract size
1 parent be1f2b8 commit a4b3d52

File tree

1 file changed

+28
-29
lines changed

1 file changed

+28
-29
lines changed

src/core/MultistrategyLockedVault.sol

Lines changed: 28 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ import { Math } from "@openzeppelin/contracts/utils/math/Math.sol";
3535
* - Users cannot transfer locked shares to other addresses
3636
* - Available shares = total balance - locked shares
3737
* - Prevents rage quit cooldown bypass through share transfers
38-
* - Use `getTransferableShares()` to check available balance for transfers
38+
* - Check `custodyInfo(user).lockedShares` to calculate available balance for transfers
3939
*
4040
* 4. **Withdrawal Rules:**
4141
* - Users can only withdraw shares if they have active custody
@@ -44,10 +44,10 @@ import { Math } from "@openzeppelin/contracts/utils/math/Math.sol";
4444
* - New rage quit required after custody is fully withdrawn
4545
* - `maxWithdraw()` and `maxRedeem()` return 0 if no custody or still in cooldown
4646
*
47-
* 5. **Utility Functions:**
48-
* - `getTransferableShares(user)`: Returns shares available for transfer
49-
* - `getRageQuitableShares(user)`: Returns shares available for rage quit initiation
50-
* - `custodyInfo(user)`: Returns custody details (locked shares, unlock time)
47+
* 5. **Querying Custody State:**
48+
* - `custodyInfo(user)`: Returns custody details (lockedShares, unlockTime)
49+
* - Transferable shares = `balanceOf(user) - custodyInfo(user).lockedShares`
50+
* - User can initiate rage quit if `custodyInfo(user).lockedShares == 0`
5151
*
5252
* ## Two-Step Cooldown Period Changes:
5353
*
@@ -78,7 +78,7 @@ import { Math } from "@openzeppelin/contracts/utils/math/Math.sol";
7878
* **Scenario A - Basic Custody Flow:**
7979
* 1. User has 1000 shares, initiates rage quit for 500 shares
8080
* 2. 500 shares locked in custody, 500 shares remain transferable
81-
* 3. `getTransferableShares(user)` returns 500, `getRageQuitableShares(user)` returns 0
81+
* 3. `custodyInfo(user).lockedShares` returns 500, user cannot initiate another rage quit
8282
* 4. After cooldown, user can withdraw up to 500 shares
8383
* 5. User withdraws 300 shares, 200 shares remain in custody
8484
* 6. User can later withdraw remaining 200 shares without new rage quit
@@ -90,13 +90,13 @@ import { Math } from "@openzeppelin/contracts/utils/math/Math.sol";
9090
* 4. Change finalized after grace period
9191
* 5. User B rage quits after finalization → uses 14-day cooldown
9292
*
93-
* **Scenario C - Utility Function Usage:**
93+
* **Scenario C - Querying Custody State:**
9494
* 1. User has 1000 shares, no active rage quit
95-
* 2. `getTransferableShares(user)` returns 1000
96-
* 3. `getRageQuitableShares(user)` returns 1000
95+
* 2. `custodyInfo(user).lockedShares` returns 0, transferable = 1000
96+
* 3. User can initiate rage quit (no active custody)
9797
* 4. User initiates rage quit for 400 shares
98-
* 5. `getTransferableShares(user)` returns 600
99-
* 6. `getRageQuitableShares(user)` returns 0 (already has active rage quit)
98+
* 5. `custodyInfo(user).lockedShares` returns 400, transferable = 600
99+
* 6. User cannot initiate another rage quit (already has active custody)
100100
*/
101101
contract MultistrategyLockedVault is MultistrategyVault, IMultistrategyLockedVault {
102102
// ============================================
@@ -134,15 +134,15 @@ contract MultistrategyLockedVault is MultistrategyVault, IMultistrategyLockedVau
134134

135135
/// @notice Initial rage quit cooldown period set at deployment
136136
/// @dev 7 days in seconds. Applied until governance changes it
137-
uint256 public constant INITIAL_RAGE_QUIT_COOLDOWN_PERIOD = 7 days;
137+
uint256 private constant INITIAL_RAGE_QUIT_COOLDOWN_PERIOD = 7 days;
138138

139139
/// @notice Minimum allowed rage quit cooldown period
140140
/// @dev 1 day in seconds. Prevents cooldown from being set too short
141-
uint256 public constant RANGE_MINIMUM_RAGE_QUIT_COOLDOWN_PERIOD = 1 days;
141+
uint256 private constant RANGE_MINIMUM_RAGE_QUIT_COOLDOWN_PERIOD = 1 days;
142142

143143
/// @notice Maximum allowed rage quit cooldown period
144144
/// @dev 30 days in seconds. Prevents cooldown from being set too long
145-
uint256 public constant RANGE_MAXIMUM_RAGE_QUIT_COOLDOWN_PERIOD = 30 days;
145+
uint256 private constant RANGE_MAXIMUM_RAGE_QUIT_COOLDOWN_PERIOD = 30 days;
146146

147147
/// @notice Grace period delay for cooldown changes
148148
/// @dev 14 days in seconds. Users have this time to rage quit under old terms
@@ -534,19 +534,15 @@ contract MultistrategyLockedVault is MultistrategyVault, IMultistrategyLockedVau
534534
revert SharesStillLocked();
535535
}
536536

537-
// Ensure user has sufficient balance
538-
uint256 userBalance = balanceOf(owner);
539-
if (userBalance < shares) {
540-
revert InsufficientBalance();
541-
}
542-
543537
// Can only withdraw up to locked amount
544538
if (shares > custody.lockedShares) {
545539
revert ExceedsCustodiedAmount();
546540
}
547541

548542
// Reduce locked shares by withdrawn amount
549-
custody.lockedShares -= shares;
543+
unchecked {
544+
custody.lockedShares -= shares;
545+
}
550546

551547
// If all custodied shares withdrawn, reset custody info
552548
if (custody.lockedShares == 0) {
@@ -572,7 +568,11 @@ contract MultistrategyLockedVault is MultistrategyVault, IMultistrategyLockedVau
572568

573569
if (custody.lockedShares > 0) {
574570
uint256 senderBalance = balanceOf(sender_);
575-
uint256 availableShares = senderBalance - custody.lockedShares;
571+
572+
uint256 availableShares;
573+
unchecked {
574+
availableShares = senderBalance - custody.lockedShares;
575+
}
576576

577577
// Revert if trying to transfer more than available shares
578578
if (amount_ > availableShares) {
@@ -625,7 +625,7 @@ contract MultistrategyLockedVault is MultistrategyVault, IMultistrategyLockedVau
625625
function maxWithdraw(
626626
address owner_,
627627
uint256 maxLoss_
628-
) public view override(MultistrategyVault, IMultistrategyVault) returns (uint256) {
628+
) external view override(MultistrategyVault, IMultistrategyVault) returns (uint256) {
629629
return maxWithdraw(owner_, maxLoss_, new address[](0));
630630
}
631631

@@ -670,11 +670,8 @@ contract MultistrategyLockedVault is MultistrategyVault, IMultistrategyLockedVau
670670
balanceOf(owner_)
671671
);
672672

673-
// Get custody info to determine locked shares
674-
uint256 lockedShares = custody.lockedShares;
675-
676673
// Return minimum of parent max and custody limit
677-
return Math.min(parentMax, lockedShares);
674+
return Math.min(parentMax, custody.lockedShares);
678675
}
679676

680677
/**
@@ -689,7 +686,7 @@ contract MultistrategyLockedVault is MultistrategyVault, IMultistrategyLockedVau
689686
function maxRedeem(
690687
address owner_,
691688
uint256 maxLoss_
692-
) public view override(MultistrategyVault, IMultistrategyVault) returns (uint256) {
689+
) external view override(MultistrategyVault, IMultistrategyVault) returns (uint256) {
693690
return maxRedeem(owner_, maxLoss_, new address[](0));
694691
}
695692

@@ -700,7 +697,9 @@ contract MultistrategyLockedVault is MultistrategyVault, IMultistrategyLockedVau
700697
* @param owner_ Address that owns the shares
701698
* @return max Maximum redeemable shares (constrained by custody)
702699
*/
703-
function maxRedeem(address owner_) public view override(MultistrategyVault, IMultistrategyVault) returns (uint256) {
700+
function maxRedeem(
701+
address owner_
702+
) external view override(MultistrategyVault, IMultistrategyVault) returns (uint256) {
704703
return maxRedeem(owner_, MAX_BPS, new address[](0));
705704
}
706705
}

0 commit comments

Comments
 (0)