Skip to content

Comments

fix: gas tests with interest accrual (1193 vs dev)#1192

Closed
yan-man wants to merge 27 commits intofix/gas-testsfrom
fix/gas-test-mintFeeShares
Closed

fix: gas tests with interest accrual (1193 vs dev)#1192
yan-man wants to merge 27 commits intofix/gas-testsfrom
fix/gas-test-mintFeeShares

Conversation

@yan-man
Copy link
Contributor

@yan-man yan-man commented Feb 4, 2026

branched off #1193, vs dev

@github-actions
Copy link

github-actions bot commented Feb 4, 2026

🌈 Test Results
No files changed, compilation skipped

Ran 14 tests for tests/gas/Spoke.Operations.gas.t.sol:SpokeOperations_Gas_Tests
[PASS] test_borrow() (gas: 1637522)
[PASS] test_liquidation_full() (gas: 10810083)
[PASS] test_liquidation_partial() (gas: 10809500)
[PASS] test_liquidation_receiveShares_full() (gas: 10775813)
[PASS] test_liquidation_receiveShares_partial() (gas: 10775232)
[PASS] test_liquidation_reportDeficit_full() (gas: 10819195)
[PASS] test_multicall_ops() (gas: 1726193)
[PASS] test_repay() (gas: 899430)
[PASS] test_setUserPositionManagersWithSig() (gas: 311532)
[PASS] test_supply() (gas: 581923)
[PASS] test_updateRiskPremium() (gas: 1309135)
[PASS] test_updateUserDynamicConfig() (gas: 588935)
[PASS] test_usingAsCollateral() (gas: 1447758)
[PASS] test_withdraw() (gas: 1947427)
Suite result: ok. 14 passed; 0 failed; 0 skipped; finished in 85.16ms (37.87ms CPU time)

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: 5, μ: 20214, ~: 20214)
Logs:
  Bound result 3

[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: 5010072)
[PASS] test_setSpoke() (gas: 5037974)
[PASS] test_setSpoke_revertsWith_InvalidAddress() (gas: 10870)
[PASS] test_setSpoke_revertsWith_OnlyDeployer(address) (runs: 5, μ: 13397, ~: 13397)
[PASS] test_setSpoke_revertsWith_SpokeAlreadySet() (gas: 15080)
Suite result: ok. 20 passed; 0 failed; 0 skipped; finished in 161.43ms (147.76ms CPU time)

Ran 14 tests for tests/gas/Spoke.Operations.gas.t.sol:SpokeOperations_ZeroRiskPremium_Gas_Tests
[PASS] test_borrow() (gas: 1383946)
[PASS] test_liquidation_full() (gas: 10710429)
[PASS] test_liquidation_partial() (gas: 10709846)
[PASS] test_liquidation_receiveShares_full() (gas: 10676159)
[PASS] test_liquidation_receiveShares_partial() (gas: 10675578)
[PASS] test_liquidation_reportDeficit_full() (gas: 10756542)
[PASS] test_multicall_ops() (gas: 1657050)
[PASS] test_repay() (gas: 824017)
[PASS] test_setUserPositionManagersWithSig() (gas: 315986)
[PASS] test_supply() (gas: 584604)
[PASS] test_updateRiskPremium() (gas: 945397)
[PASS] test_updateUserDynamicConfig() (gas: 593389)
[PASS] test_usingAsCollateral() (gas: 1112907)
[PASS] test_withdraw() (gas: 1631085)
Suite result: ok. 14 passed; 0 failed; 0 skipped; finished in 92.00ms (33.64ms CPU time)

Ran 4 tests for tests/unit/Spoke/Spoke.PermitReserve.t.sol:SpokePermitReserveTest
[PASS] test_permitReserve() (gas: 88227)
[PASS] test_permitReserve_forwards_correct_call() (gas: 35554)
[PASS] test_permitReserve_ignores_permit_reverts() (gas: 24390)
[PASS] test_permitReserve_revertsWith_ReserveNotListedIn() (gas: 22927)
Suite result: ok. 4 passed; 0 failed; 0 skipped; finished in 23.93ms (1.04ms CPU time)

Ran 17 tests for tests/unit/AccessManagerEnumerable.t.sol:AccessManagerEnumerableTest
[PASS] test_getRoleMembers_fuzz(uint256,uint256) (runs: 5, μ: 1978345, ~: 1977224)
Logs:
  Bound result 6
  Bound result 12

[PASS] test_getRoleTargetSelectors_fuzz(uint256,uint256) (runs: 5, μ: 1526335, ~: 1525471)
Logs:
  Bound result 6
  Bound result 12

[PASS] test_grantRole() (gas: 315886)
[PASS] test_grantRole_fuzz(uint64,uint256) (runs: 5, μ: 894811, ~: 919753)
Logs:
  Bound result 2

[PASS] test_revokeRole() (gas: 323138)
[PASS] test_setRoleAdmin_fuzz_trackAdminRoles_multipleRoles_multipleAdmins(uint256) (runs: 5, μ: 1523143, ~: 1825652)
Logs:
  Bound result 4

[PASS] test_setRoleAdmin_fuzz_trackRolesAndTrackAdminRoles_multipleRoles(uint256) (runs: 5, μ: 1298012, ~: 1469938)
Logs:
  Bound result 4

[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 105.25ms (104.21ms CPU time)

Ran 10 tests for tests/unit/Spoke/Spoke.PositionManager.t.sol:SpokePositionManagerTest
[PASS] test_onlyPositionManager_on_borrow() (gas: 537507)
[PASS] test_onlyPositionManager_on_repay() (gas: 562800)
[PASS] test_onlyPositionManager_on_supply() (gas: 291241)
[PASS] test_onlyPositionManager_on_updateUserDynamicConfig() (gas: 1284419)
[PASS] test_onlyPositionManager_on_updateUserRiskPremium() (gas: 1523546)
[PASS] test_onlyPositionManager_on_usingAsCollateral() (gas: 144153)
[PASS] test_onlyPositionManager_on_withdraw() (gas: 319812)
[PASS] test_renouncePositionManagerRole() (gas: 20246)
[PASS] test_renouncePositionManagerRole_noop_from_disabled() (gas: 21860)
[PASS] test_setApprovalForPositionManager(bytes32) (runs: 5, μ: 18089, ~: 18089)
Suite result: ok. 10 passed; 0 failed; 0 skipped; finished in 118.68ms (95.89ms CPU time)

Ran 7 tests for tests/unit/Spoke/Spoke.Repay.EdgeCases.t.sol:SpokeRepayEdgeCaseTest
[PASS] test_fuzz_repay_effect_on_ex_rates(uint256,uint256) (runs: 5, μ: 707516, ~: 708997)
Logs:
  Bound result 61535656045728715735036875056
  Bound result 685180691
  Bound result 136475009112242956586343982035

[PASS] test_repay_less_than_share() (gas: 609853)
[PASS] test_repay_only_base_debt_interest() (gas: 775898)
[PASS] test_repay_only_base_debt_no_premium() (gas: 654226)
[PASS] test_repay_supply_ex_rate_decr() (gas: 1462463)
[PASS] test_repay_supply_ex_rate_decr_skip_time() (gas: 1458877)
[PASS] test_repay_zero_shares_nonzero_premium_debt() (gas: 764172)
Suite result: ok. 7 passed; 0 failed; 0 skipped; finished in 154.65ms (131.70ms 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: 5, μ: 24193, ~: 24330)
Logs:
  Bound result 953
  Bound result 652288372909708709858213579545

[PASS] test_calculateInterestRate_RightToKinkPoint(uint256) (runs: 5, μ: 25350, ~: 25351)
Logs:
  Bound result 8953
  Bound result 652288372909708709858213579545

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

[PASS] test_calculateInterestRate_fuzz_ZeroDebt(uint256) (runs: 5, μ: 18958, ~: 18822)
Logs:
  Bound result 1487224953

[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 221.59ms (205.52ms 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: 5, μ: 6805, ~: 6805)
[PASS] test_hash_positionManagerUpdate_fuzz((address,bool)) (runs: 5, μ: 6193, ~: 6193)
[PASS] test_hash_repay_fuzz((address,uint256,uint256,address,uint256,uint256)) (runs: 5, μ: 6806, ~: 6806)
[PASS] test_hash_setUserPositionManagers_fuzz((address,(address,bool)[],uint256,uint256)) (runs: 5, μ: 322956, ~: 350797)
[PASS] test_hash_setUsingAsCollateral_fuzz((address,uint256,bool,address,uint256,uint256)) (runs: 5, μ: 7305, ~: 7305)
[PASS] test_hash_supply_fuzz((address,uint256,uint256,address,uint256,uint256)) (runs: 5, μ: 6849, ~: 6849)
[PASS] test_hash_updateUserDynamicConfig_fuzz((address,address,uint256,uint256)) (runs: 5, μ: 6450, ~: 6450)
[PASS] test_hash_updateUserRiskPremium_fuzz((address,address,uint256,uint256)) (runs: 5, μ: 6471, ~: 6471)
[PASS] test_hash_withdraw_fuzz((address,uint256,uint256,address,uint256,uint256)) (runs: 5, μ: 6805, ~: 6805)
Suite result: ok. 10 passed; 0 failed; 0 skipped; finished in 107.60ms (107.29ms CPU time)

Ran 7 tests for tests/unit/Spoke/Spoke.AccrueInterest.t.sol:SpokeAccrueInterestTest
[PASS] test_accrueInterest_NoActionTaken() (gas: 138862)
[PASS] test_accrueInterest_NoInterest_NoDebt(uint40) (runs: 5, μ: 647738, ~: 647466)
Logs:
  Bound result 9479

[PASS] test_accrueInterest_NoInterest_OnlySupply(uint40) (runs: 5, μ: 255982, ~: 255710)
Logs:
  Bound result 9479

[PASS] test_accrueInterest_TenPercentRp(uint256,uint40) (runs: 5, μ: 587519, ~: 587550)
Logs:
  Bound result 237204489940516001543748446066
  Bound result 9271

[PASS] test_accrueInterest_fuzz_BorrowAmountAndSkipTime(uint256,uint40) (runs: 5, μ: 546767, ~: 546865)
Logs:
  Bound result 307589881277111429604248989731
  Bound result 9271

[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: 5, μ: 4096469, ~: 4097026)
Logs:
  Bound result 309425946788297219012937972879
  Bound result 451793245268469845329932546549
  Bound result 11647
  Bound result 74768436363656985453
  Bound result 444860966668015932389501662077
  Bound result 844269475657800115044182820366
  Bound result 548707868091040472
  Bound result 85886370499055179822
  Bound result 1
  Bound result 14
  Bound result 39259
  Bound result 834
  Bound result 357751
  Bound result 444860966668015932389501662077
  Bound result 844269475657800115044182820366
  Bound result 548707868091040472
  Bound result 16068272383032175514

Suite result: ok. 6 passed; 0 failed; 1 skipped; finished in 612.83ms (575.43ms CPU time)

Ran 3 tests for tests/unit/misc/ExtSload.t.sol:ExtSloadTest
[PASS] test_extSload(bytes32) (runs: 5, μ: 9767, ~: 9767)
[PASS] test_extSloads(uint256) (runs: 5, μ: 877288, ~: 641902)
Logs:
  Bound result 940

[PASS] test_extSloads(uint256,bytes) (runs: 5, μ: 1025436, ~: 1204453)
Logs:
  Bound result 14

Suite result: ok. 3 passed; 0 failed; 0 skipped; finished in 98.49ms (98.20ms CPU time)

Ran 8 tests for tests/unit/misc/GatewayBase.t.sol:GatewayBaseTest
[PASS] test_constructor() (gas: 17151)
[PASS] test_registerSpoke_fuzz(address) (runs: 5, μ: 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: 65249)
[PASS] test_renouncePositionManagerRole_revertsWith_InvalidAddress() (gas: 74198)
[PASS] test_renouncePositionManagerRole_revertsWith_OwnableUnauthorizedAccount() (gas: 74417)
Suite result: ok. 8 passed; 0 failed; 0 skipped; finished in 113.06ms (90.27ms CPU time)

Ran 5 tests for tests/gas/Gateways.Operations.gas.t.sol:NativeTokenGateway_Gas_Tests
[PASS] test_borrowNative() (gas: 931466)
[PASS] test_repayNative() (gas: 1001589)
[PASS] test_supplyAndCollateralNative() (gas: 309441)
[PASS] test_supplyNative() (gas: 289388)
[PASS] test_withdrawNative() (gas: 516134)
Suite result: ok. 5 passed; 0 failed; 0 skipped; finished in 71.59ms (9.28ms CPU time)

Ran 8 tests for tests/gas/Gateways.Operations.gas.t.sol:SignatureGateway_Gas_Tests
[PASS] test_borrowWithSig() (gas: 647181)
[PASS] test_repayWithSig() (gas: 880781)
[PASS] test_setSelfAsUserPositionManagerWithSig() (gas: 205811)
[PASS] test_setUsingAsCollateralWithSig() (gas: 227239)
[PASS] test_supplyWithSig() (gas: 432995)
[PASS] test_updateUserDynamicConfigWithSig() (gas: 222827)
[PASS] test_updateUserRiskPremiumWithSig() (gas: 220492)
[PASS] test_withdrawWithSig() (gas: 475504)
Suite result: ok. 8 passed; 0 failed; 0 skipped; finished in 102.91ms (17.86ms CPU time)

Ran 6 tests for tests/unit/Hub/Hub.Access.t.sol:HubAccessTest
[PASS] test_change_authority() (gas: 204061)
[PASS] test_change_role_responsibility() (gas: 108219)
[PASS] test_hub_access_manager_exposure() (gas: 13417)
[PASS] test_hub_admin_access() (gas: 1347864)
[PASS] test_migrate_role_responsibility() (gas: 695238)
[PASS] test_setInterestRateData_access() (gas: 102110)
Suite result: ok. 6 passed; 0 failed; 0 skipped; finished in 53.75ms (6.74ms CPU time)

Ran 4 tests for tests/unit/Hub/Hub.Accrual.t.sol:HubAccrualTest
[PASS] test_accrual_fractionalFeeRemainderDonatedToSuppliers() (gas: 429961)
[PASS] test_accrual_fuzz_basicAccrual(uint256,uint256,uint256,uint256) (runs: 5, μ: 305376, ~: 305766)
Logs:
  Bound result 240336
  Bound result 69496
  Bound result 4615
  Bound result 555770955

[PASS] test_accrual_realizedFeesAccumulation() (gas: 467351)
[PASS] test_accrual_roundsToZero() (gas: 259241)
Suite result: ok. 4 passed; 0 failed; 0 skipped; finished in 132.95ms (85.60ms CPU time)

Ran 8 tests for tests/unit/Spoke/Spoke.Repay.Scenario.t.sol:SpokeRepayScenarioTest
[PASS] test_fuzz_repay_borrow_twice_repay_twice((uint256,uint256,uint256,uint40),(uint256,uint256,uint256,uint40)) (runs: 5, μ: 1265410, ~: 1272657)
Logs:
  Bound result 208367672
  Bound result 540294
  Bound result 109623245259112484576750683753
  Bound result 1263
  Bound result 50354475879357019595435741496
  Bound result 263

[PASS] test_fuzz_repay_multiple_users_repay_same_reserve((uint256,uint256,uint256,uint256,uint256,uint256,address),(uint256,uint256,uint256,uint256,uint256,uint256,address),(uint256,uint256,uint256,uint256,uint256,uint256,address),uint256) (runs: 5, μ: 2031117, ~: 2002466)
Logs:
  Bound result 35521638
  Bound result 81176203421215730985692698427786438291
  Bound result 119010746400778280078724075902
  Bound result 262619362825411379252910
  Bound result 17949190939892888153940303291
  Bound result 80950826076510664087
  Bound result 684334482

[PASS] test_repay_fuzz_multiple_users_multiple_assets(((uint256,uint256,uint256,uint256,uint256),(uint256,uint256,uint256,uint256,uint256),(uint256,uint256,uint256,uint256,uint256),(uint256,uint256,uint256,uint256,uint256),address),((uint256,uint256,uint256,uint256,uint256),(uint256,uint256,uint256,uint256,uint256),(uint256,uint256,uint256,uint256,uint256),(uint256,uint256,uint256,uint256,uint256),address),((uint256,uint256,uint256,uint256,uint256),(uint256,uint256,uint256,uint256,uint256),(uint256,uint256,uint256,uint256,uint256),(uint256,uint256,uint256,uint256,uint256),address),uint40) (runs: 5, μ: 6069579, ~: 6070837)
Logs:
  Bound result 98469853108740220498148447521
  Bound result 131982024
  Bound result 116517399225526502
  Bound result 12499999999999999997
  Bound result 1341942651957904745192234737585088609230901175536654532
  Bound result 17438016466678753943887865820728
  Bound result 751328689291
  Bound result 157988295730145263148275090
  Bound result 2275759165667927916113
  Bound result 1
  Bound result 8452575918
  Bound result 2834348807251805636
  Bound result 115792089237316195423570985008687907853269984665640564039457584007913129639932
  Bound result 61231253981096557722913982151550825151251736391110
  Bound result 1
  Bound result 216784
  Bound result 62426079198912245280213750863
  Bound result 31595595582394787544090247671
  Bound result 83711669789667461
  Bound result 2304011979587570615
  Bound result 455813684847602087077913799822870
  Bound result 61723456009873286998989343243341918836877216564666029
  Bound result 72682129539799449189227775289771251484
  Bound result 246462844000269
  Bound result 1

[PASS] test_repay_fuzz_two_users_multiple_assets(((uint256,uint256,uint256,uint256,uint256),(uint256,uint256,uint256,uint256,uint256),(uint256,uint256,uint256,uint256,uint256),(uint256,uint256,uint256,uint256,uint256),address),((uint256,uint256,uint256,uint256,uint256),(uint256,uint256,uint256,uint256,uint256),(uint256,uint256,uint256,uint256,uint256),(uint256,uint256,uint256,uint256,uint256),address),uint40) (runs: 5, μ: 4300898, ~: 4304294)
Logs:
  Bound result 660
  Bound result 618971568
  Bound result 125000000000000000
  Bound result 11345383135807258110
  Bound result 18666
  Bound result 2416848901162085006357853330899043873671595082034351970559937023807584503111
  Bound result 20000000000000000000
  Bound result 13713
  Bound result 500000
  Bound result 710
  Bound result 9471
  Bound result 11500000000000000000
  Bound result 50000000000000000000000000000000000000000000000000000000000000000000000
  Bound result 509019607843137254
  Bound result 9000000000000000000000
  Bound result 4429
  Bound result 335

[PASS] test_repay_partial_then_max() (gas: 700842)
[PASS] test_repay_round_trip_borrow_repay(uint256,uint256,uint40,address,uint256) (runs: 5, μ: 878079, ~: 880011)
Logs:
  Bound result 4
  Bound result 498297531617148238517417
  Bound result 465835
  Bound result 381479558105923253984856784849

[PASS] test_repay_round_trip_repay_borrow(uint256,uint256,uint256,uint40,address,uint256) (runs: 5, μ: 960555, ~: 961883)
Logs:
  Bound result 1
  Bound result 42731252303345670488
  Bound result 1402
  Bound result 1
  Bound result 1160890843375591607

[PASS] test_repay_two_users_repay_same_reserve((uint256,uint256,uint256,uint256,uint256,uint256,address),(uint256,uint256,uint256,uint256,uint256,uint256,address),uint256) (runs: 5, μ: 1499937, ~: 1499456)
Logs:
  Bound result 51357815211658894582790524924
  Bound result 102849095086241930933158640
  Bound result 124118994424291570164731570623
  Bound result 310722473864281185330171465074883744373909089061156469175077
  Bound result 47

Suite result: ok. 8 passed; 0 failed; 0 skipped; finished in 976.30ms (952.56ms CPU time)

Ran 2 tests for tests/unit/Spoke/Spoke.Repay.Validation.t.sol:SpokeRepayValidationTest
[PASS] test_repay_revertsWith_ReserveNotListed() (gas: 23184)
[PASS] test_repay_revertsWith_ReservePaused() (gas: 63682)
Suite result: ok. 2 passed; 0 failed; 0 skipped; finished in 23.70ms (376.44µs CPU time)

Ran 19 tests for tests/unit/Hub/Hub.Add.t.sol:HubAddTest
[PASS] test_add_AddCapReachedButNotExceeded_rounding() (gas: 675263)
[PASS] test_add_fuzz_AddCapReachedButNotExceeded(uint40) (runs: 5, μ: 159755, ~: 159699)
Logs:
  Bound result 9366

[PASS] test_add_fuzz_multi_asset_multi_spoke(uint256,uint256,uint256) (runs: 5, μ: 336166, ~: 335760)
Logs:
  Bound result 2
  Bound result 276197703734924979325426575862
  Bound result 4896747

[PASS] test_add_fuzz_revertsWith_AddCapExceeded(uint40) (runs: 5, μ: 112438, ~: 112382)
Logs:
  Bound result 9366

[PASS] test_add_fuzz_revertsWith_AddCapExceeded_due_to_interest(uint40,uint256,uint256) (runs: 5, μ: 274324, ~: 275701)
Logs:
  Bound result 476358262
  Bound result 386270036924979325426576441
  Bound result 4896747

[PASS] test_add_fuzz_revertsWith_InvalidShares_due_to_index(uint256,uint256,uint256) (runs: 5, μ: 229381, ~: 229381)
Logs:
  Bound result 740130867392857144266204334010
  Bound result 3126960748
  Bound result 10

[PASS] test_add_fuzz_single_asset(uint256,address,uint256) (runs: 5, μ: 343739, ~: 343852)
Logs:
  Bound result 2
  Bound result 1466075083157903748843

[PASS] test_add_fuzz_single_spoke_multi_add(uint256,uint256) (runs: 5, μ: 835677, ~: 833057)
Logs:
  Bound result 107589881277111429604248989731
  Bound result 9470

[PASS] test_add_multi_add_minimal_shares() (gas: 340303)
[PASS] test_add_revertsWith_AmountDowncastOverflow() (gas: 360699)
[PASS] test_add_revertsWith_InsufficientTransferred() (gas: 64495)
[PASS] test_add_revertsWith_InvalidAmount() (gas: 13622)
[PASS] test_add_revertsWith_InvalidShares() (gas: 229473)
[PASS] test_add_revertsWith_SharesDowncastOverflow() (gas: 224464)
[PASS] test_add_revertsWith_SpokeHalted() (gas: 99586)
[PASS] test_add_revertsWith_SpokeNotActive() (gas: 99622)
[PASS] test_add_single_asset() (gas: 331711)
Logs:
  Bound result 2
  Bound result 100000000000000000000

[PASS] test_add_with_increased_index() (gas: 316918)
[PASS] test_add_with_increased_index_with_premium() (gas: 691551)
Suite result: ok. 19 passed; 0 failed; 0 skipped; finished in 766.04ms (741.96ms CPU time)

Ran 8 tests for tests/unit/Spoke/Liquidations/Spoke.LiquidationCall.t.sol:SpokeLiquidationCallTest_LargeLiquidationBonus
[PASS] test_liquidationCall_fuzz_ManyCollaterals_ManyDebts_UserInsolvent(uint256,uint256,uint256,bool) (runs: 5, μ: 41159378, ~: 41156128)
Logs:
  Bound result 0
  Bound result 1
  Bound result 296839640696092776623130772489

[PASS] test_liquidationCall_fuzz_ManyCollaterals_ManyDebts_UserSolvent(uint256,uint256,uint256,bool) (runs: 5, μ: 41150951, ~: 41148825)
Logs:
  Bound result 0
  Bound result 1
  Bound result 296839640696092776623130772489

[PASS] test_liquidationCall_fuzz_ManyCollaterals_OneDebt_UserInsolvent(uint256,uint256,uint256,bool) (runs: 5, μ: 30477904, ~: 30448132)
Logs:
  Bound result 0
  Bound result 1
  Bound result 296839640696092776623130772489

[PASS] test_liquidationCall_fuzz_ManyCollaterals_OneDebt_UserSolvent(uint256,uint256,uint256,bool) (runs: 5, μ: 30511036, ~: 30441116)
Logs:
  Bound result 0
  Bound result 1
  Bound result 296839640696092776623130772489

[PASS] test_liquidationCall_fuzz_OneCollateral_ManyDebts_UserInsolvent(uint256,uint256,uint256,bool) (runs: 5, μ: 39170078, ~: 38494887)
Logs:
  Bound result 0
  Bound result 1
  Bound result 296839640696092776623130772489

[PASS] test_liquidationCall_fuzz_OneCollateral_ManyDebts_UserSolvent(uint256,uint256,uint256,bool) (runs: 5, μ: 39374393, ~: 38790762)
Logs:
  Bound result 0
  Bound result 1
  Bound result 296839640696092776623130772489

[PASS] test_liquidationCall_fuzz_OneCollateral_OneDebt_UserInsolvent(uint256,uint256,uint256,bool) (runs: 5, μ: 29395860, ~: 29364640)
Logs:
  Bound result 0
  Bound result 1
  Bound result 296839640696092776623130772489

[PASS] test_liquidationCall_fuzz_OneCollateral_OneDebt_UserSolvent(uint256,uint256,uint256,bool) (runs: 5, μ: 29555600, ~: 29476885)
Logs:
  Bound result 0
  Bound result 1
  Bound result 296839640696092776623130772489

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

Ran 17 tests for tests/unit/Spoke/Spoke.Repay.t.sol:SpokeRepayTest
[PASS] test_fuzz_amounts_repay_only_premium(uint256,uint256,uint40) (runs: 5, μ: 898320, ~: 898501)
Logs:
  Bound result 28440373319405028386003002998
  Bound result 3
  Bound result 20793798235469357046

[PASS] test_fuzz_repay_amounts_only_interest(uint256,uint256,uint40) (runs: 5, μ: 905039, ~: 906158)
Logs:
  Bound result 28440373319405028386003002998
  Bound result 3
  Bound result 284581507391107100921

[PASS] test_fuzz_repay_only_premium(uint256,uint40) (runs: 5, μ: 761074, ~: 758190)
Logs:
  Bound result 307589881277111429604248989731
  Bound result 9176
  Bound result 1

[PASS] test_fuzz_repay_same_block_fuzz_amounts(uint256,uint256) (runs: 5, μ: 868867, ~: 910340)
Logs:
  Bound result 307589881277111429604248989731
  Bound result 9176

[PASS] test_fuzz_repay_x_y_shares(uint256,uint40) (runs: 5, μ: 624320, ~: 621474)
Logs:
  Bound result 7589881277111429604248989731
  Bound result 9176

[PASS] test_repay() (gas: 711704)
[PASS] test_repay_all_with_accruals() (gas: 427577)
[PASS] test_repay_fuzz_amountsAndWait(uint256,uint256,uint40) (runs: 5, μ: 946032, ~: 947108)
Logs:
  Bound result 28440373319405028386003002998
  Bound result 20234343860279723851399548880
  Bound result 3

[PASS] test_repay_fuzz_amounts_base_debt(uint256,uint256,uint40) (runs: 5, μ: 969897, ~: 970201)
Logs:
  Bound result 28440373319405028386003002998
  Bound result 3
  Bound result 345455594119315262362

[PASS] test_repay_fuzz_amounts_base_debt_no_premium(uint256,uint256,uint40) (runs: 5, μ: 841070, ~: 841312)
Logs:
  Bound result 28440373319405028386003002998
  Bound result 3
  Bound result 345455594119315262362

[PASS] test_repay_fuzz_revertsWith_ERC20InsufficientBalance(uint256) (runs: 5, μ: 552126, ~: 551990)
Logs:
  Bound result 9562

[PASS] test_repay_max() (gas: 607828)
[PASS] test_repay_multiple_reserves_fuzz_amountsAndWait(uint256,uint256,uint256,uint256,uint256,uint40) (runs: 5, μ: 3371155, ~: 3372138)
Logs:
  Bound result 1
  Bound result 2
  Bound result 384967423069528117
  Bound result 10698868285874488444
  Bound result 8570
  Bound result 386709

[PASS] test_repay_only_interest() (gas: 735757)
[PASS] test_repay_revertsWith_ERC20InsufficientAllowance() (gas: 554711)
[PASS] test_repay_revertsWith_ReentrancyGuardReentrantCall() (gas: 650285)
[PASS] test_repay_same_block() (gas: 680272)
Suite result: ok. 17 passed; 0 failed; 0 skipped; finished in 1.19s (1.16s CPU time)

Ran 5 tests for tests/unit/Spoke/Spoke.ReserveConfig.t.sol:SpokeReserveConfigTest
[PASS] test_borrow_fuzz_borrowable_paused_frozen_scenarios(bool,bool,bool) (runs: 5, μ: 254464, ~: 254444)
[PASS] test_repay_fuzz_paused_scenarios(bool) (runs: 5, μ: 550782, ~: 549677)
[PASS] test_setUsingAsCollateral_fuzz_paused_frozen_scenarios(bool) (runs: 5, μ: 184059, ~: 184069)
[PASS] test_supply_paused_frozen_scenarios() (gas: 321284)
[PASS] test_withdraw_paused_scenarios() (gas: 293308)
Suite result: ok. 5 passed; 0 failed; 0 skipped; finished in 269.45ms (241.43ms 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: 5, μ: 533036, ~: 533002)
Logs:
  Bound result 70955
  Bound result 685180691
  Bound result 1
  Bound result 45728715735036875056

[PASS] test_accrueLiquidityFee_fuzz_maxLiquidityFee_with_premium_multiple_users(uint256,uint256,uint256,uint256,uint256) (runs: 5, μ: 786866, ~: 787275)
Logs:
  Bound result 67549
  Bound result 800062139
  Bound result 4
  Bound result 89473879703452351689256785169
  Bound result 47938669350974575399012617271

[PASS] test_accrueLiquidityFee_maxLiquidityFee_multi_spoke() (gas: 533076371)
[PASS] test_accrueLiquidityFee_maxLiquidityFee_multi_user() (gas: 232315194)
[PASS] test_accrueLiquidityFee_maxLiquidityFee_with_premium() (gas: 532965)
Logs:
  Bound result 5000
  Bound result 34560000
  Bound result 2
  Bound result 500000000000000000000

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

Ran 7 tests for tests/unit/Spoke/Spoke.AccrueLiquidityFee.t.sol:SpokeAccrueLiquidityFeeTest
[PASS] test_accrueLiquidityFee() (gas: 830006)
[PASS] test_accrueLiquidityFee_NoActionTaken() (gas: 123846)
[PASS] test_accrueLiquidityFee_NoInterest_OnlySupply(uint40) (runs: 5, μ: 246971, ~: 246699)
Logs:
  Bound result 9884

[PASS] test_accrueLiquidityFee_exact() (gas: 825334)
[PASS] test_accrueLiquidityFee_fuzz_BorrowAmountAndSkipTime(uint256,uint40) (runs: 5, μ: 848626, ~: 823374)
Logs:
  Bound result 307589881277111429604248989731
  Bound result 9741

[PASS] test_accrueLiquidityFee_maxLiquidityFee() (gas: 534092)
[PASS] test_accrueLiquidityFee_setUsingAsCollateral() (gas: 873458)
Suite result: ok. 7 passed; 0 failed; 0 skipped; finished in 211.63ms (185.86ms CPU time)

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

[PASS] test_addAsset_fuzz_revertsWith_InvalidAddress_feeReceiver(address,uint8,address) (runs: 5, μ: 45373, ~: 45646)
Logs:
  Bound result 1

[PASS] test_addAsset_fuzz_revertsWith_InvalidAddress_irStrategy(address,uint8,address) (runs: 5, μ: 45416, ~: 45689)
Logs:
  Bound result 1

[PASS] test_addAsset_fuzz_revertsWith_InvalidAddress_underlying(uint8,address,address) (runs: 5, μ: 36669, ~: 36669)
[PASS] test_addAsset_fuzz_revertsWith_InvalidAssetDecimals(address,uint8,address,address) (runs: 5, μ: 45926, ~: 45958)
Logs:
  Bound result 21

[PASS] test_addAsset_fuzz_revertsWith_InvalidAssetDecimals_tooLow(address,uint8,address,address) (runs: 5, μ: 46022, ~: 46174)
Logs:
  Bound result 2

[PASS] test_addAsset_fuzz_reverts_InvalidIrData(address,uint8,address,address) (runs: 5, μ: 47369, ~: 34913)
Logs:
  Bound result 2

[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: 5, μ: 126592, ~: 126616)
Logs:
  Bound result 2

[PASS] test_addSpoke_fuzz_revertsWith_AssetNotListed(uint256,(uint40,uint40,uint24,bool,bool)) (runs: 5, μ: 35255, ~: 35255)
Logs:
  Bound result 14

[PASS] test_addSpoke_fuzz_revertsWith_InvalidAddress_spoke(uint256,(uint40,uint40,uint24,bool,bool)) (runs: 5, μ: 33889, ~: 33913)
Logs:
  Bound result 2

[PASS] test_addSpoke_revertsWith_SpokeAlreadyListed() (gas: 39752)
[PASS] test_getAssetId() (gas: 73028)
[PASS] test_getAssetId_fuzz_revertsWith_AssetNotListed(address) (runs: 5, μ: 18584, ~: 18584)
[PASS] test_hub_deploy_reverts_on_InvalidConstructorInput() (gas: 831234)
[PASS] test_hub_max_riskPremium() (gas: 8566)
[PASS] test_isUnderlyingListed() (gas: 1178535)
[PASS] test_updateAssetConfig_NewFeeReceiver_noFees() (gas: 703150)
[PASS] test_updateAssetConfig_UseExistingSpokeAndListedAsFeeReceiver_revertsWith_SpokeAlreadyListed() (gas: 62255)
[PASS] test_updateAssetConfig_fuzz(uint256,(address,uint16,address,address)) (runs: 5, μ: 268097, ~: 267961)
Logs:
  Bound result 4
  Bound result 1

[PASS] test_updateAssetConfig_fuzz_FromZeroLiquidityFee(uint256,uint16) (runs: 5, μ: 826261, ~: 826155)
Logs:
  Bound result 3
  Bound result 5500
  Bound result 3
  Bound result 0
  Bound result 3
  Bound result 5500

[PASS] test_updateAssetConfig_fuzz_LiquidityFee(uint256,uint16) (runs: 5, μ: 692622, ~: 692516)
Logs:
  Bound result 3
  Bound result 5500
  Bound result 3
  Bound result 5500

[PASS] test_updateAssetConfig_fuzz_NewFeeReceiver(uint256) (runs: 5, μ: 797537, ~: 797537)
Logs:
  Bound result 4
  Bound result 4
  Bound result 1000

[PASS] test_updateAssetConfig_fuzz_NewInterestRateStrategy(uint256) (runs: 5, μ: 664113, ~: 664113)
Logs:
  Bound result 4

[PASS] test_updateAssetConfig_fuzz_ReuseFeeReceiver_revertsWith_SpokeAlreadyListed(uint256) (runs: 5, μ: 841206, ~: 841206)
Logs:
  Bound result 4
  Bound result 4
  Bound result 4
  Bound result 1000

[PASS] test_updateAssetConfig_fuzz_Scenario(uint256) (runs: 5, μ: 723606, ~: 723606)
Logs:
  Bound result 4
  Bound result 4
  Bound result 1000
  Bound result 4
  Bound result 1000
  Bound result 4
  Bound result 0
  Bound result 4
  Bound result 0
  Bound result 4
  Bound result 0
  Bound result 4
  Bound result 0

[PASS] test_updateAssetConfig_fuzz_revertsWith_InvalidInterestRateStrategy(uint256) (runs: 5, μ: 61077, ~: 61077)
Logs:
  Bound result 4

[PASS] test_updateAssetConfig_fuzz_revertsWith_InvalidLiquidityFee(uint256,(address,uint16,address,address)) (runs: 5, μ: 40147, ~: 40011)
Logs:
  Bound result 4
  Bound result 1

[PASS] test_updateAssetConfig_fuzz_revertsWith_InvalidReinvestmentController() (gas: 483451)
[PASS] test_updateAssetConfig_fuzz_revertsWith_calculateInterestRateReverts(uint256,(address,uint16,address,address)) (runs: 5, μ: 192849, ~: 192713)
Logs:
  Bound result 3
  Bound result 1070

[PASS] test_updateAssetConfig_fuzz_revertsWith_setInterestRateDataReverts(uint256,(address,uint16,address,address)) (runs: 5, μ: 96376, ~: 96240)
Logs:
  Bound result 3
  Bound result 1070

[PASS] test_updateAssetConfig_oldFeeReceiver_flags() (gas: 880494)
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: 5, μ: 59089, ~: 59054)
Logs:
  Bound result 2

[PASS] test_updateSpokeConfig_fuzz_revertsWith_SpokeNotListed(uint256,address,(uint40,uint40,uint24,bool,bool)) (runs: 5, μ: 40487, ~: 40548)
Logs:
  Bound result 3

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

Ran 15 tests for tests/unit/Spoke/Spoke.RiskPremium.EdgeCases.t.sol:SpokeRiskPremiumEdgeCasesTest
[PASS] test_riskPremium_borrowingMoreIncreasesRP() (gas: 1861698)
Logs:
  Bound result 50000000000000000000000
  Bound result 1000000000000000000000

[PASS] test_riskPremium_changesAfterAccrual() (gas: 2142833)
Logs:
  Bound result 100000000000000000000
  Bound result 31536000

[PASS] test_riskPremium_decreasesAfterCollateralAccrual() (gas: 2320573)
Logs:
  Bound result 1000000000000000000000
  Bound result 31536000

[PASS] test_riskPremium_fuzz_borrowingMoreNonDecreasesRP(uint256,uint256) (runs: 5, μ: 1843409, ~: 1843484)
Logs:
  Bound result 468905209293759551688975558841
  Bound result 11323

[PASS] test_riskPremium_fuzz_changesAfterAccrual(uint256,uint40) (runs: 5, μ: 2144223, ~: 2144545)
Logs:
  Bound result 116525424937793467200618477
  Bound result 832475324

[PASS] test_riskPremium_fuzz_increasesAfterDebtAccrual(uint256,uint40) (runs: 5, μ: 1875608, ~: 1875930)
Logs:
  Bound result 116525424937793467200618477
  Bound result 832475324

[PASS] test_riskPremium_fuzz_nonDecreasingAfterWithdrawal(uint256,uint256,uint256) (runs: 5, μ: 1254953, ~: 1258465)
Logs:
  Bound result 28440373319405028386003002998
  Bound result 276197703734924979325426575862
  Bound result 4896747

[PASS] test_riskPremium_fuzz_nonIncreasesAfterCollateralAccrual(uint256,uint40) (runs: 5, μ: 2321827, ~: 2322042)
Logs:
  Bound result 370782501227111429604248989731
  Bound result 832475324

[PASS] test_riskPremium_fuzz_supplyingLowerCRCollateral_nonIncreasesRP(uint256,uint256) (runs: 5, μ: 1551223, ~: 1545461)
Logs:
  Bound result 307589881277111429604248989731
  Bound result 11323

[PASS] test_riskPremium_increasesAfterDebtAccrual() (gas: 1892855)
Logs:
  Bound result 50000000000000000000000
  Bound result 31536000

[PASS] test_riskPremium_increasesAfterWithdrawal(uint256,uint256) (runs: 5, μ: 1178004, ~: 1177842)
Logs:
  Bound result 307589881277111429604248989731
  Bound result 11323
  Bound result 307589881277111429604248989731
  Bound result 11323
  Bound result 307589881277111429604248989731

[PASS] test_riskPremium_nonDecreasesAfterCollateralRemoval(uint256,uint256) (runs: 5, μ: 1471395, ~: 1471233)
Logs:
  Bound result 307589881277111429604248989731
  Bound result 11323

[PASS] test_riskPremium_nonIncreasingAfterRepay(uint256,uint256,uint256,uint256) (runs: 5, μ: 1495879, ~: 1492216)
Logs:
  Bound result 433606845766853651522216947804
  Bound result 154285589657018366648870226275
  Bound result 240336
  Bound result 18854884467880058033161996847

[PASS] test_riskPremium_priceChangeReducesRP(uint256,uint256) (runs: 5, μ: 2147293, ~: 2147373)
Logs:
  Bound result 340241923186884571471614299575
  Bound result 9999999900011323

[PASS] test_riskPremium_supplyingLowerCRCollateral_decreasesRP() (gas: 1560869)
Logs:
  Bound result 100000000
  Bound result 10000000000000000000000

Suite result: ok. 15 passed; 0 failed; 0 skipped; finished in 1.49s (1.46s CPU time)

Ran 5 tests for tests/unit/Spoke/Spoke.Borrow.EdgeCases.t.sol:SpokeBorrowEdgeCasesTest
[PASS] test_borrow_fuzz_rounding_effect(uint256,uint256) (runs: 5, μ: 1040481, ~: 1040618)
Logs:
  Bound result 57589881277111429604248989731
  Bound result 9327

[PASS] test_borrow_fuzz_rounding_effect_inflated_ex_rate(uint256,uint256,uint256) (runs: 5, μ: 1423800, ~: 1424111)
Logs:
  Bound result 43313684148191607974964
  Bound result 999999999999999999999997
  Bound result 389169995

[PASS] test_borrow_fuzz_rounding_effect_shares(uint256,uint256) (runs: 5, μ: 1094116, ~: 1093844)
Logs:
  Bound result 57589881277111429604248989731
  Bound result 832473328

[PASS] test_borrow_rounding_effect_multiple_actions() (gas: 1155818)
[PASS] test_borrow_rounding_effect_shares() (gas: 1093106)
Logs:
  Bound result 5000000000000000000
  Bound result 94608000

Suite result: ok. 5 passed; 0 failed; 0 skipped; finished in 387.58ms (336.67ms CPU time)

Ran 4 tests for tests/unit/Spoke/Spoke.RiskPremium.Scenario.t.sol:SpokeRiskPremiumScenarioTest
[PASS] test_getUserRiskPremium_applyInterest_two_users_two_reserves_borrowed() (gas: 3289892)
[PASS] test_getUserRiskPremium_fuzz_inflight_calcs((uint256,uint256),(uint256,uint256),(uint256,uint256),(uint256,uint256),uint40) (runs: 5, μ: 2482526, ~: 2525211)
Logs:
  Bound result 1
  Bound result 11555
  Bound result 2693
  Bound result 19274378306194969
  Bound result 99999999999999999951
  Bound result 2474
  Bound result 65
  Bound result 16183
  Bound result 240

[PASS] test_getUserRiskPremium_fuzz_two_users_two_reserves_borrowed((uint256,uint256),(uint256,uint256),(uint256,uint256),(uint256,uint256),uint16,uint16,uint40[3]) (runs: 5, μ: 2986050, ~: 3147247)
Logs:
  Bound result 141149748172405968291488280632
  Bound result 31131513872998857787324068111
  Bound result 299067823585765659
  Bound result 69023460664384170
  Bound result 63121
  Bound result 16687
  Bound result 319856857614133106
  Bound result 84384526
  Bound result 195
  Bound result 0
  Bound result 503626500
  Bound result 301638927
  Bound result 21028704

[PASS] test_riskPremiumPropagatesCorrectly_singleBorrow() (gas: 1989540)
Suite result: ok. 4 passed; 0 failed; 0 skipped; finished in 314.88ms (290.72ms CPU time)

Ran 8 tests for tests/unit/Spoke/Liquidations/Spoke.LiquidationCall.t.sol:SpokeLiquidationCallTest_LargePosition
[PASS] test_liquidationCall_fuzz_ManyCollaterals_ManyDebts_UserInsolvent(uint256,uint256,uint256,bool) (runs: 5, μ: 42750175, ~: 42373248)
Logs:
  Bound result 0
  Bound result 1
  Bound result 296839640696092776623130772489

[PASS] test_liquidationCall_fuzz_ManyCollaterals_ManyDebts_UserSolvent(uint256,uint256,uint256,bool) (runs: 5, μ: 42741271, ~: 42358509)
Logs:
  Bound result 0
  Bound result 1
  Bound result 296839640696092776623130772489

[PASS] test_liquidationCall_fuzz_ManyCollaterals_OneDebt_UserInsolvent(uint256,uint256,uint256,bool) (runs: 5, μ: 30644123, ~: 30797607)
Logs:
  Bound result 0
  Bound result 1
  Bound result 296839640696092776623130772489

[PASS] test_liquidationCall_fuzz_ManyCollaterals_OneDebt_UserSolvent(uint256,uint256,uint256,bool) (runs: 5, μ: 30635519, ~: 30790141)
Logs:
  Bound result 0
  Bound result 1
  Bound result 296839640696092776623130772489

[PASS] test_liquidationCall_fuzz_OneCollateral_ManyDebts_UserInsolvent(uint256,uint256,uint256,bool) (runs: 5, μ: 39902868, ~: 40409983)
Logs:
  Bound result 0
  Bound result 1
  Bound result 296839640696092776623130772489

[PASS] test_liquidationCall_fuzz_OneCollateral_ManyDebts_UserSolvent(uint256,uint256,uint256,bool) (runs: 5, μ: 40355490, ~: 40927440)
Logs:
  Bound result 0
  Bound result 1
  Bound result 296839640696092776623130772489

[PASS] test_liquidationCall_fuzz_OneCollateral_OneDebt_UserInsolvent(uint256,uint256,uint256,bool) (runs: 5, μ: 29217497, ~: 29180794)
Logs:
  Bound result 0
  Bound result 1
  Bound result 296839640696092776623130772489

[PASS] test_liquidationCall_fuzz_OneCollateral_OneDebt_UserSolvent(uint256,uint256,uint256,bool) (runs: 5, μ: 29374939, ~: 29297436)
Logs:
  Bound result 0
  Bound result 1
  Bound result 296839640696092776623130772489

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

Ran 16 tests for tests/unit/Hub/Hub.Draw.t.sol:HubDrawTest
[PASS] test_draw_DifferentSpokes() (gas: 362644)
[PASS] test_draw_fuzz_IncreasedBorrowRate(uint256,uint256) (runs: 5, μ: 716241, ~: 716142)
Logs:
  Bound result 3
  Bound result 7678

[PASS] test_draw_fuzz_amounts_same_block(uint256,uint256) (runs: 5, μ: 295442, ~: 295345)
Logs:
  Bound result 3
  Bound result 7678

[PASS] test_draw_fuzz_revertsWith_DrawCapExceeded(uint40) (runs: 5, μ: 82505, ~: 82369)
Logs:
  Bound result 8563

[PASS] test_draw_fuzz_revertsWith_DrawCapExceeded_due_to_interest(uint40,uint256,uint256) (runs: 5, μ: 294257, ~: 294121)
Logs:
  Bound result 476358262
  Bound result 75862
  Bound result 4896747

[PASS] test_draw_fuzz_revertsWith_InsufficientLiquidity(uint256,uint256) (runs: 5, μ: 34708, ~: 34663)
Logs:
  Bound result 3
  Bound result 7678

[PASS] test_draw_fuzz_revertsWith_InsufficientLiquidity_due_to_draw(uint256) (runs: 5, μ: 171973, ~: 171837)
Logs:
  Bound result 8563

[PASS] test_draw_fuzz_revertsWith_InsufficientLiquidity_due_to_remove(uint256) (runs: 5, μ: 133666, ~: 133572)
Logs:
  Bound result 8563

[PASS] test_draw_fuzz_revertsWith_InvalidAddress(uint256) (runs: 5, μ: 16129, ~: 16129)
[PASS] test_draw_revertsWith_DrawCapExceeded_due_to_deficit() (gas: 269542)
[PASS] test_draw_revertsWith_InsufficientLiquidity() (gas: 28462)
[PASS] test_draw_revertsWith_InsufficientLiquidity_due_to_draw() (gas: 168448)
[PASS] test_draw_revertsWith_InsufficientLiquidity_due_to_remove() (gas: 130911)
[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 636.38ms (612.44ms 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: 5, μ: 909152, ~: 909152)
Logs:
  Bound result 21536
  Bound result 307589881277111429604248989731

[PASS] test_borrow_fuzz_revertsWith_HealthFactorBelowThreshold_multiple_colls(uint256,uint256) (runs: 5, μ: 855006, ~: 855450)
Logs:
  Bound result 22920
  Bound result 5086

[PASS] test_borrow_fuzz_revertsWith_HealthFactorBelowThreshold_multiple_colls_with_interest(uint256,uint256,uint256) (runs: 5, μ: 900126, ~: 900607)
Logs:
  Bound result 3
  Bound result 3239
  Bound result 394204007

[PASS] test_borrow_fuzz_revertsWith_HealthFactorBelowThreshold_multiple_debts(uint256,uint256) (runs: 5, μ: 1094792, ~: 1095007)
Logs:
  Bound result 96547279488820184596521904
  Bound result 99999999999000000000021537

[PASS] test_borrow_fuzz_revertsWith_HealthFactorBelowThreshold_multiple_debts_with_interest(uint256,uint256,uint256) (runs: 5, μ: 1150866, ~: 1151276)
Logs:
  Bound result 75163410361181780817854932
  Bound result 150713495780544581386963296478
  Bound result 204710882

[PASS] test_borrow_fuzz_revertsWith_HealthFactorBelowThreshold_with_interest(uint256,uint256) (runs: 5, μ: 679833, ~: 679561)
Logs:
  Bound result 1741
  Bound result 13314

[PASS] test_borrow_revertsWith_HealthFactorBelowThreshold() (gas: 639377)
[PASS] test_borrow_revertsWith_HealthFactorBelowThreshold_collateral_price_drop_weth() (gas: 903402)
[PASS] test_borrow_revertsWith_HealthFactorBelowThreshold_multiple_colls() (gas: 849231)
[PASS] test_borrow_revertsWith_HealthFactorBelowThreshold_multiple_colls_collateral_price_drop_dai() (gas: 1123047)
[PASS] test_borrow_revertsWith_HealthFactorBelowThreshold_multiple_colls_collateral_price_drop_weth() (gas: 1123091)
[PASS] test_borrow_revertsWith_HealthFactorBelowThreshold_multiple_colls_with_interest() (gas: 894956)
[PASS] test_borrow_revertsWith_HealthFactorBelowThreshold_multiple_debts() (gas: 1087247)
[PASS] test_borrow_revertsWith_HealthFactorBelowThreshold_multiple_debts_with_interest() (gas: 1142259)
[PASS] test_borrow_revertsWith_HealthFactorBelowThreshold_with_interest() (gas: 674949)
[PASS] test_fuzz_borrow_revertsWith_HealthFactorBelowThreshold_multiple_colls_collateral_price_drop_dai(uint256,uint256,uint256) (runs: 5, μ: 1127045, ~: 1127214)
Logs:
  Bound result 18000000000
  Bound result 5606
  Bound result 19

[PASS] test_fuzz_borrow_revertsWith_HealthFactorBelowThreshold_multiple_colls_collateral_price_drop_weth(uint256,uint256,uint256) (runs: 5, μ: 1127642, ~: 1127594)
Logs:
  Bound result 18000000000
  Bound result 5606
  Bound result 19

Suite result: ok. 17 passed; 0 failed; 0 skipped; finished in 744.29ms (721.07ms CPU time)

Ran 8 tests for tests/unit/Hub/Hub.EliminateDeficit.t.sol:HubEliminateDeficitTest
[PASS] test_eliminateDeficit(uint256) (runs: 5, μ: 675095, ~: 675095)
[PASS] test_eliminateDeficit_fuzz_revertsWith_AccessManagedUnauthorized(address) (runs: 5, μ: 32536, ~: 32536)
[PASS] test_eliminateDeficit_fuzz_revertsWith_ArithmeticUnderflow_CallerSpokeNoFunds(uint256) (runs: 5, μ: 355686, ~: 355686)
[PASS] test_eliminateDeficit_revertsWith_InvalidAmount_ZeroAmountNoDeficit() (gas: 36016)
[PASS] test_eliminateDeficit_revertsWith_InvalidAmount_ZeroAmountWithDeficit() (gas: 351797)
[PASS] test_eliminateDeficit_revertsWith_InvalidAmount_on_UnregisteredCoveredSpoke() (gas: 36403)
[PASS] test_eliminateDeficit_revertsWith_SpokeNotActive_on_UnregisteredAsset() (gas: 387457)
[PASS] test_eliminateDeficit_revertsWith_callerSpokeNotActive() (gas: 159271)
Suite result: ok. 8 passed; 0 failed; 0 skipped; finished in 257.21ms (234.06ms CPU time)

Ran 8 tests for tests/gas/Hub.Operations.gas.t.sol:HubOperations_Gas_Tests
[PASS] test_add() (gas: 270202)
[PASS] test_deficit() (gas: 1342947)
[PASS] test_draw() (gas: 382986)
[PASS] test_payFee_transferShares() (gas: 926230)
[PASS] test_refreshPremium() (gas: 630509)
[PASS] test_remove() (gas: 342165)
[PASS] test_restore() (gas: 847644)
[PASS] test_restore_with_transfer() (gas: 848287)
Suite result: ok. 8 passed; 0 failed; 0 skipped; finished in 51.25ms (7.44ms CPU time)

Ran 6 tests for tests/unit/Hub/Hub.PayFee.t.sol:HubPayFeeTest
[PASS] test_payFee_fuzz(uint256,uint256) (runs: 5, μ: 706350, ~: 706423)
Logs:
  Bound result 307589881277111429604248989731
  Bound result 0
  Bound result 43395921806223610619707802094

[PASS] test_payFee_fuzz_with_interest(uint256,uint256,uint256) (runs: 5, μ: 706718, ~: 707091)
Logs:
  Bound result 28440373319405028386003002998
  Bound result 4896747
  Bound result 20234343860279723851399548880

[PASS] test_payFee_revertsWith_InvalidShares() (gas: 20347)
[PASS] test_payFee_revertsWith_SpokeNotActive() (gas: 61271)
[PASS] test_payFee_revertsWith_underflow_added_shares_exceeded() (gas: 138314)
[PASS] test_payFee_revertsWith_underflow_added_shares_exceeded_with_interest() (gas: 649682)
Suite result: ok. 6 passed; 0 failed; 0 skipped; finished in 207.16ms (184.41ms CPU time)

Ran 6 tests for tests/unit/Spoke/Spoke.Borrow.Scenario.t.sol:SpokeBorrowScenarioTest
[PASS] test_borrow_fuzz_multi_spoke_multi_reserves(uint256,uint256,uint256,uint256,uint256) (runs: 5, μ: 2181854, ~: 2182113)
Logs:
  Bound result 1379859933655610741298793405
  Bound result 13201078635605084377043354411
  Bound result 84519284290024108340955650084
  Bound result 97283324062632509970348013685
  Bound result 80267547

[PASS] test_borrow_fuzz_single_spoke_multi_reserves(uint256,uint256,uint256,uint256) (runs: 5, μ: 2338721, ~: 2339171)
Logs:
  Bound result 240336
  Bound result 52598354835191513996053612962
  Bound result 78567410690749811
  Bound result 14406338595446304349

[PASS] test_borrow_fuzz_single_spoke_multi_reserves_multi_user(uint256,uint256,uint256,uint256) (runs: 5, μ: 2737441, ~: 2737578)
Logs:
  Bound result 240336
  Bound result 210969655735530016
  Bound result 85940619393896041261526179817
  Bound result 46405229481110363

[PASS] test_borrow_fuzz_skip_borrow(uint256,uint256,uint256) (runs: 5, μ: 1064949, ~: 1066738)
Logs:
  Bound result 28440373319405028386003002998
  Bound result 26197703734924979325426575862
  Bound result 4896747

[PASS] test_borrow_skip_borrow() (gas: 1065288)
Logs:
  Bound result 10000000000000000000
  Bound result 20000000000000000000
  Bound result 31536000

[PASS] test_userAccountData_does_not_include_zero_cf_collateral() (gas: 1287610)
Suite result: ok. 6 passed; 0 failed; 0 skipped; finished in 473.47ms (450.23ms CPU time)

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

[PASS] test_reclaim_fullAmount() (gas: 633146)
[PASS] test_reclaim_fuzz(uint256,uint256,uint256) (runs: 5, μ: 651709, ~: 651680)
Logs:
  Bound result 28440373319405028386003002998
  Bound result 20234343860279723851399548880
  Bound result 4896747

[PASS] test_reclaim_multipleSweepsAndReclaims() (gas: 740834)
[PASS] test_reclaim_revertsWith_AssetNotListed() (gas: 13049)
[PASS] test_reclaim_revertsWith_InsufficientTransferred() (gas: 455008)
[PASS] test_reclaim_revertsWith_InsufficientTransferred_noSwept() (gas: 99957)
[PASS] test_reclaim_revertsWith_InvalidAmount_zero() (gas: 90155)
[PASS] test_reclaim_revertsWith_OnlyReinvestmentController(address) (runs: 5, μ: 91038, ~: 91038)
[PASS] test_reclaim_revertsWith_OnlyReinvestmentController_init() (gas: 40401)
[PASS] test_reclaim_revertsWith_underflow_exceedsSwept_afterSweep() (gas: 618328)
Suite result: ok. 11 passed; 0 failed; 0 skipped; finished in 200.46ms (177.34ms CPU time)

Ran 20 tests for tests/unit/Spoke/Spoke.RiskPremium.t.sol:SpokeRiskPremiumTest
[PASS] test_getUserRiskPremium_fuzz_applyInterest_two_reserves_borrowed(uint256,uint256,uint256,uint256,uint256) (runs: 5, μ: 2212015, ~: 2224997)
Logs:
  Bound result 251379859933655610834046514830
  Bound result 441228976820499341869983930545
  Bound result 49637881134709352
  Bound result 31663829919706662956
  Bound result 1808267549

[PASS] test_getUserRiskPremium_fuzz_applyingInterest(uint256,uint256,uint256,uint256) (runs: 5, μ: 1660230, ~: 1702259)
Logs:
  Bound result 240336
  Bound result 7067005440460094811487595116
  Bound result 246997527760378469
  Bound result 14488964521537037652

[PASS] test_getUserRiskPremium_fuzz_four_reserves_change_cr(uint256,uint256,uint256,uint256,uint256,uint24) (runs: 5, μ: 2040866, ~: 2038545)
Logs:
  Bound result 1685
  Bound result 1
  Bound result 2
  Bound result 335210513848158791
  Bound result 60698868285874488444
  Bound result 9479176392

[PASS] test_getUserRiskPremium_fuzz_four_reserves_change_one_price(uint256,uint256,uint256,uint256,uint256,uint256) (runs: 5, μ: 2240144, ~: 2240554)
Logs:
  Bound result 7577197680256661
  Bound result 1
  Bound result 2
  Bound result 335210513848158791
  Bound result 60698868285874488444
  Bound result 9479176392

[PASS] test_getUserRiskPremium_fuzz_four_reserves_prices_supply_debt((uint256,uint256,uint256,uint256,uint24,uint256),(uint256,uint256,uint256,uint256,uint24,uint256),(uint256,uint256,uint256,uint256,uint24,uint256),(uint256,uint256,uint256,uint256,uint24,uint256)) (runs: 5, μ: 2066249, ~: 2066980)
Logs:
  Bound result 654309232467334740319659155894
  Bound result 5748218845185672024631
  Bound result 576188240819842209
  Bound result 167504672867425
  Bound result 7877
  Bound result 2783093326875792503448
  Bound result 86629781420197427
  Bound result 5296505363937
  Bound result 3621844667327251
  Bound result 8259342835444062
  Bound result 7900125348742127
  Bound result 8619834790055632
  Bound result 9062
  Bound result 17127
  Bound result 8
  Bound result 1

[PASS] test_getUserRiskPremium_fuzz_four_reserves_supply_and_borrow(uint256,uint256,uint256,uint256,uint256) (runs: 5, μ: 1606100, ~: 1552428)
Logs:
  Bound result 251379859933655610834046514830
  Bound result 426337479169528718027169581570
  Bound result 469775847335909789
  Bound result 31663829919706662956
  Bound result 1808267549

[PASS] test_getUserRiskPremium_fuzz_single_reserve_collateral_borrowed_amount(uint256) (runs: 5, μ: 417557, ~: 417109)
Logs:
  Bound result 9824

[PASS] test_getUserRiskPremium_fuzz_supply_does_not_impact(uint256,uint256) (runs: 5, μ: 593561, ~: 593460)
Logs:
  Bound result 307589881277111429604248989731
  Bound result 9660

[PASS] test_getUserRiskPremium_fuzz_three_reserves_supply_and_borrow(uint256,uint256,uint256,uint256) (runs: 5, μ: 1242739, ~: 1274075)
Logs:
  Bound result 240336
  Bound result 229702694472305890917489621023
  Bound result 492978051461700385
  Bound result 14488964521537037652

[PASS] test_getUserRiskPremium_fuzz_two_reserves_supply_and_borrow(uint256,uint256,uint256) (runs: 5, μ: 1020410, ~: 1060272)
Logs:
  Bound result 760263968619674784738859122422
  Bound result 924979049228872128
  Bound result 4896747

[PASS] test_getUserRiskPremium_multi_reserve_collateral() (gas: 949320)
[PASS] test_getUserRiskPremium_multi_reserve_collateral_lower_rp_than_highest_cr() (gas: 1560356)
[PASS] test_getUserRiskPremium_multi_reserve_collateral_weth_partial_cover() (gas: 1280284)
[PASS] test_getUserRiskPremium_no_collateral() (gas: 97598)
[PASS] test_getUserRiskPremium_no_collateral_set() (gas: 195111)
[PASS] test_getUserRiskPremium_single_reserve_collateral() (gas: 203601)
[PASS] test_getUserRiskPremium_single_reserve_collateral_borrowed() (gas: 412065)
[PASS] test_getUserRiskPremium_two_reserves_equal_parts() (gas: 1099322)
[PASS] test_riskPremium_collateral_insufficient_to_cover_debt() (gas: 2312012)
[PASS] test_riskPremium_postActions() (gas: 1335507)
Suite result: ok. 20 passed; 0 failed; 0 skipped; finished in 1.06s (1.03s CPU time)

Ran 12 tests for tests/unit/Hub/Hub.RefreshPremium.t.sol:HubRefreshPremiumTest
[PASS] test_refreshPremium_emitsEvent() (gas: 253652)
[PASS] test_refreshPremium_fuzz_positiveDeltas(uint256,int256,int256) (runs: 5, μ: 492835, ~: 492944)
Logs:
  Bound result 999999999990000000000000000001
  Bound result 7745
  Bound result 481628582282123143583631333586

[PASS] test_refreshPremium_fuzz_withAccrual(uint256,uint256,uint256,uint256) (runs: 5, μ: 470365, ~: 481482)
Logs:
  Bound result 240336
  Bound result 601
  Bound result 658565049645239055663504730267
  Bound result 305527059267969844621518062160

[PASS] test_refreshPremium_haltedSpokesAllowed() (gas: 118708)
[PASS] test_refreshPremium_maxRiskPremiumThreshold() (gas: 906927)
[PASS] test_refreshPremium_negativeDeltas(uint256) (runs: 5, μ: 457364, ~: 457092)
Logs:
  Bound result 9834

[PASS] test_refreshPremium_negativeDeltas_withAccrual(uint256) (runs: 5, μ: 534591, ~: 534319)
Logs:
  Bound result 9834

[PASS] test_refreshPremium_revertsWith_InvalidPremiumChange_NonZeroRestoredPremiumRay() (gas: 865953)
[PASS] test_refreshPremium_revertsWith_InvalidPremiumChange_RiskPremiumThresholdExceeded_DecreasingPremium() (gas: 884431)
[PASS] test_refreshPremium_revertsWith_SpokeNotActive() (gas: 58802)
[PASS] test_refreshPremium_riskPremiumThreshold() (gas: 932397)
[PASS] test_refreshPremium_spokePremiumUpdateIsContained() (gas: 716125)
Suite result: ok. 12 passed; 0 failed; 0 skipped; finished in 354.16ms (330.51ms CPU time)

Ran 15 tests for tests/unit/Spoke/Spoke.SetUserPositionManagerWithSig.t.sol:SpokeSetUserPositionManagersWithSigTest
[PASS] test_DOMAIN_SEPARATOR() (gas: 5038167)
[PASS] test_eip712Domain() (gas: 5043459)
[PASS] test_positionManagerUpdate_typeHash() (gas: 3902)
[PASS] test_setUserPositionManager_typeHash() (gas: 15575)
[PASS] test_setUserPositionManagersWithSig() (gas: 134311)
[PASS] test_setUserPositionManagersWithSig_ERC1271() (gas: 374610)
[PASS] test_setUserPositionManagersWithSig_ERC1271_revertsWith_InvalidAccountNonce(bytes32) (runs: 5, μ: 448326, ~: 477599)
[PASS] test_setUserPositionManagersWithSig_ERC1271_revertsWith_InvalidSignature_dueTo_ExpiredDeadline() (gas: 276519)
[PASS] test_setUserPositionManagersWithSig_ERC1271_revertsWith_InvalidSignature_dueTo_InvalidHash() (gas: 327762)
[PASS] test_setUserPositionManagersWithSig_multiple_updates((address,bool)[]) (runs: 5, μ: 2551689, ~: 2660906)
[PASS] test_setUserPositionManagersWithSig_revertsWith_InvalidAccountNonce(bytes32) (runs: 5, μ: 337309, ~: 373610)
[PASS] test_setUserPositionManagersWithSig_revertsWith_InvalidSignature_dueTo_ExpiredDeadline() (gas: 32763)
[PASS] test_setUserPositionManagersWithSig_revertsWith_InvalidSignature_dueTo_InvalidSigner() (gas: 33930)
[PASS] test_setUserPositionManagersWithSig_zero_updates() (gas: 102644)
[PASS] test_useNonce_monotonic(bytes32) (runs: 5, μ: 19386, ~: 19386)
Suite result: ok. 15 passed; 0 failed; 0 skipped; finished in 376.55ms (351.76ms CPU time)

Ran 9 tests for tests/unit/Spoke/Spoke.SetUsingAsCollateral.t.sol:SpokeSetUsingAsCollateralTest
[PASS] test_setUsingAsCollateral() (gas: 310600)
[PASS] test_setUsingAsCollateral_collateralStatusUnchanged() (gas: 472037)
[PASS] test_setUsingAsCollateral_revertsWith_MaximumUserReservesExceeded() (gas: 5690440)
[PASS] test_setUsingAsCollateral_revertsWith_ReentrancyGuardReentrantCall() (gas: 764300)
[PASS] test_setUsingAsCollateral_revertsWith_ReserveFrozen() (gas: 106341)
[PASS] test_setUsingAsCollateral_revertsWith_ReserveNotListed() (gas: 28416)
[PASS] test_setUsingAsCollateral_revertsWith_ReservePaused() (gas: 65724)
[PASS] test_setUsingAsCollateral_to_limit_disable_enable_again() (gas: 5943017)
[PASS] test_setUsingAsCollateral_unlimited_whenLimitIsMax() (gas: 807227)
Suite result: ok. 9 passed; 0 failed; 0 skipped; finished in 35.23ms (11.15ms CPU time)

Ran 17 tests for tests/unit/Spoke/Spoke.Borrow.Validation.t.sol:SpokeBorrowValidationTest
[PASS] test_borrow_fuzz_revertsWith_DrawCapExceeded(uint256,uint40) (runs: 5, μ: 110580, ~: 110717)
Logs:
  Bound result 1
  Bound result 9585

[PASS] test_borrow_fuzz_revertsWith_DrawCapExceeded_due_to_interest(uint256) (runs: 5, μ: 692270, ~: 691998)
Logs:
  Bound result 9740

[PASS] test_borrow_fuzz_revertsWith_InsufficientLiquidity(uint256,uint256) (runs: 5, μ: 294746, ~: 294474)
Logs:
  Bound result 9585

[PASS] test_borrow_fuzz_revertsWith_InvalidAmount(uint256) (runs: 5, μ: 34425, ~: 34425)
Logs:
  Bound result 0

[PASS] test_borrow_fuzz_revertsWith_ReserveFrozen(uint256,uint256) (runs: 5, μ: 70794, ~: 70658)
Logs:
  Bound result 1
  Bound result 9585

[PASS] test_borrow_fuzz_revertsWith_ReserveNotBorrowable(uint256,uint256) (runs: 5, μ: 70892, ~: 70756)
Logs:
  Bound result 1
  Bound result 9585

[PASS] test_borrow_fuzz_revertsWith_ReserveNotListed(uint256,uint256) (runs: 5, μ: 27366, ~: 27094)
Logs:
  Bound result 873464769550715740573453180691

[PASS] test_borrow_fuzz_revertsWith_ReservePaused(uint256,uint256) (runs: 5, μ: 70710, ~: 70574)
Logs:
  Bound result 1
  Bound result 9585

[PASS] test_borrow_revertsWith_InsufficientLiquidity() (gas: 294407)
Logs:
  Bound result 10000000000000000000

[PASS] test_borrow_revertsWith_InvalidAmount() (gas: 35978)
Logs:
  Bound result 2

[PASS] test_borrow_revertsWith_MaximumUserReservesExceeded() (gas: 6836324)
[PASS] test_borrow_revertsWith_ReserveFrozen() (gas: 72196)
Logs:
  Bound result 2
  Bound result 1

[PASS] test_borrow_revertsWith_ReserveNotBorrowable() (gas: 72270)
Logs:
  Bound result 2
  Bound result 1

[PASS] test_borrow_revertsWith_ReserveNotListed() (gas: 28941)
Logs:
  Bound result 1

[PASS] test_borrow_revertsWith_ReservePaused() (gas: 72154)
Logs:
  Bound result 2
  Bound result 1

[PASS] test_borrow_to_limit_repay_borrow_again() (gas: 7099466)
[PASS] test_borrow_unlimited_whenLimitIsMax() (gas: 2080837)
Suite result: ok. 17 passed; 0 failed; 0 skipped; finished in 621.87ms (591.40ms CPU time)

Ran 4 tests for tests/unit/Spoke/Spoke.Borrow.t.sol:SpokeBorrowTest
[PASS] test_borrow() (gas: 1132673)
[PASS] test_borrow_fuzz_amounts(uint256,uint256) (runs: 5, μ: 1139809, ~: 1139353)
Logs:
  Bound result 307589881277111429604248989731
  Bound result 9174

[PASS] test_borrow_revertsWith_ReentrancyGuardReentrantCall_hubDraw() (gas: 399738)
[PASS] test_borrow_revertsWith_ReentrancyGuardReentrantCall_hubRefreshPremium() (gas: 526178)
Suite result: ok. 4 passed; 0 failed; 0 skipped; finished in 126.00ms (103.13ms CPU time)

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

[PASS] test_remove_all_with_interest() (gas: 414184)
[PASS] test_remove_fuzz(uint256,uint256) (runs: 5, μ: 208824, ~: 208688)
Logs:
  Bound result 1
  Bound result 8278

[PASS] test_remove_fuzz_all_liquidity_with_interest(uint256,uint256) (runs: 5, μ: 448782, ~: 455070)
Logs:
  Bound result 77111429604248989731
  Bound result 8278

[PASS] test_remove_fuzz_multi_spoke(uint256,uint256) (runs: 5, μ: 289567, ~: 289704)
Logs:
  Bound result 888247545285369762127287355776
  Bound result 8278

[PASS] test_remove_fuzz_multi_spoke_with_interest(uint256,uint256,uint256,uint256) (runs: 5, μ: 453881, ~: 464947)
Logs:
  Bound result 240336
  Bound result 49623954023794104862590597984
  Bound result 16492345978402882778078266451
  Bound result 555770955

[PASS] test_remove_revertsWith_InsufficientLiquidity() (gas: 157574)
[PASS] test_remove_revertsWith_InsufficientLiquidity_exceeding_added_amount() (gas: 146739)
[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: 184191)
[PASS] test_remove_revertsWtih_underflow_one_extra_wei() (gas: 369269)
Suite result: ok. 15 passed; 0 failed; 0 skipped; finished in 357.67ms (334.24ms CPU time)

Ran 15 tests for tests/unit/Spoke/Spoke.Supply.t.sol:SpokeSupplyTest
[PASS] test_fuzz_supply_effect_on_ex_rates(uint256,uint256) (runs: 5, μ: 697484, ~: 709209)
Logs:
  Bound result 9927
  Bound result 307589881277111429604248989731

[PASS] test_supply() (gas: 305818)
[PASS] test_supply_does_not_update_risk_premium() (gas: 1770265)
[PASS] test_supply_fuzz_amounts(uint256) (runs: 5, μ: 429954, ~: 429818)
Logs:
  Bound result 9835

[PASS] test_supply_fuzz_index_increase_no_premium(uint256,uint256,uint256,uint256) (runs: 5, μ: 680829, ~: 681100)
Logs:
  Bound result 390471423000456338802610381659
  Bound result 55737
  Bound result 0
  Bound result 2

[PASS] test_supply_fuzz_index_increase_with_premium(uint256,uint256,uint256,uint256) (runs: 5, μ: 776849, ~: 777120)
Logs:
  Bound result 390471423000456338802610381659
  Bound result 55737
  Bound result 0
  Bound result 2

[PASS] test_supply_fuzz_revertsWith_ERC20InsufficientBalance(uint256) (runs: 5, μ: 61880, ~: 61744)
Logs:
  Bound result 9835

[PASS] test_supply_index_increase_no_premium() (gas: 880032)
[PASS] test_supply_index_increase_with_premium() (gas: 937870)
[PASS] test_supply_revertsWith_ERC20InsufficientAllowance() (gas: 39609)
[PASS] test_supply_revertsWith_InvalidSupplyAmount() (gas: 42368)
[PASS] test_supply_revertsWith_ReentrancyGuardReentrantCall() (gas: 278448)
[PASS] test_supply_revertsWith_ReserveFrozen() (gas: 63450)
[PASS] test_supply_revertsWith_ReserveNotListed() (gas: 22868)
[PASS] test_supply_revertsWith_ReservePaused() (gas: 63354)
Suite result: ok. 15 passed; 0 failed; 0 skipped; finished in 492.42ms (468.53ms CPU time)

Ran 1 test for tests/unit/Spoke/Spoke.UpdateUserDynamicConfig.t.sol:SpokeUpdateUserDynamicConfigTest
[PASS] test_updateUserDynamicConfig_revertsWith_ReentrancyGuardReentrantCall() (gas: 631031)
Suite result: ok. 1 passed; 0 failed; 0 skipped; finished in 24.76ms (851.89µs CPU time)

Ran 1 test for tests/unit/Spoke/Spoke.UpdateUserRiskPremium.t.sol:SpokeUpdateUserRiskPremiumTest
[PASS] test_updateUserRiskPremium_revertsWith_ReentrancyGuardReentrantCall() (gas: 630033)
Suite result: ok. 1 passed; 0 failed; 0 skipped; finished in 23.96ms (811.43µs CPU time)

Ran 7 tests for tests/unit/Hub/Hub.ReportDeficit.t.sol:HubReportDeficitTest
[PASS] test_reportDeficit_fuzz_revertsWith_SurplusDrawnDeficitReported(uint256) (runs: 5, μ: 232481, ~: 232345)
Logs:
  Bound result 10585

[PASS] test_reportDeficit_fuzz_revertsWith_SurplusPremiumRayDeficitReported(uint256) (runs: 5, μ: 233397, ~: 233261)
Logs:
  Bound result 10585

[PASS] test_reportDeficit_fuzz_with_premium(uint256,uint256,uint256,uint256) (runs: 5, μ: 680116, ~: 682769)
Logs:
  Bound result 240336
  Bound result 555770955
  Bound result 178808
  Bound result 34853063093323925748250951516542

[PASS] test_reportDeficit_halted() (gas: 264489)
[PASS] test_reportDeficit_revertsWith_InvalidAmount() (gas: 24884)
[PASS] test_...*[Comment body truncated]*

@github-actions
Copy link

github-actions bot commented Feb 4, 2026

♻️ Forge Gas Snapshots

Path Value
snapshots/Hub.Operations.json
add ↑13% (+9701) 86,333
add: with transfer ↑8% (+9701) 124,730
draw ↑14% (+12711) 103,499
eliminateDeficit: full ↑8% (+6865) 89,272
eliminateDeficit: partial ↑7% (+6865) 98,877
payFee ↑4% (+2801) 73,617
refreshPremium ↑12% (+9601) 89,037
remove: full ↑11% (+9665) 97,439
remove: partial ↑11% (+9665) 97,439
reportDeficit ↑8% (+9911) 127,550
restore: full ↑17% (+12711) 89,382
restore: full - with transfer ↑8% (+13067) 182,347
restore: partial ↑15% (+12711) 97,984
restore: partial - with transfer ↑9% (+12711) 155,964
transferShares ↑14% (+9601) 79,231
mintFeeShares 85,552
snapshots/NativeTokenGateway.Operations.json
borrowNative ↑5% (+12414) 244,607
repayNative ↑8% (+12885) 183,335
supplyAsCollateralNative ↓0% (-531) 163,998
supplyNative ↓0% (-424) 138,872
withdrawNative: full ↓0% (-420) 128,841
withdrawNative: partial ↓0% (-525) 140,851
snapshots/SignatureGateway.Operations.json
borrowWithSig ↑6% (+12414) 229,662
repayWithSig ↑7% (+12885) 203,595
supplyWithSig ↑5% (+7761) 165,343
updateUserDynamicConfigWithSig ↑1% (+683) 102,252
updateUserRiskPremiumWithSig ↑1% (+683) 101,089
withdrawWithSig ↑6% (+10390) 189,167
snapshots/Spoke.Getters.json
getUserAccountData: supplies: 1, borrows: 0 ↑0% (+42) 49,636
getUserAccountData: supplies: 2, borrows: 0 ↑0% (+84) 81,544
getUserAccountData: supplies: 2, borrows: 1 ↑0% (+171) 101,680
getUserAccountData: supplies: 2, borrows: 2 ↑0% (+258) 126,061
snapshots/Spoke.Operations.ZeroRiskPremium.json
borrow: first ↑7% (+12840) 203,392
borrow: second action, same reserve ↑8% (+12840) 183,068
liquidationCall (receiveShares): full ↑4% (+12587) 298,726
liquidationCall (receiveShares): partial ↑4% (+12587) 298,144
liquidationCall (reportDeficit): full ↑3% (+11935) 383,934
liquidationCall: full ↑4% (+12180) 333,055
liquidationCall: partial ↑4% (+12180) 332,473
permitReserve + repay (multicall) ↑7% (+12798) 186,318
permitReserve + supply (multicall) ↑6% (+9701) 163,442
permitReserve + supply + enable collateral (multicall) ↑0% (+121) 168,303
repay: full ↑10% (+12798) 146,046
repay: partial ↑10% (+12798) 145,366
supply + enable collateral (multicall) ↑7% (+9701) 140,973
supply: 0 borrows, collateral disabled ↓0% (-531) 126,755
supply: 0 borrows, collateral enabled ↑9% (+9701) 122,525
supply: second action, same reserve ↓0% (-531) 109,655
updateUserRiskPremium: 1 borrow ↑0% (+129) 95,841
updateUserRiskPremium: 2 borrows ↑1% (+857) 106,249
usingAsCollateral: 1 borrow, disable ↑0% (+129) 105,885
usingAsCollateral: 2 borrows, disable ↑0% (+216) 127,521
withdraw: 0 borrows, full ↓0% (-525) 127,430
withdraw: 0 borrows, partial ↓0% (-483) 137,020
withdraw: 1 borrow, partial ↓0% (-396) 159,586
withdraw: 2 borrows, partial ↓0% (-309) 181,210
withdraw: non collateral ↑9% (+10348) 121,560
snapshots/Spoke.Operations.json
borrow: first ↑5% (+12414) 271,901
borrow: second action, same reserve ↑6% (+12414) 214,577
liquidationCall (receiveShares): full ↑4% (+12161) 330,344
liquidationCall (receiveShares): partial ↑4% (+12161) 329,762
liquidationCall (reportDeficit): full ↑3% (+11935) 388,151
liquidationCall: full ↑3% (+11754) 364,673
liquidationCall: partial ↑3% (+11754) 364,091
permitReserve + repay (multicall) ↑7% (+12798) 194,797
permitReserve + supply (multicall) ↑6% (+9701) 163,442
permitReserve + supply + enable collateral (multicall) ↑0% (+121) 168,303
repay: full ↑9% (+12798) 149,725
repay: partial ↑9% (+12798) 153,845
supply + enable collateral (multicall) ↑7% (+9701) 140,973
supply: 0 borrows, collateral disabled ↓0% (-531) 126,755
supply: 0 borrows, collateral enabled ↑9% (+9701) 122,525
supply: second action, same reserve ↓0% (-531) 109,655
updateUserRiskPremium: 1 borrow ↑7% (+9817) 158,888
updateUserRiskPremium: 2 borrows ↑10% (+20233) 219,566
usingAsCollateral: 1 borrow, disable ↑6% (+9817) 168,929
usingAsCollateral: 2 borrows, disable ↑9% (+19592) 248,834
withdraw: 0 borrows, full ↓0% (-525) 127,430
withdraw: 0 borrows, partial ↓0% (-483) 137,020
withdraw: 1 borrow, partial ↑4% (+9292) 220,128
withdraw: 2 borrows, partial ↑7% (+19067) 300,021
withdraw: non collateral ↑9% (+10348) 121,560
🔕 Unchanged
Path Value
snapshots/SignatureGateway.Operations.json
setSelfAsUserPositionManagerWithSig 75,385
setUsingAsCollateralWithSig 58,546
snapshots/Spoke.Getters.json
getUserAccountData: supplies: 0, borrows: 0 12,992
snapshots/Spoke.Operations.ZeroRiskPremium.json
setUserPositionManagersWithSig: disable 47,051
setUserPositionManagersWithSig: enable 68,951
updateUserDynamicConfig: 1 collateral 74,523
updateUserDynamicConfig: 2 collaterals 89,391
usingAsCollateral: 0 borrows, enable 59,594
usingAsCollateral: 1 borrow, enable 42,482
usingAsCollateral: 2 borrows, enable 42,494
snapshots/Spoke.Operations.json
setUserPositionManagersWithSig: disable 47,051
setUserPositionManagersWithSig: enable 68,951
updateUserDynamicConfig: 1 collateral 74,523
updateUserDynamicConfig: 2 collaterals 89,391
usingAsCollateral: 0 borrows, enable 59,594
usingAsCollateral: 1 borrow, enable 42,482
usingAsCollateral: 2 borrows, enable 42,494

@github-actions
Copy link

github-actions bot commented Feb 4, 2026

Forge Build Sizes

Contract Runtime Size (B) Initcode Size (B) Runtime Margin (B) Initcode Margin (B)
Hub ↑2% (+508) 24,055 ↑2% (+508) 24,252 ↓49% (-508) 521 ↓2% (-508) 24,900
SpokeConfigurator ↓5% (-662) 11,666 ↓5% (-662) 11,862 ↑5% (+662) 12,910 ↑2% (+662) 37,290
🔕 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
SpokeInstance 24,193 25,000 383 24,152
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

@yan-man yan-man changed the base branch from rft/mint-fee-shares-2 to fix/preview February 6, 2026 03:19
@yan-man yan-man marked this pull request as ready for review February 6, 2026 04:42
@yan-man yan-man changed the base branch from fix/preview to fix/gas-tests February 6, 2026 14:54
@yan-man yan-man changed the title fix: gas tests with interest accrual (mintFeeShares) fix: gas tests with interest accrual (1193 vs dev) Feb 6, 2026
@yan-man
Copy link
Contributor Author

yan-man commented Feb 10, 2026

decided to leave minting out of accrual

@yan-man yan-man closed this Feb 10, 2026
@yan-man yan-man deleted the fix/gas-test-mintFeeShares branch February 10, 2026 13:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants