Skip to content

Commit

Permalink
Refactor Liquid requestRedeem twice test
Browse files Browse the repository at this point in the history
  • Loading branch information
lucasia committed Oct 16, 2024
1 parent 0fce2da commit 82cb18e
Show file tree
Hide file tree
Showing 5 changed files with 74 additions and 64 deletions.
4 changes: 2 additions & 2 deletions packages/contracts/src/token/ERC1155/RedeemOptimizerFIFO.sol
Original file line number Diff line number Diff line change
Expand Up @@ -118,8 +118,8 @@ contract RedeemOptimizerFIFO is IRedeemOptimizer {
if (amountAtPeriod > 0) {
cacheDepositPeriods[arrayIndex] = depositPeriod;

// check if we will go "over" the Amount To Find.
if (amountFound + amountAtPeriod > optimizerParams.amountToFind) {
// check if we found the amount to find
if (amountFound + amountAtPeriod >= optimizerParams.amountToFind) {
uint256 amountToInclude = optimizerParams.amountToFind - amountFound; // we only need the amount that brings us to amountToFind

// only include equivalent amount of shares for the amountToInclude assets
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -114,70 +114,24 @@ contract LiquidContinuousMultiTokenVaultTest is LiquidContinuousMultiTokenVaultT
assertEq(assetManagerStartBalance + vaultStartBalance, _asset.balanceOf(assetManager));
}

function test__LiquidContinuousVaultTest__RequestRedeemTwice() public {
uint256 redeemPeriod = 32;
uint256 requestRedeemPeriod = redeemPeriod - _liquidVault.noticePeriod();
function test__LiquidContinuousVaultTest__RequestRedeemTwiceMultipleDepositsFullShares() public {
IMTVTestParamArray testParams = new IMTVTestParamArray();

IMTVTestParamArray testParamsArray = new IMTVTestParamArray();
testParamsArray.addTestParam(
TestParam({ principal: 101 * _scale, depositPeriod: 1, redeemPeriod: redeemPeriod })
);
testParamsArray.addTestParam(
TestParam({ principal: 202 * _scale, depositPeriod: 2, redeemPeriod: redeemPeriod })
);
testParamsArray.addTestParam(
TestParam({ principal: 303 * _scale, depositPeriod: 3, redeemPeriod: redeemPeriod })
);
testParamsArray.addTestParam(
TestParam({ principal: 404 * _scale, depositPeriod: 4, redeemPeriod: redeemPeriod })
);

_testDepositOnly(alice, _liquidVault, testParamsArray.all());
// run in some deposits
uint256 baseDepositAmount = 100 * _scale;
for (uint256 i = 0; i <= 10; ++i) {
testParams.addTestParam(
TestParam({ principal: (baseDepositAmount * i) + 1 * _scale, depositPeriod: i, redeemPeriod: 1000 })
);
}

// warp to the request redeem period
_warpToPeriod(_liquidVault, requestRedeemPeriod);
_testDepositOnly(alice, _liquidVault, testParams.all());

// ------------ requestRedeem #1 ------------
uint256 oneShare = 1 * _scale; // a little over the first deposit shares
uint256 sharesToRedeem1 = testParamsArray.get(0).principal + oneShare; // a little over the first deposit shares
vm.prank(alice);
// uint256 requestId1 = _liquidVault.requestSell(sharesToRedeem1);
uint256 requestId1 = _liquidVault.requestRedeem(sharesToRedeem1, alice, alice);
(uint256[] memory unlockDepositPeriods1, uint256[] memory unlockShares1) =
_liquidVault.unlockRequests(alice, requestId1);

assertEq(2, unlockDepositPeriods1.length, "unlock request1 depositPeriods incorrect");
assertEq(
testParamsArray.get(0).depositPeriod, unlockDepositPeriods1[0], "wrong unlock request1 deposit period - 0"
);
assertEq(testParamsArray.get(0).principal, unlockShares1[0], "wrong unlock request1 shares - 0");

assertEq(
testParamsArray.get(1).depositPeriod, unlockDepositPeriods1[1], "wrong unlock request1 deposit period - 1"
);
assertEq(oneShare, unlockShares1[1], "wrong unlock request1 shares - 1");
_testRequestRedeem(alice, _liquidVault, _split(testParams, 0, 1), 31);

// ------------ requestRedeem #2 ------------

uint256 sharesToRedeem2 = testParamsArray.get(1).principal; // a little over the second deposit shares
vm.prank(alice);
uint256 requestId2 = _liquidVault.requestRedeem(sharesToRedeem2, alice, alice);
(uint256[] memory unlockDepositPeriods2, uint256[] memory unlockShares2) =
_liquidVault.unlockRequests(alice, requestId2);

assertEq(3, unlockDepositPeriods2.length, "unlock request2 depositPeriods incorrect");
assertEq(
testParamsArray.get(0).depositPeriod, unlockDepositPeriods2[0], "wrong unlock request2 deposit period - 0"
);
assertEq(testParamsArray.get(0).principal, unlockShares2[0], "wrong unlock request2 shares - 0");
assertEq(
testParamsArray.get(1).depositPeriod, unlockDepositPeriods2[1], "wrong unlock request2 deposit period - 1"
);
assertEq(testParamsArray.get(1).principal, unlockShares2[1], "wrong unlock request2 shares - 1");
assertEq(
testParamsArray.get(2).depositPeriod, unlockDepositPeriods2[2], "wrong unlock request2 deposit period - 2"
);
assertEq(oneShare, unlockShares2[2], "wrong unlock request2 shares - 2");
_testRequestRedeem(alice, _liquidVault, _split(testParams, 2, 3), 41);
}

function test__LiquidContinuousVaultTest__ShouldRevertWithdrawAssetIfNotOwner() public {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,14 +42,36 @@ contract IMTVTestParamArray {
return _allTestParams;
}

function depositPeriods() public view returns (uint256[] memory depositPeriods_) {
uint256[] memory _depositPeriods = new uint256[](_allTestParams.length);

function totalPrincipal() public view returns (uint256 totalPrincipal_) {
uint256 principal = 0;
for (uint256 i = 0; i < _allTestParams.length; i++) {
principal += _allTestParams[i].principal;
}
return principal;
}

function deposits() public view returns (uint256[] memory depositPeriods_, uint256[] memory principals_) {
uint256 length_ = _allTestParams.length;

uint256[] memory _depositPeriods = new uint256[](length_);
uint256[] memory _principals = new uint256[](length_);

for (uint256 i = 0; i < length_; i++) {
_depositPeriods[i] = _allTestParams[i].depositPeriod;
_principals[i] = _allTestParams[i].principal;
}

return _depositPeriods;
return (_depositPeriods, _principals);
}

function depositPeriods() public view returns (uint256[] memory depositPeriods_) {
(depositPeriods_,) = deposits();
return depositPeriods_;
}

function principals() public view returns (uint256[] memory principals_) {
(, principals_) = deposits();
return principals_;
}

function createAccountArray(address account, uint256 size) public pure returns (address[] memory accounts_) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -295,6 +295,17 @@ abstract contract IMultiTokenVaultTestBase is Test {
return TestParam({ principal: principal, depositPeriod: depositPeriod, redeemPeriod: redeemPeriod });
}

function _split(IMTVTestParamArray origTestParams, uint256 from, uint256 to)
public
returns (IMTVTestParamArray newTestParams_)
{
IMTVTestParamArray newTestParams = new IMTVTestParamArray();
for (uint256 i = from; i <= to; i++) {
newTestParams.addTestParam(origTestParams.get(i));
}
return newTestParams;
}

/// @dev - creates a message string for assertions
function _assertMsg(string memory prefix, IMultiTokenVault vault, uint256 numPeriods)
internal
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { Timer } from "@credbull/timelock/Timer.sol";
import { DeployLiquidMultiTokenVault } from "@script/DeployLiquidMultiTokenVault.s.sol";
import { IMultiTokenVaultTestBase } from "@test/test/token/ERC1155/IMultiTokenVaultTestBase.t.sol";
import { SimpleUSDC } from "@test/test/token/SimpleUSDC.t.sol";
import { IMTVTestParamArray } from "@test/test/token/ERC1155/IMTVTestParamArray.t.sol";

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

Expand Down Expand Up @@ -122,6 +123,28 @@ abstract contract LiquidContinuousMultiTokenVaultTestBase is IMultiTokenVaultTes
return actualAssetsAtPeriod;
}

/// @dev - requestRedeem over multiple deposit and principals into one requestRedeemPeriod
function _testRequestRedeem(
address account,
LiquidContinuousMultiTokenVault liquidVault,
IMTVTestParamArray testParams,
uint256 requestRedeemPeriod // we are testing multiple deposits into one redeemPeriod
) internal virtual {
_warpToPeriod(_liquidVault, requestRedeemPeriod);

uint256 sharesToRedeem = testParams.totalPrincipal();

vm.prank(account);
uint256 requestId = liquidVault.requestRedeem(sharesToRedeem, account, account);
(uint256[] memory unlockDepositPeriods, uint256[] memory unlockShares) =
liquidVault.unlockRequests(account, requestId);

(uint256[] memory expectedDepositPeriods, uint256[] memory expectedShares) = testParams.deposits();

assertEq(expectedDepositPeriods, unlockDepositPeriods, "deposit periods mismatch for requestRedeem");
assertEq(expectedShares, unlockShares, "shares mismatch for requestRedeem");
}

function _expectedReturns(uint256, /* shares */ IMultiTokenVault vault, TestParam memory testParam)
internal
view
Expand Down

0 comments on commit 82cb18e

Please sign in to comment.