Skip to content

Commit 754a4a5

Browse files
merge in dev
2 parents 0e09f62 + d94444a commit 754a4a5

File tree

9 files changed

+201
-73
lines changed

9 files changed

+201
-73
lines changed
Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
{
2-
"borrowNative": "225854",
3-
"repayNative": "164373",
4-
"supplyAsCollateralNative": "159402",
5-
"supplyNative": "135195",
6-
"withdrawNative: full": "124808",
7-
"withdrawNative: partial": "135810"
2+
"borrowNative": "225898",
3+
"repayNative": "164439",
4+
"supplyAsCollateralNative": "159468",
5+
"supplyNative": "135230",
6+
"withdrawNative: full": "124826",
7+
"withdrawNative: partial": "135832"
88
}
Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
{
2-
"borrowWithSig": "213087",
3-
"repayWithSig": "184645",
2+
"borrowWithSig": "213131",
3+
"repayWithSig": "184711",
44
"setSelfAsUserPositionManagerWithSig": "75385",
5-
"setUsingAsCollateralWithSig": "85365",
6-
"supplyWithSig": "151427",
7-
"updateUserDynamicConfigWithSig": "63098",
8-
"updateUserRiskPremiumWithSig": "62068",
9-
"withdrawWithSig": "130063"
5+
"setUsingAsCollateralWithSig": "85387",
6+
"supplyWithSig": "151462",
7+
"updateUserDynamicConfigWithSig": "63120",
8+
"updateUserRiskPremiumWithSig": "62090",
9+
"withdrawWithSig": "130080"
1010
}

snapshots/Spoke.Getters.json

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
2-
"getUserAccountData: supplies: 0, borrows: 0": "12992",
3-
"getUserAccountData: supplies: 1, borrows: 0": "49194",
4-
"getUserAccountData: supplies: 2, borrows: 0": "80660",
5-
"getUserAccountData: supplies: 2, borrows: 1": "101176",
6-
"getUserAccountData: supplies: 2, borrows: 2": "120523"
2+
"getUserAccountData: supplies: 0, borrows: 0": "13014",
3+
"getUserAccountData: supplies: 1, borrows: 0": "49216",
4+
"getUserAccountData: supplies: 2, borrows: 0": "80682",
5+
"getUserAccountData: supplies: 2, borrows: 1": "101198",
6+
"getUserAccountData: supplies: 2, borrows: 2": "120545"
77
}

snapshots/Spoke.Operations.ZeroRiskPremium.json

Lines changed: 25 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,31 @@
11
{
2-
"borrow: first": "202616",
3-
"borrow: second action, same reserve": "182482",
4-
"liquidationCall (receiveShares): full": "313835",
5-
"liquidationCall (receiveShares): partial": "313253",
6-
"liquidationCall (reportDeficit): full": "376047",
7-
"liquidationCall: full": "330557",
8-
"liquidationCall: partial": "329975",
9-
"permitReserve + repay (multicall)": "162413",
10-
"permitReserve + supply (multicall)": "146047",
11-
"permitReserve + supply + enable collateral (multicall)": "160476",
12-
"repay: full": "121773",
13-
"repay: partial": "126731",
2+
"borrow: first": "202638",
3+
"borrow: second action, same reserve": "182504",
4+
"liquidationCall (receiveShares): full": "313857",
5+
"liquidationCall (receiveShares): partial": "313275",
6+
"liquidationCall (reportDeficit): full": "376069",
7+
"liquidationCall: full": "330579",
8+
"liquidationCall: partial": "329997",
9+
"permitReserve + repay (multicall)": "162457",
10+
"permitReserve + supply (multicall)": "146091",
11+
"permitReserve + supply + enable collateral (multicall)": "160542",
12+
"repay: full": "121795",
13+
"repay: partial": "126753",
1414
"setUserPositionManagersWithSig: disable": "47039",
1515
"setUserPositionManagersWithSig: enable": "68951",
16-
"supply + enable collateral (multicall)": "140678",
17-
"supply: 0 borrows, collateral disabled": "122159",
18-
"supply: 0 borrows, collateral enabled": "105130",
19-
"supply: second action, same reserve": "105059",
20-
"updateUserDynamicConfig: 1 collateral": "74523",
21-
"updateUserDynamicConfig: 2 collaterals": "89391",
22-
"updateUserRiskPremium: 1 borrow": "95589",
23-
"updateUserRiskPremium: 2 borrows": "106052",
24-
"usingAsCollateral: 0 borrows, enable": "59594",
25-
"usingAsCollateral: 1 borrow, disable": "105633",
26-
"usingAsCollateral: 1 borrow, enable": "42482",
27-
"usingAsCollateral: 2 borrows, disable": "127269",
28-
"usingAsCollateral: 2 borrows, enable": "42494",
16+
"supply + enable collateral (multicall)": "140744",
17+
"supply: 0 borrows, collateral disabled": "122181",
18+
"supply: 0 borrows, collateral enabled": "105152",
19+
"supply: second action, same reserve": "105081",
20+
"updateUserDynamicConfig: 1 collateral": "74545",
21+
"updateUserDynamicConfig: 2 collaterals": "89413",
22+
"updateUserRiskPremium: 1 borrow": "95611",
23+
"updateUserRiskPremium: 2 borrows": "106074",
24+
"usingAsCollateral: 0 borrows, enable": "59616",
25+
"usingAsCollateral: 1 borrow, disable": "105655",
26+
"usingAsCollateral: 1 borrow, enable": "42504",
27+
"usingAsCollateral: 2 borrows, disable": "127291",
28+
"usingAsCollateral: 2 borrows, enable": "42516",
2929
"withdraw: 0 borrows, full": "126526",
3030
"withdraw: 0 borrows, partial": "131727",
3131
"withdraw: 1 borrow, partial": "158430",

snapshots/Spoke.Operations.json

Lines changed: 25 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,31 @@
11
{
2-
"borrow: first": "271122",
3-
"borrow: second action, same reserve": "213988",
4-
"liquidationCall (receiveShares): full": "345450",
5-
"liquidationCall (receiveShares): partial": "344868",
6-
"liquidationCall (reportDeficit): full": "370664",
7-
"liquidationCall: full": "362172",
8-
"liquidationCall: partial": "361590",
9-
"permitReserve + repay (multicall)": "160314",
10-
"permitReserve + supply (multicall)": "146047",
11-
"permitReserve + supply + enable collateral (multicall)": "160476",
12-
"repay: full": "115852",
13-
"repay: partial": "135210",
2+
"borrow: first": "271144",
3+
"borrow: second action, same reserve": "214010",
4+
"liquidationCall (receiveShares): full": "345472",
5+
"liquidationCall (receiveShares): partial": "344890",
6+
"liquidationCall (reportDeficit): full": "370686",
7+
"liquidationCall: full": "362194",
8+
"liquidationCall: partial": "361612",
9+
"permitReserve + repay (multicall)": "160349",
10+
"permitReserve + supply (multicall)": "146091",
11+
"permitReserve + supply + enable collateral (multicall)": "160542",
12+
"repay: full": "115874",
13+
"repay: partial": "135232",
1414
"setUserPositionManagersWithSig: disable": "47039",
1515
"setUserPositionManagersWithSig: enable": "68951",
16-
"supply + enable collateral (multicall)": "140678",
17-
"supply: 0 borrows, collateral disabled": "122159",
18-
"supply: 0 borrows, collateral enabled": "105130",
19-
"supply: second action, same reserve": "105059",
20-
"updateUserDynamicConfig: 1 collateral": "74523",
21-
"updateUserDynamicConfig: 2 collaterals": "89391",
22-
"updateUserRiskPremium: 1 borrow": "158302",
23-
"updateUserRiskPremium: 2 borrows": "218701",
24-
"usingAsCollateral: 0 borrows, enable": "59594",
25-
"usingAsCollateral: 1 borrow, disable": "168343",
26-
"usingAsCollateral: 1 borrow, enable": "42482",
27-
"usingAsCollateral: 2 borrows, disable": "247914",
28-
"usingAsCollateral: 2 borrows, enable": "42494",
16+
"supply + enable collateral (multicall)": "140744",
17+
"supply: 0 borrows, collateral disabled": "122181",
18+
"supply: 0 borrows, collateral enabled": "105152",
19+
"supply: second action, same reserve": "105081",
20+
"updateUserDynamicConfig: 1 collateral": "74545",
21+
"updateUserDynamicConfig: 2 collaterals": "89413",
22+
"updateUserRiskPremium: 1 borrow": "158324",
23+
"updateUserRiskPremium: 2 borrows": "218723",
24+
"usingAsCollateral: 0 borrows, enable": "59616",
25+
"usingAsCollateral: 1 borrow, disable": "168365",
26+
"usingAsCollateral: 1 borrow, enable": "42504",
27+
"usingAsCollateral: 2 borrows, disable": "247936",
28+
"usingAsCollateral: 2 borrows, enable": "42516",
2929
"withdraw: 0 borrows, full": "126526",
3030
"withdraw: 0 borrows, partial": "131727",
3131
"withdraw: 1 borrow, partial": "218638",

src/spoke/Spoke.sol

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -128,20 +128,20 @@ abstract contract Spoke is
128128
) external restricted returns (uint256) {
129129
require(hub != address(0), InvalidAddress());
130130
require(assetId <= MAX_ALLOWED_ASSET_ID, InvalidAssetId());
131-
require(!_reserveExists[hub][assetId], ReserveExists());
132-
_reserveExists[hub][assetId] = true;
131+
require(!_isAssetIdListed(hub, assetId, _hubAssetIdToReserveId[hub][assetId]), ReserveExists());
133132

134133
_validateReserveConfig(config);
135134
_validateDynamicReserveConfig(dynamicConfig);
136135
uint256 reserveId = _reserveCount++;
137-
uint32 dynamicConfigKey; // 0 as first key to use
136+
_hubAssetIdToReserveId[hub][assetId] = reserveId;
138137

139138
(address underlying, uint8 decimals) = IHubBase(hub).getAssetUnderlyingAndDecimals(assetId);
140139
require(underlying != address(0), AssetNotListed());
141140
require(decimals <= WadRayMath.WAD_DECIMALS, InvalidAssetDecimals());
142141

143142
_updateReservePriceSource(reserveId, priceSource);
144143

144+
uint32 dynamicConfigKey; // 0 as first key to use
145145
_reserves[reserveId] = Reserve({
146146
underlying: underlying,
147147
hub: IHubBase(hub),
@@ -527,6 +527,13 @@ abstract contract Spoke is
527527
return reserve.hub.getSpokeTotalOwed(reserve.assetId, address(this));
528528
}
529529

530+
/// @inheritdoc ISpoke
531+
function getReserveId(address hub, uint256 assetId) external view returns (uint256) {
532+
uint256 reserveId = _hubAssetIdToReserveId[hub][assetId];
533+
require(_isAssetIdListed(hub, assetId, reserveId), ReserveNotListed());
534+
return reserveId;
535+
}
536+
530537
/// @inheritdoc ISpoke
531538
function getReserve(uint256 reserveId) external view returns (Reserve memory) {
532539
return _reserves.get(reserveId);
@@ -891,6 +898,14 @@ abstract contract Spoke is
891898
}
892899
}
893900

901+
function _isAssetIdListed(
902+
address hub,
903+
uint256 assetId,
904+
uint256 reserveId
905+
) internal view returns (bool) {
906+
return _reserves[reserveId].assetId == assetId && address(_reserves[reserveId].hub) == hub;
907+
}
908+
894909
/// @notice Returns whether `manager` is active & approved positionManager for `user`.
895910
function _isPositionManager(address user, address manager) internal view returns (bool) {
896911
if (user == manager) return true;

src/spoke/SpokeStorage.sol

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,9 @@ abstract contract SpokeStorage {
1818
/// @dev Map of reserve identifiers to their Reserve data.
1919
mapping(uint256 reserveId => ISpoke.Reserve) internal _reserves;
2020

21-
/// @dev Map of hub addresses and asset identifiers to whether the reserve exists.
22-
mapping(address hub => mapping(uint256 assetId => bool)) internal _reserveExists;
21+
/// @dev Map of hub addresses and asset identifiers to the reserve identifier.
22+
mapping(address hub => mapping(uint256 assetId => uint256 reserveId))
23+
internal _hubAssetIdToReserveId;
2324

2425
/// @dev Map of reserve identifiers and dynamic configuration keys to the dynamic configuration data.
2526
mapping(uint256 reserveId => mapping(uint32 dynamicConfigKey => ISpoke.DynamicReserveConfig))

src/spoke/interfaces/ISpoke.sol

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -462,6 +462,13 @@ interface ISpoke is ISpokeBase, IAccessManaged, IIntentConsumer, IExtSload, IMul
462462
/// @dev Count includes reserves that are not currently active.
463463
function getReserveCount() external view returns (uint256);
464464

465+
/// @notice Returns the reserve identifier for a given assetId in a Hub.
466+
/// @dev It reverts if no reserve is associated with the given assetId.
467+
/// @param hub The address of the Hub.
468+
/// @param assetId The identifier of the asset on the Hub.
469+
/// @return The identifier of the reserve.
470+
function getReserveId(address hub, uint256 assetId) external view returns (uint256);
471+
465472
/// @notice Returns the reserve struct data in storage.
466473
/// @dev It reverts if the reserve associated with the given reserve identifier is not listed.
467474
/// @param reserveId The identifier of the reserve.

tests/unit/Spoke/Spoke.Config.t.sol

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,7 @@ contract SpokeConfigTest is SpokeBase {
173173

174174
assertEq(spoke1.getReserveConfig(reserveId), newReserveConfig);
175175
assertEq(_getLatestDynamicReserveConfig(spoke1, reserveId), newDynReserveConfig);
176+
assertEq(spoke1.getReserveId(address(hub1), usdzAssetId), reserveId);
176177
}
177178

178179
function test_addReserve_fuzz_revertsWith_AssetNotListed() public {
@@ -300,6 +301,110 @@ contract SpokeConfigTest is SpokeBase {
300301
);
301302
}
302303

304+
function test_getReserveId_fuzz(uint256 reserveId) public view {
305+
reserveId = bound(reserveId, 0, spoke1.getReserveCount() - 1);
306+
uint256 assetId = spoke1.getReserve(reserveId).assetId;
307+
308+
uint256 returnedId = spoke1.getReserveId(address(hub1), assetId);
309+
assertEq(returnedId, getReserveIdByAssetId(spoke1, hub1, assetId));
310+
}
311+
312+
function test_getReserveId_fuzz_multipleHubs(uint256 reserveId) public {
313+
(IHub hub2, ) = hub2Fixture();
314+
(IHub hub3, ) = hub3Fixture();
315+
316+
vm.startPrank(ADMIN);
317+
spoke1.addReserve(
318+
address(hub2),
319+
0,
320+
_deployMockPriceFeed(spoke1, 2000e8),
321+
spokeInfo[spoke1].weth.reserveConfig,
322+
spokeInfo[spoke1].weth.dynReserveConfig
323+
);
324+
spoke1.addReserve(
325+
address(hub2),
326+
1,
327+
_deployMockPriceFeed(spoke1, 2000e8),
328+
spokeInfo[spoke1].usdx.reserveConfig,
329+
spokeInfo[spoke1].usdx.dynReserveConfig
330+
);
331+
spoke1.addReserve(
332+
address(hub2),
333+
2,
334+
_deployMockPriceFeed(spoke1, 2000e8),
335+
spokeInfo[spoke1].dai.reserveConfig,
336+
spokeInfo[spoke1].dai.dynReserveConfig
337+
);
338+
spoke1.addReserve(
339+
address(hub2),
340+
3,
341+
_deployMockPriceFeed(spoke1, 2000e8),
342+
spokeInfo[spoke1].wbtc.reserveConfig,
343+
spokeInfo[spoke1].wbtc.dynReserveConfig
344+
);
345+
346+
spoke1.addReserve(
347+
address(hub3),
348+
0,
349+
_deployMockPriceFeed(spoke1, 2000e8),
350+
spokeInfo[spoke1].dai.reserveConfig,
351+
spokeInfo[spoke1].dai.dynReserveConfig
352+
);
353+
spoke1.addReserve(
354+
address(hub3),
355+
1,
356+
_deployMockPriceFeed(spoke1, 2000e8),
357+
spokeInfo[spoke1].usdx.reserveConfig,
358+
spokeInfo[spoke1].usdx.dynReserveConfig
359+
);
360+
spoke1.addReserve(
361+
address(hub3),
362+
2,
363+
_deployMockPriceFeed(spoke1, 2000e8),
364+
spokeInfo[spoke1].wbtc.reserveConfig,
365+
spokeInfo[spoke1].wbtc.dynReserveConfig
366+
);
367+
spoke1.addReserve(
368+
address(hub3),
369+
3,
370+
_deployMockPriceFeed(spoke1, 2000e8),
371+
spokeInfo[spoke1].weth.reserveConfig,
372+
spokeInfo[spoke1].weth.dynReserveConfig
373+
);
374+
375+
IHub.SpokeConfig memory spokeConfig = IHub.SpokeConfig({
376+
active: true,
377+
halted: false,
378+
addCap: Constants.MAX_ALLOWED_SPOKE_CAP,
379+
drawCap: Constants.MAX_ALLOWED_SPOKE_CAP,
380+
riskPremiumThreshold: Constants.MAX_ALLOWED_COLLATERAL_RISK
381+
});
382+
383+
hub2.addSpoke(0, address(spoke1), spokeConfig);
384+
hub2.addSpoke(1, address(spoke1), spokeConfig);
385+
hub2.addSpoke(2, address(spoke1), spokeConfig);
386+
hub2.addSpoke(3, address(spoke1), spokeConfig);
387+
388+
hub3.addSpoke(0, address(spoke1), spokeConfig);
389+
hub3.addSpoke(1, address(spoke1), spokeConfig);
390+
hub3.addSpoke(2, address(spoke1), spokeConfig);
391+
hub3.addSpoke(3, address(spoke1), spokeConfig);
392+
vm.stopPrank();
393+
394+
reserveId = bound(reserveId, 0, spoke1.getReserveCount() - 1);
395+
uint256 assetId = spoke1.getReserve(reserveId).assetId;
396+
address hub = address(spoke1.getReserve(reserveId).hub);
397+
398+
uint256 returnedId = spoke1.getReserveId(hub, assetId);
399+
assertEq(returnedId, getReserveIdByAssetId(spoke1, IHub(hub), assetId));
400+
}
401+
402+
function test_getReserveId_fuzz_revertsWith_ReserveNotListed(uint256 assetId) public {
403+
assetId = bound(assetId, hub1.getAssetCount(), UINT256_MAX);
404+
vm.expectRevert(ISpoke.ReserveNotListed.selector, address(spoke1));
405+
spoke1.getReserveId(address(hub1), assetId);
406+
}
407+
303408
function test_updateLiquidationConfig_targetHealthFactor() public {
304409
uint128 newTargetHealthFactor = HEALTH_FACTOR_LIQUIDATION_THRESHOLD + 1;
305410

0 commit comments

Comments
 (0)