Skip to content

Commit

Permalink
chore: Split multi deposit redeem testing into own function. Update p…
Browse files Browse the repository at this point in the history
…rincipal with offset in offset testing
  • Loading branch information
lucasia committed Oct 19, 2024
1 parent b484cec commit 0c85e6c
Show file tree
Hide file tree
Showing 5 changed files with 46 additions and 45 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ contract MultiTokenVaultTest is IMultiTokenVaultTestBase {
}

function test__MultiTokenVaulTest__SimpleDeposit() public {
uint256 assetToSharesRatio = 1;
uint256 assetToSharesRatio = 2;

IMultiTokenVault vault = _createMultiTokenVault(_asset, assetToSharesRatio, 10);

Expand All @@ -65,7 +65,7 @@ contract MultiTokenVaultTest is IMultiTokenVaultTestBase {
}

function test__MultiTokenVaulTest__DepositAndRedeem() public {
uint256 assetToSharesRatio = 1;
uint256 assetToSharesRatio = 3;

_transferAndAssert(_asset, _owner, _charlie, 100_000 * _scale);

Expand Down Expand Up @@ -136,7 +136,7 @@ contract MultiTokenVaultTest is IMultiTokenVaultTestBase {
}

function test__MultiTokenVaulTest__MultipleDepositsAndRedeem() public {
uint256 assetToSharesRatio = 2;
uint256 assetToSharesRatio = 4;

// setup
IMultiTokenVault vault = _createMultiTokenVault(_asset, assetToSharesRatio, 10);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import { ERC1967Proxy } from "@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy
import { YieldStrategyScenarioTest } from "@test/src/yield/strategy/YieldStrategyScenarioTest.t.sol";

import { Frequencies } from "@test/src/yield/Frequencies.t.sol";
import { console2 } from "forge-std/console2.sol";

contract MultipleRateYieldStrategyScenarioTest is YieldStrategyScenarioTest {
IYieldStrategy internal yieldStrategy;
Expand Down Expand Up @@ -47,7 +46,6 @@ contract MultipleRateYieldStrategyScenarioTest is YieldStrategyScenarioTest {
uint256 tenor,
uint256 decimals
) private returns (MultipleRateContext) {
console2.log("maturityperiod", MATURITY_PERIOD);
MultipleRateContext _context = new MultipleRateContext();
_context = MultipleRateContext(
address(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import { Timer } from "@credbull/timelock/Timer.sol";
import { TestParamSet } from "@test/test/token/ERC1155/TestParamSet.t.sol";

import { Test } from "forge-std/Test.sol";
import { console2 } from "forge-std/console2.sol";

abstract contract IMultiTokenVaultTestBase is Test {
using TestParamSet for TestParamSet.TestParam[];
Expand Down Expand Up @@ -39,27 +38,39 @@ abstract contract IMultiTokenVaultTestBase is Test {
uint256[] memory assetsAtPeriods = _testRedeemOnly(account, vault, testParams, sharesAtPeriods);

// ------------------- deposits w/ redeems across multiple deposits -------------------
_testVaultCombineDepositsForRedeem(account, vault, testParams, 2);

_warpToPeriod(vault, prevVaultPeriodsElapsed); // restore previous period state

return (sharesAtPeriods, assetsAtPeriods);
}

/// @dev test the vault deposits and redeems across multiple deposit periods
function _testVaultCombineDepositsForRedeem(
address account,
IMultiTokenVault vault,
TestParamSet.TestParam[] memory testParams,
uint256 splitBefore
) internal returns (uint256[] memory sharesAtPeriods_, uint256 assetsAtPeriods1_, uint256 assetsAtPeriods2_) {
// NB - test all of the deposits BEFORE redeems. verifies no side-effects from deposits when redeeming.
_testDepositOnly(account, vault, testParams);
uint256[] memory sharesAtPeriods = _testDepositOnly(account, vault, testParams);

// NB - test all of the redeems AFTER deposits. verifies no side-effects from deposits when redeeming.
uint256 finalRedeemPeriod = testParams.latestRedeemPeriod();

if (testParams.length > 2) {
// split into two batches
(TestParamSet.TestParam[] memory redeemParams1, TestParamSet.TestParam[] memory redeemParams2) =
testParams._splitBefore(2);
// split into two batches
(TestParamSet.TestParam[] memory redeemParams1, TestParamSet.TestParam[] memory redeemParams2) =
testParams._splitBefore(splitBefore);

uint256 partialRedeemPeriod = finalRedeemPeriod - 2;
_testRedeemMultiDeposit(account, vault, redeemParams1, partialRedeemPeriod);
_testRedeemMultiDeposit(account, vault, redeemParams2, finalRedeemPeriod);
} else {
_testRedeemMultiDeposit(account, vault, testParams, finalRedeemPeriod);
}
assertLe(2, redeemParams1.length, "redeem params array 1 should have multiple params");
assertLe(2, redeemParams2.length, "redeem params array 2 should have multiple params");

_warpToPeriod(vault, prevVaultPeriodsElapsed); // restore previous period state
uint256 partialRedeemPeriod = finalRedeemPeriod - 2;

return (sharesAtPeriods, assetsAtPeriods);
uint256 assetsAtPeriods1 = _testRedeemMultiDeposit(account, vault, redeemParams1, partialRedeemPeriod);
uint256 assetsAtPeriods2 = _testRedeemMultiDeposit(account, vault, redeemParams2, finalRedeemPeriod);

return (sharesAtPeriods, assetsAtPeriods1, assetsAtPeriods2);
}

/// @dev test Vault at specified redeemPeriod and other "interesting" redeem periods
Expand Down Expand Up @@ -262,7 +273,7 @@ abstract contract IMultiTokenVaultTestBase is Test {
IMultiTokenVault vault,
TestParamSet.TestParam[] memory depositTestParams,
uint256 redeemPeriod // we are testing multiple deposits into one redeemPeriod
) internal virtual {
) internal virtual returns (uint256 assets_) {
_warpToPeriod(vault, redeemPeriod);

IERC20 asset = IERC20(vault.asset());
Expand Down Expand Up @@ -290,6 +301,8 @@ abstract contract IMultiTokenVaultTestBase is Test {
);
assertEq(prevSharesBalance[i] - sharesAtPeriod, sharesBalance[i], "shares balance incorrect");
}

return assets;
}

/// @dev performance / load test harness to execute a number of deposits first, and then redeem after
Expand Down Expand Up @@ -340,23 +353,16 @@ abstract contract IMultiTokenVaultTestBase is Test {
uint256 assets = 0;
vm.startPrank(account);

console2.log("---------------------- redeeming -------------------------------");

// @dev - IMultiTokenVault we don't support redeeming across deposit periods. redeem period by period instead.
for (uint256 i = 0; i < depositTestParams.length; ++i) {
uint256 depositPeriod = depositTestParams[i].depositPeriod;
uint256 sharesAtPeriod =
vault.convertToSharesForDepositPeriod(depositTestParams[i].principal, depositPeriod);

console2.log("depositPeriod=%s principal=%s", depositPeriod, depositTestParams[i].principal);
console2.log("user balance at period", vault.balanceOf(account, depositPeriod));

assets += vault.redeemForDepositPeriod(sharesAtPeriod, account, account, depositTestParams[i].depositPeriod);
}
vm.stopPrank();

console2.log("------------------------ redeeming End -----------------------------");

return assets;
}

Expand Down
17 changes: 9 additions & 8 deletions packages/contracts/test/test/token/ERC1155/TestParamSet.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -16,18 +16,18 @@ library TestParamSet {
pure
returns (TestParam[] memory testParamsWithOffsets_)
{
uint256[6] memory offsetNumPeriodsArr =
uint256[6] memory offsetAmounts =
[0, 1, 2, testParam.redeemPeriod - 1, testParam.redeemPeriod, testParam.redeemPeriod + 1];

TestParam[] memory testParamsWithOffsets = new TestParam[](offsetNumPeriodsArr.length);
TestParam[] memory testParamsWithOffsets = new TestParam[](offsetAmounts.length);

for (uint256 i = 0; i < offsetNumPeriodsArr.length; i++) {
uint256 offsetNumPeriods = offsetNumPeriodsArr[i];
for (uint256 i = 0; i < offsetAmounts.length; i++) {
uint256 offsetAmount = offsetAmounts[i];

TestParam memory testParamsWithOffset = TestParam({
principal: testParam.principal,
depositPeriod: testParam.depositPeriod + offsetNumPeriods,
redeemPeriod: testParam.redeemPeriod + offsetNumPeriods
principal: testParam.principal * (1 + offsetAmount),
depositPeriod: testParam.depositPeriod + offsetAmount,
redeemPeriod: testParam.redeemPeriod + offsetAmount
});

testParamsWithOffsets[i] = testParamsWithOffset;
Expand Down Expand Up @@ -122,7 +122,8 @@ library TestParamSet {
pure
returns (TestParam[] memory leftSet_, TestParam[] memory rightSet_)
{
assert(splitBefore <= origTestParams.length);
// assert we can actually split in two at the splitBefore
assert(splitBefore < (origTestParams.length - 1));

// Initialize leftSet and rightSet arrays with their respective sizes
TestParam[] memory leftSet = new TestParam[](splitBefore); // Elements before splitBefore
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,6 @@ import { TestParamSet } from "@test/test/token/ERC1155/TestParamSet.t.sol";

import { IERC20Metadata } from "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol";

import { console2 } from "forge-std/console2.sol";

abstract contract LiquidContinuousMultiTokenVaultTestBase is IMultiTokenVaultTestBase {
using TestParamSet for TestParamSet.TestParam[];

Expand Down Expand Up @@ -158,16 +156,18 @@ abstract contract LiquidContinuousMultiTokenVaultTestBase is IMultiTokenVaultTes
IMultiTokenVault vault,
TestParamSet.TestParam[] memory depositTestParams,
uint256 redeemPeriod // we are testing multiple deposits into one redeemPeriod
) internal virtual {
) internal virtual returns (uint256 assets_) {
LiquidContinuousMultiTokenVault liquidVault = LiquidContinuousMultiTokenVault(address(vault));

super._testRedeemMultiDeposit(account, vault, depositTestParams, redeemPeriod);
uint256 assets = super._testRedeemMultiDeposit(account, vault, depositTestParams, redeemPeriod);

// verify the requestRedeems are released
(uint256[] memory unlockDepositPeriods, uint256[] memory unlockAmounts) =
liquidVault.unlockRequests(account, redeemPeriod);
assertEq(0, unlockDepositPeriods.length, "unlock should be released");
assertEq(0, unlockAmounts.length, "unlock should be released");

return assets;
}

/// @dev - requestRedeem AND redeem over multiple deposit and principals into one requestRedeemPeriod
Expand All @@ -176,14 +176,14 @@ abstract contract LiquidContinuousMultiTokenVaultTestBase is IMultiTokenVaultTes
IMultiTokenVault vault,
TestParamSet.TestParam[] memory depositTestParams,
uint256 redeemPeriod // we are testing multiple deposits into one redeemPeriod
) internal virtual override {
) internal virtual override returns (uint256 assets_) {
LiquidContinuousMultiTokenVault liquidVault = LiquidContinuousMultiTokenVault(address(vault));

// first requestRedeem
_testRequestRedeemMultiDeposit(account, liquidVault, depositTestParams, redeemPeriod);

// now redeem
_testRedeemAfterRequestRedeemMultiDeposit(account, vault, depositTestParams, redeemPeriod);
return _testRedeemAfterRequestRedeemMultiDeposit(account, vault, depositTestParams, redeemPeriod);
}

/// @dev execute a redeem on the vault across multiple deposit periods.~
Expand All @@ -197,10 +197,6 @@ abstract contract LiquidContinuousMultiTokenVaultTestBase is IMultiTokenVaultTes

_warpToPeriod(vault, redeemPeriod); // warp the vault to redeem period

console2.log("depositTestParams.totalPrincipal()", depositTestParams.totalPrincipal());
console2.log("liquidVault.totalSupply()", liquidVault.totalSupply());
console2.log("liquidVault.totalAssets()", liquidVault.totalAssets());

vm.prank(account);
return liquidVault.redeem(depositTestParams.totalPrincipal(), account, account);
}
Expand Down

0 comments on commit 0c85e6c

Please sign in to comment.