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

fix: actions #60

Open
wants to merge 15 commits into
base: master
Choose a base branch
from
Prev Previous commit
Next Next commit
chore: add latest vault
Schlagonia committed Oct 11, 2024
commit 9d8fe4a1fed4d5814b694e1355a64a68c06e2b6a
41 changes: 41 additions & 0 deletions src/managers/RoleManager.sol
Original file line number Diff line number Diff line change
@@ -6,8 +6,10 @@ import {Registry} from "../registry/Registry.sol";
import {Accountant} from "../accountants/Accountant.sol";
import {Roles} from "@yearn-vaults/interfaces/Roles.sol";
import {IVault} from "@yearn-vaults/interfaces/IVault.sol";
import {ReleaseRegistry} from "../registry/ReleaseRegistry.sol";
import {Strings} from "@openzeppelin/contracts/utils/Strings.sol";
import {ERC20} from "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import {IVaultFactory} from "@yearn-vaults/interfaces/IVaultFactory.sol";
import {DebtAllocatorFactory} from "../debtAllocators/DebtAllocatorFactory.sol";

/// @title Yearn V3 Vault Role Manager.
@@ -83,6 +85,7 @@ contract RoleManager is Positions {

/// @notice Mapping of vault addresses to its config.
mapping(address => VaultConfig) public vaultConfig;

/// @notice Mapping of underlying asset, api version and category to vault.
mapping(address => mapping(string => mapping(uint256 => address)))
internal _assetToVault;
@@ -650,6 +653,44 @@ contract RoleManager is Positions {
return _assetToVault[_asset][_apiVersion][_category];
}

/**
* @notice Get the latest vault for a specific asset.
* @dev This will default to using category 1.
* @param _asset The underlying asset used.
* @return _vault latest vault for the specified `_asset` if any.
*/
function latestVault(
address _asset
) external view virtual returns (address) {
return latestVault(_asset, 1);
}

/**
* @notice Get the latest vault for a specific asset.
* @param _asset The underlying asset used.
* @param _category The category of the vault.
* @return _vault latest vault for the specified `_asset` if any.
*/
function latestVault(
address _asset,
uint256 _category
) public view virtual returns (address _vault) {
address releaseRegistry = Registry(getPositionHolder(REGISTRY))
.releaseRegistry();
uint256 numReleases = ReleaseRegistry(releaseRegistry).numReleases();

for (uint256 i = numReleases; i > 0; --i) {
string memory apiVersion = IVaultFactory(
ReleaseRegistry(releaseRegistry).factories(i - 1)
).apiVersion();

_vault = _assetToVault[_asset][apiVersion][_category];
if (_vault != address(0)) {
break;
}
}
}

/**
* @notice Check if a vault is managed by this contract.
* @dev This will check if the `asset` variable in the struct has been
13 changes: 13 additions & 0 deletions src/registry/Registry.sol
Original file line number Diff line number Diff line change
@@ -105,6 +105,9 @@ contract Registry is Governance {
// Custom name for this Registry.
string public name;

// A previous registry to fallback to as well.
address public legacyRegistry;

// Mapping for any address that is allowed to tag a vault.
mapping(address => bool) public taggers;

@@ -533,4 +536,14 @@ contract Registry is Governance {

emit UpdateTagger(_account, _canTag);
}

/**
* @notice Set a legacy registry to fallback to.
* @param _legacyRegistry The address of the legacy registry.
*/
function setLegacyRegistry(
address _legacyRegistry
) external virtual onlyGovernance {
legacyRegistry = _legacyRegistry;
}
}
51 changes: 51 additions & 0 deletions src/test/managers/TestRoleManager.t.sol
Original file line number Diff line number Diff line change
@@ -2,6 +2,7 @@
pragma solidity ^0.8.18;

import "forge-std/console2.sol";
import {MockFactory} from "../../mocks/MockFactory.sol";
import {Setup, RoleManager, IVault, Roles, MockStrategy, DebtAllocator} from "../utils/Setup.sol";

contract TestRoleManager is Setup {
@@ -1156,4 +1157,54 @@ contract TestRoleManager is Setup {

assertEq(newVault.role_manager(), daddy);
}

function test_latestVault() public {
// Deploy multiple vaults with different API versions
vm.prank(daddy);
address vault1 = roleManager.newVault(
address(asset),
1,
"Vault1",
"V1"
);

assertEq(roleManager.latestVault(address(asset)), vault1);

vm.prank(daddy);
address vault2 = roleManager.newVault(
address(asset),
2,
"Vault2",
"V2"
);

assertEq(roleManager.latestVault(address(asset)), vault1);
assertEq(roleManager.latestVault(address(asset), 2), vault2);

MockFactory newFactory = new MockFactory("1.0.0");
MockStrategy newStrategy = new MockStrategy(address(asset), "1.0.0");

vm.prank(daddy);
address vault4 = roleManager.newVault(
address(newStrategy),
1,
"Vault4",
"V2"
);

assertEq(roleManager.latestVault(address(asset)), vault1);
assertEq(roleManager.latestVault(address(asset), 2), vault2);
assertEq(roleManager.latestVault(address(newStrategy)), vault4);
// Check for a non-existent asset
assertEq(roleManager.latestVault(address(0x123)), address(0));

releaseRegistry.newRelease(address(newFactory), address(newStrategy));

assertEq(roleManager.latestVault(address(asset)), vault1);
assertEq(roleManager.latestVault(address(asset), 2), vault2);
// Check that the latest vault is still vault3
assertEq(roleManager.latestVault(address(newStrategy)), vault4);
// Check for a non-existent asset
assertEq(roleManager.latestVault(address(0x123)), address(0));
}
}