Skip to content

feat: skim on spoke (enable pushing liquidity)#1062

Open
DhairyaSethi wants to merge 30 commits intodevfrom
feat/spoke-skimmed
Open

feat: skim on spoke (enable pushing liquidity)#1062
DhairyaSethi wants to merge 30 commits intodevfrom
feat/spoke-skimmed

Conversation

@DhairyaSethi
Copy link
Member

@DhairyaSethi DhairyaSethi commented Dec 15, 2025

Introduces supplySkimmed & repaySkimmed on Spoke; actions identical to their counterparts (supply, repay) with the exception to liquidity transfer. These methods do not consume allowance and pull required liquidity from the user wallet, and rather expect it be to be transferred outside the context of these actions.

This enables better UX by batching transfers, and cheaper gateways which do not need to temporarily hold tokens by pulling tokens from user, approving spoke & having spoke pull from itself; can pull tokens from user wallet to hub directly and use the skimmed variants.

This also allows anyone to permisionless-ly claim donated tokens to the hub.

Todo (blocked due to code-size & std constraints atm)

  • inline caller arg to avoid using msg.sender on internal methods
  • introduce flag to gatekeep this feature on spokes

@github-actions
Copy link

github-actions bot commented Dec 15, 2025

Forge Build Sizes

Contract Runtime Size (B) Initcode Size (B) Runtime Margin (B) Initcode Margin (B)
LiquidationLogic.spoke ↓0% (-23) 9,806 ↓0% (-23) 9,838 ↑0% (+23) 14,770 ↑0% (+23) 39,314
NativeTokenGateway ↓1% (-80) 6,107 ↓1% (-80) 6,524 ↑0% (+80) 18,469 ↑0% (+80) 42,628
SignatureGateway ↓1% (-154) 11,331 ↓1% (-154) 11,870 ↑1% (+154) 13,245 ↑0% (+154) 37,282
SpokeInstance ↑1% (+230) 24,572 ↑1% (+230) 25,379 ↓98% (-230) 4 ↓1% (-230) 23,773
TreasurySpoke ↑1% (+22) 3,621 ↑1% (+22) 4,036 ↓0% (-22) 20,955 ↓0% (-22) 45,116
🔕 Unchanged
Contract Runtime Size (B) Initcode Size (B) Runtime Margin (B) Initcode Margin (B)
AaveOracle 2,834 3,488 21,742 45,664
AccessManager 12,985 14,210 11,591 34,942
AccessManagerEnumerable 16,881 18,699 7,695 30,453
Address 44 94 24,532 49,058
Arrays 44 94 24,532 49,058
Arrays.hub 16 44 24,560 49,108
Arrays.spoke 16 44 24,560 49,108
AssetInterestRateStrategy 2,704 2,889 21,872 46,263
AssetLogic 44 94 24,532 49,058
AssetLogic.hub 16 44 24,560 49,108
AuthorityUtils 44 94 24,532 49,058
AuthorityUtils.hub 16 44 24,560 49,108
AuthorityUtils.spoke 16 44 24,560 49,108
Bytes 44 94 24,532 49,058
Bytes.spoke 16 44 24,560 49,108
Comparators 44 94 24,532 49,058
Comparators.hub 16 44 24,560 49,108
Comparators.spoke 16 44 24,560 49,108
Constants 499 551 24,077 48,601
Create2Utils 134 184 24,442 48,968
DeployUtils 44 94 24,532 49,058
DeployWrapper 3,330 3,358 21,246 45,794
ECDSA 44 94 24,532 49,058
ECDSA.spoke 16 44 24,560 49,108
EIP712Hash (src/position-manager/libraries/EIP712Hash.sol) 441 493 24,135 48,659
EIP712Hash (src/spoke/libraries/EIP712Hash.sol) 171 221 24,405 48,931
EIP712Hash.spoke 166 194 24,410 48,958
EIP712Types 44 94 24,532 49,058
ERC1967Proxy 135 891 24,441 48,261
ERC1967Utils 44 94 24,532 49,058
EnumerableSet 44 94 24,532 49,058
EnumerableSet.hub 16 44 24,560 49,108
Errors 44 94 24,532 49,058
ExtSloadWrapper 394 422 24,182 48,730
GatewayBaseWrapper 2,400 2,675 22,176 46,477
Hashes 44 94 24,532 49,058
Hub 23,547 23,744 1,029 25,408
HubConfigurator 13,833 14,029 10,743 35,123
JsonBindings 12,853 12,905 11,723 36,247
KeyValueList 44 94 24,532 49,058
KeyValueList.spoke 16 44 24,560 49,108
KeyValueListWrapper 957 985 23,619 48,167
LibBit 44 94 24,532 49,058
LibBit.spoke 16 44 24,560 49,108
LiquidationLogic 12,440 12,492 12,136 36,660
LiquidationLogicWrapper 18,567 18,741 6,009 30,411
LowLevelCall 44 94 24,532 49,058
Math 44 94 24,532 49,058
Math.hub 16 44 24,560 49,108
Math.spoke 16 44 24,560 49,108
MathUtils 44 94 24,532 49,058
MathUtils.hub 16 44 24,560 49,108
MathUtils.spoke 16 44 24,560 49,108
MockERC1271Wallet 828 962 23,748 48,190
MockERC20 2,540 3,006 22,036 46,146
MockNoncesKeyed 858 886 23,718 48,266
MockPriceFeed 737 1,395 23,839 47,757
MockReentrantCaller 882 1,083 23,694 48,069
MockSkimSpoke 1,116 1,275 23,460 47,877
NoncesKeyed 644 672 23,932 48,480
NoncesKeyed.spoke 387 413 24,189 48,739
Panic 44 94 24,532 49,058
Panic.hub 16 44 24,560 49,108
Panic.spoke 16 44 24,560 49,108
PercentageMath 44 94 24,532 49,058
PercentageMath.hub 16 44 24,560 49,108
PercentageMath.spoke 16 44 24,560 49,108
PercentageMathWrapper 632 660 23,944 48,492
PositionStatusMap 44 94 24,532 49,058
PositionStatusMap.spoke 16 44 24,560 49,108
PositionStatusMapWrapper 3,341 3,369 21,235 45,783
Premium 44 94 24,532 49,058
Premium.hub 16 44 24,560 49,108
Premium.spoke 16 44 24,560 49,108
ProxyAdmin 1,320 1,556 23,256 47,596
RescuableWrapper 908 1,042 23,668 48,110
ReserveFlagsMap 44 94 24,532 49,058
ReserveFlagsMap.spoke 16 44 24,560 49,108
ReserveFlagsMapWrapper 928 956 23,648 48,196
Roles 218 269 24,358 48,883
SafeCast 44 94 24,532 49,058
SafeCast.hub 16 44 24,560 49,108
SafeCast.spoke 16 44 24,560 49,108
SafeERC20 44 94 24,532 49,058
SafeERC20.hub 16 44 24,560 49,108
SafeERC20.spoke 16 44 24,560 49,108
SharesMath 44 94 24,532 49,058
SharesMath.hub 16 44 24,560 49,108
SignatureChecker 44 94 24,532 49,058
SignatureChecker.spoke 16 44 24,560 49,108
SlotDerivation 44 94 24,532 49,058
SlotDerivation.hub 16 44 24,560 49,108
SlotDerivation.spoke 16 44 24,560 49,108
SpokeConfigurator 12,328 12,524 12,248 36,628
SpokeUtils 96 146 24,480 49,006
SpokeUtils.spoke 71 99 24,505 49,053
SpokeUtilsWrapper 1,827 1,855 22,749 47,297
StorageSlot 44 94 24,532 49,058
StorageSlot.hub 16 44 24,560 49,108
StorageSlot.spoke 16 44 24,560 49,108
TestnetERC20 3,649 4,525 20,927 44,627
Time 44 94 24,532 49,058
TransientSlot 44 94 24,532 49,058
TransientSlot.spoke 16 44 24,560 49,108
TransparentUpgradeableProxy 1,419 4,078 23,157 45,074
UnitPriceFeed 777 1,771 23,799 47,381
UserPositionUtils (src/spoke/libraries/UserPositionDebt.sol) 44 94 24,532 49,058
UserPositionUtils (src/spoke/libraries/UserPositionUtils.sol) 44 94 24,532 49,058
UserPositionUtils.spoke 16 44 24,560 49,108
UserPositionUtilsWrapper (tests/mocks/UserPositionDebtWrapper.sol) 3,263 3,291 21,313 45,861
UserPositionUtilsWrapper (tests/mocks/UserPositionUtilsWrapper.sol) 3,263 3,291 21,313 45,861
Utils 44 94 24,532 49,058
WETH9 2,148 2,614 22,428 46,538
WadRayMath 44 94 24,532 49,058
WadRayMath.hub 16 44 24,560 49,108
WadRayMath.spoke 16 44 24,560 49,108
WadRayMathWrapper 1,514 1,542 23,062 47,610

@github-actions
Copy link

github-actions bot commented Dec 15, 2025

🌈 Test Results
No files changed, compilation skipped

Ran 20 tests for tests/unit/AaveOracle.t.sol:AaveOracleTest
[PASS] test_DECIMALS() (gas: 8326)
[PASS] test_constructor() (gas: 18428)
[PASS] test_description() (gas: 12039)
[PASS] test_fuzz_constructor(uint8) (runs: 5000, μ: 19888, ~: 20214)
Logs:
  Bound result 1

[PASS] test_getReservePrice() (gas: 48776)
[PASS] test_getReservePrice_revertsWith_InvalidPrice() (gas: 48047)
[PASS] test_getReservePrice_revertsWith_InvalidSource() (gas: 10898)
[PASS] test_getReservePrices() (gas: 80715)
[PASS] test_getReservePrices_revertsWith_InvalidSource() (gas: 50930)
[PASS] test_getReserveSource() (gas: 48946)
[PASS] test_setReserveSource() (gas: 45988)
[PASS] test_setReserveSource_revertsWith_InvalidPrice() (gas: 102779)
[PASS] test_setReserveSource_revertsWith_InvalidSource() (gas: 17228)
[PASS] test_setReserveSource_revertsWith_InvalidSourceDecimals() (gas: 17065)
[PASS] test_setReserveSource_revertsWith_OnlySpoke() (gas: 13021)
[PASS] test_setReserveSource_revertsWith_OracleMismatch() (gas: 5088044)
[PASS] test_setSpoke() (gas: 5115944)
[PASS] test_setSpoke_revertsWith_InvalidAddress() (gas: 10870)
[PASS] test_setSpoke_revertsWith_OnlyDeployer(address) (runs: 5000, μ: 13397, ~: 13397)
[PASS] test_setSpoke_revertsWith_SpokeAlreadySet() (gas: 15080)
Suite result: ok. 20 passed; 0 failed; 0 skipped; finished in 1.14s (1.11s CPU time)

Ran 10 tests for tests/unit/PercentageMath.t.sol:PercentageMathTests
[PASS] test_constants() (gas: 8604)
[PASS] test_fromBpsDown() (gas: 9654)
[PASS] test_percentDiv() (gas: 14993)
[PASS] test_percentDivUp_ge_value(uint256,uint256) (runs: 5000, μ: 15133, ~: 15261)
Logs:
  Bound result 100
  Bound result 68691281934999

[PASS] test_percentDivUp_le_value(uint256,uint256) (runs: 5000, μ: 15344, ~: 15347)
Logs:
  Bound result 90101
  Bound result 68691281934999

[PASS] test_percentDiv_fuzz(uint256,uint256) (runs: 5000, μ: 12605, ~: 12760)
[PASS] test_percentMul() (gas: 14932)
[PASS] test_percentMulUp_ge_value(uint256,uint256) (runs: 5000, μ: 15327, ~: 15330)
Logs:
  Bound result 90101
  Bound result 68691281934999

[PASS] test_percentMulUp_le_value(uint256,uint256) (runs: 5000, μ: 15136, ~: 15264)
Logs:
  Bound result 100
  Bound result 68691281934999

[PASS] test_percentMul_fuzz(uint256,uint256) (runs: 5000, μ: 11534, ~: 12063)
Suite result: ok. 10 passed; 0 failed; 0 skipped; finished in 1.53s (1.53s CPU time)

Ran 5 tests for tests/unit/Spoke/Spoke.AccrueLiquidityFee.EdgeCases.t.sol:SpokeAccrueLiquidityFeeEdgeCasesTest
[PASS] test_accrueLiquidityFee_fuzz_maxLiquidityFee_with_premium(uint256,uint256,uint256,uint256) (runs: 5000, μ: 545283, ~: 545336)
Logs:
  Bound result 12668
  Bound result 480000000
  Bound result 1
  Bound result 15771

[PASS] test_accrueLiquidityFee_fuzz_maxLiquidityFee_with_premium_multiple_users(uint256,uint256,uint256,uint256,uint256) (runs: 5000, μ: 804402, ~: 804502)
Logs:
  Bound result 4438
  Bound result 480000000
  Bound result 0
  Bound result 777
  Bound result 4115

[PASS] test_accrueLiquidityFee_maxLiquidityFee_multi_spoke() (gas: 646257614)
[PASS] test_accrueLiquidityFee_maxLiquidityFee_multi_user() (gas: 263943484)
[PASS] test_accrueLiquidityFee_maxLiquidityFee_with_premium() (gas: 545398)
Logs:
  Bound result 5000
  Bound result 34560000
  Bound result 2
  Bound result 500000000000000000000

Suite result: ok. 5 passed; 0 failed; 0 skipped; finished in 19.31s (19.29s CPU time)

Ran 17 tests for tests/unit/AccessManagerEnumerable.t.sol:AccessManagerEnumerableTest
[PASS] test_getRoleMembers_fuzz(uint256,uint256) (runs: 5000, μ: 1981460, ~: 1980367)
Logs:
  Bound result 9
  Bound result 10

[PASS] test_getRoleTargetSelectors_fuzz(uint256,uint256) (runs: 5000, μ: 1528820, ~: 1527966)
Logs:
  Bound result 9
  Bound result 10

[PASS] test_grantRole() (gas: 315886)
[PASS] test_grantRole_fuzz(uint64,uint256) (runs: 5000, μ: 916110, ~: 919753)
Logs:
  Bound result 8

[PASS] test_revokeRole() (gas: 323138)
[PASS] test_setRoleAdmin_fuzz_trackAdminRoles_multipleRoles_multipleAdmins(uint256) (runs: 5000, μ: 2159661, ~: 2257477)
Logs:
  Bound result 12

[PASS] test_setRoleAdmin_fuzz_trackRolesAndTrackAdminRoles_multipleRoles(uint256) (runs: 5000, μ: 1974061, ~: 2114661)
Logs:
  Bound result 12

[PASS] test_setRoleAdmin_trackAdminOfRoles() (gas: 606131)
[PASS] test_setRoleAdmin_trackAdminOfRoles_changeAdminRole() (gas: 577217)
[PASS] test_setRoleAdmin_trackAdminRoles() (gas: 602311)
[PASS] test_setRoleAdmin_trackRolesAndTrackAdminRoles() (gas: 378311)
[PASS] test_setRoleGuardian_trackRoles() (gas: 263932)
[PASS] test_setTargetFunctionRole() (gas: 414440)
[PASS] test_setTargetFunctionRole_multipleTargets() (gas: 1103911)
[PASS] test_setTargetFunctionRole_removeTarget() (gas: 894967)
[PASS] test_setTargetFunctionRole_skipAddToAdminRole() (gas: 30940)
[PASS] test_setTargetFunctionRole_withReplace() (gas: 549104)
Suite result: ok. 17 passed; 0 failed; 0 skipped; finished in 22.60s (22.60s CPU time)

Ran 23 tests for tests/unit/AssetInterestRateStrategy.t.sol:AssetInterestRateStrategyTest
[PASS] test_calculateInterestRate_AtKinkPoint() (gas: 24326)
Logs:
  Bound result 2000
  Bound result 778565440757296803935461404101

[PASS] test_calculateInterestRate_AtMaxUtilization() (gas: 24621)
Logs:
  Bound result 10000
  Bound result 778565440757296803935461404101

[PASS] test_calculateInterestRate_LeftToKinkPoint(uint256) (runs: 5000, μ: 24195, ~: 24330)
Logs:
  Bound result 137
  Bound result 252173843969976304268974536488

[PASS] test_calculateInterestRate_RightToKinkPoint(uint256) (runs: 5000, μ: 25302, ~: 25351)
Logs:
  Bound result 8137
  Bound result 252173843969976304268974536488

[PASS] test_calculateInterestRate_ZeroDebtZeroLiquidity() (gas: 18771)
Logs:
  Bound result 0

[PASS] test_calculateInterestRate_fuzz_ZeroDebt(uint256) (runs: 5000, μ: 19070, ~: 18822)
Logs:
  Bound result 3124043968137

[PASS] test_calculateInterestRate_revertsWith_InterestRateDataNotSet() (gas: 11225)
[PASS] test_deploy_revertsWith_InvalidAddress() (gas: 3746)
[PASS] test_getBaseVariableBorrowRate() (gas: 14812)
[PASS] test_getInterestRateData() (gas: 19290)
[PASS] test_getMaxVariableBorrowRate() (gas: 15258)
[PASS] test_getOptimalUsageRatio() (gas: 14705)
[PASS] test_getVariableRateSlope1() (gas: 14791)
[PASS] test_getVariableRateSlope2() (gas: 14746)
[PASS] test_maxBorrowRate() (gas: 8312)
[PASS] test_maxOptimalRatio() (gas: 8312)
[PASS] test_minOptimalRatio() (gas: 8321)
[PASS] test_setInterestRateData() (gas: 68999)
[PASS] test_setInterestRateData_revertsWith_InvalidMaxRate() (gas: 41819)
[PASS] test_setInterestRateData_revertsWith_InvalidOptimalUsageRatio() (gas: 42380)
[PASS] test_setInterestRateData_revertsWith_InvalidRateData() (gas: 35269)
[PASS] test_setInterestRateData_revertsWith_OnlyHub() (gas: 23502)
[PASS] test_setInterestRateData_revertsWith_Slope2MustBeGteSlope1() (gas: 37658)
Suite result: ok. 23 passed; 0 failed; 0 skipped; finished in 1.12s (1.10s CPU time)

Ran 7 tests for tests/unit/Spoke/Spoke.AccrueLiquidityFee.t.sol:SpokeAccrueLiquidityFeeTest
[PASS] test_accrueLiquidityFee() (gas: 863133)
[PASS] test_accrueLiquidityFee_NoActionTaken() (gas: 122406)
[PASS] test_accrueLiquidityFee_NoInterest_OnlySupply(uint40) (runs: 5000, μ: 245524, ~: 245476)
Logs:
  Bound result 9

[PASS] test_accrueLiquidityFee_exact() (gas: 869041)
[PASS] test_accrueLiquidityFee_fuzz_BorrowAmountAndSkipTime(uint256,uint40) (runs: 5000, μ: 939952, ~: 961834)
Logs:
  Bound result 68691281934999
  Bound result 0

[PASS] test_accrueLiquidityFee_maxLiquidityFee() (gas: 546435)
[PASS] test_accrueLiquidityFee_setUsingAsCollateral() (gas: 895591)
Suite result: ok. 7 passed; 0 failed; 0 skipped; finished in 18.86s (18.83s CPU time)

Ran 10 tests for tests/unit/misc/EIP712Hash.t.sol:EIP712HashTest
[PASS] test_constants() (gas: 13531)
[PASS] test_hash_borrow_fuzz((address,uint256,uint256,address,uint256,uint256)) (runs: 5000, μ: 6805, ~: 6805)
[PASS] test_hash_positionManagerUpdate_fuzz((address,bool)) (runs: 5000, μ: 6193, ~: 6193)
[PASS] test_hash_repay_fuzz((address,uint256,uint256,address,uint256,uint256)) (runs: 5000, μ: 6806, ~: 6806)
[PASS] test_hash_setUserPositionManagers_fuzz((address,(address,bool)[],uint256,uint256)) (runs: 5000, μ: 453554, ~: 449260)
[PASS] test_hash_setUsingAsCollateral_fuzz((address,uint256,bool,address,uint256,uint256)) (runs: 5000, μ: 7305, ~: 7305)
[PASS] test_hash_supply_fuzz((address,uint256,uint256,address,uint256,uint256)) (runs: 5000, μ: 6849, ~: 6849)
[PASS] test_hash_updateUserDynamicConfig_fuzz((address,address,uint256,uint256)) (runs: 5000, μ: 6450, ~: 6450)
[PASS] test_hash_updateUserRiskPremium_fuzz((address,address,uint256,uint256)) (runs: 5000, μ: 6471, ~: 6471)
[PASS] test_hash_withdraw_fuzz((address,uint256,uint256,address,uint256,uint256)) (runs: 5000, μ: 6805, ~: 6805)
Suite result: ok. 10 passed; 0 failed; 0 skipped; finished in 21.54s (21.54s CPU time)

Ran 9 tests for tests/unit/libraries/KeyValueList.t.sol:KeyValueListTest
[PASS] test_add_unique() (gas: 354262)
[PASS] test_fuzz_add(uint256,uint256) (runs: 5000, μ: 231309, ~: 232296)
[PASS] test_fuzz_add_unique(uint256,uint256) (runs: 5000, μ: 254898, ~: 258916)
Logs:
  Bound result 100

[PASS] test_fuzz_get(uint256[]) (runs: 5000, μ: 408309, ~: 409179)
[PASS] test_fuzz_get_uninitialized(uint256[]) (runs: 5000, μ: 279586, ~: 261724)
[PASS] test_fuzz_get_uninitialized_sorted(uint256[]) (runs: 5000, μ: 186074, ~: 161338)
[PASS] test_fuzz_sortByKey(uint256[]) (runs: 5000, μ: 466086, ~: 460867)
[PASS] test_fuzz_sortByKey_length(uint256) (runs: 5000, μ: 216294, ~: 213254)
Logs:
  Bound result 37

[PASS] test_fuzz_sortByKey_with_collision(uint256[]) (runs: 5000, μ: 545195, ~: 542150)
Suite result: ok. 9 passed; 0 failed; 0 skipped; finished in 70.31s (70.31s CPU time)

Ran 2 tests for tests/unit/libraries/LiquidationLogic/LiquidationLogic.CollateralToLiquidate.t.sol:LiquidationLogicCollateralToLiquidateTest
[PASS] test_calculateCollateralAmountToLiquidate() (gas: 168084)
[PASS] test_calculateCollateralToLiquidate_fuzz((address,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256)) (runs: 5000, μ: 191156, ~: 179848)
Logs:
  Bound result 2
  Bound result 6
  Bound result 10000000000000000
  Bound result 99000000000000000000000000172
  Bound result 10
  Bound result 64
  Bound result 14
  Bound result 82670246428927098368730
  Bound result 13794

Suite result: ok. 2 passed; 0 failed; 0 skipped; finished in 2.70s (2.68s CPU time)

Ran 3 tests for tests/unit/libraries/LiquidationLogic/LiquidationLogic.DebtToLiquidate.t.sol:LiquidationLogicDebtToLiquidateTest
[PASS] test_calculateDebtToLiquidate_fuzz((uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256)) (runs: 5000, μ: 39323, ~: 39471)
Logs:
  Bound result 1631194238
  Bound result 10585
  Bound result 3436
  Bound result 1187448874948792728
  Bound result 232473893725761368
  Bound result 7575125999959706
  Bound result 15
  Bound result 306286583169637935431906209884
  Bound result 75679658657443156232320694161
  Bound result 101634016077
  Bound result 57926430471

[PASS] test_calculateDebtToLiquidate_fuzz_AmountAdjustedDueToDust((uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256)) (runs: 5000, μ: 41703, ~: 41935)
Logs:
  Bound result 93579292091157007683231866179993536758897104800
  Bound result 14500
  Bound result 6893
  Bound result 1463399899474967115
  Bound result 1271652003141224367
  Bound result 106485013
  Bound result 10
  Bound result 2
  Bound result 99000123186774180279090739079
  Bound result 50155560136721
  Bound result 1195352612939
  Bound result 106485013
  Bound result 44074032691

[PASS] test_calculateDebtToLiquidate_fuzz_ImpossibleToAdjustForDust((uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256)) (runs: 5000, μ: 41899, ~: 41879)
Logs:
  Bound result 1631194238
  Bound result 10585
  Bound result 3436
  Bound result 1187448874948792728
  Bound result 232473893725761368
  Bound result 7575125999959706
  Bound result 15
  Bound result 306286583169637935431906209884
  Bound result 75679658657443156232320694161
  Bound result 101634016077
  Bound result 57926430471
  Bound result 5
  Bound result 10000000000000000
  Bound result 101634016077

Suite result: ok. 3 passed; 0 failed; 0 skipped; finished in 4.64s (4.61s CPU time)

Ran 7 tests for tests/unit/libraries/LiquidationLogic/LiquidationLogic.DebtToTargetHealthFactor.t.sol:LiquidationLogicDebtToTargetHealthFactorTest
[PASS] test_calculateDebtToTargetHealthFactor_HealthFactorEqualsTargetHealthFactor((uint256,uint256,uint256,uint256,uint256,uint256,uint256)) (runs: 5000, μ: 23324, ~: 23367)
Logs:
  Bound result 3116123919
  Bound result 10725
  Bound result 2977
  Bound result 1486249897798496545
  Bound result 555054242782847130
  Bound result 6199474701275945
  Bound result 9

[PASS] test_calculateDebtToTargetHealthFactor_NoPrecisionLoss() (gas: 27855)
[PASS] test_calculateDebtToTargetHealthFactor_PrecisionLoss() (gas: 17346)
[PASS] test_calculateDebtToTargetHealthFactor_UnitPrice() (gas: 27855)
[PASS] test_calculateDebtToTargetHealthFactor_fuzz_NoRevert((uint256,uint256,uint256,uint256,uint256,uint256,uint256)) (runs: 5000, μ: 20530, ~: 20495)
Logs:
  Bound result 3116123919
  Bound result 10725
  Bound result 2977
  Bound result 1486249897798496545
  Bound result 555054242782847130
  Bound result 6199474701275945
  Bound result 9

[PASS] test_calculateDebtToTargetHealthFactor_fuzz_revertsWith_DivisionByZero_ZeroAssetPrice((uint256,uint256,uint256,uint256,uint256,uint256,uint256)) (runs: 5000, μ: 22833, ~: 22876)
Logs:
  Bound result 3116123919
  Bound result 10725
  Bound result 2977
  Bound result 1486249897798496545
  Bound result 555054242782847130
  Bound result 6199474701275945
  Bound result 9

[PASS] test_calculateDebtToTargetHealthFactor_revertsWith_ArithmeticError_TargetHealthFactorLessThanHealthFactor((uint256,uint256,uint256,uint256,uint256,uint256,uint256)) (runs: 5000, μ: 22585, ~: 22628)
Logs:
  Bound result 3116123919
  Bound result 10725
  Bound result 2977
  Bound result 1486249897798496545
  Bound result 555054242782847130
  Bound result 6199474701275945
  Bound result 9

Suite result: ok. 7 passed; 0 failed; 0 skipped; finished in 3.01s (2.98s CPU time)

Ran 16 tests for tests/unit/libraries/LiquidationLogic/LiquidationLogic.EvaluateDeficit.t.sol:LiquidationLogicEvaluateDeficitTest
[PASS] test_evaluateDeficit_CRE_SCCM_DRE_BRCM() (gas: 8928)
[PASS] test_evaluateDeficit_CRE_SCCM_DRE_BRCO() (gas: 8896)
[PASS] test_evaluateDeficit_CRE_SCCM_DRN_BRCM() (gas: 8917)
[PASS] test_evaluateDeficit_CRE_SCCM_DRN_BRCO() (gas: 8884)
[PASS] test_evaluateDeficit_CRE_SCCO_DRE_BRCM() (gas: 8910)
[PASS] test_evaluateDeficit_CRE_SCCO_DRE_BRCO() (gas: 8977)
[PASS] test_evaluateDeficit_CRE_SCCO_DRN_BRCM() (gas: 8942)
[PASS] test_evaluateDeficit_CRE_SCCO_DRN_BRCO() (gas: 8930)
[PASS] test_evaluateDeficit_CRN_SCCM_DRE_BRCM() (gas: 8930)
[PASS] test_evaluateDeficit_CRN_SCCM_DRE_BRCO() (gas: 8919)
[PASS] test_evaluateDeficit_CRN_SCCM_DRN_BRCM() (gas: 8853)
[PASS] test_evaluateDeficit_CRN_SCCM_DRN_BRCO() (gas: 8886)
[PASS] test_evaluateDeficit_CRN_SCCO_DRE_BRCM() (gas: 8863)
[PASS] test_evaluateDeficit_CRN_SCCO_DRE_BRCO() (gas: 8920)
[PASS] test_evaluateDeficit_CRN_SCCO_DRN_BRCM() (gas: 8871)
[PASS] test_evaluateDeficit_CRN_SCCO_DRN_BRCO() (gas: 8949)
Suite result: ok. 16 passed; 0 failed; 0 skipped; finished in 25.38ms (1.29ms CPU time)

Ran 4 tests for tests/unit/libraries/LiquidationLogic/LiquidationLogic.ExecuteLiquidation.t.sol:LiquidationLogicExecuteLiquidationTest
[PASS] test_executeLiquidation() (gas: 368581)
[PASS] test_executeLiquidation_revertsWith_InvalidDebtToCover() (gas: 81007)
[PASS] test_executeLiquidation_revertsWith_MustNotLeaveDust_Collateral() (gas: 141309)
[PASS] test_executeLiquidation_revertsWith_MustNotLeaveDust_Debt() (gas: 141861)
Suite result: ok. 4 passed; 0 failed; 0 skipped; finished in 32.81ms (1.53ms CPU time)

Ran 3 tests for tests/unit/libraries/LiquidationLogic/LiquidationLogic.LiquidateCollateral.t.sol:LiquidationLogicLiquidateCollateralTest
[PASS] test_liquidateCollateral_fuzz(uint256,uint256,bool) (runs: 5000, μ: 204007, ~: 189003)
Logs:
  Bound result 12400
  Bound result 8907

[PASS] test_liquidateCollateral_revertsWith_ArithmeticUnderflow() (gas: 28059)
[PASS] test_liquidateCollateral_revertsWith_ArithmeticUnderflow_FeeShares() (gas: 124023)
Suite result: ok. 3 passed; 0 failed; 0 skipped; finished in 2.68s (2.66s CPU time)

Ran 4 tests for tests/unit/libraries/LiquidationLogic/LiquidationLogic.LiquidateDebt.t.sol:LiquidationLogicLiquidateDebtTest
[PASS] test_liquidateDebt_fuzz(uint256) (runs: 5000, μ: 228388, ~: 218590)
[PASS] test_liquidateDebt_revertsWith_ArithmeticUnderflow() (gas: 106082)
[PASS] test_liquidateDebt_revertsWith_InsufficientAllowance() (gas: 118587)
[PASS] test_liquidateDebt_revertsWith_InsufficientBalance() (gas: 177134)
Suite result: ok. 4 passed; 0 failed; 0 skipped; finished in 2.67s (2.64s CPU time)

Ran 4 tests for tests/unit/libraries/LiquidationLogic/LiquidationLogic.LiquidateUser.t.sol:LiquidationLogicLiquidateUserTest
[PASS] test_liquidateUser() (gas: 369668)
[PASS] test_liquidateUser_revertsWith_InvalidDebtToCover() (gas: 73786)
[PASS] test_liquidateUser_revertsWith_MustNotLeaveDust_Collateral() (gas: 138106)
[PASS] test_liquidateUser_revertsWith_MustNotLeaveDust_Debt() (gas: 142699)
Suite result: ok. 4 passed; 0 failed; 0 skipped; finished in 33.67ms (1.67ms CPU time)

Ran 5 tests for tests/unit/Spoke/Spoke.Borrow.EdgeCases.t.sol:SpokeBorrowEdgeCasesTest
[PASS] test_borrow_fuzz_rounding_effect(uint256,uint256) (runs: 5000, μ: 1044173, ~: 1044278)
Logs:
  Bound result 68691281934999
  Bound result 100

[PASS] test_borrow_fuzz_rounding_effect_inflated_ex_rate(uint256,uint256,uint256) (runs: 5000, μ: 1417952, ~: 1418030)
Logs:
  Bound result 296285550962542058341725
  Bound result 19719730187176753505116
  Bound result 76769155

[PASS] test_borrow_fuzz_rounding_effect_shares(uint256,uint256) (runs: 5000, μ: 1086857, ~: 1086608)
Logs:
  Bound result 68691281934999
  Bound result 832464101

[PASS] test_borrow_rounding_effect_multiple_actions() (gas: 1147299)
[PASS] test_borrow_rounding_effect_shares() (gas: 1085870)
Logs:
  Bound result 5000000000000000000
  Bound result 94608000

Suite result: ok. 5 passed; 0 failed; 0 skipped; finished in 57.61s (57.59s CPU time)

Ran 3 tests for tests/unit/misc/ExtSload.t.sol:ExtSloadTest
[PASS] test_extSload(bytes32) (runs: 5000, μ: 9767, ~: 9767)
[PASS] test_extSloads(uint256) (runs: 5000, μ: 950474, ~: 926350)
Logs:
  Bound result 812

[PASS] test_extSloads(uint256,bytes) (runs: 5000, μ: 1008291, ~: 970986)
Logs:
  Bound result 362

Suite result: ok. 3 passed; 0 failed; 0 skipped; finished in 59.45s (59.45s CPU time)

Ran 8 tests for tests/unit/misc/GatewayBase.t.sol:GatewayBaseTest
[PASS] test_constructor() (gas: 17151)
[PASS] test_registerSpoke_fuzz(address) (runs: 5000, μ: 41629, ~: 41629)
[PASS] test_registerSpoke_revertsWith_InvalidAddress() (gas: 13119)
[PASS] test_registerSpoke_revertsWith_OwnableUnauthorizedAccount() (gas: 13791)
[PASS] test_registerSpoke_unregister() (gas: 36076)
[PASS] test_renouncePositionManagerRole() (gas: 65381)
[PASS] test_renouncePositionManagerRole_revertsWith_InvalidAddress() (gas: 74264)
[PASS] test_renouncePositionManagerRole_revertsWith_OwnableUnauthorizedAccount() (gas: 74483)
Suite result: ok. 8 passed; 0 failed; 0 skipped; finished in 388.97ms (365.24ms CPU time)

Ran 5 tests for tests/gas/Gateways.Operations.gas.t.sol:NativeTokenGateway_Gas_Tests
[PASS] test_borrowNative() (gas: 918465)
[PASS] test_repayNative() (gas: 1002897)
[PASS] test_supplyAndCollateralNative() (gas: 318874)
[PASS] test_supplyNative() (gas: 288589)
[PASS] test_withdrawNative() (gas: 508874)
Suite result: ok. 5 passed; 0 failed; 0 skipped; finished in 48.48ms (4.11ms CPU time)

Ran 8 tests for tests/gas/Gateways.Operations.gas.t.sol:SignatureGateway_Gas_Tests
[PASS] test_borrowWithSig() (gas: 745694)
[PASS] test_repayWithSig() (gas: 1008015)
[PASS] test_setSelfAsUserPositionManagerWithSig() (gas: 209728)
[PASS] test_setUsingAsCollateralWithSig() (gas: 289435)
[PASS] test_supplyWithSig() (gas: 475749)
[PASS] test_updateUserDynamicConfigWithSig() (gas: 145369)
[PASS] test_updateUserRiskPremiumWithSig() (gas: 143300)
[PASS] test_withdrawWithSig() (gas: 409984)
Suite result: ok. 8 passed; 0 failed; 0 skipped; finished in 51.10ms (7.93ms CPU time)

Ran 6 tests for tests/unit/Hub/Hub.Access.t.sol:HubAccessTest
[PASS] test_change_authority() (gas: 206690)
[PASS] test_change_role_responsibility() (gas: 121258)
[PASS] test_hub_access_manager_exposure() (gas: 13439)
[PASS] test_hub_admin_access() (gas: 1350388)
[PASS] test_migrate_role_responsibility() (gas: 708988)
[PASS] test_setInterestRateData_access() (gas: 102667)
Suite result: ok. 6 passed; 0 failed; 0 skipped; finished in 31.24ms (3.89ms CPU time)

Ran 8 tests for tests/unit/libraries/LiquidationLogic/LiquidationLogic.LiquidationAmounts.t.sol:LiquidationLogicLiquidationAmountsTest
[PASS] test_calculateLiquidationAmounts_EnoughCollateral() (gas: 169813)
[PASS] test_calculateLiquidationAmounts_InsufficientCollateral() (gas: 170541)
[PASS] test_calculateLiquidationAmounts_fuzz_EnoughCollateral_CollateralDust((address,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256)) (runs: 5000, μ: 288844, ~: 277758)
Logs:
  Bound result 3
  Bound result 2767
  Bound result 443124196721905572
  Bound result 14843
  Bound result 8
  Bound result 18
  Bound result 13290
  Bound result 5661
  Bound result 1999999999999999997
  Bound result 443124196721905572
  Bound result 9304570613870847
  Bound result 9
  Bound result 999999999999999999999999999997
  Bound result 1000000000000000000000000000
  Bound result 28591
  Bound result 54527
  Bound result 6504484831365108
  Bound result 7
  Bound result 1109
  Bound result 18850239771387979476210927906
  Bound result 0
  Bound result 6504484831365108
  Bound result 26
  Bound result 115792089237316195423570985008687907853269984665640564039457584007913129639935

[PASS] test_calculateLiquidationAmounts_fuzz_EnoughCollateral_NoCollateralDust((address,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256)) (runs: 5000, μ: 243692, ~: 231934)
Logs:
  Bound result 3
  Bound result 2767
  Bound result 443124196721905572
  Bound result 14843
  Bound result 8
  Bound result 18
  Bound result 13290
  Bound result 5661
  Bound result 1999999999999999997
  Bound result 443124196721905572
  Bound result 9304570613870847
  Bound result 9
  Bound result 999999999999999999999999999997
  Bound result 1000000000000000000000000000
  Bound result 28591
  Bound result 54527
  Bound result 6504484831365108
  Bound result 7
  Bound result 1109
  Bound result 18850239771387979476210927906
  Bound result 0
  Bound result 18850239771387979476210927906
  Bound result 999999999999999999999999999997

[PASS] test_calculateLiquidationAmounts_fuzz_EnoughCollateral_NoDebtLeft((address,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256)) (runs: 5000, μ: 262809, ~: 251040)
Logs:
  Bound result 391762538475647744
  Bound result 0
  Bound result 959804390379038008
  Bound result 12087
  Bound result 8
  Bound result 438393217242929691103475268170435612484073883784447656382796550499
  Bound result 10137
  Bound result 2313
  Bound result 1153531738482573669
  Bound result 959804390379038008
  Bound result 2569909759757257
  Bound result 9
  Bound result 746147330359976826318441258212
  Bound result 99000000000003459472025164618
  Bound result 179039
  Bound result 181570
  Bound result 5769650721586967
  Bound result 7
  Bound result 8486
  Bound result 309955423935783634928677254734
  Bound result 1
  Bound result 438393217242929691103475268170435612484073883784447656382796550499
  Bound result 10137
  Bound result 2313
  Bound result 1153531738482573669
  Bound result 959804390379038008
  Bound result 2569909759757257
  Bound result 9
  Bound result 746147330359976826318441258212
  Bound result 99000000000003459472025164618
  Bound result 179039
  Bound result 181570
  Bound result 2569909759757257
  Bound result 179039
  Bound result 309955423935783634928677254734
  Bound result 746147330359976826318441258212

[PASS] test_calculateLiquidationAmounts_fuzz_InsufficientCollateral((address,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256)) (runs: 5000, μ: 248379, ~: 237131)
Logs:
  Bound result 625826667456391056
  Bound result 9075
  Bound result 10
  Bound result 14997
  Bound result 6
  Bound result 757548863479561673878577320344364997848070589160422296788726413501
  Bound result 14997
  Bound result 5135
  Bound result 1915776230364223623
  Bound result 10
  Bound result 2949106770800383
  Bound result 14
  Bound result 11280861844667
  Bound result 8092978207437969752885516185
  Bound result 15836908187
  Bound result 7105830021
  Bound result 241
  Bound result 14
  Bound result 2389
  Bound result 581521752335628449483975424688
  Bound result 3
  Bound result 581521752335628449483975424688
  Bound result 11280861844667

[PASS] test_calculateLiquidationAmounts_fuzz_revertsWith_MustNotLeaveDust_Collateral((address,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256)) (runs: 5000, μ: 271771, ~: 260263)
Logs:
  Bound result 3886412
  Bound result 2
  Bound result 147
  Bound result 12468
  Bound result 6
  Bound result 28951245481117846533722652
  Bound result 12468
  Bound result 3739
  Bound result 1000109044247905327
  Bound result 147
  Bound result 1766670143596910
  Bound result 14
  Bound result 885000589634409638603543244567
  Bound result 45625495039344622427514351693
  Bound result 1
  Bound result 45089934476
  Bound result 9035404749081580
  Bound result 15
  Bound result 274
  Bound result 471071379138868438154450132077
  Bound result 5
  Bound result 9035404749081580
  Bound result 3252684925
  Bound result 115792089237316195423570985008687907853269984665640564039457584007913129639935

[PASS] test_calculateLiquidationAmounts_fuzz_revertsWith_MustNotLeaveDust_Debt((address,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256)) (runs: 5000, μ: 254651, ~: 242790)
Logs:
  Bound result 391762538475647744
  Bound result 0
  Bound result 959804390379038008
  Bound result 12087
  Bound result 8
  Bound result 438393217242929691103475268170435612484073883784447656382796550499
  Bound result 10137
  Bound result 2313
  Bound result 1153531738482573669
  Bound result 959804390379038008
  Bound result 2569909759757257
  Bound result 9
  Bound result 746147330359976826318441258212
  Bound result 99000000000003459472025164618
  Bound result 179039
  Bound result 181570
  Bound result 5769650721586967
  Bound result 7
  Bound result 8486
  Bound result 309955423935783634928677254734
  Bound result 1
  Bound result 438393217242929691103475268170435612484073883784447656382796550499
  Bound result 10137
  Bound result 2313
  Bound result 1153531738482573669
  Bound result 959804390379038008
  Bound result 2569909759757257
  Bound result 9
  Bound result 746147330359976826318441258212
  Bound result 99000000000003459472025164618
  Bound result 179039
  Bound result 181570
  Bound result 2569909759757257
  Bound result 179039

Suite result: ok. 8 passed; 0 failed; 0 skipped; finished in 34.74s (34.71s CPU time)

Ran 4 tests for tests/unit/libraries/LiquidationLogic/LiquidationLogic.LiquidationBonus.t.sol:LiquidationLogicLiquidationBonusTest
[PASS] test_calculateLiquidationBonus_MinBonusDueToRounding() (gas: 12488)
[PASS] test_calculateLiquidationBonus_PartialBonus() (gas: 12509)
[PASS] test_calculateLiquidationBonus_fuzz_ConstantBonus(uint256,uint256,uint256,uint256) (runs: 5000, μ: 20339, ~: 20128)
Logs:
  Bound result 0
  Bound result 6054
  Bound result 0
  Bound result 12789

[PASS] test_calculateLiquidationBonus_fuzz_MaxBonus(uint256,uint256,uint256,uint256) (runs: 5000, μ: 23283, ~: 23072)
Logs:
  Bound result 0
  Bound result 6054
  Bound result 0
  Bound result 12789
  Bound result 0

Suite result: ok. 4 passed; 0 failed; 0 skipped; finished in 1.16s (1.13s CPU time)

Ran 11 tests for tests/unit/libraries/LiquidationLogic/LiquidationLogic.ValidateLiquidationCall.t.sol:LiquidationLogicValidateLiquidationCallTest
[PASS] test_validateLiquidationCall() (gas: 26036)
[PASS] test_validateLiquidationCall_revertsWith_CannotReceiveShares() (gas: 259738)
[PASS] test_validateLiquidationCall_revertsWith_HealthFactorNotBelowThreshold() (gas: 31769)
[PASS] test_validateLiquidationCall_revertsWith_InvalidDebtToCover() (gas: 26861)
[PASS] test_validateLiquidationCall_revertsWith_ReserveNotBorrowed() (gas: 26980)
[PASS] test_validateLiquidationCall_revertsWith_ReserveNotEnabledAsCollateral_NotUsingAsCollateral() (gas: 27033)
[PASS] test_validateLiquidationCall_revertsWith_ReserveNotEnabledAsCollateral_ZeroCollateralFactor() (gas: 27018)
[PASS] test_validateLiquidationCall_revertsWith_ReserveNotSupplied() (gas: 26947)
[PASS] test_validateLiquidationCall_revertsWith_ReservePaused_CollateralPaused() (gas: 31989)
[PASS] test_validateLiquidationCall_revertsWith_ReservePaused_DebtPaused() (gas: 31989)
[PASS] test_validateLiquidationCall_revertsWith_SelfLiquidation() (gas: 33724)
Suite result: ok. 11 passed; 0 failed; 0 skipped; finished in 26.15ms (1.56ms CPU time)

Ran 28 tests for tests/unit/MathUtils.t.sol:MathUtilsTest
[PASS] test_add_edge_cases() (gas: 4679)
[PASS] test_add_negative_operand(uint256,int256) (runs: 5000, μ: 9072, ~: 8834)
Logs:
  Bound result -57896044618658097711785492504343953926634992332820282013197946218740589849150

[PASS] test_add_positive_operand(uint256,int256) (runs: 5000, μ: 3920, ~: 3916)
[PASS] test_calculateLinearInterest() (gas: 4368)
[PASS] test_calculateLinearInterest_add_edge() (gas: 4890)
[PASS] test_calculateLinearInterest_edge_cases() (gas: 16246)
Logs:
  Bound result 0
  Bound result 1
  Bound result 864000000
  Bound result 864000000

[PASS] test_calculateLinearInterest_reverts_on_past_timestamp(uint40) (runs: 5000, μ: 7547, ~: 7381)
Logs:
  Bound result 9

[PASS] test_constants() (gas: 3110)
[PASS] test_fuzz_calculateLinearInterest(uint96,uint40,uint256) (runs: 5000, μ: 8587, ~: 8824)
Logs:
  Bound result 10765498

[PASS] test_fuzz_divUp(uint256,uint256) (runs: 5000, μ: 3540, ~: 3544)
[PASS] test_fuzz_mulDivDown(uint256,uint256,uint256) (runs: 5000, μ: 3516, ~: 3577)
[PASS] test_fuzz_mulDivUp(uint256,uint256,uint256) (runs: 5000, μ: 3596, ~: 3724)
[PASS] test_min(uint256,uint256) (runs: 5000, μ: 3281, ~: 3282)
[PASS] test_mulDivDown_NoRemainder() (gas: 3223)
[PASS] test_mulDivDown_RevertOnDivByZero() (gas: 3107)
[PASS] test_mulDivDown_RevertOnOverflow() (gas: 3183)
[PASS] test_mulDivDown_WithRemainder() (gas: 3268)
[PASS] test_mulDivDown_ZeroAOrB() (gas: 3721)
[PASS] test_mulDivUp_NoRemainder() (gas: 3249)
[PASS] test_mulDivUp_RevertOnDivByZero() (gas: 3084)
[PASS] test_mulDivUp_RevertOnOverflow() (gas: 3140)
[PASS] test_mulDivUp_WithRemainder() (gas: 3248)
[PASS] test_mulDivUp_ZeroAOrB() (gas: 3792)
[PASS] test_signedSub(uint256,uint256) (runs: 5000, μ: 8596, ~: 8530)
Logs:
  Bound result 68691281934999
  Bound result 100

[PASS] test_signedSub_revertsWith_SafeCastOverflowedUintToInt(uint256) (runs: 5000, μ: 7652, ~: 7702)
Logs:
  Bound result 57896044618658097711785492504343953926634992332820282019728792007080608788105

[PASS] test_uncheckedAdd(uint256,uint256) (runs: 5000, μ: 3447, ~: 3438)
[PASS] test_uncheckedExp(uint256,uint256) (runs: 5000, μ: 12474, ~: 9798)
[PASS] test_uncheckedSub(uint256,uint256) (runs: 5000, μ: 3444, ~: 3526)
Suite result: ok. 28 passed; 0 failed; 0 skipped; finished in 2.56s (2.54s CPU time)

Ran 19 tests for tests/unit/Hub/Hub.Add.t.sol:HubAddTest
[PASS] test_add_AddCapReachedButNotExceeded_rounding() (gas: 667246)
[PASS] test_add_fuzz_AddCapReachedButNotExceeded(uint40) (runs: 5000, μ: 157893, ~: 157848)
Logs:
  Bound result 9

[PASS] test_add_fuzz_multi_asset_multi_spoke(uint256,uint256,uint256) (runs: 5000, μ: 332479, ~: 332628)
Logs:
  Bound result 3
  Bound result 218470873395738003579119570309
  Bound result 446067553769140138733721804

[PASS] test_add_fuzz_revertsWith_AddCapExceeded(uint40) (runs: 5000, μ: 112438, ~: 112393)
Logs:
  Bound result 9

[PASS] test_add_fuzz_revertsWith_AddCapExceeded_due_to_interest(uint40,uint256,uint256) (runs: 5000, μ: 267084, ~: 266951)
Logs:
  Bound result 1291
  Bound result 1071208440522043736492
  Bound result 173721804

[PASS] test_add_fuzz_revertsWith_InvalidShares_due_to_index(uint256,uint256,uint256) (runs: 5000, μ: 223922, ~: 224119)
Logs:
  Bound result 999999999900000000000000002810
  Bound result 3122066688
  Bound result 6

[PASS] test_add_fuzz_single_asset(uint256,address,uint256) (runs: 5000, μ: 342383, ~: 342405)
Logs:
  Bound result 0
  Bound result 1100000000000000000000000000

[PASS] test_add_fuzz_single_spoke_multi_add(uint256,uint256) (runs: 5000, μ: 805220, ~: 805253)
Logs:
  Bound result 68691281934999
  Bound result 100

[PASS] test_add_multi_add_minimal_shares() (gas: 322520)
[PASS] test_add_revertsWith_AmountDowncastOverflow() (gas: 360306)
[PASS] test_add_revertsWith_InsufficientTransferred() (gas: 64504)
[PASS] test_add_revertsWith_InvalidAmount() (gas: 13631)
[PASS] test_add_revertsWith_InvalidShares() (gas: 223458)
[PASS] test_add_revertsWith_SharesDowncastOverflow() (gas: 224358)
[PASS] test_add_revertsWith_SpokeHalted() (gas: 99705)
[PASS] test_add_revertsWith_SpokeNotActive() (gas: 99741)
[PASS] test_add_single_asset() (gas: 330255)
Logs:
  Bound result 2
  Bound result 100000000000000000000

[PASS] test_add_with_increased_index() (gas: 301312)
[PASS] test_add_with_increased_index_with_premium() (gas: 680739)
Suite result: ok. 19 passed; 0 failed; 0 skipped; finished in 43.69s (43.66s CPU time)

Ran 32 tests for tests/unit/libraries/PositionStatusMap.t.sol:PositionStatusMapTest
[PASS] test_borrowCount() (gas: 108134)
[PASS] test_borrowCount(uint256) (runs: 5000, μ: 1917223, ~: 1758187)
Logs:
  Bound result 812

[PASS] test_borrowCount_ignoresInvalidBits() (gas: 122795)
[PASS] test_bucketId() (gas: 8922)
[PASS] test_collateralCount() (gas: 108082)
[PASS] test_collateralCount(uint256) (runs: 5000, μ: 1932844, ~: 1774211)
Logs:
  Bound result 812

[PASS] test_collateralCount_ignoresInvalidBits() (gas: 122986)
[PASS] test_constants() (gas: 44556)
[PASS] test_fls() (gas: 509035)
[PASS] test_fromBitId(uint256,uint256) (runs: 5000, μ: 14040, ~: 14336)
Logs:
  Bound result 151
  Bound result 100

[PASS] test_fuzz_setBorrowing(uint256,bool) (runs: 5000, μ: 22255, ~: 32137)
[PASS] test_fuzz_setUseAsCollateral(uint256,bool) (runs: 5000, μ: 22307, ~: 32189)
[PASS] test_getBucketWord(uint256) (runs: 5000, μ: 14179, ~: 14179)
[PASS] test_isUsingAsCollateralOrBorrowing_slot0() (gas: 108352)
[PASS] test_isUsingAsCollateralOrBorrowing_slot1() (gas: 43997)
[PASS] test_isolateBorrowing(uint256) (runs: 5000, μ: 153030, ~: 153030)
[PASS] test_isolateBorrowingUntil(uint256,uint256) (runs: 5000, μ: 144702, ~: 144367)
[PASS] test_isolateCollateral(uint256) (runs: 5000, μ: 152949, ~: 152949)
[PASS] test_isolateCollateralUntil(uint256,uint256) (runs: 5000, μ: 144637, ~: 144302)
[PASS] test_isolateUntil(uint256,uint256) (runs: 5000, μ: 134619, ~: 134612)
[PASS] test_next(uint256) (runs: 5000, μ: 20068, ~: 18925)
Logs:
  Bound result 649

[PASS] test_nextBorrowing(uint256) (runs: 5000, μ: 17982, ~: 16874)
Logs:
  Bound result 649

[PASS] test_nextBorrowing_continuous() (gas: 61801685)
[PASS] test_nextCollateral(uint256) (runs: 5000, μ: 18197, ~: 16983)
Logs:
  Bound result 649

[PASS] test_nextCollateral_continuous() (gas: 62157760)
[PASS] test_next_continuous() (gas: 89136467)
[PASS] test_popCount(bytes32) (runs: 5000, μ: 37881, ~: 38011)
[PASS] test_setBorrowing_slot0() (gas: 43906)
[PASS] test_setBorrowing_slot1() (gas: 43942)
[PASS] test_setUseAsCollateral_slot0() (gas: 44158)
[PASS] test_setUseAsCollateral_slot1() (gas: 44140)
[PASS] test_setters_use_correct_slot(uint256) (runs: 5000, μ: 36549, ~: 41309)
Suite result: ok. 32 passed; 0 failed; 0 skipped; finished in 161.93s (161.92s CPU time)

Ran 5 tests for tests/unit/Rescuable.t.sol:RescuableTest
[PASS] test_constructor() (gas: 12531)
[PASS] test_rescueNative_fuzz(uint256) (runs: 5000, μ: 33302, ~: 33478)
Logs:
  Bound result 3124043968137

[PASS] test_rescueNative_revertsWith_OnlyRescueGuardian() (gas: 11089)
[PASS] test_rescueToken_fuzz(uint256) (runs: 5000, μ: 206640, ~: 206759)
Logs:
  Bound result 3124043968137

[PASS] test_rescueToken_revertsWith_OnlyRescueGuardian() (gas: 180556)
Suite result: ok. 5 passed; 0 failed; 0 skipped; finished in 3.27s (3.25s CPU time)

Ran 7 tests for tests/unit/ReserveFlags.t.sol:ReserveFlagsTests
[PASS] test_constants() (gas: 12118)
[PASS] test_create_fuzz(bool,bool,bool,bool) (runs: 5000, μ: 14707, ~: 14707)
[PASS] test_setBorrowable_fuzz(uint8) (runs: 5000, μ: 13338, ~: 13338)
[PASS] test_setFrozen_fuzz(uint8) (runs: 5000, μ: 13280, ~: 13280)
[PASS] test_setPaused_fuzz(uint8) (runs: 5000, μ: 13289, ~: 13289)
[PASS] test_setReceiveSharesEnabled_fuzz(uint8) (runs: 5000, μ: 13196, ~: 13196)
[PASS] test_set_flags() (gas: 65513)
Suite result: ok. 7 passed; 0 failed; 0 skipped; finished in 1.30s (1.30s CPU time)

Ran 10 tests for tests/unit/misc/SignatureGateway/SignatureGateway.Constants.t.sol:SignatureGatewayConstantsTest
[PASS] test_DOMAIN_SEPARATOR() (gas: 5650)
[PASS] test_borrow_typeHash() (gas: 9867)
[PASS] test_constructor() (gas: 3749)
[PASS] test_eip712Domain() (gas: 10940)
[PASS] test_repay_typeHash() (gas: 9813)
[PASS] test_setUsingAsCollateral_typeHash() (gas: 9802)
[PASS] test_supply_typeHash() (gas: 9826)
[PASS] test_updateUserDynamicConfig_typeHash() (gas: 9910)
[PASS] test_updateUserRiskPremium_typeHash() (gas: 9867)
[PASS] test_withdraw_typeHash() (gas: 9912)
Suite result: ok. 10 passed; 0 failed; 0 skipped; finished in 27.41ms (2.06ms CPU time)

Ran 5 tests for tests/unit/misc/SignatureGateway/SignatureGateway.PermitReserve.t.sol:SignatureGatewayPermitReserveTest
[PASS] test_permitReserve() (gas: 101650)
[PASS] test_permitReserve_forwards_correct_call() (gas: 51189)
[PASS] test_permitReserve_ignores_permit_reverts() (gas: 40214)
[PASS] test_permitReserve_revertsWith_ReserveNotListed() (gas: 31085)
[PASS] test_permitReserve_revertsWith_SpokeNotRegistered() (gas: 29416)
Suite result: ok. 5 passed; 0 failed; 0 skipped; finished in 25.36ms (1.37ms CPU time)

Ran 2 tests for tests/unit/misc/SignatureGateway/SignatureGateway.Reverts.InsufficientAllowance.t.sol:SignatureGateway_InsufficientAllowance_Test
[PASS] test_repayWithSig_revertsWith_ERC20InsufficientAllowance() (gas: 454681)
[PASS] test_supplyWithSig_revertsWith_ERC20InsufficientAllowance() (gas: 87450)
Suite result: ok. 2 passed; 0 failed; 0 skipped; finished in 32.88ms (3.09ms CPU time)

Ran 40 tests for tests/unit/misc/NativeTokenGateway.t.sol:NativeTokenGatewayTest
[PASS] test_borrowNative() (gas: 664493)
Logs:
  Bound result 5000000000000000000

[PASS] test_borrowNative_fuzz(uint256) (runs: 5000, μ: 663893, ~: 664824)
Logs:
  Bound result 3124043968137

[PASS] test_borrowNative_revertsWith_InvalidAmount() (gas: 32426)
[PASS] test_borrowNative_revertsWith_NotNativeWrappedAsset() (gas: 32501)
[PASS] test_borrowNative_revertsWith_ReentrancyGuardReentrantCall_hubDraw() (gas: 283257)
[PASS] test_borrowNative_revertsWith_ReentrancyGuardReentrantCall_spokeBorrow() (gas: 271226)
[PASS] test_borrowNative_revertsWith_SpokeNotRegistered() (gas: 25340)
[PASS] test_constructor() (gas: 12715)
[PASS] test_constructor_revertsWith_InvalidAddress() (gas: 5958)
[PASS] test_fallback_revertsWith_UnsupportedAction() (gas: 17616)
[PASS] test_receive_revertsWith_UnsupportedAction() (gas: 17408)
[PASS] test_repayNative() (gas: 750526)
Logs:
  Bound result 5000000000000000000

[PASS] test_repayNative_excessAmount() (gas: 659057)
[PASS] test_repayNative_fuzz(uint256) (runs: 5000, μ: 746020, ~: 751085)
Logs:
  Bound result 3124043968137

[PASS] test_repayNative_fuzz_withInterest(uint256,uint256) (runs: 5000, μ: 669902, ~: 665136)
Logs:
  Bound result 90000068691281935000
  Bound result 25920101

[PASS] test_repayNative_revertsWith_InvalidAmount() (gas: 32560)
[PASS] test_repayNative_revertsWith_NativeAmountMismatch() (gas: 30030)
[PASS] test_repayNative_revertsWith_NotNativeWrappedAsset() (gas: 39328)
[PASS] test_repayNative_revertsWith_ReentrancyGuardReentrantCall_hubRestore() (gas: 319651)
[PASS] test_repayNative_revertsWith_ReentrancyGuardReentrantCall_spokeRepay() (gas: 304152)
[PASS] test_repayNative_revertsWith_SpokeNotRegistered() (gas: 38728)
[PASS] test_supplyAndCollateralNative() (gas: 327433)
Logs:
  Bound result 100000000000000000000

[PASS] test_supplyAndCollateralNative_fuzz(uint256) (runs: 5000, μ: 327748, ~: 327461)
Logs:
  Bound result 3124043968137

[PASS] test_supplyNative() (gas: 299105)
Logs:
  Bound result 100000000000000000000

[PASS] test_supplyNative_fuzz(uint256) (runs: 5000, μ: 299419, ~: 299132)
Logs:
  Bound result 3124043968137

[PASS] test_supplyNative_revertsWith_InvalidAmount() (gas: 32514)
[PASS] test_supplyNative_revertsWith_NativeAmountMismatch() (gas: 30014)
[PASS] test_supplyNative_revertsWith_NotNativeWrappedAsset() (gas: 39294)
[PASS] test_supplyNative_revertsWith_ReentrancyGuardReentrantCall_hubAdd() (gas: 328241)
[PASS] test_supplyNative_revertsWith_ReentrancyGuardReentrantCall_spokeSupply() (gas: 317060)
[PASS] test_supplyNative_revertsWith_SpokeNotRegistered() (gas: 38740)
[PASS] test_withdrawNative() (gas: 332036)
Logs:
  Bound result 100000000000000000000

[PASS] test_withdrawNative_fuzz(uint256) (runs: 5000, μ: 331640, ~: 332108)
Logs:
  Bound result 3124043968137

[PASS] test_withdrawNative_fuzz_allBalance(uint256) (runs: 5000, μ: 268178, ~: 267976)
Logs:
  Bound result 3124043968137

[PASS] test_withdrawNative_fuzz_allBalanceWithInterest(uint256,uint256) (runs: 5000, μ: 615439, ~: 615372)
Logs:
  Bound result 68691281934999
  Bound result 100

[PASS] test_withdrawNative_revertsWith_InvalidAmount() (gas: 32523)
[PASS] test_withdrawNative_revertsWith_NotNativeWrappedAsset() (gas: 32556)
[PASS] test_withdrawNative_revertsWith_ReentrancyGuardReentrantCall_hubRemove() (gas: 300164)
[PASS] test_withdrawNative_revertsWith_ReentrancyGuardReentrantCall_spokeWithdraw() (gas: 271288)
[PASS] test_withdrawNative_revertsWith_SpokeNotRegistered() (gas: 25395)
Suite result: ok. 40 passed; 0 failed; 0 skipped; finished in 63.60s (63.58s CPU time)

Ran 3 tests for tests/unit/NoncesKeyed.t.sol:NoncesKeyedTest
[PASS] test_useCheckedNonce_monotonic(bytes32) (runs: 5000, μ: 12863, ~: 12863)
[PASS] test_useCheckedNonce_revertsWith_InvalidAccountNonce(bytes32) (runs: 5000, μ: 95268, ~: 94363)
[PASS] test_useNonce_monotonic(bytes32) (runs: 5000, μ: 13531, ~: 13531)
Suite result: ok. 3 passed; 0 failed; 0 skipped; finished in 3.91s (3.91s CPU time)

Ran 7 tests for tests/unit/misc/SignatureGateway/SignatureGateway.Reverts.SpokeNotRegistered.t.sol:SignatureGateway_SpokeNotRegistered_Test
[PASS] test_borrowWithSig_revertsWith_SpokeNotRegistered((address,uint256,uint256,address,uint256,uint256)) (runs: 5000, μ: 13428, ~: 13428)
[PASS] test_repayWithSig_revertsWith_SpokeNotRegistered((address,uint256,uint256,address,uint256,uint256)) (runs: 5000, μ: 13428, ~: 13428)
[PASS] test_setUsingAsCollateralWithSig_revertsWith_SpokeNotRegistered((address,uint256,bool,address,uint256,uint256)) (runs: 5000, μ: 13397, ~: 13397)
[PASS] test_supplyWithSig_revertsWith_SpokeNotRegistered((address,uint256,uint256,address,uint256,uint256)) (runs: 5000, μ: 13471, ~: 13471)
[PASS] test_updateUserDynamicConfigWithSig_revertsWith_SpokeNotRegistered((address,address,uint256,uint256)) (runs: 5000, μ: 13682, ~: 13682)
[PASS] test_updateUserRiskPremiumWithSig_revertsWith_SpokeNotRegistered((address,address,uint256,uint256)) (runs: 5000, μ: 13749, ~: 13749)
[PASS] test_withdrawWithSig_revertsWith_SpokeNotRegistered((address,uint256,uint256,address,uint256,uint256)) (runs: 5000, μ: 13493, ~: 13493)
Suite result: ok. 7 passed; 0 failed; 0 skipped; finished in 13.02s (12.99s CPU time)

Ran 7 tests for tests/unit/misc/SignatureGateway/SignatureGateway.Reverts.Unauthorized.t.sol:SignatureGateway_Unauthorized_PositionManagerActive_Test
[PASS] test_borrowWithSig_revertsWith_Unauthorized() (gas: 80553)
[PASS] test_repayWithSig_revertsWith_Unauthorized() (gas: 107941)
[PASS] test_setUsingAsCollateralWithSig_revertsWith_Unauthorized() (gas: 73058)
[PASS] test_supplyWithSig_revertsWith_Unauthorized() (gas: 115055)
[PASS] test_updateUserDynamicConfigWithSig_revertsWith_Unauthorized() (gas: 81409)
[PASS] test_updateUserRiskPremiumWithSig_revertsWith_Unauthorized() (gas: 81586)
[PASS] test_withdrawWithSig_revertsWith_Unauthorized() (gas: 79520)
Suite result: ok. 7 passed; 0 failed; 0 skipped; finished in 28.61ms (4.07ms CPU time)

Ran 7 tests for tests/unit/misc/SignatureGateway/SignatureGateway.Reverts.Unauthorized.t.sol:SignatureGateway_Unauthorized_PositionManagerNotActive_Test
[PASS] test_borrowWithSig_revertsWith_Unauthorized() (gas: 78345)
[PASS] test_repayWithSig_revertsWith_Unauthorized() (gas: 105733)
[PASS] test_setUsingAsCollateralWithSig_revertsWith_Unauthorized() (gas: 70850)
[PASS] test_supplyWithSig_revertsWith_Unauthorized() (gas: 112847)
[PASS] test_updateUserDynamicConfigWithSig_revertsWith_Unauthorized() (gas: 79201)
[PASS] test_updateUserRiskPremiumWithSig_revertsWith_Unauthorized() (gas: 79378)
[PASS] test_withdrawWithSig_revertsWith_Unauthorized() (gas: 77312)
Suite result: ok. 7 passed; 0 failed; 0 skipped; finished in 28.50ms (4.21ms CPU time)

Ran 4 tests for tests/unit/misc/SignatureGateway/SignatureGateway.SetSelfAsUserPositionManagerWithSig.t.sol:SignatureGatewaySetSelfAsUserPositionManagerTest
[PASS] test_setSelfAsUserPositionManagerWithSig() (gas: 140660)
[PASS] test_setSelfAsUserPositionManagerWithSig_forwards_correct_call() (gas: 32923)
[PASS] test_setSelfAsUserPositionManagerWithSig_ignores_underlying_spoke_reverts() (gas: 29653)
[PASS] test_setSelfAsUserPositionManagerWithSig_revertsWith_SpokeNotRegistered() (gas: 16476)
Suite result: ok. 4 passed; 0 failed; 0 skipped; finished in 24.66ms (1.12ms CPU time)

Ran 11 tests for tests/unit/misc/SignatureGateway/SignatureGateway.t.sol:SignatureGatewayTest
[PASS] test_borrowWithSig() (gas: 798121)
[PASS] test_renouncePositionManagerRole() (gas: 27599)
[PASS] test_renouncePositionManagerRole_revertsWith_OnlyOwner() (gas: 18090)
[PASS] test_repayWithSig() (gas: 795185)
[PASS] test_setSelfAsUserPositionManagerWithSig() (gas: 312015)
[PASS] test_setUsingAsCollateralWithSig() (gas: 619168)
[PASS] test_supplyWithSig() (gas: 580859)
[PASS] test_updateUserDynamicConfigWithSig() (gas: 321947)
[PASS] test_updateUserRiskPremiumWithSig() (gas: 1014011)
[PASS] test_useNonce_monotonic(bytes32) (runs: 5000, μ: 13369, ~: 13369)
[PASS] test_withdrawWithSig() (gas: 590970)
Suite result: ok. 11 passed; 0 failed; 0 skipped; finished in 469.35ms (445.36ms CPU time)

Ran 3 tests for tests/unit/Spoke/Spoke.Access.t.sol:SpokeAccessTest
[PASS] testAccess_change_authority() (gas: 536750)
[PASS] testAccess_hub_functions_callable_by_spokes() (gas: 569443)
[PASS] testAccess_spoke_admin_config_access() (gas: 514152)
Suite result: ok. 3 passed; 0 failed; 0 skipped; finished in 26.14ms (2.93ms CPU time)

Ran 21 tests for tests/unit/misc/SignatureGateway/SignatureGateway.Reverts.InvalidSignature.t.sol:SignatureGatewayInvalidSignatureTest
[PASS] test_borrowWithSig_revertsWith_InvalidAccountNonce(bytes32) (runs: 5000, μ: 158378, ~: 157920)
[PASS] test_borrowWithSig_revertsWith_InvalidSignature_dueTo_ExpiredDeadline() (gas: 39135)
[PASS] test_borrowWithSig_revertsWith_InvalidSignature_dueTo_InvalidSigner() (gas: 37324)
[PASS] test_repayWithSig_revertsWith_InvalidAccountNonce(bytes32) (runs: 5000, μ: 158334, ~: 157876)
[PASS] test_repayWithSig_revertsWith_InvalidSignature_dueTo_ExpiredDeadline() (gas: 39068)
[PASS] test_repayWithSig_revertsWith_InvalidSignature_dueTo_InvalidSigner() (gas: 37368)
[PASS] test_setUsingAsCollateralWithSig_revertsWith_InvalidAccountNonce(bytes32) (runs: 5000, μ: 157660, ~: 158796)
[PASS] test_setUsingAsCollateralWithSig_revertsWith_InvalidSignature_dueTo_ExpiredDeadline() (gas: 39096)
[PASS] test_setUsingAsCollateralWithSig_revertsWith_InvalidSignature_dueTo_InvalidSigner() (gas: 37394)
[PASS] test_supplyWithSig_revertsWith_InvalidAccountNonce(bytes32) (runs: 5000, μ: 158375, ~: 157917)
[PASS] test_supplyWithSig_revertsWith_InvalidSignature_dueTo_ExpiredDeadline() (gas: 39113)
[PASS] test_supplyWithSig_revertsWith_InvalidSignature_dueTo_InvalidSigner() (gas: 37356)
[PASS] test_updateUserDynamicConfigWithSig_revertsWith_InvalidAccountNonce(bytes32) (runs: 5000, μ: 144659, ~: 143334)
[PASS] test_updateUserDynamicConfigWithSig_revertsWith_InvalidSignatureDueTo_InvalidSigner() (gas: 25338)
[PASS] test_updateUserDynamicConfigWithSig_revertsWith_InvalidSignature_dueTo_ExpiredDeadline() (gas: 27068)
[PASS] test_updateUserRiskPremiumWithSig_revertsWith_InvalidAccountNonce(bytes32) (runs: 5000, μ: 144696, ~: 143371)
[PASS] test_updateUserRiskPremiumWithSig_revertsWith_InvalidSignatureDueTo_InvalidSigner() (gas: 25360)
[PASS] test_updateUserRiskPremiumWithSig_revertsWith_InvalidSignature_dueTo_ExpiredDeadline() (gas: 27105)
[PASS] test_withdrawWithSig_revertsWith_InvalidAccountNonce(bytes32) (runs: 5000, μ: 158376, ~: 157918)
[PASS] test_withdrawWithSig_revertsWith_InvalidSignature_dueTo_ExpiredDeadline() (gas: 39155)
[PASS] test_withdrawWithSig_revertsWith_InvalidSignature_dueTo_InvalidSigner() (gas: 37366)
Suite result: ok. 21 passed; 0 failed; 0 skipped; finished in 41.05s (41.03s CPU time)

Ran 17 tests for tests/unit/Spoke/Spoke.Borrow.HealthFactor.t.sol:SpokeBorrowHealthFactorTest
[PASS] test_borrow_fuzz_revertsWith_HealthFactorBelowThreshold_collateral_price_drop(uint256,uint256) (runs: 5000, μ: 911513, ~: 911490)
Logs:
  Bound result 100
  Bound result 68691281934999

[PASS] test_borrow_fuzz_revertsWith_HealthFactorBelowThreshold_multiple_colls(uint256,uint256) (runs: 5000, μ: 858183, ~: 858634)
Logs:
  Bound result 5000000000000000000
  Bound result 8761

[PASS] test_borrow_fuzz_revertsWith_HealthFactorBelowThreshold_multiple_colls_with_interest(uint256,uint256,uint256) (runs: 5000, μ: 894875, ~: 894960)
Logs:
  Bound result 150000000000000000
  Bound result 102
  Bound result 407511039

[PASS] test_borrow_fuzz_revertsWith_HealthFactorBelowThreshold_multiple_debts(uint256,uint256) (runs: 5000, μ: 1098935, ~: 1099167)
Logs:
  Bound result 99999999999068691281935000
  Bound result 99999999999000000000000101

[PASS] test_borrow_fuzz_revertsWith_HealthFactorBelowThreshold_multiple_debts_with_interest(uint256,uint256,uint256) (runs: 5000, μ: 1138305, ~: 1138424)
Logs:
  Bound result 864000
  Bound result 1280000000000000000
  Bound result 572495017

[PASS] test_borrow_fuzz_revertsWith_HealthFactorBelowThreshold_with_interest(uint256,uint256) (runs: 5000, μ: 674180, ~: 674357)
Logs:
  Bound result 34560000
  Bound result 22606

[PASS] test_borrow_revertsWith_HealthFactorBelowThreshold() (gas: 641632)
[PASS] test_borrow_revertsWith_HealthFactorBelowThreshold_collateral_price_drop_weth() (gas: 905740)
[PASS] test_borrow_revertsWith_HealthFactorBelowThreshold_multiple_colls() (gas: 852415)
[PASS] test_borrow_revertsWith_HealthFactorBelowThreshold_multiple_colls_collateral_price_drop_dai() (gas: 1126284)
[PASS] test_borrow_revertsWith_HealthFactorBelowThreshold_multiple_colls_collateral_price_drop_weth() (gas: 1126328)
[PASS] test_borrow_revertsWith_HealthFactorBelowThreshold_multiple_colls_with_interest() (gas: 889969)
[PASS] test_borrow_revertsWith_HealthFactorBelowThreshold_multiple_debts() (gas: 1091407)
[PASS] test_borrow_revertsWith_HealthFactorBelowThreshold_multiple_debts_with_interest() (gas: 1130089)
[PASS] test_borrow_revertsWith_HealthFactorBelowThreshold_with_interest() (gas: 669063)
[PASS] test_fuzz_borrow_revertsWith_HealthFactorBelowThreshold_multiple_colls_collateral_price_drop_dai(uint256,uint256,uint256) (runs: 5000, μ: 1130482, ~: 1130831)
Logs:
  Bound result 1000000000
  Bound result 5000000000000000000
  Bound result 1353

[PASS] test_fuzz_borrow_revertsWith_HealthFactorBelowThreshold_multiple_colls_collateral_price_drop_weth(uint256,uint256,uint256) (runs: 5000, μ: 1130943, ~: 1130853)
Logs:
  Bound result 1000000000
  Bound result 5000000000000000000
  Bound result 1353

Suite result: ok. 17 passed; 0 failed; 0 skipped; finished in 121.30s (121.28s CPU time)

Ran 38 tests for tests/unit/Hub/Hub.Config.t.sol:HubConfigTest
[PASS] test_addAsset_fuzz(address,uint8,address) (runs: 5000, μ: 390345, ~: 390384)
Logs:
  Bound result 18

[PASS] test_addAsset_fuzz_revertsWith_InvalidAddress_feeReceiver(address,uint8,address) (runs: 5000, μ: 45290, ~: 44992)
Logs:
  Bound result 2

[PASS] test_addAsset_fuzz_revertsWith_InvalidAddress_irStrategy(address,uint8,address) (runs: 5000, μ: 45333, ~: 45035)
Logs:
  Bound result 2

[PASS] test_addAsset_fuzz_revertsWith_InvalidAddress_underlying(uint8,address,address) (runs: 5000, μ: 36719, ~: 36719)
[PASS] test_addAsset_fuzz_revertsWith_InvalidAssetDecimals(address,uint8,address,address) (runs: 5000, μ: 45945, ~: 45986)
Logs:
  Bound result 36

[PASS] test_addAsset_fuzz_revertsWith_InvalidAssetDecimals_tooLow(address,uint8,address,address) (runs: 5000, μ: 46021, ~: 46308)
Logs:
  Bound result 0

[PASS] test_addAsset_fuzz_reverts_InvalidIrData(address,uint8,address,address) (runs: 5000, μ: 83102827715, ~: 34963)
Logs:
  Bound result 17

[PASS] test_addAsset_revertsWith_BlockTimestampDowncastOverflow() (gas: 956634)
[PASS] test_addAsset_revertsWith_DrawnRateDowncastOverflow() (gas: 953770)
[PASS] test_addAsset_reverts_UnderlyingAlreadyListed() (gas: 48980)
[PASS] test_addSpoke_fuzz(uint256,(uint40,uint40,uint24,bool,bool)) (runs: 5000, μ: 126676, ~: 126726)
Logs:
  Bound result 3

[PASS] test_addSpoke_fuzz_revertsWith_AssetNotListed(uint256,(uint40,uint40,uint24,bool,bool)) (runs: 5000, μ: 35246, ~: 35235)
Logs:
  Bound result 18093

[PASS] test_addSpoke_fuzz_revertsWith_InvalidAddress_spoke(uint256,(uint40,uint40,uint24,bool,bool)) (runs: 5000, μ: 33929, ~: 33979)
Logs:
  Bound result 3

[PASS] test_addSpoke_revertsWith_SpokeAlreadyListed() (gas: 39773)
[PASS] test_getAssetId() (gas: 73160)
[PASS] test_getAssetId_fuzz_revertsWith_AssetNotListed(address) (runs: 5000, μ: 18561, ~: 18561)
[PASS] test_hub_deploy_reverts_on_InvalidConstructorInput() (gas: 828595)
[PASS] test_hub_max_riskPremium() (gas: 8610)
[PASS] test_isUnderlyingListed() (gas: 1178402)
[PASS] test_updateAssetConfig_NewFeeReceiver_noFees() (gas: 719381)
[PASS] test_updateAssetConfig_NewFeeReceiver_revertsWith_SpokeNotActive_noFees() (gas: 618740)
[PASS] test_updateAssetConfig_UseExistingSpokeAndListedAsFeeReceiver_revertsWith_SpokeAlreadyListed() (gas: 70708)
[PASS] test_updateAssetConfig_fuzz(uint256,(address,uint16,address,address)) (runs: 5000, μ: 269292, ~: 269609)
Logs:
  Bound result 1
  Bound result 79

[PASS] test_updateAssetConfig_fuzz_FromZeroLiquidityFee(uint256,uint16) (runs: 5000, μ: 822257, ~: 822117)
Logs:
  Bound result 3
  Bound result 1
  Bound result 3
  Bound result 0
  Bound result 3
  Bound result 1

[PASS] test_updateAssetConfig_fuzz_LiquidityFee(uint256,uint16) (runs: 5000, μ: 724650, ~: 724510)
Logs:
  Bound result 3
  Bound result 1
  Bound result 3
  Bound result 1

[PASS] test_updateAssetConfig_fuzz_NewFeeReceiver(uint256) (runs: 5000, μ: 823646, ~: 823680)
Logs:
  Bound result 3
  Bound result 3
  Bound result 1000

[PASS] test_updateAssetConfig_fuzz_NewInterestRateStrategy(uint256) (runs: 5000, μ: 698246, ~: 698280)
Logs:
  Bound result 3

[PASS] test_updateAssetConfig_fuzz_ReuseFeeReceiver_revertsWith_SpokeAlreadyListed(uint256) (runs: 5000, μ: 875247, ~: 875281)
Logs:
  Bound result 3
  Bound result 3
  Bound result 3
  Bound result 1000

[PASS] test_updateAssetConfig_fuzz_Scenario(uint256) (runs: 5000, μ: 700552, ~: 700605)
Logs:
  Bound result 3
  Bound result 3
  Bound result 1000
  Bound result 3
  Bound result 1000
  Bound result 3
  Bound result 0
  Bound result 3
  Bound result 0
  Bound result 3
  Bound result 0
  Bound result 3
  Bound result 0

[PASS] test_updateAssetConfig_fuzz_revertsWith_InvalidInterestRateStrategy(uint256) (runs: 5000, μ: 61083, ~: 61136)
Logs:
  Bound result 3

[PASS] test_updateAssetConfig_fuzz_revertsWith_InvalidLiquidityFee(uint256,(address,uint16,address,address)) (runs: 5000, μ: 40146, ~: 40042)
Logs:
  Bound result 1
  Bound result 79

[PASS] test_updateAssetConfig_fuzz_revertsWith_InvalidReinvestmentController() (gas: 485646)
[PASS] test_updateAssetConfig_fuzz_revertsWith_calculateInterestRateReverts(uint256,(address,uint16,address,address)) (runs: 5000, μ: 198832, ~: 199256)
Logs:
  Bound result 4
  Bound result 85

[PASS] test_updateAssetConfig_fuzz_revertsWith_setInterestRateDataReverts(uint256,(address,uint16,address,address)) (runs: 5000, μ: 95928, ~: 96293)
Logs:
  Bound result 0
  Bound result 12

[PASS] test_updateAssetConfig_oldFeeReceiver_flags() (gas: 880156)
Logs:
  Bound result 1
  Bound result 500
  Bound result 3
  Bound result 1000
  Bound result 5
  Bound result 500
  Bound result 3
  Bound result 1000

[PASS] test_updateSpokeConfig_fuzz(uint256,(uint40,uint40,uint24,bool,bool)) (runs: 5000, μ: 59224, ~: 59284)
Logs:
  Bound result 1

[PASS] test_updateSpokeConfig_fuzz_revertsWith_SpokeNotListed(uint256,address,(uint40,uint40,uint24,bool,bool)) (runs: 5000, μ: 40525, ~: 40592)
Logs:
  Bound result 1

[PASS] test_updateSpokeConfig_revertsWith_AssetNotListed() (gas: 29639)
Suite result: ok. 38 passed; 0 failed; 0 skipped; finished in 93.59s (93.56s CPU time)

Ran 16 tests for tests/unit/Hub/Hub.Draw.t.sol:HubDrawTest
[PASS] test_draw_DifferentSpokes() (gas: 355531)
[PASS] test_draw_fuzz_IncreasedBorrowRate(uint256,uint256) (runs: 5000, μ: 696684, ~: 696813)
Logs:
  Bound result 3
  Bound result 100

[PASS] test_draw_fuzz_amounts_same_block(uint256,uint256) (runs: 5000, μ: 289105, ~: 289127)
Logs:
  Bound result 3
  Bound result 100

[PASS] test_draw_fuzz_revertsWith_DrawCapExceeded(uint40) (runs: 5000, μ: 82329, ~: 82284)
Logs:
  Bound result 9

[PASS] test_draw_fuzz_revertsWith_DrawCapExceeded_due_to_interest(uint40,uint256,uint256) (runs: 5000, μ: 287068, ~: 287313)
Logs:
  Bound result 1291
  Bound result 70309
  Bound result 173721804

[PASS] test_draw_fuzz_revertsWith_InsufficientLiquidity(uint256,uint256) (runs: 5000, μ: 34736, ~: 34512)
Logs:
  Bound result 3
  Bound result 100

[PASS] test_draw_fuzz_revertsWith_InsufficientLiquidity_due_to_draw(uint256) (runs: 5000, μ: 172781, ~: 172492)
Logs:
  Bound result 3124043968137

[PASS] test_draw_fuzz_revertsWith_InsufficientLiquidity_due_to_remove(uint256) (runs: 5000, μ: 134500, ~: 134296)
Logs:
  Bound result 3124043968137

[PASS] test_draw_fuzz_revertsWith_InvalidAddress(uint256) (runs: 5000, μ: 16138, ~: 16138)
[PASS] test_draw_revertsWith_DrawCapExceeded_due_to_deficit() (gas: 270488)
[PASS] test_draw_revertsWith_InsufficientLiquidity() (gas: 28289)
[PASS] test_draw_revertsWith_InsufficientLiquidity_due_to_draw() (gas: 169103)
[PASS] test_draw_revertsWith_InsufficientLiquidity_due_to_remove() (gas: 131632)
[PASS] test_draw_revertsWith_InvalidAmount() (gas: 16269)
[PASS] test_draw_revertsWith_SpokeHalted() (gas: 61452)
[PASS] test_draw_revertsWith_SpokeNotActive() (gas: 61391)
Suite result: ok. 16 passed; 0 failed; 0 skipped; finished in 22.79s (22.76s CPU time)

Ran 8 tests for tests/unit/Hub/Hub.EliminateDeficit.t.sol:HubEliminateDeficitTest
[PASS] test_eliminateDeficit(uint256) (runs: 5000, μ: 663609, ~: 663609)
[PASS] test_eliminateDeficit_fuzz_revertsWith_AccessManagedUnauthorized(address) (runs: 5000, μ: 32580, ~: 32580)
[PASS] test_eliminateDeficit_fuzz_revertsWith_ArithmeticUnderflow_CallerSpokeNoFunds(uint256) (runs: 5000, μ: 352008, ~: 352008)
[PASS] test_eliminateDeficit_revertsWith_InvalidAmount_ZeroAmountNoDeficit() (gas: 36025)
[PASS] test_eliminateDeficit_revertsWith_InvalidAmount_ZeroAmountWithDeficit() (gas: 348183)
[PASS] test_eliminateDeficit_revertsWith_InvalidAmount_on_UnregisteredCoveredSpoke() (gas: 36412)
[PASS] test_eliminateDeficit_revertsWith_SpokeNotActive_on_UnregisteredAsset() (gas: 384005)
[PASS] test_eliminateDeficit_revertsWith_callerSpokeNotActive() (gas: 159412)
Suite result: ok. 8 passed; 0 failed; 0 skipped; finished in 16.03s (16.00s CPU time)

Ran 6 tests for tests/unit/Hub/Hub.MintFeeShares.t.sol:HubMintFeeSharesTest
[PASS] test_mintFeeShares() (gas: 311928)
[PASS] test_mintFeeShares_noFees() (gas: 367828)
[PASS] test_mintFeeShares_noShares() (gas: 293092)
[PASS] test_mintFeeShares_revertsWith_AccessManagedUnauthorized() (gas: 24139)
[PASS] test_mintFeeShares_revertsWith_AssetNotListed() (gas: 27553)
[PASS] test_mintFeeShares_revertsWith_SpokeNotActive() (gas: 242774)
Suite result: ok. 6 passed; 0 failed; 0 skipped; finished in 27.26ms (3.86ms CPU time)

Ran 9 tests for tests/gas/Hub.Operations.gas.t.sol:HubOperations_Gas_Tests
[PASS] test_add() (gas: 270130)
[PASS] test_deficit() (gas: 1342498)
[PASS] test_draw() (gas: 418586)
[PASS] test_mintFeeShares() (gas: 499967)
[PASS] test_payFee_transferShares() (gas: 968820)
[PASS] test_refreshPremium() (gas: 634672)
[PASS] test_remove() (gas: 310697)
[PASS] test_restore() (gas: 877878)
[PASS] test_restore_with_transfer() (gas: 878543)
Suite result: ok. 9 passed; 0 failed; 0 skipped; finished in 49.26ms (6.87ms CPU time)

Ran 6 tests for tests/unit/Hub/Hub.PayFee.t.sol:HubPayFeeTest
[PASS] test_payFee_fuzz(uint256,uint256) (runs: 5000, μ: 703888, ~: 704052)
Logs:
  Bound result 68691281934999
  Bound result 0
  Bound result 100

[PASS] test_payFee_fuzz_with_interest(uint256,uint256,uint256) (runs: 5000, μ: 704337, ~: 704600)
Logs:
  Bound result 615514462186775432459
  Bound result 10765498
  Bound result 571193127101173104469

[PASS] test_payFee_revertsWith_InvalidShares() (gas: 20356)
[PASS] test_payFee_revertsWith_SpokeNotActive() (gas: 61390)
[PASS] test_payFee_revertsWith_underflow_added_shares_exceeded() (gas: 138740)
[PASS] test_payFee_revertsWith_underflow_added_shares_exceeded_with_interest() (gas: 643431)
Suite result: ok. 6 passed; 0 failed; 0 skipped; finished in 24.59s (24.57s CPU time)

Ran 7 tests for tests/unit/Spoke/Spoke.AccrueInterest.t.sol:SpokeAccrueInterestTest
[PASS] test_accrueInterest_NoActionTaken() (gas: 133520)
[PASS] test_accrueInterest_NoInterest_NoDebt(uint40) (runs: 5000, μ: 633846, ~: 633675)
Logs:
  Bound result 9

[PASS] test_accrueInterest_NoInterest_OnlySupply(uint40) (runs: 5000, μ: 250630, ~: 250633)
Logs:
  Bound result 9

[PASS] test_accrueInterest_TenPercentRp(uint256,uint40) (runs: 5000, μ: 579918, ~: 580383)
Logs:
  Bound result 68691281934999
  Bound result 0

[PASS] test_accrueInterest_fuzz_BorrowAmountAndSkipTime(uint256,uint40) (runs: 5000, μ: 539235, ~: 539632)
Logs:
  Bound result 68691281934999
  Bound result 0

[SKIP: pending rft] test_accrueInterest_fuzz_RPBorrowAndSkipTime((uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256),uint40) (runs: 0, μ: 0, ~: 0)
[PASS] test_accrueInterest_fuzz_RatesRPBorrowAndSkipTime((uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256),(uint96,uint96,uint96,uint96),uint40) (runs: 5000, μ: 4060905, ~: 4077044)
Logs:
  Bound result 542387912941963860137333173539
  Bound result 300000000000000000000000000
  Bound result 15275
  Bound result 24292
  Bound result 22696
  Bound result 1646
  Bound result 13000
  Bound result 965875254
  Bound result 6085
  Bound result 18674
  Bound result 22639
  Bound result 19993
  Bound result 0
  Bound result 22696
  Bound result 1646
  Bound result 13000
  Bound result 965875254

Suite result: ok. 6 passed; 0 failed; 1 skipped; finished in 111.30s (111.27s CPU time)

Ran 11 tests for tests/unit/Hub/Hub.Reclaim.t.sol:HubReclaimTest
[PASS] test_reclaim() (gas: 652774)
Logs:
  Bound result 1000000000000000000000
  Bound result 500000000000000000000
  Bound result 200000000000000000000

[PASS] test_reclaim_fullAmount() (gas: 635224)
[PASS] test_reclaim_fuzz(uint256,uint256,uint256) (runs: 5000, μ: 654453, ~: 653712)
Logs:
  Bound result 615514462186775432459
  Bound result 571193127101173104469
  Bound result 564283877115702805413

[PASS] test_reclaim_multipleSweepsAndReclaims() (gas: 743828)
[PASS] test_reclaim_revertsWith_AssetNotListed() (gas: 13093)
[PASS] test_reclaim_revertsWith_InsufficientTransferred() (gas: 456516)
[PASS] test_reclaim_revertsWith_InsufficientTransferred_noSwept() (gas: 102551)
[PASS] test_reclaim_revertsWith_InvalidAmount_zero() (gas: 92721)
[PASS] test_reclaim_revertsWith_OnlyReinvestmentController(address) (runs: 5000, μ: 93604, ~: 93604)
[PASS] test_reclaim_revertsWith_OnlyReinvestmentController_init() (gas: 40516)
[PASS] test_reclaim_reverts...*[Comment body truncated]*

@github-actions
Copy link

github-actions bot commented Dec 15, 2025

♻️ Forge Gas Snapshots

Path Value
snapshots/NativeTokenGateway.Operations.json
borrowNative ↑0% (+154) 228,810
repayNative ↓4% (-6700) 159,771
supplyAsCollateralNative ↓4% (-6245) 153,888
supplyNative ↓9% (-12149) 123,613
withdrawNative: full ↑0% (+35) 125,592
withdrawNative: partial ↑0% (+44) 136,790
snapshots/SignatureGateway.Operations.json
borrowWithSig ↑0% (+142) 214,031
repayWithSig ↓7% (-12317) 174,426
setUsingAsCollateralWithSig ↑0% (+44) 85,431
supplyWithSig ↓12% (-18514) 133,480
updateUserDynamicConfigWithSig ↑0% (+56) 63,176
updateUserRiskPremiumWithSig ↑0% (+56) 62,146
withdrawWithSig ↑0% (+35) 130,847
snapshots/Spoke.Getters.json
getUserAccountData: supplies: 0, borrows: 0 ↑0% (+56) 13,070
getUserAccountData: supplies: 1, borrows: 0 ↑0% (+68) 49,494
getUserAccountData: supplies: 2, borrows: 0 ↑0% (+80) 81,182
getUserAccountData: supplies: 2, borrows: 1 ↑0% (+92) 101,623
getUserAccountData: supplies: 2, borrows: 2 ↑0% (+104) 120,895
snapshots/Spoke.Operations.ZeroRiskPremium.json
borrow: first ↑0% (+80) 190,464
borrow: second action, same reserve ↑0% (+80) 170,330
liquidationCall (receiveShares): full ↑0% (+116) 303,373
liquidationCall (receiveShares): partial ↑0% (+116) 302,791
liquidationCall (reportDeficit): full ↑0% (+80) 367,766
liquidationCall: full ↑0% (+116) 321,009
liquidationCall: partial ↑0% (+116) 320,427
permitReserve + repay (multicall) ↑0% (+82) 164,658
permitReserve + supply (multicall) ↑0% (+64) 146,820
permitReserve + supply + enable collateral (multicall) ↑0% (+108) 161,315
repay: full ↑0% (+38) 123,952
repay: partial ↑0% (+38) 128,910
supply + enable collateral (multicall) ↑0% (+108) 141,517
supply: 0 borrows, collateral disabled ↑0% (+20) 122,866
supply: 0 borrows, collateral enabled ↑0% (+20) 105,837
supply: second action, same reserve ↑0% (+20) 105,766
updateUserDynamicConfig: 1 collateral ↑0% (+68) 74,613
updateUserDynamicConfig: 2 collaterals ↑0% (+80) 89,493
updateUserRiskPremium: 1 borrow ↑0% (+80) 95,814
updateUserRiskPremium: 2 borrows ↑0% (+80) 105,494
usingAsCollateral: 0 borrows, enable ↑0% (+44) 59,660
usingAsCollateral: 1 borrow, disable ↑0% (+80) 105,858
usingAsCollateral: 1 borrow, enable ↑0% (+44) 42,548
usingAsCollateral: 2 borrows, disable ↑0% (+92) 127,419
usingAsCollateral: 2 borrows, enable ↑0% (+44) 42,560
withdraw: 0 borrows, full ↑0% (+24) 127,979
withdraw: 0 borrows, partial ↑0% (+24) 132,875
withdraw: 1 borrow, partial ↑0% (+36) 160,018
withdraw: 2 borrows, partial ↑0% (+48) 174,588
repaySkimmed: full 107538
repaySkimmed: partial 112496
supplySkimmed: 0 borrows, collateral disabled 106925
supplySkimmed: 0 borrows, collateral enabled 89862
supplySkimmed: second action, same reserve 89825
snapshots/Spoke.Operations.json
borrow: first ↑0% (+110) 259,429
borrow: second action, same reserve ↑0% (+110) 202,295
liquidationCall (receiveShares): full ↑0% (+146) 335,447
liquidationCall (receiveShares): partial ↑0% (+146) 334,865
liquidationCall (reportDeficit): full ↑0% (+80) 359,966
liquidationCall: full ↑0% (+146) 353,083
liquidationCall: partial ↑0% (+146) 352,501
permitReserve + repay (multicall) ↑0% (+66) 162,110
permitReserve + supply (multicall) ↑0% (+64) 146,820
permitReserve + supply + enable collateral (multicall) ↑0% (+108) 161,315
repay: full ↑0% (+38) 118,031
repay: partial ↑0% (+38) 137,389
supply + enable collateral (multicall) ↑0% (+108) 141,517
supply: 0 borrows, collateral disabled ↑0% (+20) 122,866
supply: 0 borrows, collateral enabled ↑0% (+20) 105,837
supply: second action, same reserve ↑0% (+20) 105,766
updateUserDynamicConfig: 1 collateral ↑0% (+68) 74,613
updateUserDynamicConfig: 2 collaterals ↑0% (+80) 89,493
updateUserRiskPremium: 1 borrow ↑0% (+110) 149,203
updateUserRiskPremium: 2 borrows ↑0% (+128) 199,483
usingAsCollateral: 0 borrows, enable ↑0% (+44) 59,660
usingAsCollateral: 1 borrow, disable ↑0% (+110) 159,244
usingAsCollateral: 1 borrow, enable ↑0% (+44) 42,548
usingAsCollateral: 2 borrows, disable ↑0% (+140) 229,404
usingAsCollateral: 2 borrows, enable ↑0% (+44) 42,560
withdraw: 0 borrows, full ↑0% (+24) 127,979
withdraw: 0 borrows, partial ↑0% (+24) 132,875
withdraw: 1 borrow, partial ↑0% (+66) 210,902
withdraw: 2 borrows, partial ↑0% (+96) 257,108
repaySkimmed: full 101617
repaySkimmed: partial 120975
supplySkimmed: 0 borrows, collateral disabled 106925
supplySkimmed: 0 borrows, collateral enabled 89862
supplySkimmed: second action, same reserve 89825
🔕 Unchanged
Path Value
snapshots/Hub.Operations.json
add 86,703
add: with transfer 108,000
draw 104,159
eliminateDeficit: full 72,578
eliminateDeficit: partial 82,183
mintFeeShares 82,752
payFee 70,816
refreshPremium 70,373
remove: full 75,607
remove: partial 80,745
reportDeficit 111,893
restore: full 76,563
restore: full - with transfer 169,172
restore: partial 85,273
restore: partial - with transfer 143,253
transferShares 69,630
snapshots/SignatureGateway.Operations.json
setSelfAsUserPositionManagerWithSig 75,385
snapshots/Spoke.Operations.ZeroRiskPremium.json
setUserPositionManagersWithSig: disable 47,039
setUserPositionManagersWithSig: enable 68,951
withdraw: non collateral 105,902
snapshots/Spoke.Operations.json
setUserPositionManagersWithSig: disable 47,039
setUserPositionManagersWithSig: enable 68,951
withdraw: non collateral 105,902

address onBehalfOf
) external returns (uint256, uint256);

function supplySkimmed(
Copy link
Member

Choose a reason for hiding this comment

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

so you would say that any spoke should have this functionality?

Copy link
Member Author

Choose a reason for hiding this comment

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

yes given the UX benefits, we can put this behind a gov feature flag to disable for spokes which might want flexibility (maybe RWA regulations don't like batching for ex)

userPosition.suppliedShares += suppliedShares.toUint120();

emit Supply(reserveId, msg.sender, onBehalfOf, suppliedShares, amount);
return _supply(reserveId, amount, onBehalfOf, false);
Copy link
Contributor

Choose a reason for hiding this comment

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

for both supply and repay, since the transfer caller -> hub does not impact calculations if made earlier than in current logic, might be interesting to do the transfer before calling the internal function, so we don't need to pass a true/false arg & perform an extra if check

Copy link
Contributor

Choose a reason for hiding this comment

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

and would allow to revert earlier if no allowance given.

And with the nonReentrant guards we want to add to those functions, this behavior should be safe enough, wdyt ?

Copy link
Member Author

Choose a reason for hiding this comment

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

nice one! yeah it just increases the diff, mainly on restore since we need to cap transferred amount to max debt and wanted to avoid this complexity

@DhairyaSethi DhairyaSethi changed the title Feat/spoke skimmed feat: skim on spoke (enable pushing liquidity) Jan 6, 2026
@DhairyaSethi DhairyaSethi changed the base branch from main to dev January 16, 2026 12:51
@DhairyaSethi DhairyaSethi marked this pull request as ready for review January 16, 2026 12:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants