Skip to content

rft: Mint fee shares when realized fees exceed one share#1193

Open
CheyenneAtapour wants to merge 24 commits intodevfrom
fix/preview
Open

rft: Mint fee shares when realized fees exceed one share#1193
CheyenneAtapour wants to merge 24 commits intodevfrom
fix/preview

Conversation

@CheyenneAtapour
Copy link
Contributor

No description provided.

@CheyenneAtapour CheyenneAtapour marked this pull request as ready for review February 4, 2026 21:25
Copy link
Contributor

@yan-man yan-man left a comment

Choose a reason for hiding this comment

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

doesnt have new accrue tests testing the <1 share scenario but maybe you can merge this first and do that after

@miguelmtzinf miguelmtzinf changed the base branch from rft/delayed-first-mint to dev February 5, 2026 16:09
@CheyenneAtapour CheyenneAtapour changed the title fix: Preview logic to match asset logic rft: Mint perfect fee shares during accrual Feb 5, 2026
@yan-man yan-man self-requested a review February 5, 2026 20:53
@github-actions
Copy link

github-actions bot commented Feb 5, 2026

🌈 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: 5042760)
[PASS] test_setSpoke() (gas: 5070661)
[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.09s (1.07s 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, μ: 15134, ~: 15261)
Logs:
  Bound result 100
  Bound result 68691281934999

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

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

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

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

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

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

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

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

[PASS] test_setRoleAdmin_fuzz_trackRolesAndTrackAdminRoles_multipleRoles(uint256) (runs: 5000, μ: 1968904, ~: 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.51s (22.51s 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, μ: 24185, ~: 24330)
Logs:
  Bound result 137
  Bound result 252173843969976304268974536488

[PASS] test_calculateInterestRate_RightToKinkPoint(uint256) (runs: 5000, μ: 25304, ~: 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, μ: 19068, ~: 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.13s (1.12s 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 20.84s (20.84s 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, μ: 231310, ~: 232296)
[PASS] test_fuzz_add_unique(uint256,uint256) (runs: 5000, μ: 254915, ~: 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, μ: 186097, ~: 161338)
[PASS] test_fuzz_sortByKey(uint256[]) (runs: 5000, μ: 465906, ~: 459263)
[PASS] test_fuzz_sortByKey_length(uint256) (runs: 5000, μ: 217735, ~: 216676)
Logs:
  Bound result 37

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

Ran 2 tests for tests/unit/libraries/LiquidationLogic/LiquidationLogic.CollateralToLiquidate.t.sol:LiquidationLogicCollateralToLiquidateTest
[PASS] test_calculateCollateralAmountToLiquidate() (gas: 169667)
[PASS] test_calculateCollateralToLiquidate_fuzz((address,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256)) (runs: 5000, μ: 192178, ~: 181491)
Logs:
  Bound result 0
  Bound result 17
  Bound result 10000000000000000
  Bound result 99000000000000000000000000103
  Bound result 10
  Bound result 56
  Bound result 8
  Bound result 78202359784651765
  Bound result 12700

Suite result: ok. 2 passed; 0 failed; 0 skipped; finished in 2.82s (2.80s 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, μ: 39308, ~: 39446)
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, μ: 41690, ~: 41917)
Logs:
  Bound result 13320048750803124334871884125283778579980385564631
  Bound result 11073
  Bound result 6736
  Bound result 1000000000269639555
  Bound result 273795621399015394
  Bound result 223905455001848
  Bound result 8
  Bound result 1953557536943405561079807841
  Bound result 25962196786638024172746823045
  Bound result 414655
  Bound result 428923
  Bound result 223905455001848
  Bound result 251

[PASS] test_calculateDebtToLiquidate_fuzz_ImpossibleToAdjustForDust((uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256)) (runs: 5000, μ: 41893, ~: 41876)
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.75s (4.72s 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, μ: 23316, ~: 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, μ: 20522, ~: 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, μ: 22825, ~: 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, μ: 22577, ~: 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.11s (3.08s 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 35.66ms (1.33ms CPU time)

Ran 4 tests for tests/unit/libraries/LiquidationLogic/LiquidationLogic.ExecuteLiquidation.t.sol:LiquidationLogicExecuteLiquidationTest
[PASS] test_executeLiquidation() (gas: 368709)
[PASS] test_executeLiquidation_revertsWith_InvalidDebtToCover() (gas: 81094)
[PASS] test_executeLiquidation_revertsWith_MustNotLeaveDust_Collateral() (gas: 141576)
[PASS] test_executeLiquidation_revertsWith_MustNotLeaveDust_Debt() (gas: 142080)
Suite result: ok. 4 passed; 0 failed; 0 skipped; finished in 33.13ms (1.66ms CPU time)

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

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

Ran 4 tests for tests/unit/libraries/LiquidationLogic/LiquidationLogic.LiquidateDebt.t.sol:LiquidationLogicLiquidateDebtTest
[PASS] test_liquidateDebt_fuzz(uint256) (runs: 5000, μ: 241700, ~: 231902)
[PASS] test_liquidateDebt_revertsWith_ArithmeticUnderflow() (gas: 106343)
[PASS] test_liquidateDebt_revertsWith_InsufficientAllowance() (gas: 118848)
[PASS] test_liquidateDebt_revertsWith_InsufficientBalance() (gas: 177343)
Suite result: ok. 4 passed; 0 failed; 0 skipped; finished in 2.84s (2.82s CPU time)

Ran 4 tests for tests/unit/libraries/LiquidationLogic/LiquidationLogic.LiquidateUser.t.sol:LiquidationLogicLiquidateUserTest
[PASS] test_liquidateUser() (gas: 369796)
[PASS] test_liquidateUser_revertsWith_InvalidDebtToCover() (gas: 73873)
[PASS] test_liquidateUser_revertsWith_MustNotLeaveDust_Collateral() (gas: 138373)
[PASS] test_liquidateUser_revertsWith_MustNotLeaveDust_Debt() (gas: 142918)
Suite result: ok. 4 passed; 0 failed; 0 skipped; finished in 34.03ms (1.84ms 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, μ: 958085, ~: 935242)
Logs:
  Bound result 812

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

Suite result: ok. 3 passed; 0 failed; 0 skipped; finished in 59.66s (59.66s 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: 65293)
[PASS] test_renouncePositionManagerRole_revertsWith_InvalidAddress() (gas: 74220)
[PASS] test_renouncePositionManagerRole_revertsWith_OwnableUnauthorizedAccount() (gas: 74439)
Suite result: ok. 8 passed; 0 failed; 0 skipped; finished in 382.29ms (357.22ms CPU time)

Ran 5 tests for tests/gas/Gateways.Operations.gas.t.sol:NativeTokenGateway_Gas_Tests
[PASS] test_borrowNative() (gas: 916955)
[PASS] test_repayNative() (gas: 988663)
[PASS] test_supplyAndCollateralNative() (gas: 304591)
[PASS] test_supplyNative() (gas: 286192)
[PASS] test_withdrawNative() (gas: 507722)
Suite result: ok. 5 passed; 0 failed; 0 skipped; finished in 48.04ms (4.17ms CPU time)

Ran 8 tests for tests/gas/Gateways.Operations.gas.t.sol:SignatureGateway_Gas_Tests
[PASS] test_borrowWithSig() (gas: 744532)
[PASS] test_repayWithSig() (gas: 979640)
[PASS] test_setSelfAsUserPositionManagerWithSig() (gas: 209574)
[PASS] test_setUsingAsCollateralWithSig() (gas: 289067)
[PASS] test_supplyWithSig() (gas: 460365)
[PASS] test_updateUserDynamicConfigWithSig() (gas: 145257)
[PASS] test_updateUserRiskPremiumWithSig() (gas: 143188)
[PASS] test_withdrawWithSig() (gas: 409166)
Suite result: ok. 8 passed; 0 failed; 0 skipped; finished in 51.92ms (8.30ms CPU time)

Ran 6 tests for tests/unit/Hub/Hub.Access.t.sol:HubAccessTest
[PASS] test_change_authority() (gas: 206170)
[PASS] test_change_role_responsibility() (gas: 110322)
[PASS] test_hub_access_manager_exposure() (gas: 13417)
[PASS] test_hub_admin_access() (gas: 1349984)
[PASS] test_migrate_role_responsibility() (gas: 697580)
[PASS] test_setInterestRateData_access() (gas: 102213)
Suite result: ok. 6 passed; 0 failed; 0 skipped; finished in 26.82ms (3.88ms CPU time)

Ran 4 tests for tests/unit/Hub/Hub.Accrual.t.sol:HubAccrualTest
[PASS] test_accrual_fractionalFeeRemainderDonatedToSuppliers() (gas: 430787)
[PASS] test_accrual_fuzz_basicAccrual(uint256,uint256,uint256,uint256) (runs: 5000, μ: 305716, ~: 306062)
Logs:
  Bound result 896
  Bound result 82
  Bound result 72
  Bound result 13237

[PASS] test_accrual_realizedFeesAccumulation() (gas: 468250)
[PASS] test_accrual_roundsToZero() (gas: 259600)
Suite result: ok. 4 passed; 0 failed; 0 skipped; finished in 5.03s (5.01s CPU time)

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

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

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

[PASS] test_accrueInterest_fuzz_BorrowAmountAndSkipTime(uint256,uint40) (runs: 5000, μ: 547209, ~: 547601)
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, μ: 4092873, ~: 4109324)
Logs:
  Bound result 908257647648327451499034123637
  Bound result 45000000000000000000
  Bound result 530
  Bound result 11926
  Bound result 9989
  Bound result 1710
  Bound result 999999999999999998
  Bound result 2427
  Bound result 2874
  Bound result 14252
  Bound result 12268
  Bound result 22752
  Bound result 3824
  Bound result 9989
  Bound result 1710
  Bound result 91742262345709016
  Bound result 2427

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

Ran 8 tests for tests/unit/libraries/LiquidationLogic/LiquidationLogic.LiquidationAmounts.t.sol:LiquidationLogicLiquidationAmountsTest
[PASS] test_calculateLiquidationAmounts_EnoughCollateral() (gas: 171422)
[PASS] test_calculateLiquidationAmounts_InsufficientCollateral() (gas: 172150)
[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, μ: 290020, ~: 279525)
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, μ: 244682, ~: 233560)
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, μ: 263708, ~: 252562)
Logs:
  Bound result 774975171687097701
  Bound result 2537
  Bound result 50000
  Bound result 13461
  Bound result 13
  Bound result 864000000
  Bound result 13461
  Bound result 744
  Bound result 1999999999999998877
  Bound result 50000
  Bound result 6666176345628416
  Bound result 10
  Bound result 19841
  Bound result 99000000000000000000000015502
  Bound result 645140
  Bound result 133
  Bound result 15
  Bound result 7
  Bound result 6
  Bound result 129
  Bound result 0
  Bound result 864000000
  Bound result 13461
  Bound result 744
  Bound result 1999999999999998877
  Bound result 50000
  Bound result 6666176345628416
  Bound result 10
  Bound result 19841
  Bound result 99000000000000000000000015502
  Bound result 645140
  Bound result 133
  Bound result 6666176345628416
  Bound result 209
  Bound result 1000000000000000000000000000130
  Bound result 115792089237316195423570985008687907853269984665640564039457584007913129555026

[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, μ: 249867, ~: 238727)
Logs:
  Bound result 763442436258262485
  Bound result 48
  Bound result 8037
  Bound result 14651
  Bound result 18
  Bound result 400000000000000000
  Bound result 14651
  Bound result 6536
  Bound result 1999999999999998877
  Bound result 8037
  Bound result 2091
  Bound result 14
  Bound result 1125000000000000000000
  Bound result 99000000019150094060736361194
  Bound result 36150839631783498065174
  Bound result 400
  Bound result 3
  Bound result 18
  Bound result 5839
  Bound result 14122
  Bound result 4
  Bound result 14122
  Bound result 1125000000000000000000

[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, μ: 272922, ~: 261948)
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, μ: 255491, ~: 244311)
Logs:
  Bound result 774975171687097701
  Bound result 2537
  Bound result 50000
  Bound result 13461
  Bound result 13
  Bound result 864000000
  Bound result 13461
  Bound result 744
  Bound result 1999999999999998877
  Bound result 50000
  Bound result 6666176345628416
  Bound result 10
  Bound result 19841
  Bound result 99000000000000000000000015502
  Bound result 645140
  Bound result 133
  Bound result 15
  Bound result 7
  Bound result 6
  Bound result 129
  Bound result 0
  Bound result 864000000
  Bound result 13461
  Bound result 744
  Bound result 1999999999999998877
  Bound result 50000
  Bound result 6666176345628416
  Bound result 10
  Bound result 19841
  Bound result 99000000000000000000000015502
  Bound result 645140
  Bound result 133
  Bound result 6666176345628416
  Bound result 209

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

Ran 4 tests for tests/unit/libraries/LiquidationLogic/LiquidationLogic.LiquidationBonus.t.sol:LiquidationLogicLiquidationBonusTest
[PASS] test_calculateLiquidationBonus_MinBonusDueToRounding() (gas: 12466)
[PASS] test_calculateLiquidationBonus_PartialBonus() (gas: 12487)
[PASS] test_calculateLiquidationBonus_fuzz_ConstantBonus(uint256,uint256,uint256,uint256) (runs: 5000, μ: 20319, ~: 20106)
Logs:
  Bound result 0
  Bound result 4975
  Bound result 720000000000000000
  Bound result 13963

[PASS] test_calculateLiquidationBonus_fuzz_MaxBonus(uint256,uint256,uint256,uint256) (runs: 5000, μ: 23240, ~: 23028)
Logs:
  Bound result 0
  Bound result 4975
  Bound result 720000000000000000
  Bound result 13963
  Bound result 0

Suite result: ok. 4 passed; 0 failed; 0 skipped; finished in 1.17s (1.15s 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 25.87ms (1.39ms 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, μ: 7544, ~: 7381)
Logs:
  Bound result 9

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

[PASS] test_fuzz_divUp(uint256,uint256) (runs: 5000, μ: 3540, ~: 3544)
[PASS] test_fuzz_mulDivDown(uint256,uint256,uint256) (runs: 5000, μ: 3515, ~: 3577)
[PASS] test_fuzz_mulDivUp(uint256,uint256,uint256) (runs: 5000, μ: 3595, ~: 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, μ: 8594, ~: 8530)
Logs:
  Bound result 68691281934999
  Bound result 100

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

[PASS] test_uncheckedAdd(uint256,uint256) (runs: 5000, μ: 3447, ~: 3438)
[PASS] test_uncheckedExp(uint256,uint256) (runs: 5000, μ: 12470, ~: 9800)
[PASS] test_uncheckedSub(uint256,uint256) (runs: 5000, μ: 3444, ~: 3526)
Suite result: ok. 28 passed; 0 failed; 0 skipped; finished in 2.66s (2.65s 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, μ: 533621, ~: 533674)
Logs:
  Bound result 31616
  Bound result 288000000
  Bound result 0
  Bound result 934

[PASS] test_accrueLiquidityFee_fuzz_maxLiquidityFee_with_premium_multiple_users(uint256,uint256,uint256,uint256,uint256) (runs: 5000, μ: 788029, ~: 788132)
Logs:
  Bound result 15359
  Bound result 160000000
  Bound result 0
  Bound result 2266004076
  Bound result 12665

[PASS] test_accrueLiquidityFee_maxLiquidityFee_multi_spoke() (gas: 533764044)
[PASS] test_accrueLiquidityFee_maxLiquidityFee_multi_user() (gas: 232616934)
[PASS] test_accrueLiquidityFee_maxLiquidityFee_with_premium() (gas: 533736)
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.21s (19.18s CPU time)

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

[PASS] test_accrueLiquidityFee_exact() (gas: 826803)
[PASS] test_accrueLiquidityFee_fuzz_BorrowAmountAndSkipTime(uint256,uint40) (runs: 5000, μ: 866170, ~: 888125)
Logs:
  Bound result 68691281934999
  Bound result 0

[PASS] test_accrueLiquidityFee_maxLiquidityFee() (gas: 534808)
[PASS] test_accrueLiquidityFee_setUsingAsCollateral() (gas: 874743)
Suite result: ok. 7 passed; 0 failed; 0 skipped; finished in 17.87s (17.85s CPU time)

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

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

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

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

[PASS] test_add_fuzz_revertsWith_InvalidShares_due_to_index(uint256,uint256,uint256) (runs: 5000, μ: 229428, ~: 229626)
Logs:
  Bound result 39135985462082304283475163306
  Bound result 1600710546
  Bound result 7

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

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

[PASS] test_add_multi_add_minimal_shares() (gas: 340724)
[PASS] test_add_revertsWith_AmountDowncastOverflow() (gas: 360880)
[PASS] test_add_revertsWith_InsufficientTransferred() (gas: 64495)
[PASS] test_add_revertsWith_InvalidAmount() (gas: 13622)
[PASS] test_add_revertsWith_InvalidShares() (gas: 229729)
[PASS] test_add_revertsWith_SharesDowncastOverflow() (gas: 224474)
[PASS] test_add_revertsWith_SpokeHalted() (gas: 99586)
[PASS] test_add_revertsWith_SpokeNotActive() (gas: 99622)
[PASS] test_add_single_asset() (gas: 331817)
Logs:
  Bound result 2
  Bound result 100000000000000000000

[PASS] test_add_with_increased_index() (gas: 317304)
[PASS] test_add_with_increased_index_with_premium() (gas: 692146)
Suite result: ok. 19 passed; 0 failed; 0 skipped; finished in 45.98s (45.95s CPU time)

Ran 32 tests for tests/unit/libraries/PositionStatusMap.t.sol:PositionStatusMapTest
[PASS] test_borrowCount() (gas: 108134)
[PASS] test_borrowCount(uint256) (runs: 5000, μ: 1924689, ~: 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, μ: 1940360, ~: 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, μ: 14039, ~: 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, μ: 144728, ~: 144367)
[PASS] test_isolateCollateral(uint256) (runs: 5000, μ: 152949, ~: 152949)
[PASS] test_isolateCollateralUntil(uint256,uint256) (runs: 5000, μ: 144663, ~: 144302)
[PASS] test_isolateUntil(uint256,uint256) (runs: 5000, μ: 134619, ~: 134612)
[PASS] test_next(uint256) (runs: 5000, μ: 20051, ~: 18925)
Logs:
  Bound result 649

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

[PASS] test_nextBorrowing_continuous() (gas: 61801685)
[PASS] test_nextCollateral(uint256) (runs: 5000, μ: 18178, ~: 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 162.42s (162.41s 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.49s (3.47s 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.36s (1.36s 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 26.93ms (2.03ms CPU time)

Ran 5 tests for tests/unit/misc/SignatureGateway/SignatureGateway.PermitReserve.t.sol:SignatureGatewayPermitReserveTest
[PASS] test_permitReserve() (gas: 101562)
[PASS] test_permitReserve_forwards_correct_call() (gas: 51057)
[PASS] test_permitReserve_ignores_permit_reverts() (gas: 40082)
[PASS] test_permitReserve_revertsWith_ReserveNotListed() (gas: 30997)
[PASS] test_permitReserve_revertsWith_SpokeNotRegistered() (gas: 29372)
Suite result: ok. 5 passed; 0 failed; 0 skipped; finished in 25.97ms (1.41ms CPU time)

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

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

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

[PASS] test_borrowNative_revertsWith_InvalidAmount() (gas: 32382)
[PASS] test_borrowNative_revertsWith_NotNativeWrappedAsset() (gas: 32457)
[PASS] test_borrowNative_revertsWith_ReentrancyGuardReentrantCall_hubDraw() (gas: 283081)
[PASS] test_borrowNative_revertsWith_ReentrancyGuardReentrantCall_spokeBorrow() (gas: 271138)
[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: 756750)
Logs:
  Bound result 5000000000000000000

[PASS] test_repayNative_excessAmount() (gas: 675404)
[PASS] test_repayNative_fuzz(uint256) (runs: 5000, μ: 752433, ~: 757309)
Logs:
  Bound result 3124043968137

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

[PASS] test_repayNative_revertsWith_InvalidAmount() (gas: 32463)
[PASS] test_repayNative_revertsWith_NativeAmountMismatch() (gas: 30030)
[PASS] test_repayNative_revertsWith_NotNativeWrappedAsset() (gas: 39231)
[PASS] test_repayNative_revertsWith_ReentrancyGuardReentrantCall_hubRestore() (gas: 326421)
[PASS] test_repayNative_revertsWith_ReentrancyGuardReentrantCall_spokeRepay() (gas: 303368)
[PASS] test_repayNative_revertsWith_SpokeNotRegistered() (gas: 38728)
[PASS] test_supplyAndCollateralNative() (gas: 333462)
Logs:
  Bound result 100000000000000000000

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

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

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

[PASS] test_supplyNative_revertsWith_InvalidAmount() (gas: 32417)
[PASS] test_supplyNative_revertsWith_NativeAmountMismatch() (gas: 30014)
[PASS] test_supplyNative_revertsWith_NotNativeWrappedAsset() (gas: 39197)
[PASS] test_supplyNative_revertsWith_ReentrancyGuardReentrantCall_hubAdd() (gas: 374220)
[PASS] test_supplyNative_revertsWith_ReentrancyGuardReentrantCall_spokeSupply() (gas: 336133)
[PASS] test_supplyNative_revertsWith_SpokeNotRegistered() (gas: 38740)
[PASS] test_withdrawNative() (gas: 331476)
Logs:
  Bound result 100000000000000000000

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

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

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

[PASS] test_withdrawNative_revertsWith_InvalidAmount() (gas: 32479)
[PASS] test_withdrawNative_revertsWith_NotNativeWrappedAsset() (gas: 32512)
[PASS] test_withdrawNative_revertsWith_ReentrancyGuardReentrantCall_hubRemove() (gas: 300080)
[PASS] test_withdrawNative_revertsWith_ReentrancyGuardReentrantCall_spokeWithdraw() (gas: 271200)
[PASS] test_withdrawNative_revertsWith_SpokeNotRegistered() (gas: 25395)
Suite result: ok. 40 passed; 0 failed; 0 skipped; finished in 64.97s (64.94s 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.87s (3.87s CPU time)

Ran 21 tests for tests/unit/misc/SignatureGateway/SignatureGateway.Reverts.InvalidSignature.t.sol:SignatureGatewayInvalidSignatureTest
[PASS] test_borrowWithSig_revertsWith_InvalidAccountNonce(bytes32) (runs: 5000, μ: 158334, ~: 157876)
[PASS] test_borrowWithSig_revertsWith_InvalidSignature_dueTo_ExpiredDeadline() (gas: 39091)
[PASS] test_borrowWithSig_revertsWith_InvalidSignature_dueTo_InvalidSigner() (gas: 37280)
[PASS] test_repayWithSig_revertsWith_InvalidAccountNonce(bytes32) (runs: 5000, μ: 158290, ~: 157832)
[PASS] test_repayWithSig_revertsWith_InvalidSignature_dueTo_ExpiredDeadline() (gas: 39024)
[PASS] test_repayWithSig_revertsWith_InvalidSignature_dueTo_InvalidSigner() (gas: 37324)
[PASS] test_setUsingAsCollateralWithSig_revertsWith_InvalidAccountNonce(bytes32) (runs: 5000, μ: 157616, ~: 158752)
[PASS] test_setUsingAsCollateralWithSig_revertsWith_InvalidSignature_dueTo_ExpiredDeadline() (gas: 39052)
[PASS] test_setUsingAsCollateralWithSig_revertsWith_InvalidSignature_dueTo_InvalidSigner() (gas: 37350)
[PASS] test_supplyWithSig_revertsWith_InvalidAccountNonce(bytes32) (runs: 5000, μ: 158331, ~: 157873)
[PASS] test_supplyWithSig_revertsWith_InvalidSignature_dueTo_ExpiredDeadline() (gas: 39069)
[PASS] test_supplyWithSig_revertsWith_InvalidSignature_dueTo_InvalidSigner() (gas: 37312)
[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, μ: 158332, ~: 157874)
[PASS] test_withdrawWithSig_revertsWith_InvalidSignature_dueTo_ExpiredDeadline() (gas: 39111)
[PASS] test_withdrawWithSig_revertsWith_InvalidSignature_dueTo_InvalidSigner() (gas: 37322)
Suite result: ok. 21 passed; 0 failed; 0 skipped; finished in 41.87s (41.85s 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, μ: 1041838, ~: 1041944)
Logs:
  Bound result 68691281934999
  Bound result 100

[PASS] test_borrow_fuzz_rounding_effect_inflated_ex_rate(uint256,uint256,uint256) (runs: 5000, μ: 1425585, ~: 1425669)
Logs:
  Bound result 30762942293
  Bound result 1948145
  Bound result 83975040

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

[PASS] test_borrow_rounding_effect_multiple_actions() (gas: 1157695)
[PASS] test_borrow_rounding_effect_shares() (gas: 1094559)
Logs:
  Bound result 5000000000000000000
  Bound result 94608000

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

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

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

[PASS] test_payFee_revertsWith_InvalidShares() (gas: 20347)
[PASS] test_payFee_revertsWith_SpokeNotActive() (gas: 61271)
[PASS] test_payFee_revertsWith_underflow_added_shares_exceeded() (gas: 138423)
[PASS] test_payFee_revertsWith_underflow_added_shares_exceeded_with_interest() (gas: 650235)
Suite result: ok. 6 passed; 0 failed; 0 skipped; finished in 25.20s (25.18s 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 12.91s (12.89s 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: 80421)
[PASS] test_repayWithSig_revertsWith_Unauthorized() (gas: 113623)
[PASS] test_setUsingAsCollateralWithSig_revertsWith_Unauthorized() (gas: 72970)
[PASS] test_supplyWithSig_revertsWith_Unauthorized() (gas: 140050)
[PASS] test_updateUserDynamicConfigWithSig_revertsWith_Unauthorized() (gas: 81365)
[PASS] test_updateUserRiskPremiumWithSig_revertsWith_Unauthorized() (gas: 81542)
[PASS] test_withdrawWithSig_revertsWith_Unauthorized() (gas: 79432)
Suite result: ok. 7 passed; 0 failed; 0 skipped; finished in 29.44ms (4.16ms 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: 78213)
[PASS] test_repayWithSig_revertsWith_Unauthorized() (gas: 111415)
[PASS] test_setUsingAsCollateralWithSig_revertsWith_Unauthorized() (gas: 70762)
[PASS] test_supplyWithSig_revertsWith_Unauthorized() (gas: 137842)
[PASS] test_updateUserDynamicConfigWithSig_revertsWith_Unauthorized() (gas: 79157)
[PASS] test_updateUserRiskPremiumWithSig_revertsWith_Unauthorized() (gas: 79334)
[PASS] test_withdrawWithSig_revertsWith_Unauthorized() (gas: 77224)
Suite result: ok. 7 passed; 0 failed; 0 skipped; finished in 28.59ms (4.15ms CPU time)

Ran 4 tests for tests/unit/misc/SignatureGateway/SignatureGateway.SetSelfAsUserPositionManagerWithSig.t.sol:SignatureGatewaySetSelfAsUserPositionManagerTest
[PASS] test_setSelfAsUserPositionManagerWithSig() (gas: 140462)
[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.96ms (1.18ms CPU time)

Ran 11 tests for tests/unit/misc/SignatureGateway/SignatureGateway.t.sol:SignatureGatewayTest
[PASS] test_borrowWithSig() (gas: 796183)
[PASS] test_renouncePositionManagerRole() (gas: 27555)
[PASS] test_renouncePositionManagerRole_revertsWith_OnlyOwner() (gas: 18090)
[PASS] test_repayWithSig() (gas: 803572)
[PASS] test_setSelfAsUserPositionManagerWithSig() (gas: 310932)
[PASS] test_setUsingAsCollateralWithSig() (gas: 617562)
[PASS] test_supplyWithSig() (gas: 588934)
[PASS] test_updateUserDynamicConfigWithSig() (gas: 320918)
[PASS] test_updateUserRiskPremiumWithSig() (gas: 1010400)
[PASS] test_useNonce_monotonic(bytes32) (runs: 5000, μ: 13369, ~: 13369)
[PASS] test_withdrawWithSig() (gas: 589098)
Suite result: ok. 11 passed; 0 failed; 0 skipped; finished in 483.42ms (459.35ms CPU time)

Ran 3 tests for tests/unit/Spoke/Spoke.Access.t.sol:SpokeAccessTest
[PASS] testAccess_change_authority() (gas: 536450)
[PASS] testAccess_hub_functions_callable_by_spokes() (gas: 567674)
[PASS] testAccess_spoke_admin_config_access() (gas: 513776)
Suite result: ok. 3 passed; 0 failed; 0 skipped; finished in 27.68ms (3.06ms CPU time)

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

[PASS] test_reclaim_fullAmount() (gas: 633500)
[PASS] test_reclaim_fuzz(uint256,uint256,uint256) (runs: 5000, μ: 652729, ~: 651940)
Logs:
  Bound result 615514462186775432459
  Bound result 571193127101173104469
  Bound result 564283877115702805413

[PASS] test_reclaim_multipleSweepsAndReclaims() (gas: 741376)
[PASS] test_reclaim_revertsWith_AssetNotListed() (gas: 13049)
[PASS] test_reclaim_revertsWith_InsufficientTransferred() (gas: 455268)
[PASS] test_reclaim_revertsWith_InsufficientTransferred_noSwept() (gas: 102066)
[PASS] test_reclaim_revertsWith_InvalidAmount_zero() (gas: 92258)
[PASS] test_reclaim_revertsWith_OnlyReinvestmentController(address) (runs: 5000, μ: 93141, ~: 93141)
[PASS] test_reclaim_revertsWith_OnlyReinvestmentController_init() (gas: 40401)
[PASS] test_reclaim_revertsWith_underflow_exceedsSwept_afterSweep() (gas: 618602)
Suite result: ok. 11 passed; 0 failed; 0 skipped; finished in 14.81s (14.78s CPU time)

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

[PASS] test_addAsset_fuzz_revertsWith_InvalidAddress_feeReceiver(address,uint8,address) (runs: 5000, μ: 45261, ~: 44964)
Logs:
  Bound result 12

[PASS] test_addAsset_fuzz_revertsWith_InvalidAddress_irStrategy(address,uint8,address) (runs: 5000, μ: 45304, ~: 45007)
Logs:
  Bound result 12

[PASS] test_addAsset_fuzz_revertsWith_InvalidAddress_underlying(uint8,address,address) (runs: 5000, μ: 36669, ~: 36669)
[PASS] test_addAsset_fuzz_revertsWith_InvalidAssetDecimals(address,uint8,address,address) (runs: 5000, μ: 45915, ~: 45958)
Logs:
  Bound result 77

[PASS] test_addAsset_fuzz_revertsWith_InvalidAssetDecimals_tooLow(address,uint8,address,address) (runs: 5000, μ: 46038, ~: 46325)
Logs:
  Bound result 5

[PASS] test_addAsset_fuzz_reverts_InvalidIrData(address,uint8,address,address) (runs: 5000, μ: 79480398740, ~: 34913)
Logs:
  Bound result 1

[PASS] test_addAsset_revertsWith_BlockTimestampDowncastOverflow() (gas: 956689)
[PASS] test_addAsset_revertsWith_DrawnRateDowncastOverflow() (gas: 953822)
[PASS] test_addAsset_reverts_UnderlyingAlreadyListed() (gas: 48908)
[PASS] test_addSpoke_fuzz(uint256,(uint40,uint40,uint24,bool,bool)) (runs: 5000, μ: 126566, ~: 126616)
Logs:
  Bound result 0

[PASS] test_addSpoke_fuzz_revertsWith_AssetNotListed(uint256,(uint40,uint40,uint24,bool,bool)) (runs: 5000, μ: 35266, ~: 35255)
Logs:
  Bound result 5192296858534809181786422619668480

[PASS] test_addSpoke_fuzz_revertsWith_InvalidAddress_spoke(uint256,(uint40,uint40,uint24,bool,bool)) (runs: 5000, μ: 33863, ~: 33913)
Logs:
  Bound result 0

[PASS] test_addSpoke_revertsWith_SpokeAlreadyListed() (gas: 39752)
[PASS] test_getAssetId() (gas: 73028)
[PASS] test_getAssetId_fuzz_revertsWith_AssetNotListed(address) (runs: 5000, μ: 18584, ~: 18584)
[PASS] test_hub_deploy_reverts_on_InvalidConstructorInput() (gas: 831006)
[PASS] test_hub_max_riskPremium() (gas: 8566)
[PASS] test_isUnderlyingListed() (gas: 1178546)
[PASS] test_updateAssetConfig_NewFeeReceiver_noFees() (gas: 703717)
[PASS] test_updateAssetConfig_UseExistingSpokeAndListedAsFeeReceiver_revertsWith_SpokeAlreadyListed() (gas: 62261)
[PASS] test_updateAssetConfig_fuzz(uint256,(address,uint16,address,address)) (runs: 5000, μ: 267758, ~: 268081)
Logs:
  Bound result 2
  Bound result 79

[PASS] test_updateAssetConfig_fuzz_FromZeroLiquidityFee(uint256,uint16) (runs: 5000, μ: 826953, ~: 826813)
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, μ: 693221, ~: 693081)
Logs:
  Bound result 3
  Bound result 1
  Bound result 3
  Bound result 1

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

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

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

[PASS] test_updateAssetConfig_fuzz_Scenario(uint256) (runs: 5000, μ: 724265, ~: 724318)
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, μ: 61030, ~: 61083)
Logs:
  Bound result 3

[PASS] test_updateAssetConfig_fuzz_revertsWith_InvalidLiquidityFee(uint256,(address,uint16,address,address)) (runs: 5000, μ: 40115, ~: 40011)
Logs:
  Bound result 2
  Bound result 79

[PASS] test_updateAssetConfig_fuzz_revertsWith_InvalidReinvestmentController() (gas: 483812)
[PASS] test_updateAssetConfig_fuzz_revertsWith_calculateInterestRateReverts(uint256,(address,uint16,address,address)) (runs: 5000, μ: 194389, ~: 194827)
Logs:
  Bound result 0
  Bound result 1270

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

[PASS] test_updateAssetConfig_oldFeeReceiver_flags() (gas: 880987)
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, μ: 59116, ~: 59174)
Logs:
  Bound result 0

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

[PASS] test_updateSpokeConfig_revertsWith_AssetNotListed() (gas: 29640)
Suite result: ok. 37 passed; 0 failed; 0 skipped; finished in 93.05s (93.03s CPU time)

Ran 12 tests for tests/unit/Hub/Hub.RefreshPremium.t.sol:HubRefreshPremiumTest
[PASS] test_refreshPremium_emitsEvent() (gas: 253978)
[PASS] test_refreshPremium_fuzz_positiveDeltas(uint256,int256,int256) (runs: 5000, μ: 487825, ~: 493123)
Logs:
  Bound result 999999999910000000000000000001
  Bound result 1
  Bound result 2408

[PASS] test_refreshPremium_fuzz_withAccrual(uint256,uint256,uint256,uint256) (runs: 5000, μ: 473154, ~: 482674)
Logs:
  Bound result 900
  Bound result 75
  Bound result 720000000000000000
  Bound result 213201578440785225088721549752

[PASS] test_refreshPremium_haltedSpokesAllowed() (gas: 120811)
[PASS] test_refreshPremium_maxRiskPremiumThreshold() (gas: 907800)
[PASS] test_refreshPremium_negativeDeltas(uint256) (runs: 5000, μ: 457608, ~: 458155)
Logs:
  Bound result 3124043968137

[PASS] test_refreshPremium_negativeDeltas_withAccrual(uint256) (runs: 5000, μ: 535415, ~: 535636)
Logs:
  Bound result 3124043968137

[PASS] test_refreshPremium_revertsWith_InvalidPremiumChange_NonZeroRestoredPremiumRay() (gas: 866835)
[PASS] test_refreshPremium_revertsWith_InvalidPremiumChange_RiskPremiumThresholdExceeded_DecreasingPremium() (gas: 885201)
[PASS] test_refreshPremium_revertsWith_SpokeNotActive() (gas: 58802)
[PASS] test_refreshPremium_riskPremiumThreshold() (gas: 933279)
[PASS] test_refreshPremium_spokePremiumUpdateIsContained() (gas: 716930)
Suite result: ok. 12 passed; 0 failed; 0 skipped; finished in 20.56s (20.53s CPU time)

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

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

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

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

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

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

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

[PASS] test_draw_fuzz_revertsWith_InvalidAddress(uint256) (runs: 5000, μ: 16129, ~: 16129)
[PASS] test_draw_revertsWith_DrawCapExceeded_due_to_deficit() (gas: 269890)
[PASS] test_draw_revertsWith_InsufficientLiquidity() (gas: 28473)
[PASS] test_draw_revertsWith_InsufficientLiquidity_due_to_draw() (gas: 168682)
[PASS] test_draw_revertsWith_InsufficientLiquidity_due_to_remove() (gas: 131094)
[PASS] test_draw_revertsWith_InvalidAmount() (gas: 16260)
[PASS] test_draw_revertsWith_SpokeHalted() (gas: 61333)
[PASS] test_draw_revertsWith_SpokeNotActive() (gas: 61272)
Suite result: ok. 16 passed; 0 failed; 0 skipped; finished in 24.02s (23.99s CPU time)

Ran 15 tests for tests/unit/Hub/Hub.Remove.t.sol:HubRemoveTest
[PASS] test_remove() (gas: 210560)
Logs:
  Bound result 2
  Bound result 100000000000000000000

[PASS] test_remove_all_with_interest() (gas: 414788)
[PASS] test_remove_fuzz(uint256,uint256) (runs: 5000, μ: 209327, ~: 209266)
Logs:
  Bound result 4
  Bound result 100

[PASS] test_remove_fuzz_all_liquidity_with_interest(uint256,uint256) (runs: 5000, μ: 456111, ~: 461381)
Logs:
  Bound result 68691281934999
  Bound result 100

[PASS] test_remove_fuzz_multi_spoke(uint256,uint256) (runs: 5000, μ: 290139, ~: 290242)
Logs:
  Bound result 68691281934999
  Bound result 100

[PASS] test_remove_fuzz_multi_spoke_with_interest(uint256,uint256,uint256,uint256) (runs: 5000, μ: 458861, ~: 465202)
Logs:
  Bound result 931
  Bound result 24091
  Bound result 21580
  Bound result 9348

[PASS] test_remove_revertsWith_InsufficientLiquidity() (gas: 157797)
[PASS] test_remove_revertsWith_InsufficientLiquidity_exceeding_added_amount() (gas: 146833)
[PASS] test_remove_revertsWith_InsufficientLiquidity_zero_added() (gas: 21367)
[PASS] test_remove_revertsWith_InvalidAddress() (gas: 16462)
[PASS] test_remove_revertsWith_InvalidAmount() (gas: 18619)
[PASS] test_remove_revertsWith_SpokeHalted() (gas: 61852)
[PASS] test_remove_revertsWith_SpokeNotActive() (gas: 61761)
[PASS] test_remove_revertsWith_underflow_exceeding_added_amount() (gas: 184415)
[PASS] test_remove_revertsWtih_underflow_one_extra_wei() (gas: 370116)
Suite result: ok. 15 passed; 0 failed; 0 skipped; finished in 31.41s (31.39s CPU time)

Ran 8 tests for tests/unit/Hub/Hub.EliminateDeficit.t.sol:HubEliminateDeficitTest
[PASS] test_eliminateDeficit(uint256) (runs: 5000, μ: 676465, ~: 676465)
[PASS] test_eliminateDeficit_fuzz_revertsWith_AccessManagedUnauthorized(address) (runs: 5000, μ: 32536, ~: 32536)
[PASS] test_eliminateDeficit_fuzz_revertsWith_ArithmeticUnderflow_CallerSpokeNoFunds(uint256) (runs: 5000, μ: 356244, ~: 356244)
[PASS] test_eliminateDeficit_revertsWith_InvalidAmount_ZeroAmountNoDeficit() (gas: 36016)
[PASS] test_eliminateDeficit_revertsWith_InvalidAmount_ZeroAmountWithDeficit() (gas: 352349)
[PASS] test_eliminateDeficit_revertsWith_InvalidAmount_on_UnregisteredCoveredSpoke() (gas: 36403)
[PASS] test_eliminateDeficit_revertsWith_SpokeNotActive_on_UnregisteredAsset() (gas: 387994)
[PASS] test_eliminateDeficit_revertsWith_callerSpokeNotActive() (gas: 159271)
Suite result: ok. 8 passed; 0 failed; 0 skipped; finished in 16.73s (16.70s CPU time)

Ran 8 tests for tests/gas/Hub.Operations.gas.t.sol:HubOperations_Gas_Tests
[PASS] test_add() (gas: 269522)
[PASS] test_deficit() (gas: 1350665)
[PASS] test_draw() (gas: 417756)
[PASS] test_payFee_transferShares() (gas: 980175)
[PASS] test_refreshPremium() (gas: 633867)
[PASS] test_remove() (gas: 309580)
[PASS] test_restore() (gas: 903369)
[PASS] test_restore_with_transfer() (gas: 904012)
Suite result: ok. 8 passed; 0 failed; 0 skipped; finished in 50.45ms (6.50ms CPU time)

Ran 14 tests for tests/gas/Spoke.Operations.gas.t.sol:SpokeOperations_Gas_Tests
[PASS] test_borrow() (gas: 1362426)
[PASS] test_liquidation_full() (gas: 10901703)
[PASS] test_liquidation_partial() (gas: 10901120)
[PASS] test_liquidation_receiveShares_full() (gas: 10884418)
[PASS] test_liq...*[Comment body truncated]*

@github-actions
Copy link

github-actions bot commented Feb 5, 2026

♻️ Forge Gas Snapshots

Path Value
snapshots/Hub.Operations.json
add ↓0% (-304) 86,399
add: with transfer ↓0% (-304) 107,696
draw ↓0% (-222) 103,937
eliminateDeficit: full ↓0% (-340) 72,238
eliminateDeficit: partial ↓0% (-340) 81,843
payFee ↑4% (+2913) 73,729
refreshPremium ↓1% (-410) 69,963
remove: full ↓1% (-473) 75,134
remove: partial ↓0% (-340) 80,405
reportDeficit ↑9% (+10034) 121,927
restore: full ↑17% (+12834) 89,397
restore: full - with transfer ↑8% (+13201) 182,373
restore: partial ↑15% (+12834) 98,107
restore: partial - with transfer ↑9% (+12834) 156,087
transferShares ↑14% (+9713) 79,343
mintFeeShares 82,752
snapshots/NativeTokenGateway.Operations.json
borrowNative ↓0% (-277) 228,379
repayNative ↑0% (+85) 166,556
supplyAsCollateralNative ↓0% (-304) 159,829
supplyNative ↓0% (-243) 135,519
withdrawNative: full ↓0% (-233) 125,324
withdrawNative: partial ↓0% (-292) 136,454
snapshots/SignatureGateway.Operations.json
borrowWithSig ↓0% (-277) 213,612
repayWithSig ↑0% (+85) 186,828
supplyWithSig ↓0% (-243) 151,751
withdrawWithSig ↓0% (-234) 130,578
snapshots/Spoke.Getters.json
getUserAccountData: supplies: 1, borrows: 0 ↑0% (+48) 49,474
getUserAccountData: supplies: 2, borrows: 0 ↑0% (+96) 81,198
getUserAccountData: supplies: 2, borrows: 1 ↑0% (+183) 101,714
getUserAccountData: supplies: 2, borrows: 2 ↑0% (+270) 121,061
snapshots/Spoke.Operations.ZeroRiskPremium.json
borrow: first ↑7% (+12969) 203,353
borrow: second action, same reserve ↑8% (+12969) 183,219
liquidationCall (receiveShares): full ↑4% (+12828) 316,089
liquidationCall (receiveShares): partial ↑4% (+12828) 315,507
liquidationCall (reportDeficit): full ↑3% (+12399) 378,782
liquidationCall: full ↑4% (+12536) 333,433
liquidationCall: partial ↑4% (+12536) 332,851
permitReserve + repay (multicall) ↓0% (-2) 164,574
permitReserve + supply (multicall) ↓0% (-304) 146,452
permitReserve + supply + enable collateral (multicall) ↓0% (-304) 160,903
repay: full ↓0% (-2) 123,912
repay: partial ↓0% (-2) 128,870
supply + enable collateral (multicall) ↓0% (-304) 141,105
supply: 0 borrows, collateral disabled ↓0% (-304) 122,542
supply: 0 borrows, collateral enabled ↓0% (-304) 105,513
supply: second action, same reserve ↓0% (-304) 105,442
updateUserRiskPremium: 1 borrow ↑0% (+135) 95,869
updateUserRiskPremium: 2 borrows ↑1% (+866) 106,280
usingAsCollateral: 1 borrow, disable ↑0% (+135) 105,913
usingAsCollateral: 2 borrows, disable ↑0% (+222) 127,549
withdraw: 0 borrows, full ↓0% (-425) 127,530
withdraw: 0 borrows, partial ↓0% (-244) 132,607
withdraw: 1 borrow, partial ↓0% (-290) 159,692
withdraw: 2 borrows, partial ↓0% (-70) 174,470
withdraw: non collateral ↓0% (-292) 105,610
snapshots/Spoke.Operations.json
borrow: first ↑5% (+12646) 271,965
borrow: second action, same reserve ↑6% (+12646) 214,831
liquidationCall (receiveShares): full ↑4% (+12505) 347,810
liquidationCall (receiveShares): partial ↑4% (+12505) 347,228
liquidationCall (reportDeficit): full ↑3% (+12399) 373,399
liquidationCall: full ↑3% (+12213) 365,154
liquidationCall: partial ↑3% (+12213) 364,572
permitReserve + repay (multicall) ↓0% (-1) 162,043
permitReserve + supply (multicall) ↓0% (-304) 146,452
permitReserve + supply + enable collateral (multicall) ↓0% (-304) 160,903
repay: full ↓0% (-2) 117,991
repay: partial ↓0% (-2) 137,349
supply + enable collateral (multicall) ↓0% (-304) 141,105
supply: 0 borrows, collateral disabled ↓0% (-304) 122,542
supply: 0 borrows, collateral enabled ↓0% (-304) 105,513
supply: second action, same reserve ↓0% (-304) 105,442
updateUserRiskPremium: 1 borrow ↑7% (+9935) 159,028
updateUserRiskPremium: 2 borrows ↑10% (+20466) 219,821
usingAsCollateral: 1 borrow, disable ↑6% (+9935) 169,069
usingAsCollateral: 2 borrows, disable ↑9% (+19822) 249,086
withdraw: 0 borrows, full ↓0% (-425) 127,530
withdraw: 0 borrows, partial ↓0% (-244) 132,607
withdraw: 1 borrow, partial ↑5% (+9510) 220,346
withdraw: 2 borrows, partial ↓0% (-716) 256,296
withdraw: non collateral ↓0% (-292) 105,610
🔕 Unchanged
Path Value
snapshots/SignatureGateway.Operations.json
setSelfAsUserPositionManagerWithSig 75,385
setUsingAsCollateralWithSig 85,387
updateUserDynamicConfigWithSig 63,120
updateUserRiskPremiumWithSig 62,090
snapshots/Spoke.Getters.json
getUserAccountData: supplies: 0, borrows: 0 13,014
snapshots/Spoke.Operations.ZeroRiskPremium.json
setUserPositionManagersWithSig: disable 47,039
setUserPositionManagersWithSig: enable 68,951
updateUserDynamicConfig: 1 collateral 74,545
updateUserDynamicConfig: 2 collaterals 89,413
usingAsCollateral: 0 borrows, enable 59,616
usingAsCollateral: 1 borrow, enable 42,504
usingAsCollateral: 2 borrows, enable 42,516
snapshots/Spoke.Operations.json
setUserPositionManagersWithSig: disable 47,039
setUserPositionManagersWithSig: enable 68,951
updateUserDynamicConfig: 1 collateral 74,545
updateUserDynamicConfig: 2 collaterals 89,413
usingAsCollateral: 0 borrows, enable 59,616
usingAsCollateral: 1 borrow, enable 42,504
usingAsCollateral: 2 borrows, enable 42,516

@github-actions
Copy link

github-actions bot commented Feb 5, 2026

Forge Build Sizes

Contract Runtime Size (B) Initcode Size (B) Runtime Margin (B) Initcode Margin (B)
Hub ↑2% (+456) 24,003 ↑2% (+456) 24,200 ↓44% (-456) 573 ↓2% (-456) 24,952
🔕 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
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,318 12,370 12,258 36,782
LiquidationLogic.spoke 9,772 9,804 14,804 39,348
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
NativeTokenGateway 6,187 6,604 18,389 42,548
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
SignatureGateway 11,485 12,024 13,091 37,128
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
SpokeInstance 24,352 25,159 224 23,993
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
TreasurySpoke 3,599 4,014 20,977 45,138
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

Copy link
Member

@DhairyaSethi DhairyaSethi left a comment

Choose a reason for hiding this comment

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

title is wrong, this doesn't do perfect shares, it just delays minting until one share

@CheyenneAtapour CheyenneAtapour changed the title rft: Mint perfect fee shares during accrual rft: Mint fee shares when realized fees exceed one share Feb 6, 2026
) internal view returns (uint256, uint256) {
(uint256 feeAmount, uint256 feeShares) = asset.getFee(drawnIndex, previousIndex);

uint256 realizedFees = feeShares > 0 ? 0 : feeAmount;
Copy link
Member

Choose a reason for hiding this comment

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

this is kinda confusing at first glance so pls add a comment saying how when feeShares are non zero it means all of feeAmount is minted else not OR revisit how getFee helper returns information, possibly passing it through an intermediary wrapper which does this logic

Copy link
Member

Choose a reason for hiding this comment

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

the logic is correct tho, and exactly how i did it in accrue but in isolation is weird


uint256 realizedFees = feeShares > 0 ? 0 : feeAmount;

uint256 aggregatedOwedRay = _calculateAggregatedOwedRay({
Copy link
Member

Choose a reason for hiding this comment

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

this is being recalculated for the third from bc of getFee, lets see if we can cache it

Comment on lines +231 to +235
/// @notice Calculates the amount of unrealized fee shares since last accrual.
function unrealizedFeeShares(IHub.Asset storage asset) internal view returns (uint256) {
(, uint256 feeShares) = asset.getFee(asset.getDrawnIndex(), asset.drawnIndex);
return feeShares;
}
Copy link
Member

Choose a reason for hiding this comment

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

this should not be needed anymore right

}

/// @notice Calculates the amount of fee shares derived from the index growth due to interest accrual.
/// @dev The true liquidity growth is always greater than accrued fees, even with 100.00% liquidity fee.
Copy link
Member

Choose a reason for hiding this comment

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

this comment is not true anymore i think? anyway something for later

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