Skip to content

Commit

Permalink
Changed TestParamSet to be a library and operate on arrays. Moved Tes…
Browse files Browse the repository at this point in the history
…tParam into TestParamSet
  • Loading branch information
lucasia committed Oct 17, 2024
1 parent 3638ccf commit 6b819be
Show file tree
Hide file tree
Showing 8 changed files with 230 additions and 194 deletions.
55 changes: 32 additions & 23 deletions packages/contracts/test/src/token/ERC1155/MultiTokenVaultTest.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ pragma solidity ^0.8.20;
import { IMultiTokenVault } from "@credbull/token/ERC1155/IMultiTokenVault.sol";
import { MultiTokenVault } from "@credbull/token/ERC1155/MultiTokenVault.sol";
import { IMultiTokenVaultTestBase } from "@test/test/token/ERC1155/IMultiTokenVaultTestBase.t.sol";
import { IMTVTestParams } from "@test/test/token/ERC1155/IMTVTestParams.t.sol";
import { TestParamSet } from "@test/test/token/ERC1155/TestParamSet.t.sol";
import { MultiTokenVaultDailyPeriods } from "@test/test/token/ERC1155/MultiTokenVaultDailyPeriods.t.sol";
import { ERC1967Proxy } from "@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol";

Expand All @@ -13,6 +13,8 @@ import { SimpleUSDC } from "@test/test/token/SimpleUSDC.t.sol";
import { IERC20Metadata } from "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol";

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

IERC20Metadata internal _asset;
uint256 internal _scale;

Expand All @@ -21,9 +23,9 @@ contract MultiTokenVaultTest is IMultiTokenVaultTestBase {
address private _bob = makeAddr("bob");
address private _charlie = makeAddr("charlie");

TestParam internal _testParams1;
TestParam internal _testParams2;
TestParam internal _testParams3;
TestParamSet.TestParam internal _testParams1;
TestParamSet.TestParam internal _testParams2;
TestParamSet.TestParam internal _testParams3;

function setUp() public virtual {
vm.prank(_owner);
Expand All @@ -32,9 +34,9 @@ contract MultiTokenVaultTest is IMultiTokenVaultTestBase {
_scale = 10 ** _asset.decimals();
_transferAndAssert(_asset, _owner, _alice, 100_000 * _scale);

_testParams1 = TestParam({ principal: 500 * _scale, depositPeriod: 10, redeemPeriod: 21 });
_testParams2 = TestParam({ principal: 300 * _scale, depositPeriod: 15, redeemPeriod: 17 });
_testParams3 = TestParam({ principal: 700 * _scale, depositPeriod: 30, redeemPeriod: 55 });
_testParams1 = TestParamSet.TestParam({ principal: 500 * _scale, depositPeriod: 10, redeemPeriod: 21 });
_testParams2 = TestParamSet.TestParam({ principal: 300 * _scale, depositPeriod: 15, redeemPeriod: 17 });
_testParams3 = TestParamSet.TestParam({ principal: 700 * _scale, depositPeriod: 30, redeemPeriod: 55 });
}

function test__MultiTokenVaulTest__SimpleDeposit() public {
Expand Down Expand Up @@ -76,7 +78,8 @@ contract MultiTokenVaultTest is IMultiTokenVaultTestBase {
function test__MultiTokenVaulTest__RedeemBeforeDepositPeriodReverts() public {
MultiTokenVault vault = _createMultiTokenVault(_asset, 1, 10);

TestParam memory testParam = TestParam({ principal: 1001 * _scale, depositPeriod: 2, redeemPeriod: 1 });
TestParamSet.TestParam memory testParam =
TestParamSet.TestParam({ principal: 1001 * _scale, depositPeriod: 2, redeemPeriod: 1 });

// deposit period > redeem period should fail
vm.expectRevert(
Expand All @@ -93,7 +96,8 @@ contract MultiTokenVaultTest is IMultiTokenVaultTestBase {
function test__MultiTokenVaulTest__CurrentBeforeRedeemPeriodReverts() public {
MultiTokenVault vault = _createMultiTokenVault(_asset, 1, 10);

TestParam memory testParam = TestParam({ principal: 1001 * _scale, depositPeriod: 1, redeemPeriod: 3 });
TestParamSet.TestParam memory testParam =
TestParamSet.TestParam({ principal: 1001 * _scale, depositPeriod: 1, redeemPeriod: 3 });

uint256 currentPeriod = testParam.redeemPeriod - 1;

Expand All @@ -113,7 +117,8 @@ contract MultiTokenVaultTest is IMultiTokenVaultTestBase {
function test__MultiTokenVaulTest__RedeemOverMaxSharesReverts() public {
MultiTokenVault vault = _createMultiTokenVault(_asset, 1, 10);

TestParam memory testParam = TestParam({ principal: 1001 * _scale, depositPeriod: 1, redeemPeriod: 3 });
TestParamSet.TestParam memory testParam =
TestParamSet.TestParam({ principal: 1001 * _scale, depositPeriod: 1, redeemPeriod: 3 });

uint256 sharesToRedeem = 1;

Expand Down Expand Up @@ -188,15 +193,19 @@ contract MultiTokenVaultTest is IMultiTokenVaultTestBase {
uint256 assetToSharesRatio = 2;
uint256 redeemPeriod = 2001;

IMTVTestParams testParams = new IMTVTestParams();
testParams.add(TestParam({ principal: 1001 * _scale, depositPeriod: 1, redeemPeriod: redeemPeriod }));
testParams.add(TestParam({ principal: 2002 * _scale, depositPeriod: 202, redeemPeriod: redeemPeriod }));
testParams.add(TestParam({ principal: 3003 * _scale, depositPeriod: 303, redeemPeriod: redeemPeriod }));
TestParamSet.TestParam[] memory _batchTestParams = new TestParamSet.TestParam[](3);

_batchTestParams[0] =
TestParamSet.TestParam({ principal: 1001 * _scale, depositPeriod: 1, redeemPeriod: redeemPeriod });
_batchTestParams[1] =
TestParamSet.TestParam({ principal: 2002 * _scale, depositPeriod: 202, redeemPeriod: redeemPeriod });
_batchTestParams[2] =
TestParamSet.TestParam({ principal: 3003 * _scale, depositPeriod: 303, redeemPeriod: redeemPeriod });

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

uint256[] memory shares = _testDepositOnly(_alice, vault, testParams);
uint256[] memory depositPeriods = testParams.depositPeriods();
uint256[] memory shares = _testDepositOnly(_alice, vault, _batchTestParams);
uint256[] memory depositPeriods = _batchTestParams.depositPeriods();

// ------------------------ batch convert to assets ------------------------
uint256[] memory assets = vault.convertToAssetsForDepositPeriodBatch(shares, depositPeriods, redeemPeriod);
Expand All @@ -219,7 +228,7 @@ contract MultiTokenVaultTest is IMultiTokenVaultTestBase {
);

// ------------------------ batch approvalForAll safeBatchTransferFrom balance ------------------------
uint256[] memory aliceBalances = _testBalanceOfBatch(_alice, vault, testParams, assetToSharesRatio);
uint256[] memory aliceBalances = _testBalanceOfBatch(_alice, vault, _batchTestParams, assetToSharesRatio);

// have alice approve bob for all
vm.prank(_alice);
Expand All @@ -229,27 +238,27 @@ contract MultiTokenVaultTest is IMultiTokenVaultTestBase {
vm.prank(_bob);
vault.safeBatchTransferFrom(_alice, _charlie, depositPeriods, aliceBalances, "");

_testBalanceOfBatch(_charlie, vault, testParams, assetToSharesRatio); // verify bob
_testBalanceOfBatch(_charlie, vault, _batchTestParams, assetToSharesRatio); // verify bob
}

function _testBalanceOfBatch(
address account,
IMultiTokenVault vault,
IMTVTestParams testParams,
TestParamSet.TestParam[] memory testParams,
uint256 assetToSharesRatio
) internal view returns (uint256[] memory balances_) {
address[] memory accounts = testParams.accountArray(account);
uint256[] memory balances = vault.balanceOfBatch(accounts, testParams.depositPeriods());
assertEq(3, balances.length, "balances size incorrect");

assertEq(testParams.get(0).principal / assetToSharesRatio, balances[0], "balance mismatch period 0");
assertEq(testParams.get(1).principal / assetToSharesRatio, balances[1], "balance mismatch period 1");
assertEq(testParams.get(2).principal / assetToSharesRatio, balances[2], "balance mismatch period 2");
assertEq(testParams[0].principal / assetToSharesRatio, balances[0], "balance mismatch period 0");
assertEq(testParams[1].principal / assetToSharesRatio, balances[1], "balance mismatch period 1");
assertEq(testParams[2].principal / assetToSharesRatio, balances[2], "balance mismatch period 2");

return balances;
}

function _expectedReturns(uint256, /* shares */ IMultiTokenVault vault, TestParam memory testParam)
function _expectedReturns(uint256, /* shares */ IMultiTokenVault vault, TestParamSet.TestParam memory testParam)
internal
view
override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,21 +6,22 @@ import { RedeemOptimizerFIFO } from "@credbull/token/ERC1155/RedeemOptimizerFIFO
import { IMultiTokenVault } from "@credbull/token/ERC1155/IMultiTokenVault.sol";

import { MultiTokenVaultTest } from "@test/src/token/ERC1155/MultiTokenVaultTest.t.sol";
import { IMTVTestParams } from "@test/test/token/ERC1155/IMTVTestParams.t.sol";
import { TestParamSet } from "@test/test/token/ERC1155/TestParamSet.t.sol";

contract RedeemOptimizerTest is MultiTokenVaultTest {
using TestParamSet for TestParamSet.TestParam[];

address private _owner = makeAddr("owner");
address private _alice = makeAddr("alice");

IMTVTestParams private testParams;
TestParamSet.TestParam[] private testParams;

function setUp() public override {
super.setUp();

testParams = new IMTVTestParams();
testParams.add(_testParams1);
testParams.add(_testParams2);
testParams.add(_testParams3);
testParams.push(_testParams1);
testParams.push(_testParams2);
testParams.push(_testParams3);
}

function test__RedeemOptimizerTest__RedeemAllShares() public {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,22 +4,25 @@ pragma solidity ^0.8.20;
import { LiquidContinuousMultiTokenVault } from "@credbull/yield/LiquidContinuousMultiTokenVault.sol";
import { LiquidContinuousMultiTokenVaultTestBase } from "@test/test/yield/LiquidContinuousMultiTokenVaultTestBase.t.sol";
import { IAccessControl } from "@openzeppelin/contracts/access/IAccessControl.sol";
import { IMTVTestParams } from "@test/test/token/ERC1155/IMTVTestParams.t.sol";

import { TestParamSet } from "@test/test/token/ERC1155/TestParamSet.t.sol";

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

function test__RequestRedeemTest__RedeemAtTenor() public {
testVaultAtOffsets(
alice,
_liquidVault,
TestParam({ principal: 100 * _scale, depositPeriod: 0, redeemPeriod: _liquidVault.TENOR() })
TestParamSet.TestParam({ principal: 100 * _scale, depositPeriod: 0, redeemPeriod: _liquidVault.TENOR() })
);
}

function test__LiquidContinuousVaultTest__RedeemBeforeTenor() public {
testVaultAtOffsets(
bob,
_liquidVault,
TestParam({ principal: 100 * _scale, depositPeriod: 0, redeemPeriod: _liquidVault.TENOR() })
TestParamSet.TestParam({ principal: 100 * _scale, depositPeriod: 0, redeemPeriod: _liquidVault.TENOR() })
);
}

Expand All @@ -34,7 +37,8 @@ contract LiquidContinuousMultiTokenVaultTest is LiquidContinuousMultiTokenVaultT
function test__LiquidContinuousVaultTest__DepositRedeem() public {
LiquidContinuousMultiTokenVault liquidVault = _liquidVault; // _createLiquidContinueMultiTokenVault(_vaultParams);

TestParam memory testParams = TestParam({ principal: 2_000 * _scale, depositPeriod: 10, redeemPeriod: 70 });
TestParamSet.TestParam memory testParams =
TestParamSet.TestParam({ principal: 2_000 * _scale, depositPeriod: 10, redeemPeriod: 70 });

uint256 assetStartBalance = _asset.balanceOf(alice);

Expand Down Expand Up @@ -92,7 +96,8 @@ contract LiquidContinuousMultiTokenVaultTest is LiquidContinuousMultiTokenVaultT
function test__LiquidContinuousVaultTest__WithdrawAssetFromVault() public {
LiquidContinuousMultiTokenVault liquidVault = _liquidVault;

TestParam memory testParams = TestParam({ principal: 2_000 * _scale, depositPeriod: 10, redeemPeriod: 70 });
TestParamSet.TestParam memory testParams =
TestParamSet.TestParam({ principal: 2_000 * _scale, depositPeriod: 10, redeemPeriod: 70 });
address assetManager = getAssetManager();

// ---------------- deposit ----------------
Expand All @@ -115,45 +120,54 @@ contract LiquidContinuousMultiTokenVaultTest is LiquidContinuousMultiTokenVaultT
}

function test__LiquidContinuousVaultTest__RedeemMultiPeriodsAllShares() public {
IMTVTestParams depositTestParams = new IMTVTestParams();
uint256 depositPeriods = 5;
TestParamSet.TestParam[] memory depositTestParams = new TestParamSet.TestParam[](depositPeriods);

// run in some deposits
uint256 baseDepositAmount = 100 * _scale;
for (uint256 i = 0; i <= 10; ++i) {
depositTestParams.add(
TestParam({ principal: (baseDepositAmount * i) + 1 * _scale, depositPeriod: i, redeemPeriod: 1000 })
);
for (uint256 i = 0; i < depositPeriods; ++i) {
depositTestParams[i] = TestParamSet.TestParam({
principal: (baseDepositAmount * i) + 1 * _scale,
depositPeriod: i,
redeemPeriod: 100
});
}

_testDepositOnly(alice, _liquidVault, depositTestParams);

// ------------ requestRedeem #1 -----------
uint256 redeemPeriod1 = 31;
IMTVTestParams redeemParams1 = _split(depositTestParams, 0, 2);
TestParamSet.TestParam[] memory redeemParams1 = depositTestParams._split(0, 2);
assertEq(3, redeemParams1.length, "array not split 1");

_testRequestRedeemMultiDeposit(alice, _liquidVault, redeemParams1, 31);

// ------------ requestRedeem #2 ------------
uint256 redeemPeriod2 = 41;
IMTVTestParams redeemParams2 = _split(depositTestParams, 3, 4);
TestParamSet.TestParam[] memory redeemParams2 = depositTestParams._split(3, 4);
assertEq(2, redeemParams2.length, "array not split 2");

_testRequestRedeemMultiDeposit(alice, _liquidVault, redeemParams2, 41);

// ------------ redeems ------------
// NB - call the redeem AFTER the multiple requestRedeems. verify multiple requestRedeems work.

_testRedeemMultiDeposit(alice, _liquidVault, redeemParams1, redeemPeriod1);

_testRedeemMultiDeposit(alice, _liquidVault, redeemParams2, redeemPeriod2);
}

function test__LiquidContinuousVaultTest__RedeemMultiPeriodsPartialShares() public {
IMTVTestParams depositTestParams = new IMTVTestParams();
uint256 depositPeriods = 5;
TestParamSet.TestParam[] memory depositTestParams = new TestParamSet.TestParam[](depositPeriods);

// run in some deposits
uint256 baseDepositAmount = 100 * _scale;
for (uint256 i = 0; i <= 10; ++i) {
depositTestParams.add(
TestParam({ principal: (baseDepositAmount * i) + 1 * _scale, depositPeriod: i, redeemPeriod: 1000 })
);
for (uint256 i = 0; i < depositPeriods; ++i) {
depositTestParams[i] = TestParamSet.TestParam({
principal: (baseDepositAmount * i) + 1 * _scale,
depositPeriod: i,
redeemPeriod: 1000
});
}

_testDepositOnly(alice, _liquidVault, depositTestParams);
Expand All @@ -163,17 +177,17 @@ contract LiquidContinuousMultiTokenVaultTest is LiquidContinuousMultiTokenVaultT
// ------------ requestRedeem #1 ------------
uint256 redeemPeriod1 = 30;

IMTVTestParams redeemParams1 = _split(depositTestParams, 0, 2);
redeemParams1.set(2, partialShares);
TestParamSet.TestParam[] memory redeemParams1 = depositTestParams._split(0, 2);
redeemParams1[2].principal = partialShares;

_testRequestRedeemMultiDeposit(alice, _liquidVault, redeemParams1, redeemPeriod1);

// ------------ requestRedeem #2 ------------
uint256 redeemPeriod2 = 50;

IMTVTestParams redeemParams2 = _split(depositTestParams, 2, 4);
redeemParams2.set(0, depositTestParams.get(2).principal - partialShares);
redeemParams2.set(2, partialShares);
TestParamSet.TestParam[] memory redeemParams2 = depositTestParams._split(2, 4);
redeemParams2[0].principal = (depositTestParams[2].principal - partialShares);
redeemParams2[2].principal = partialShares;

_testRequestRedeemMultiDeposit(alice, _liquidVault, redeemParams2, redeemPeriod2);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { RedeemOptimizerFIFO } from "@credbull/token/ERC1155/RedeemOptimizerFIFO
import { Timer } from "@credbull/timelock/Timer.sol";

import { LiquidContinuousMultiTokenVaultTestBase } from "@test/test/yield/LiquidContinuousMultiTokenVaultTestBase.t.sol";
import { TestParamSet } from "@test/test/token/ERC1155/TestParamSet.t.sol";

import { ERC1967Proxy } from "@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol";
import { IAccessControl } from "@openzeppelin/contracts/access/IAccessControl.sol";
Expand All @@ -33,7 +34,8 @@ contract LiquidContinuousMultiTokenVaultUtilTest is LiquidContinuousMultiTokenVa
uint256 scale = 10 ** asset.decimals();
_transferAndAssert(asset, _vaultAuth.owner, alice, 1_000_000_000 * scale);

TestParam memory testParams = TestParam({ principal: 2_000 * scale, depositPeriod: 11, redeemPeriod: 71 });
TestParamSet.TestParam memory testParams =
TestParamSet.TestParam({ principal: 2_000 * scale, depositPeriod: 11, redeemPeriod: 71 });

_warpToPeriod(vaultProxy, testParams.depositPeriod);

Expand Down Expand Up @@ -81,8 +83,11 @@ contract LiquidContinuousMultiTokenVaultUtilTest is LiquidContinuousMultiTokenVa
}

function test__LiquidContinuousMultiTokenVaultUtil__PauseDepositAndRedeem() public {
TestParam memory testParams =
TestParam({ principal: 100 * _scale, depositPeriod: 0, redeemPeriod: _liquidVault.minUnlockPeriod() });
TestParamSet.TestParam memory testParams = TestParamSet.TestParam({
principal: 100 * _scale,
depositPeriod: 0,
redeemPeriod: _liquidVault.minUnlockPeriod()
});

vm.prank(alice);
_asset.approve(address(_liquidVault), testParams.principal); // grant vault allowance on alice's principal
Expand Down
Loading

0 comments on commit 6b819be

Please sign in to comment.