Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions snapshots/Hub.Operations.json
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
{
"add": "88006",
"add: with transfer": "109613",
"add: with transfer": "109616",
"draw": "105931",
"eliminateDeficit: full": "59781",
"eliminateDeficit: partial": "69429",
"eliminateDeficit: full": "73573",
"eliminateDeficit: partial": "83221",
"mintFeeShares": "84007",
"payFee": "72302",
"refreshPremium": "71999",
Expand Down
2 changes: 1 addition & 1 deletion src/hub/Hub.sol
Original file line number Diff line number Diff line change
Expand Up @@ -352,7 +352,7 @@ contract Hub is IHub, AccessManaged {
uint256 assetId,
uint256 amount,
address spoke
) external returns (uint256) {
) external restricted returns (uint256) {
Asset storage asset = _assets[assetId];
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

check asset is registered

SpokeData storage callerSpoke = _spokes[assetId][msg.sender];
SpokeData storage coveredSpoke = _spokes[assetId][spoke];
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

check coveredSpoke is registered

Expand Down
1 change: 1 addition & 0 deletions src/libraries/types/Roles.sol
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,5 @@ library Roles {
uint64 public constant HUB_ADMIN_ROLE = 1;
uint64 public constant SPOKE_ADMIN_ROLE = 2;
uint64 public constant USER_POSITION_UPDATER_ROLE = 3;
uint64 public constant HUB_UMBRELLA_ROLE = 4;
}
10 changes: 10 additions & 0 deletions tests/Base.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,7 @@ abstract contract Base is Test {
address internal HUB_ADMIN = makeAddr('HUB_ADMIN');
address internal SPOKE_ADMIN = makeAddr('SPOKE_ADMIN');
address internal USER_POSITION_UPDATER = makeAddr('USER_POSITION_UPDATER');
address internal HUB_UMBRELLA = makeAddr('HUB_UMBRELLA');
address internal TREASURY_ADMIN = makeAddr('TREASURY_ADMIN');
address internal LIQUIDATOR = makeAddr('LIQUIDATOR');
address internal POSITION_MANAGER = makeAddr('POSITION_MANAGER');
Expand Down Expand Up @@ -303,6 +304,9 @@ abstract contract Base is Test {
manager.grantRole(Roles.USER_POSITION_UPDATER_ROLE, SPOKE_ADMIN, 0);
manager.grantRole(Roles.USER_POSITION_UPDATER_ROLE, USER_POSITION_UPDATER, 0);

manager.grantRole(Roles.HUB_UMBRELLA_ROLE, HUB_ADMIN, 0);
manager.grantRole(Roles.HUB_UMBRELLA_ROLE, HUB_UMBRELLA, 0);

// Grant responsibilities to roles
{
bytes4[] memory selectors = new bytes4[](7);
Expand Down Expand Up @@ -333,6 +337,12 @@ abstract contract Base is Test {
selectors[5] = IHub.mintFeeShares.selector;
manager.setTargetFunctionRole(address(targetHub), selectors, Roles.HUB_ADMIN_ROLE);
}

{
bytes4[] memory selectors = new bytes4[](1);
selectors[0] = IHub.eliminateDeficit.selector;
manager.setTargetFunctionRole(address(targetHub), selectors, Roles.HUB_UMBRELLA_ROLE);
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can you put this into a helper func, will be easier to refactor later

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this could be refactored via the payload engine PR, like for other roles

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yep let's do it there

vm.stopPrank();
}

Expand Down
3 changes: 3 additions & 0 deletions tests/gas/Hub.Operations.gas.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -279,6 +279,9 @@ contract HubOperations_Gas_Tests is Base {
type(uint256).max
);

vm.prank(ADMIN);
accessManager.grantRole(Roles.HUB_UMBRELLA_ROLE, address(spoke1), 0);

vm.prank(address(spoke1));
hub1.reportDeficit(daiAssetId, drawnDebt, premiumDelta);
vm.snapshotGasLastCall('Hub.Operations', 'reportDeficit');
Expand Down
6 changes: 6 additions & 0 deletions tests/unit/Hub/Hub.Access.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,12 @@ contract HubAccessTest is HubBase {
// Hub Admin can update spoke config
vm.prank(HUB_ADMIN);
hub1.updateSpokeConfig(assetAId, address(spoke1), spokeConfig);

// Only registered spoke with Hub Umbrella or Hub Admin role can eliminate deficit
vm.expectRevert(
abi.encodeWithSelector(IAccessManaged.AccessManagedUnauthorized.selector, address(this))
);
hub1.eliminateDeficit(daiAssetId, 1000, address(spoke1));
}

function test_setInterestRateData_access() public {
Expand Down
20 changes: 20 additions & 0 deletions tests/unit/Hub/Hub.EliminateDeficit.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@ contract HubEliminateDeficitTest is HubBase {
_callerSpoke = address(spoke2);
_coveredSpoke = address(spoke1);
_otherSpoke = address(spoke3);

vm.prank(ADMIN);
accessManager.grantRole(Roles.HUB_UMBRELLA_ROLE, address(_callerSpoke), 0);
}

function test_eliminateDeficit_revertsWith_InvalidAmount_ZeroAmountNoDeficit() public {
Expand All @@ -48,7 +51,24 @@ contract HubEliminateDeficitTest is HubBase {
hub1.eliminateDeficit(_assetId, vm.randomUint(_deficitAmountRay, UINT256_MAX), _coveredSpoke);
}

function test_eliminateDeficit_fuzz_revertsWith_AccessManagedUnauthorized(address caller) public {
(bool immediate, uint32 delay) = IAccessManager(hub1.authority()).canCall(
caller,
address(hub1),
IHub.eliminateDeficit.selector
);
vm.assume(!immediate || delay > 0);
vm.expectRevert(
abi.encodeWithSelector(IAccessManaged.AccessManagedUnauthorized.selector, caller)
);
vm.prank(caller);
hub1.eliminateDeficit(_assetId, vm.randomUint(), _coveredSpoke);
}

function test_eliminateDeficit_fuzz_revertsWith_callerSpokeNotActive(address caller) public {
vm.prank(ADMIN);
accessManager.grantRole(Roles.HUB_UMBRELLA_ROLE, caller, 0);

vm.assume(!hub1.getSpoke(_assetId, caller).active);
vm.expectRevert(IHub.SpokeNotActive.selector);
vm.prank(caller);
Expand Down
Loading