From 00e47062f26ce61fdfa1581e631c352cd0189bb2 Mon Sep 17 00:00:00 2001 From: Ian Lucas Date: Mon, 27 Jan 2025 10:03:02 -0500 Subject: [PATCH] chore: LiquidStone enables investor role checking by default --- .../script/DeployLiquidMultiTokenVault.s.sol | 3 ++- .../yield/LiquidContinuousMultiTokenVault.sol | 4 +++- .../test/src/LiquidStoneNinetyDayTest.t.sol | 1 + .../LiquidContinuousMultiTokenVaultTest.t.sol | 17 +++++++++++++---- ...iquidContinuousMultiTokenVaultUtilTest.t.sol | 5 +++++ .../DeployAndLoadLiquidMultiTokenVault.s.sol | 3 ++- ...iquidContinuousMultiTokenVaultTestBase.t.sol | 5 +++++ 7 files changed, 31 insertions(+), 7 deletions(-) diff --git a/packages/contracts/script/DeployLiquidMultiTokenVault.s.sol b/packages/contracts/script/DeployLiquidMultiTokenVault.s.sol index cacb2c02..83be7d79 100644 --- a/packages/contracts/script/DeployLiquidMultiTokenVault.s.sol +++ b/packages/contracts/script/DeployLiquidMultiTokenVault.s.sol @@ -130,7 +130,8 @@ contract DeployLiquidMultiTokenVault is TomlConfig { redeemOptimizer: redeemOptimizer, vaultStartTimestamp: startTimestamp, redeemNoticePeriod: 1, - contextParams: contextParams + contextParams: contextParams, + shouldCheckInvestorRole: true }); return vaultParams; diff --git a/packages/contracts/src/yield/LiquidContinuousMultiTokenVault.sol b/packages/contracts/src/yield/LiquidContinuousMultiTokenVault.sol index ee72408a..cd25abf8 100644 --- a/packages/contracts/src/yield/LiquidContinuousMultiTokenVault.sol +++ b/packages/contracts/src/yield/LiquidContinuousMultiTokenVault.sol @@ -60,6 +60,7 @@ contract LiquidContinuousMultiTokenVault is uint256 vaultStartTimestamp; uint256 redeemNoticePeriod; TripleRateContext.ContextParams contextParams; + bool shouldCheckInvestorRole; } IYieldStrategy public _yieldStrategy; @@ -67,7 +68,7 @@ contract LiquidContinuousMultiTokenVault is uint256 public _vaultStartTimestamp; // [Jan-2025] added - must be after previous fields due to upgrading - bool public _shouldCheckInvestorRole = false; + bool public _shouldCheckInvestorRole = true; uint256 private constant ZERO_REQUEST_ID = 0; @@ -106,6 +107,7 @@ contract LiquidContinuousMultiTokenVault is _yieldStrategy = vaultParams.yieldStrategy; _redeemOptimizer = vaultParams.redeemOptimizer; _vaultStartTimestamp = vaultParams.vaultStartTimestamp; + _shouldCheckInvestorRole = vaultParams.shouldCheckInvestorRole; if (vaultParams.contextParams.frequency != 360 && vaultParams.contextParams.frequency != 365) { revert LiquidContinuousMultiTokenVault__InvalidFrequency(vaultParams.contextParams.frequency); diff --git a/packages/contracts/test/src/LiquidStoneNinetyDayTest.t.sol b/packages/contracts/test/src/LiquidStoneNinetyDayTest.t.sol index f03e9fd5..32f5ada6 100644 --- a/packages/contracts/test/src/LiquidStoneNinetyDayTest.t.sol +++ b/packages/contracts/test/src/LiquidStoneNinetyDayTest.t.sol @@ -29,6 +29,7 @@ contract DeployLiquidStoneNinetyDay is DeployLiquidMultiTokenVault { vaultParams.redeemNoticePeriod = 0; vaultParams.contextParams.fullRateScaled = 10 * scale; vaultParams.contextParams.initialReducedRate.interestRate = 0; // zero for less than tenor + vaultParams.shouldCheckInvestorRole = false; return vaultParams; } diff --git a/packages/contracts/test/src/yield/LiquidContinuousMultiTokenVaultTest.t.sol b/packages/contracts/test/src/yield/LiquidContinuousMultiTokenVaultTest.t.sol index 90385e67..4d654af6 100644 --- a/packages/contracts/test/src/yield/LiquidContinuousMultiTokenVaultTest.t.sol +++ b/packages/contracts/test/src/yield/LiquidContinuousMultiTokenVaultTest.t.sol @@ -300,7 +300,7 @@ contract LiquidContinuousMultiTokenVaultTest is LiquidContinuousMultiTokenVaultT address nonInvestorWallet = makeAddr("nonInvestorWallet"); address anyWallet = address(0); // any wallet is fine - not involved in validation - // enable investor checking + // ensure the investor check is enabled vm.prank(_vaultAuth.operator); _liquidVault.setShouldCheckInvestorRole(true); @@ -310,8 +310,7 @@ contract LiquidContinuousMultiTokenVaultTest is LiquidContinuousMultiTokenVaultT nonInvestorWallet ); - // ======================= deposits ======================= - // function deposit(uint256 assets, address receiver) external returns (uint256 shares); + // ======================= deposits fail ======================= vm.prank(investorWallet); vm.expectRevert(investorOnlyError); liquidVault.deposit(anyParam.principal, nonInvestorWallet); // IMultiToken @@ -324,7 +323,7 @@ contract LiquidContinuousMultiTokenVaultTest is LiquidContinuousMultiTokenVaultT vm.expectRevert(investorOnlyError); liquidVault.deposit(anyParam.principal, nonInvestorWallet, anyWallet); // IComponent - // ======================= redeems ======================= + // ======================= redeems fail ======================= vm.prank(investorWallet); vm.expectRevert(investorOnlyError); liquidVault.redeemForDepositPeriod(anyParam.principal, anyWallet, nonInvestorWallet, anyParam.depositPeriod); @@ -342,6 +341,16 @@ contract LiquidContinuousMultiTokenVaultTest is LiquidContinuousMultiTokenVaultT vm.prank(investorWallet); vm.expectRevert(investorOnlyError); liquidVault.redeem(anyParam.principal, anyWallet, nonInvestorWallet); // IComponent + + // ======================= grant access - succeeds ======================= + // grant investor role + vm.startPrank(_vaultAuth.owner); + _liquidVault.grantRole(_liquidVault.INVESTOR_ROLE(), nonInvestorWallet); + vm.stopPrank(); + + // deposit should succeed (no revert) + vm.prank(investorWallet); + liquidVault.deposit(0, nonInvestorWallet); // IMultiToken } // Scenario: Calculating returns for a standard investment diff --git a/packages/contracts/test/src/yield/LiquidContinuousMultiTokenVaultUtilTest.t.sol b/packages/contracts/test/src/yield/LiquidContinuousMultiTokenVaultUtilTest.t.sol index 303d1a6e..f4272d4e 100644 --- a/packages/contracts/test/src/yield/LiquidContinuousMultiTokenVaultUtilTest.t.sol +++ b/packages/contracts/test/src/yield/LiquidContinuousMultiTokenVaultUtilTest.t.sol @@ -36,6 +36,11 @@ contract LiquidContinuousMultiTokenVaultUtilTest is LiquidContinuousMultiTokenVa TestParamSet.TestParam memory testParams = TestParamSet.TestParam({ principal: 2_000 * scale, depositPeriod: 11, redeemPeriod: 71 }); + // whitelist alice as an investor + vm.startPrank(_vaultAuth.owner); + vaultProxy.grantRole(vaultProxy.INVESTOR_ROLE(), alice); + vm.stopPrank(); + _warpToPeriod(vaultProxy, testParams.depositPeriod); vm.startPrank(alice); diff --git a/packages/contracts/test/test/script/DeployAndLoadLiquidMultiTokenVault.s.sol b/packages/contracts/test/test/script/DeployAndLoadLiquidMultiTokenVault.s.sol index a8ea06e1..ae31e665 100644 --- a/packages/contracts/test/test/script/DeployAndLoadLiquidMultiTokenVault.s.sol +++ b/packages/contracts/test/test/script/DeployAndLoadLiquidMultiTokenVault.s.sol @@ -91,10 +91,11 @@ contract DeployAndLoadLiquidMultiTokenVault is DeployLiquidMultiTokenVault { IERC20 asset = IERC20(vault.asset()); uint256 scale = 10 ** IERC20Metadata(vault.asset()).decimals(); - // --------------------- gift user funds --------------------- + // --------------------- gift user funds & whitelist --------------------- vm.startBroadcast(_owner.key()); asset.transfer(userWallet.addr(), 1_000_000 * scale); + vault.grantRole(vault.INVESTOR_ROLE(), userWallet.addr()); vm.stopBroadcast(); // --------------------- load deposits --------------------- diff --git a/packages/contracts/test/test/yield/LiquidContinuousMultiTokenVaultTestBase.t.sol b/packages/contracts/test/test/yield/LiquidContinuousMultiTokenVaultTestBase.t.sol index 5ac0dbd2..2c090e8b 100644 --- a/packages/contracts/test/test/yield/LiquidContinuousMultiTokenVaultTestBase.t.sol +++ b/packages/contracts/test/test/yield/LiquidContinuousMultiTokenVaultTestBase.t.sol @@ -39,6 +39,11 @@ abstract contract LiquidContinuousMultiTokenVaultTestBase is IMultiTokenVaultTes DeployLiquidMultiTokenVault _deployVault = new DeployLiquidMultiTokenVault(); _liquidVault = _deployVault.run(_vaultAuth); + // disable the investor whitelist check - test users are already complex + // tested instead specifically in test__LiquidContinuousMultiTokenVault__AccountNotInvestorReverts + vm.prank(_vaultAuth.operator); + _liquidVault.setShouldCheckInvestorRole(false); + // warp to a "real time" time rather than block.timestamp=1 vm.warp(_liquidVault._vaultStartTimestamp() + 1);