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
4 changes: 2 additions & 2 deletions snapshots/Hub.Operations.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
"add": "88006",
"add: with transfer": "109613",
"draw": "105931",
"eliminateDeficit: full": "59781",
"eliminateDeficit: partial": "69429",
"eliminateDeficit: full": "59808",
"eliminateDeficit: partial": "69456",
"mintFeeShares": "84007",
"payFee": "72302",
"refreshPremium": "71999",
Expand Down
10 changes: 7 additions & 3 deletions src/hub/Hub.sol
Original file line number Diff line number Diff line change
Expand Up @@ -358,9 +358,8 @@ contract Hub is IHub, AccessManaged {
SpokeData storage coveredSpoke = _spokes[assetId][spoke];

asset.accrue();
_validateEliminateDeficit(callerSpoke, amount);

uint256 deficitRay = coveredSpoke.deficitRay;
_validateEliminateDeficit(callerSpoke, amount, deficitRay);
uint256 deficitAmountRay = (amount < deficitRay.fromRayUp()) ? amount.toRay() : deficitRay;

uint120 shares = asset.toAddedSharesUp(deficitAmountRay.fromRayUp()).toUint120();
Copy link
Member

Choose a reason for hiding this comment

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

we are checking deficitRay > 0, what if shares is still 0?

Expand Down Expand Up @@ -894,9 +893,14 @@ contract Hub is IHub, AccessManaged {
require(premiumAmountRay <= premiumRay, SurplusPremiumRayDeficitReported(premiumRay));
}

function _validateEliminateDeficit(SpokeData storage spoke, uint256 amount) internal view {
function _validateEliminateDeficit(
SpokeData storage spoke,
uint256 amount,
uint256 deficitRay
) internal view {
require(spoke.active, SpokeNotActive());
Copy link
Member

Choose a reason for hiding this comment

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

as discussed, it's incosistent that caller spoke can execute this while being paused, which results in a decrease of added shares (similar to remove, where paused flag checks are in place).

require(amount > 0, InvalidAmount());
require(deficitRay > 0, InsufficientDeficit());
}

function _validatePayFeeShares(SpokeData storage senderSpoke, uint256 feeShares) internal view {
Expand Down
3 changes: 3 additions & 0 deletions src/hub/interfaces/IHub.sol
Original file line number Diff line number Diff line change
Expand Up @@ -250,6 +250,9 @@ interface IHub is IHubBase, IAccessManaged {
/// @dev The `irData` must be empty if the interest rate strategy is not updated.
error InvalidInterestRateStrategy();

/// @notice Thrown when there is no deficit to be eliminated.
error InsufficientDeficit();

/// @notice Adds a new asset to the Hub.
/// @dev The same underlying asset address cannot be added as an asset multiple times.
/// @dev The fee receiver is added as a new spoke with maximum add cap and zero draw cap.
Expand Down
6 changes: 6 additions & 0 deletions tests/unit/Hub/Hub.EliminateDeficit.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,12 @@ contract HubEliminateDeficitTest is HubBase {
hub1.eliminateDeficit(_assetId, 0, _coveredSpoke);
}

function test_eliminateDeficit_revertsWith_InsufficientDeficit() public {
vm.expectRevert(IHub.InsufficientDeficit.selector);
vm.prank(_callerSpoke);
hub1.eliminateDeficit(_assetId, 1, _coveredSpoke);
}

// Caller spoke does not have funds
function test_eliminateDeficit_fuzz_revertsWith_ArithmeticUnderflow_CallerSpokeNoFunds(
uint256
Expand Down
Loading