Skip to content

Commit

Permalink
Update Liquid Deploy and Load script to load data around cut-off times
Browse files Browse the repository at this point in the history
  • Loading branch information
lucasia committed Oct 18, 2024
1 parent 09e8e34 commit 95bb311
Show file tree
Hide file tree
Showing 7 changed files with 74 additions and 19 deletions.
2 changes: 2 additions & 0 deletions packages/contracts/resource/local.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ asset_manager = "0x976EA74026E726554dB657fA54763abd0C3a0aa9"
full_rate_bps = 10_00
# rate in basis points, e.g. 5.5% = 550 bps
reduced_rate_bps = 5_50
# January 1, 2024 2:00:00 PM UTC = 1704117600
vault_start_timestamp = 1704117600

[evm.contracts.upside_vault]
# 2 decimal place percentage (meaining value divided by 100) as integer.
Expand Down
17 changes: 11 additions & 6 deletions packages/contracts/script/DeployLiquidMultiTokenVault.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,10 @@ contract DeployLiquidMultiTokenVault is TomlConfig {
using stdToml for string;

string private _tomlConfig;
LiquidContinuousMultiTokenVault.VaultAuth public _vaultAuth;
LiquidContinuousMultiTokenVault.VaultAuth internal _vaultAuth;

uint256 public constant NOTICE_PERIOD = 1;
string public constant CONTRACT_TOML_KEY = ".evm.contracts.liquid_continuous_multi_token_vault";

constructor() {
_tomlConfig = loadTomlConfiguration();
Expand Down Expand Up @@ -103,11 +104,9 @@ contract DeployLiquidMultiTokenVault is TomlConfig {
IYieldStrategy yieldStrategy,
IRedeemOptimizer redeemOptimizer
) public view returns (LiquidContinuousMultiTokenVault.VaultParams memory vaultParams_) {
string memory contractKey = ".evm.contracts.liquid_continuous_multi_token_vault";
uint256 fullRateBasisPoints = _tomlConfig.readUint(string.concat(contractKey, ".full_rate_bps"));
uint256 reducedRateBasisPoints = _tomlConfig.readUint(string.concat(contractKey, ".reduced_rate_bps"));
uint256 startTimestamp =
_readUintWithDefault(_tomlConfig, string.concat(contractKey, ".vault_start_timestamp"), block.timestamp);
uint256 fullRateBasisPoints = _tomlConfig.readUint(string.concat(CONTRACT_TOML_KEY, ".full_rate_bps"));
uint256 reducedRateBasisPoints = _tomlConfig.readUint(string.concat(CONTRACT_TOML_KEY, ".reduced_rate_bps"));
uint256 startTimestamp = _startTimestamp();

uint256 scale = 10 ** asset.decimals();

Expand Down Expand Up @@ -135,6 +134,12 @@ contract DeployLiquidMultiTokenVault is TomlConfig {
return vaultParams;
}

function _startTimestamp() internal view virtual returns (uint256 startTimestamp_) {
return _readUintWithDefault(
_tomlConfig, string.concat(CONTRACT_TOML_KEY, ".vault_start_timestamp"), block.timestamp
);
}

function _usdcOrDeployMock(address contractOwner) internal returns (IERC20Metadata asset) {
bool shouldDeployMocks = _readBoolWithDefault(_tomlConfig, ".evm.deploy_mocks", false);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import { IAccessControl } from "@openzeppelin/contracts/access/IAccessControl.so
import { IERC20Metadata } from "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol";
import { PausableUpgradeable } from "@openzeppelin/contracts-upgradeable/utils/PausableUpgradeable.sol";

// Tets relation to the Utility / operational aspects of the LiquidContinuousMultiTokenVault
// Tests related to the Utility / operational aspects of the LiquidContinuousMultiTokenVault
contract LiquidContinuousMultiTokenVaultUtilTest is LiquidContinuousMultiTokenVaultTestBase {
function test__LiquidContinuousMultiTokenVaultUtil__Upgradeability() public {
LiquidContinuousMultiTokenVaultMock vaultImpl = new LiquidContinuousMultiTokenVaultMock();
Expand Down Expand Up @@ -212,14 +212,13 @@ contract LiquidContinuousMultiTokenVaultUtilTest is LiquidContinuousMultiTokenVa
_setPeriodAndAssert(_liquidVault, 10);
}

// vm.startPrank(_vaultAuth.operator);
function _setPeriodAndAssert(LiquidContinuousMultiTokenVault vault, uint256 newPeriod) internal {
assertTrue(
Timer.timestamp() >= (vault._vaultStartTimestamp() - newPeriod * 24 hours),
"trying to set period before block.timestamp"
);

_setPeriod(vault, newPeriod);
_setPeriod(_vaultAuth.operator, vault, newPeriod);

assertEq(newPeriod, (block.timestamp - vault._vaultStartTimestamp()) / 24 hours, "timestamp not set correctly");
assertEq(newPeriod, vault.currentPeriod(), "period not set correctly");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,17 +60,18 @@ contract DeployAndLoadLiquidMultiTokenVault is DeployLiquidMultiTokenVault {
}

// --------------------- load deposits ---------------------
_loadDepositsAndRequestSells(vault, _alice, 10);
_loadDepositsAndRequestSells(vault, _bob, 1);
_loadDepositsAndRequestSells(vault, _charlie, 2);
_loadDepositsAndRequestSells(vault, _alice, 10, 0);
_loadDepositsAndRequestSells(vault, _bob, 1, 1);
_loadDepositsAndRequestSells(vault, _charlie, 2, -1);

return vault;
}

function _loadDepositsAndRequestSells(
LiquidContinuousMultiTokenVault vault,
AnvilWallet userWallet,
uint256 userDepositMultiplier
uint256 userDepositMultiplier,
int256 userOffsetInSeconds // exercise deposits/redeems around cut-off times
) internal {
IERC20 asset = IERC20(vault.asset());
uint256 scale = 10 ** IERC20Metadata(vault.asset()).decimals();
Expand All @@ -92,7 +93,7 @@ contract DeployAndLoadLiquidMultiTokenVault is DeployLiquidMultiTokenVault {

for (uint256 depositPeriod = 0; depositPeriod <= vault.TENOR(); ++depositPeriod) {
// first set the start time / period as operator
_setPeriod(vault, depositPeriod);
_setPeriod(vault, depositPeriod, userOffsetInSeconds);

if (depositPeriod % 7 == 0) {
// skip deposits every 7th day
Expand All @@ -119,9 +120,19 @@ contract DeployAndLoadLiquidMultiTokenVault is DeployLiquidMultiTokenVault {
console2.log("VaultSupply after deposits %s -> %s", prevSupply, vault.totalSupply());
}

function _setPeriod(LiquidContinuousMultiTokenVault vault, uint256 newPeriod) public {
function _setPeriod(LiquidContinuousMultiTokenVault vault, uint256 newPeriod, int256 offsetInSeconds) public {
uint256 prevPeriod = vault.currentPeriod();

uint256 newPeriodInSeconds = newPeriod * 1 days;

// add (or subtract) an offset number of seconds from the newPeriod
if (offsetInSeconds >= 0) {
newPeriodInSeconds += uint256(offsetInSeconds);
} else {
// if newPeriod is 0 and offset is negative, just stay at 0
newPeriodInSeconds -= newPeriod == 0 ? 0 : uint256(int256(-offsetInSeconds));
}

uint256 currentTime = Timer.timestamp();

uint256 newStartTime =
Expand All @@ -133,6 +144,14 @@ contract DeployAndLoadLiquidMultiTokenVault is DeployLiquidMultiTokenVault {

console2.log("VaultCurrentPeriod updated %s -> %s", prevPeriod, vault.currentPeriod());
}

function startTimestamp() public view virtual returns (uint256 startTimestamp_) {
return _startTimestamp();
}

function auth() public view virtual returns (LiquidContinuousMultiTokenVault.VaultAuth memory auth_) {
return _vaultAuth;
}
}

//Anvil Accounts
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;

import { LiquidContinuousMultiTokenVault } from "@credbull/yield/LiquidContinuousMultiTokenVault.sol";
import { LiquidContinuousMultiTokenVaultTestBase } from "@test/test/yield/LiquidContinuousMultiTokenVaultTestBase.t.sol";
import { DeployAndLoadLiquidMultiTokenVault } from "./DeployAndLoadLiquidMultiTokenVault.s.sol";

contract DeployAndLoadLiquidMultiTokenVaultTest is LiquidContinuousMultiTokenVaultTestBase {
DeployAndLoadLiquidMultiTokenVault internal _deployVault;

function setUp() public override {
_deployVault = new DeployAndLoadLiquidMultiTokenVault();

uint256 vaultStartTimestamp = _deployVault.startTimestamp();
vm.warp(vaultStartTimestamp); // warp to a "real time" time rather than block.timestamp=1

_liquidVault = _deployVault.run();
}

/// @dev - this SHOULD work, but will have knock-off effects to yield/returns and pending requests
function test__DeployAndLoadLiquidMultiTokenVaultTest__VerifyCutoffs() public {
LiquidContinuousMultiTokenVault.VaultAuth memory vaultAuth = _deployVault.auth();

_setPeriod(vaultAuth.operator, _liquidVault, 0);
_setPeriod(vaultAuth.operator, _liquidVault, 30);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ library TestParamSet {
}

// Calculate the total principal across all TestParams
function latestRedeemPeriod(TestParam[] memory self) internal pure returns (uint256 latestRedeemPeriod) {
function latestRedeemPeriod(TestParam[] memory self) internal pure returns (uint256 latestRedeemPeriod_) {
uint256 _latestRedeemPeriod = 0;
for (uint256 i = 0; i < self.length; i++) {
uint256 redeemPeriod = self[i].redeemPeriod;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,13 @@ abstract contract LiquidContinuousMultiTokenVaultTestBase is IMultiTokenVaultTes
address internal alice = makeAddr("alice");
address internal bob = makeAddr("bob");

function setUp() public {
function setUp() public virtual {
DeployLiquidMultiTokenVault _deployVault = new DeployLiquidMultiTokenVault();
_liquidVault = _deployVault.run(_vaultAuth);

// warp to a "real time" time rather than block.timestamp=1
vm.warp(_liquidVault._vaultStartTimestamp() + 1);

_asset = IERC20Metadata(_liquidVault.asset());
_scale = 10 ** _asset.decimals();

Expand Down Expand Up @@ -224,14 +227,14 @@ abstract contract LiquidContinuousMultiTokenVaultTestBase is IMultiTokenVaultTes
vm.warp(warpToTimeInSeconds);
}

function _setPeriod(LiquidContinuousMultiTokenVault vault, uint256 newPeriod) public {
function _setPeriod(address operator, LiquidContinuousMultiTokenVault vault, uint256 newPeriod) public {
uint256 newPeriodInSeconds = newPeriod * 1 days;
uint256 currentTime = Timer.timestamp();

uint256 newStartTime =
currentTime > newPeriodInSeconds ? (currentTime - newPeriodInSeconds) : (newPeriodInSeconds - currentTime);

vm.prank(_vaultAuth.operator);
vm.prank(operator);
vault.setVaultStartTimestamp(newStartTime);
}

Expand Down

0 comments on commit 95bb311

Please sign in to comment.