Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: deconstruct SV data [sup-9184] #24

Merged
merged 10 commits into from
Nov 4, 2024
18 changes: 0 additions & 18 deletions src/ISuperVault.sol
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,6 @@ interface ISuperVault is IERC1155Receiver {
// STRUCTS //
//////////////////////////////////////////////////////////////

/// @notice Struct to hold SuperVault strategy data
struct SuperVaultStrategyData {
address vaultManager;
uint256 numberOfSuperforms;
uint256 depositLimit;
uint256[] superformIds;
uint256[] weights;
}

/// @notice Struct to hold rebalance arguments
/// @notice superformIdsRebalanceFrom must be an ordered array of superform IDs with no duplicates
/// @param superformIdsRebalanceFrom Array of superform IDs to rebalance from
Expand Down Expand Up @@ -147,15 +138,6 @@ interface ISuperVault is IERC1155Receiver {
/// @param vaultManager_ The new vault manager
function setVaultManager(address vaultManager_) external;

/// @notice Returns the SuperVault data
/// @return numberOfSuperforms The number of Superforms
/// @return superformIds Array of Superform IDs
/// @return weights Array of weights for each Superform
function getSuperVaultData()
external
view
returns (uint256 numberOfSuperforms, uint256[] memory superformIds, uint256[] memory weights);

/// @notice Returns whether a Superform ID is whitelisted
/// @param superformIds Array of Superform IDs
/// @return isWhitelisted Array of booleans indicating whether each Superform ID is whitelisted
Expand Down
15 changes: 0 additions & 15 deletions src/ISuperVaultFactory.sol
Original file line number Diff line number Diff line change
Expand Up @@ -64,21 +64,6 @@ interface ISuperVaultFactory {
/// @return Whether the SuperVault exists
function isSuperVault(address superVault_) external view returns (bool);

/// @notice Returns the data for a SuperVault
/// @param superVault_ Address of the SuperVault
/// @return numberOfSuperforms The number of Superforms
/// @return superformIds Array of Superform IDs
/// @return weights Array of weights for each Superform
function getSuperVaultData(address superVault_)
external
view
returns (uint256 numberOfSuperforms, uint256[] memory superformIds, uint256[] memory weights);

/// @notice Returns the Superform IDs for a SuperVault
/// @param superVault_ Address of the SuperVault
/// @return Array of Superform IDs
function getSuperformIds(address superVault_) external view returns (uint256[] memory);

/// @notice Returns all SuperVaults
/// @return Array of SuperVault addresses
//function getSuperVaults() external view returns (address[] memory);
Expand Down
67 changes: 34 additions & 33 deletions src/SuperVault.sol
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,9 @@ contract SuperVault is BaseStrategy, ISuperVault {
/// @notice The address of the SuperVault Strategist
address public strategist;

/// @notice The address of the SuperVault Vault Manager
address public vaultManager;

/// @notice The address of the SuperRegistry contract
ISuperRegistry public immutable superRegistry;

Expand All @@ -52,15 +55,24 @@ contract SuperVault is BaseStrategy, ISuperVault {
/// @notice The maximum allowed slippage (1% = 100)
uint256 public constant MAX_SLIPPAGE = 100;

/// @notice Struct containing SuperVault strategy data
SuperVaultStrategyData private SV;
/// @notice The number of Superforms in the vault
uint256 public numberOfSuperforms;

/// @notice The deposit limit for the vault
uint256 public depositLimit;

/// @notice Mapping to track whitelisted Superform IDs
mapping(uint256 => bool) public whitelistedSuperformIds;

/// @notice Array of whitelisted Superform IDs for easy access
uint256[] public whitelistedSuperformIdArray;

/// @notice Array of Superform IDs in the vault
uint256[] public superformIds;

/// @notice Array of weights for each Superform in the vault
uint256[] public weights;

//////////////////////////////////////////////////////////////
// MODIFIERS //
//////////////////////////////////////////////////////////////
Expand All @@ -75,7 +87,7 @@ contract SuperVault is BaseStrategy, ISuperVault {

/// @notice Ensures that only the Vault Manager can call the function
modifier onlyVaultManager() {
if (SV.vaultManager != msg.sender) {
if (vaultManager != msg.sender) {
revert NOT_VAULT_MANAGER();
}
_;
Expand Down Expand Up @@ -103,7 +115,7 @@ contract SuperVault is BaseStrategy, ISuperVault {
)
BaseStrategy(asset_, name_)
{
uint256 numberOfSuperforms = superformIds_.length;
numberOfSuperforms = superformIds_.length;

if (numberOfSuperforms == 0) {
revert ZERO_SUPERFORMS();
Expand Down Expand Up @@ -156,11 +168,10 @@ contract SuperVault is BaseStrategy, ISuperVault {
if (totalWeight != TOTAL_WEIGHT) revert INVALID_WEIGHTS();

strategist = strategist_;
SV.vaultManager = vaultManager_;
SV.numberOfSuperforms = numberOfSuperforms;
SV.superformIds = superformIds_;
SV.weights = startingWeights_;
SV.depositLimit = depositLimit_;
vaultManager = vaultManager_;
superformIds = superformIds_;
weights = startingWeights_;
depositLimit = depositLimit_;
}

//////////////////////////////////////////////////////////////
Expand All @@ -169,7 +180,7 @@ contract SuperVault is BaseStrategy, ISuperVault {

/// @inheritdoc ISuperVault
function setDepositLimit(uint256 depositLimit_) external override onlyVaultManager {
SV.depositLimit = depositLimit_;
depositLimit = depositLimit_;

emit DepositLimitSet(depositLimit_);
}
Expand Down Expand Up @@ -198,12 +209,11 @@ contract SuperVault is BaseStrategy, ISuperVault {

{
/// @dev caching to avoid multiple SLOADs
uint256 numberOfSuperforms = SV.numberOfSuperforms;
uint256 foundCount;

for (uint256 i; i < lenRebalanceFrom; ++i) {
for (uint256 j; j < numberOfSuperforms; ++j) {
if (rebalanceArgs.superformIdsRebalanceFrom[i] == SV.superformIds[j]) {
if (rebalanceArgs.superformIdsRebalanceFrom[i] == superformIds[j]) {
foundCount++;
break;
}
Expand Down Expand Up @@ -284,7 +294,7 @@ contract SuperVault is BaseStrategy, ISuperVault {
/// @inheritdoc ISuperVault
function setVaultManager(address vaultManager_) external override onlyManagement {
if (vaultManager_ == address(0)) revert ZERO_ADDRESS();
SV.vaultManager = vaultManager_;
vaultManager = vaultManager_;

emit VaultManagerSet(vaultManager_);
}
Expand All @@ -293,15 +303,6 @@ contract SuperVault is BaseStrategy, ISuperVault {
// EXTERNAL VIEW/PURE FUNCTIONS //
//////////////////////////////////////////////////////////////

/// @inheritdoc ISuperVault
function getSuperVaultData()
external
view
returns (uint256 numberOfSuperforms, uint256[] memory superformIds, uint256[] memory weights)
{
return (SV.numberOfSuperforms, SV.superformIds, SV.weights);
}

/// @inheritdoc ISuperVault
function getIsWhitelisted(uint256[] memory superformIds) external view returns (bool[] memory isWhitelisted) {
uint256 length = superformIds.length;
Expand Down Expand Up @@ -361,7 +362,7 @@ contract SuperVault is BaseStrategy, ISuperVault {
/// @inheritdoc BaseStrategy
function availableDepositLimit(address /*_owner*/ ) public view override returns (uint256) {
uint256 totalAssets = TokenizedStrategy.totalAssets();
uint256 depositLimit = SV.depositLimit;
uint256 depositLimit = depositLimit;
return totalAssets >= depositLimit ? 0 : depositLimit - totalAssets;
}

Expand Down Expand Up @@ -412,8 +413,8 @@ contract SuperVault is BaseStrategy, ISuperVault {
/// @return totalAssets The total assets of the vault
function _harvestAndReport() internal view override returns (uint256 totalAssets) {
uint256 totalAssetsInVaults;
uint256 numberOfSuperforms = SV.numberOfSuperforms;
uint256[] memory superformIds = SV.superformIds;
uint256 numberOfSuperforms = numberOfSuperforms;
uint256[] memory superformIds = superformIds;

address superPositions = _getAddress(keccak256("SUPER_POSITIONS"));

Expand Down Expand Up @@ -444,9 +445,9 @@ contract SuperVault is BaseStrategy, ISuperVault {
view
returns (MultiVaultSFData memory mvData)
{
uint256 numberOfSuperforms = SV.numberOfSuperforms;
uint256 numberOfSuperforms = numberOfSuperforms;

mvData.superformIds = SV.superformIds;
mvData.superformIds = superformIds;
mvData.amounts = new uint256[](numberOfSuperforms);
mvData.maxSlippages = new uint256[](numberOfSuperforms);
mvData.liqRequests = new LiqRequest[](numberOfSuperforms);
Expand All @@ -468,11 +469,11 @@ contract SuperVault is BaseStrategy, ISuperVault {

if (isDeposit) {
/// @notice rounding down to avoid one-off issue
mvData.amounts[i] = amount_.mulDiv(SV.weights[i], TOTAL_WEIGHT, Math.Rounding.Down);
mvData.amounts[i] = amount_.mulDiv(weights[i], TOTAL_WEIGHT, Math.Rounding.Down);
mvData.outputAmounts[i] = superformContract.previewDepositTo(mvData.amounts[i]);
} else {
/// @dev assets
mvData.outputAmounts[i] = amount_.mulDiv(SV.weights[i], TOTAL_WEIGHT, Math.Rounding.Down);
mvData.outputAmounts[i] = amount_.mulDiv(weights[i], TOTAL_WEIGHT, Math.Rounding.Down);
/// @dev shares - in 4626Form this uses convertToShares in 5115Form this uses previewDeposit
mvData.amounts[i] = superformContract.previewDepositTo(mvData.outputAmounts[i]);
}
Expand Down Expand Up @@ -683,10 +684,10 @@ contract SuperVault is BaseStrategy, ISuperVault {
/// @notice assign remaining weight to the last index
newWeights[length - 1] = TOTAL_WEIGHT - totalAssignedWeight;

/// @dev update SV weights
SV.weights = newWeights;
SV.superformIds = finalSuperformIds;
SV.numberOfSuperforms = length;
/// @dev update SV data
weights = newWeights;
superformIds = finalSuperformIds;
numberOfSuperforms = length;

emit RebalanceComplete(finalSuperformIds, newWeights);
}
Expand Down
14 changes: 0 additions & 14 deletions src/SuperVaultFactory.sol
Original file line number Diff line number Diff line change
Expand Up @@ -137,20 +137,6 @@ contract SuperVaultFactory is ISuperVaultFactory, AccessControl {
return registeredSuperVaults[superVault_];
}

function getSuperVaultData(address superVault_)
external
view
returns (uint256 numberOfSuperforms, uint256[] memory superformIds, uint256[] memory weights)
{
return ISuperVault(superVault_).getSuperVaultData();
}

/// @inheritdoc ISuperVaultFactory
function getSuperformIds(address superVault_) external view returns (uint256[] memory) {
(, uint256[] memory superformIds,) = ISuperVault(superVault_).getSuperVaultData();
return superformIds;
}

/// @inheritdoc ISuperVaultFactory
function getSuperVaultCount() external view returns (uint256) {
return superVaults.length;
Expand Down
5 changes: 4 additions & 1 deletion test/SuperVault.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -1200,7 +1200,10 @@ contract SuperVaultTest is ProtocolActions {
(address superFormSuperVault,,) = SUPER_VAULT_ID1.getSuperform();
address superVaultAddress = IBaseForm(superFormSuperVault).getVaultAddress();
uint256[] memory svDataWeights = new uint256[](underlyingSuperformIds.length);
(,, svDataWeights) = SuperVault(superVaultAddress).getSuperVaultData();
SuperVault vault = SuperVault(superVaultAddress);
for (uint256 i; i < underlyingSuperformIds.length; i++) {
svDataWeights[i] = vault.weights(i);
}
uint256[] memory underlyingIndexes = _calculateUnderlyingIndexes();
uint256[] memory calculatedWeights = _calculateRealWeights(superVaultAddress, underlyingIndexes);

Expand Down
40 changes: 0 additions & 40 deletions test/SuperVaultFactory.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -150,46 +150,6 @@ contract SuperVaultFactoryTest is ProtocolActions {
vm.stopPrank();
}

function test_getSuperVaultData() public {
vm.prank(deployer);
address superVaultTest = factory.createSuperVault(
getContract(ETH, "USDC"),
deployer,
deployer,
"USDCSuperVaultMorphoEulerAave",
type(uint256).max,
underlyingSuperformIds,
weights
);
(uint256 numberOfSuperforms, uint256[] memory superformIds, uint256[] memory weightsReceived) =
factory.getSuperVaultData(address(superVaultTest));
assertEq(numberOfSuperforms, underlyingSuperformIds.length);
assertEq(superformIds.length, underlyingSuperformIds.length);
assertEq(weightsReceived.length, underlyingSuperformIds.length);
for (uint256 i = 0; i < underlyingSuperformIds.length; i++) {
assertEq(superformIds[i], underlyingSuperformIds[i]);
assertEq(weightsReceived[i], weights[i]);
}
}

function test_getSuperformIds() public {
vm.prank(deployer);
address superVaultTest = factory.createSuperVault(
getContract(ETH, "USDC"),
deployer,
deployer,
"USDCSuperVaultMorphoEulerAave",
type(uint256).max,
underlyingSuperformIds,
weights
);
uint256[] memory superformIds = factory.getSuperformIds(address(superVaultTest));
assertEq(superformIds.length, underlyingSuperformIds.length);
for (uint256 i = 0; i < underlyingSuperformIds.length; i++) {
assertEq(superformIds[i], underlyingSuperformIds[i]);
}
}

function test_getSuperVaultCount() public {
vm.startPrank(deployer);
factory.createSuperVault(
Expand Down