Skip to content

Conversation

@CheyenneAtapour
Copy link
Contributor

@CheyenneAtapour CheyenneAtapour commented Oct 18, 2025

Please don't merge in, only for debugging and informational purposes

This PR examines the gas cost of the worst case scenario for liquidations and borrowing. As a user enables more collaterals, this increases the gas cost of actions which calculate user risk premium, as the algorithm for risk premium must loop through all collateral assets. Currently, OpenZeppelin's implementation of quicksort is being used, which has worst-case performance when the array is sorted (either in ascending or descending order). The purpose of this PR is to find the limit on the number of collaterals where actions on a user position succeed, and to avoid the scenario of a user's position being unable to be liquidated due to out-of-gas exceptions. This work was foundational to motivate the implementation in #974

@github-actions
Copy link

github-actions bot commented Oct 18, 2025

Forge Build Sizes

🔕 Unchanged
Contract Runtime Size (B) Initcode Size (B) Runtime Margin (B) Initcode Margin (B)
AaveOracle 1,842 2,580 22,734 46,572
AccessManager 10,198 11,423 14,378 37,729
Address 44 94 24,532 49,058
Arrays 44 94 24,532 49,058
AssetInterestRateStrategy 2,349 2,534 22,227 46,618
AssetLogic 44 94 24,532 49,058
AuthorityUtils 44 94 24,532 49,058
Bytes 44 94 24,532 49,058
Comparators 44 94 24,532 49,058
Constants 395 447 24,181 48,705
ECDSA 44 94 24,532 49,058
EIP712Hash 441 493 24,135 48,659
EIP712Types 44 94 24,532 49,058
ERC1967Proxy 122 934 24,454 48,218
ERC1967Utils 44 94 24,532 49,058
EnumerableSet 44 94 24,532 49,058
Errors 44 94 24,532 49,058
GatewayBaseWrapper 1,810 2,085 22,766 47,067
Hub 20,721 20,955 3,855 28,197
HubConfigurator 9,981 10,254 14,595 38,898
JsonBindings 9,244 9,296 15,332 39,856
KeyValueList 44 94 24,532 49,058
KeyValueListWrapper 802 830 23,774 48,322
LibBit 44 94 24,532 49,058
LiquidationLogic 5,779 5,831 18,797 43,321
LiquidationLogicWrapper 10,117 10,291 14,459 38,861
Math 44 94 24,532 49,058
MathUtils 44 94 24,532 49,058
MockERC1271Wallet 599 733 23,977 48,419
MockERC20 1,913 2,379 22,663 46,773
MockPriceFeed 642 1,300 23,934 47,852
MockSpokeInstance 24,241 25,049 335 24,103
NativeTokenGateway 4,929 5,346 19,647 43,806
NoncesKeyed 624 652 23,952 48,500
NoncesKeyedMock 735 763 23,841 48,389
Panic 44 94 24,532 49,058
PercentageMath 44 94 24,532 49,058
PercentageMathWrapper 592 620 23,984 48,532
PositionStatusMap 44 94 24,532 49,058
PositionStatusMapWrapper 2,407 2,435 22,169 46,717
ProxyAdmin 977 1,213 23,599 47,939
RescuableWrapper 770 904 23,806 48,248
Roles 153 203 24,423 48,949
SafeCast 44 94 24,532 49,058
SafeERC20 44 94 24,532 49,058
SafeTransferLib 44 94 24,532 49,058
SharesMath 44 94 24,532 49,058
SignatureChecker 44 94 24,532 49,058
SignatureGateway 10,158 10,669 14,418 38,483
SlotDerivation 44 94 24,532 49,058
SpokeConfigurator 7,259 7,532 17,317 41,620
SpokeInstance 24,179 24,915 397 24,237
StorageSlot 44 94 24,532 49,058
TestnetERC20 2,810 3,686 21,766 45,466
Time 44 94 24,532 49,058
TransientSlot 44 94 24,532 49,058
TransparentUpgradeableProxy 1,073 3,445 23,503 45,707
TreasurySpoke 2,437 2,838 22,139 46,314
UnitPriceFeed 700 1,635 23,876 47,517
Utils 44 94 24,532 49,058
WETH9 1,864 2,330 22,712 46,822
WadRayMath 44 94 24,532 49,058
WadRayMathWrapper 1,252 1,280 23,324 47,872

@github-actions
Copy link

github-actions bot commented Oct 18, 2025

🌈 Test Results
No files changed, compilation skipped

Ran 17 tests for tests/unit/AaveOracle.t.sol:AaveOracleTest
[PASS] test_constructor() (gas: 440456)
[PASS] test_decimals() (gas: 8387)
[PASS] test_deploy_revertsWith_InvalidAddress() (gas: 38089)
[PASS] test_description() (gas: 12094)
[PASS] test_fuzz_constructor(uint8) (runs: 5000, μ: 444409, ~: 444703)
[PASS] test_getReservePrice() (gas: 47409)
[PASS] test_getReservePrice_revertsWith_InvalidPrice() (gas: 46669)
[PASS] test_getReservePrice_revertsWith_InvalidSource() (gas: 10976)
[PASS] test_getReservePrices() (gas: 79551)
[PASS] test_getReservePrices_revertsWith_InvalidSource() (gas: 49352)
[PASS] test_getReserveSource() (gas: 47584)
[PASS] test_setReserveSource() (gas: 44466)
[PASS] test_setReserveSource_revertsWith_InvalidPrice() (gas: 97683)
[PASS] test_setReserveSource_revertsWith_InvalidSource() (gas: 15327)
[PASS] test_setReserveSource_revertsWith_InvalidSourceDecimals() (gas: 15149)
[PASS] test_setReserveSource_revertsWith_OnlySpoke() (gas: 11049)
[PASS] test_spoke() (gas: 10614)
Suite result: ok. 17 passed; 0 failed; 0 skipped; finished in 526.20ms (511.51ms CPU time)

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

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

[PASS] test_calculateInterestRate_LeftToKinkPoint(uint256) (runs: 5000, μ: 24535, ~: 24690)
[PASS] test_calculateInterestRate_RightToKinkPoint(uint256) (runs: 5000, μ: 25653, ~: 25690)
[PASS] test_calculateInterestRate_ZeroDebtZeroLiquidity() (gas: 18944)
Logs:
  Bound result 0

[PASS] test_calculateInterestRate_fuzz_ZeroDebt(uint256) (runs: 5000, μ: 19177, ~: 18950)
[PASS] test_calculateInterestRate_revertsWith_InterestRateDataNotSet() (gas: 11361)
[PASS] test_deploy_revertsWith_InvalidAddress() (gas: 36318)
[PASS] test_getBaseVariableBorrowRate() (gas: 14864)
[PASS] test_getInterestRateData() (gas: 19653)
[PASS] test_getMaxVariableBorrowRate() (gas: 15312)
[PASS] test_getOptimalUsageRatio() (gas: 14735)
[PASS] test_getVariableRateSlope1() (gas: 14810)
[PASS] test_getVariableRateSlope2() (gas: 14877)
[PASS] test_maxBorrowRate() (gas: 8431)
[PASS] test_maxOptimalRatio() (gas: 8431)
[PASS] test_minOptimalRatio() (gas: 8440)
[PASS] test_setInterestRateData() (gas: 69812)
[PASS] test_setInterestRateData_revertsWith_InvalidMaxRate() (gas: 42072)
[PASS] test_setInterestRateData_revertsWith_InvalidOptimalUsageRatio() (gas: 43120)
[PASS] test_setInterestRateData_revertsWith_InvalidRateData() (gas: 35395)
[PASS] test_setInterestRateData_revertsWith_OnlyHub() (gas: 23786)
[PASS] test_setInterestRateData_revertsWith_Slope2MustBeGteSlope1() (gas: 37980)
Suite result: ok. 23 passed; 0 failed; 0 skipped; finished in 988.31ms (981.99ms CPU time)

Ran 8 tests for tests/unit/misc/EIP712Hash.t.sol:EIP712HashTest
[PASS] test_constants() (gas: 5450)
[PASS] test_hash_borrow_fuzz((address,uint256,uint256,address,uint256,uint256)) (runs: 5000, μ: 4659, ~: 4659)
[PASS] test_hash_repay_fuzz((address,uint256,uint256,address,uint256,uint256)) (runs: 5000, μ: 4615, ~: 4615)
[PASS] test_hash_setUsingAsCollateral_fuzz((address,uint256,bool,address,uint256,uint256)) (runs: 5000, μ: 4902, ~: 4902)
[PASS] test_hash_supply_fuzz((address,uint256,uint256,address,uint256,uint256)) (runs: 5000, μ: 4703, ~: 4703)
[PASS] test_hash_updateUserDynamicConfig_fuzz((address,address,uint256,uint256)) (runs: 5000, μ: 4441, ~: 4441)
[PASS] test_hash_updateUserRiskPremium_fuzz((address,address,uint256,uint256)) (runs: 5000, μ: 4462, ~: 4462)
[PASS] test_hash_withdraw_fuzz((address,uint256,uint256,address,uint256,uint256)) (runs: 5000, μ: 4681, ~: 4681)
Suite result: ok. 8 passed; 0 failed; 0 skipped; finished in 895.43ms (895.21ms CPU time)

Ran 8 tests for tests/unit/misc/GatewayBase.t.sol:GatewayBaseTest
[PASS] test_constructor() (gas: 17646)
[PASS] test_registerSpoke_fuzz(address) (runs: 5000, μ: 42033, ~: 42033)
[PASS] test_registerSpoke_revertsWith_InvalidAddress() (gas: 13345)
[PASS] test_registerSpoke_revertsWith_OwnableUnauthorizedAccount() (gas: 14077)
[PASS] test_registerSpoke_unregister() (gas: 36599)
[PASS] test_renouncePositionManagerRole() (gas: 65377)
[PASS] test_renouncePositionManagerRole_revertsWith_InvalidAddress() (gas: 76673)
[PASS] test_renouncePositionManagerRole_revertsWith_OwnableUnauthorizedAccount() (gas: 76834)
Suite result: ok. 8 passed; 0 failed; 0 skipped; finished in 437.47ms (420.46ms CPU time)

Ran 5 tests for tests/gas/Gateways.Operations.gas.t.sol:NativeTokenGateway_Gas_Tests
[PASS] test_borrowNative() (gas: 953756)
[PASS] test_repayNative() (gas: 1173746)
[PASS] test_supplyAndCollateralNative() (gas: 329814)
[PASS] test_supplyNative() (gas: 288235)
[PASS] test_withdrawNative() (gas: 509716)
Suite result: ok. 5 passed; 0 failed; 0 skipped; finished in 34.83ms (5.07ms CPU time)

Ran 8 tests for tests/gas/Gateways.Operations.gas.t.sol:SignatureGateway_Gas_Tests
[PASS] test_borrowWithSig() (gas: 784874)
[PASS] test_repayWithSig() (gas: 1126977)
[PASS] test_setSelfAsUserPositionManagerWithSig() (gas: 201454)
[PASS] test_setUsingAsCollateralWithSig() (gas: 327525)
[PASS] test_supplyWithSig() (gas: 462429)
[PASS] test_updateUserDynamicConfigWithSig() (gas: 137923)
[PASS] test_updateUserRiskPremiumWithSig() (gas: 135442)
[PASS] test_withdrawWithSig() (gas: 409950)
Suite result: ok. 8 passed; 0 failed; 0 skipped; finished in 48.31ms (21.20ms CPU time)

Ran 6 tests for tests/unit/Hub/Hub.Access.t.sol:HubAccessTest
[PASS] test_change_authority() (gas: 2312210)
[PASS] test_change_role_responsibility() (gas: 102590)
[PASS] test_hub_access_manager_exposure() (gas: 12684)
[PASS] test_hub_admin_access() (gas: 1155460)
[PASS] test_migrate_role_responsibility() (gas: 398872)
[PASS] test_setInterestRateData_access() (gas: 103513)
Suite result: ok. 6 passed; 0 failed; 0 skipped; finished in 22.72ms (3.68ms CPU time)

Ran 21 tests for tests/unit/Hub/Hub.Add.t.sol:HubAddTest
[PASS] test_add_AddCapReachedButNotExceeded_rounding() (gas: 631811)
[PASS] test_add_fuzz_AddCapReachedButNotExceeded(uint40) (runs: 5000, μ: 158797, ~: 158764)
[PASS] test_add_fuzz_multi_asset_multi_spoke(uint256,uint256,uint256) (runs: 5000, μ: 316363, ~: 316498)
[PASS] test_add_fuzz_revertsWith_AddCapExceeded(uint40) (runs: 5000, μ: 78821, ~: 78788)
[PASS] test_add_fuzz_revertsWith_AddCapExceeded_due_to_interest(uint40,uint256,uint256) (runs: 5000, μ: 271055, ~: 271128)
[PASS] test_add_fuzz_revertsWith_InvalidShares_due_to_index(uint256,uint256,uint256) (runs: 5000, μ: 206911, ~: 207091)
[PASS] test_add_fuzz_revertsWith_TransferFromFailed(uint256) (runs: 5000, μ: 83041, ~: 82766)
[PASS] test_add_fuzz_single_asset(uint256,address,uint256) (runs: 5000, μ: 340138, ~: 340076)
[PASS] test_add_fuzz_single_spoke_multi_add(uint256,uint256) (runs: 5000, μ: 743365, ~: 743458)
[PASS] test_add_multi_add_minimal_shares() (gas: 317740)
[PASS] test_add_revertsWith_AmountDowncastOverflow() (gas: 201665)
[PASS] test_add_revertsWith_InvalidAddress() (gas: 15807)
[PASS] test_add_revertsWith_InvalidAmount() (gas: 15852)
[PASS] test_add_revertsWith_InvalidShares() (gas: 206093)
[PASS] test_add_revertsWith_SharesDowncastOverflow() (gas: 38130)
[PASS] test_add_revertsWith_SpokeNotActive() (gas: 59848)
[PASS] test_add_revertsWith_SpokePaused() (gas: 59965)
[PASS] test_add_revertsWith_TransferFromFailed() (gas: 79340)
[PASS] test_add_single_asset() (gas: 328062)
Logs:
  Bound result 2
  Bound result 100000000000000000000

[PASS] test_add_with_increased_index() (gas: 301019)
[PASS] test_add_with_increased_index_with_premium() (gas: 655566)
Suite result: ok. 21 passed; 0 failed; 0 skipped; finished in 44.77s (44.74s CPU time)

Ran 35 tests for tests/unit/Hub/Hub.Config.t.sol:HubConfigTest
[PASS] test_addAsset_fuzz(address,uint8,address) (runs: 5000, μ: 867160, ~: 867192)
[PASS] test_addAsset_fuzz_revertsWith_InvalidAddress_feeReceiver(address,uint8,address) (runs: 5000, μ: 46700, ~: 47004)
[PASS] test_addAsset_fuzz_revertsWith_InvalidAddress_irStrategy(address,uint8,address) (runs: 5000, μ: 46731, ~: 47035)
[PASS] test_addAsset_fuzz_revertsWith_InvalidAddress_underlying(uint8,address,address) (runs: 5000, μ: 37656, ~: 37656)
[PASS] test_addAsset_fuzz_revertsWith_InvalidAssetDecimals(address,uint8,address,address) (runs: 5000, μ: 47198, ~: 47015)
[PASS] test_addAsset_fuzz_revertsWith_InvalidAssetDecimals_tooLow(address,uint8,address,address) (runs: 5000, μ: 47481, ~: 47714)
[PASS] test_addAsset_fuzz_reverts_InvalidIrData(address,uint8,address,address) (runs: 5000, μ: 39910, ~: 36285)
[PASS] test_addAsset_revertsWith_BlockTimestampDowncastOverflow() (gas: 81198)
[PASS] test_addAsset_revertsWith_DrawnRateDowncastOverflow() (gas: 78127)
[PASS] test_addSpoke_fuzz(uint256,(uint40,uint40,uint24,bool,bool)) (runs: 5000, μ: 125822, ~: 125878)
[PASS] test_addSpoke_fuzz_revertsWith_AssetNotListed(uint256,(uint40,uint40,uint24,bool,bool)) (runs: 5000, μ: 34699, ~: 34687)
[PASS] test_addSpoke_fuzz_revertsWith_InvalidAddress_spoke(uint256,(uint40,uint40,uint24,bool,bool)) (runs: 5000, μ: 33287, ~: 33343)
[PASS] test_addSpoke_revertsWith_SpokeAlreadyListed() (gas: 38880)
[PASS] test_hub_deploy_revertsWith_InvalidAddress() (gas: 47281)
[PASS] test_hub_max_riskPremium() (gas: 8503)
[PASS] test_updateAssetConfig_NewFeeReceiver_noFees() (gas: 699915)
[PASS] test_updateAssetConfig_NewFeeReceiver_revertsWith_SpokeNotActive_noFees() (gas: 613001)
[PASS] test_updateAssetConfig_UseExistingSpokeAndListedAsFeeReceiver_revertsWith_SpokeAlreadyListed() (gas: 72287)
[PASS] test_updateAssetConfig_fuzz(uint256,(address,uint16,address,address)) (runs: 5000, μ: 268957, ~: 269163)
[PASS] test_updateAssetConfig_fuzz_FromZeroLiquidityFee(uint256,uint16) (runs: 5000, μ: 788266, ~: 788150)
[PASS] test_updateAssetConfig_fuzz_LiquidityFee(uint256,uint16) (runs: 5000, μ: 693453, ~: 693376)
[PASS] test_updateAssetConfig_fuzz_NewFeeReceiver(uint256) (runs: 5000, μ: 791113, ~: 791219)
[PASS] test_updateAssetConfig_fuzz_NewInterestRateStrategy(uint256) (runs: 5000, μ: 1171424, ~: 1171530)
[PASS] test_updateAssetConfig_fuzz_ReuseFeeReceiver_revertsWith_SpokeAlreadyListed(uint256) (runs: 5000, μ: 842338, ~: 842444)
[PASS] test_updateAssetConfig_fuzz_Scenario(uint256) (runs: 5000, μ: 680921, ~: 680975)
[PASS] test_updateAssetConfig_fuzz_UseExistingSpokeAsFeeReceiver_revertsWith_SpokeAlreadyListed(uint256) (runs: 5000, μ: 71885, ~: 71885)
[PASS] test_updateAssetConfig_fuzz_revertsWith_InvalidInterestRateStrategy(uint256) (runs: 5000, μ: 59946, ~: 60000)
[PASS] test_updateAssetConfig_fuzz_revertsWith_InvalidLiquidityFee(uint256,(address,uint16,address,address)) (runs: 5000, μ: 41031, ~: 40885)
[PASS] test_updateAssetConfig_fuzz_revertsWith_InvalidReinvestmentController() (gas: 500775)
[PASS] test_updateAssetConfig_fuzz_revertsWith_calculateInterestRateReverts(uint256,(address,uint16,address,address)) (runs: 5000, μ: 202321, ~: 202526)
[PASS] test_updateAssetConfig_fuzz_revertsWith_setInterestRateDataReverts(uint256,(address,uint16,address,address)) (runs: 5000, μ: 65169, ~: 65023)
[PASS] test_updateAssetConfig_oldFeeReceiver_flags() (gas: 842921)
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, μ: 58409, ~: 58475)
[PASS] test_updateSpokeConfig_fuzz_revertsWith_SpokeNotListed(uint256,address,(uint40,uint40,uint24,bool,bool)) (runs: 5000, μ: 40378, ~: 40442)
[PASS] test_updateSpokeConfig_revertsWith_AssetNotListed() (gas: 29290)
Suite result: ok. 35 passed; 0 failed; 0 skipped; finished in 95.75s (95.73s CPU time)

Ran 16 tests for tests/unit/Hub/Hub.Draw.t.sol:HubDrawTest
[PASS] test_draw_DifferentSpokes() (gas: 361294)
[PASS] test_draw_fuzz_IncreasedBorrowRate(uint256,uint256) (runs: 5000, μ: 666663, ~: 666576)
[PASS] test_draw_fuzz_amounts_same_block(uint256,uint256) (runs: 5000, μ: 291030, ~: 290893)
[PASS] test_draw_fuzz_revertsWith_DrawCapExceeded(uint40) (runs: 5000, μ: 81232, ~: 81199)
[PASS] test_draw_fuzz_revertsWith_DrawCapExceeded_due_to_interest(uint40,uint256,uint256) (runs: 5000, μ: 295203, ~: 295314)
[PASS] test_draw_fuzz_revertsWith_InsufficientLiquidity(uint256,uint256) (runs: 5000, μ: 33864, ~: 33665)
[PASS] test_draw_fuzz_revertsWith_InsufficientLiquidity_due_to_draw(uint256) (runs: 5000, μ: 184898, ~: 184625)
[PASS] test_draw_fuzz_revertsWith_InsufficientLiquidity_due_to_remove(uint256) (runs: 5000, μ: 130299, ~: 130104)
[PASS] test_draw_fuzz_revertsWith_InvalidAddress(uint256) (runs: 5000, μ: 15735, ~: 15735)
[PASS] test_draw_revertsWith_DrawCapExceeded_due_to_deficit() (gas: 261318)
[PASS] test_draw_revertsWith_InsufficientLiquidity() (gas: 27943)
[PASS] test_draw_revertsWith_InsufficientLiquidity_due_to_draw() (gas: 181201)
[PASS] test_draw_revertsWith_InsufficientLiquidity_due_to_remove() (gas: 127414)
[PASS] test_draw_revertsWith_InvalidAmount() (gas: 15855)
[PASS] test_draw_revertsWith_SpokeNotActive() (gas: 59672)
[PASS] test_draw_revertsWith_SpokePaused() (gas: 59745)
Suite result: ok. 16 passed; 0 failed; 0 skipped; finished in 22.95s (22.93s CPU time)

Ran 6 tests for tests/unit/Hub/Hub.EliminateDeficit.t.sol:HubEliminateDeficitTest
[PASS] test_eliminateDeficit(uint256) (runs: 5000, μ: 490067, ~: 490067)
[PASS] test_eliminateDeficit_allowSpokePaused() (gas: 336107)
[PASS] test_eliminateDeficit_fuzz_revertsWith_InvalidAmount_Excess(uint256) (runs: 5000, μ: 246915, ~: 246915)
[PASS] test_eliminateDeficit_fuzz_revertsWith_callerSpokeNotActive(address) (runs: 5000, μ: 29141, ~: 29141)
[PASS] test_eliminateDeficit_revertsWith_InvalidAmount_ZeroAmountNoDeficit() (gas: 20068)
[PASS] test_eliminateDeficit_revertsWith_InvalidAmount_ZeroAmountWithDeficit() (gas: 248037)
Suite result: ok. 6 passed; 0 failed; 0 skipped; finished in 12.38s (12.35s CPU time)

Ran 5 tests for tests/unit/Hub/Hub.MintFeeShares.t.sol:HubMintFeeSharesTest
[PASS] test_mintFeeShares() (gas: 318604)
[PASS] test_mintFeeShares_noFees() (gas: 376022)
[PASS] test_mintFeeShares_noShares() (gas: 312395)
[PASS] test_mintFeeShares_revertsWith_AccessManagedUnauthorized() (gas: 25025)
[PASS] test_mintFeeShares_revertsWith_SpokeNotActive() (gas: 254595)
Suite result: ok. 5 passed; 0 failed; 0 skipped; finished in 20.48ms (3.86ms CPU time)

Ran 8 tests for tests/gas/Hub.Operations.gas.t.sol:HubOperations_Gas_Tests
[PASS] test_add() (gas: 133353)
[PASS] test_deficit() (gas: 1084266)
[PASS] test_draw() (gas: 379629)
[PASS] test_mintFeeShares() (gas: 460643)
[PASS] test_payFee_transferShares() (gas: 943347)
[PASS] test_refreshPremium() (gas: 649491)
[PASS] test_remove() (gas: 285083)
[PASS] test_restore() (gas: 707841)
Suite result: ok. 8 passed; 0 failed; 0 skipped; finished in 28.67ms (5.67ms CPU time)

Ran 6 tests for tests/unit/Hub/Hub.PayFee.t.sol:HubPayFeeTest
[PASS] test_payFee_fuzz(uint256,uint256) (runs: 5000, μ: 657187, ~: 657382)
[PASS] test_payFee_fuzz_with_interest(uint256,uint256,uint256) (runs: 5000, μ: 657610, ~: 657890)
[PASS] test_payFee_revertsWith_InvalidShares() (gas: 20182)
[PASS] test_payFee_revertsWith_SpokeNotActive() (gas: 59705)
[PASS] test_payFee_revertsWith_underflow_added_shares_exceeded() (gas: 136612)
[PASS] test_payFee_revertsWith_underflow_added_shares_exceeded_with_interest() (gas: 615835)
Suite result: ok. 6 passed; 0 failed; 0 skipped; finished in 23.20s (23.18s CPU time)

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

[PASS] test_reclaim_fullAmount() (gas: 663963)
[PASS] test_reclaim_fuzz(uint256,uint256,uint256) (runs: 5000, μ: 684831, ~: 684295)
[PASS] test_reclaim_multipleSweepsAndReclaims() (gas: 791531)
[PASS] test_reclaim_revertsWith_AssetNotListed() (gas: 12461)
[PASS] test_reclaim_revertsWith_InvalidAmount_zero() (gas: 93051)
[PASS] test_reclaim_revertsWith_OnlyReinvestmentController(address) (runs: 5000, μ: 93916, ~: 93916)
[PASS] test_reclaim_revertsWith_OnlyReinvestmentController_init() (gas: 40297)
[PASS] test_reclaim_revertsWith_underflow_exceedsSwept() (gas: 98515)
[PASS] test_reclaim_revertsWith_underflow_exceedsSwept_afterSweep() (gas: 471677)
Suite result: ok. 10 passed; 0 failed; 0 skipped; finished in 14.57s (14.56s CPU time)

Ran 7 tests for tests/unit/Spoke/Spoke.AccrueInterest.t.sol:SpokeAccrueInterestTest
[PASS] test_accrueInterest_NoActionTaken() (gas: 134049)
[PASS] test_accrueInterest_NoInterest_NoDebt(uint40) (runs: 5000, μ: 645749, ~: 645586)
[PASS] test_accrueInterest_NoInterest_OnlySupply(uint40) (runs: 5000, μ: 255275, ~: 255305)
[PASS] test_accrueInterest_TenPercentRp(uint256,uint40) (runs: 5000, μ: 593437, ~: 593857)
[PASS] test_accrueInterest_fuzz_BorrowAmountAndSkipTime(uint256,uint40) (runs: 5000, μ: 553772, ~: 553768)
[PASS] test_accrueInterest_fuzz_RPBorrowAndSkipTime((uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256),uint40) (runs: 5000, μ: 4060105, ~: 4080298)
[PASS] test_accrueInterest_fuzz_RatesRPBorrowAndSkipTime((uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256),(uint96,uint96,uint96,uint96),uint40) (runs: 5000, μ: 4130506, ~: 4148600)
Suite result: ok. 7 passed; 0 failed; 0 skipped; finished in 222.21s (222.18s CPU time)

Ran 11 tests for tests/unit/Hub/Hub.RefreshPremium.t.sol:HubRefreshPremiumTest
[PASS] test_refreshPremium_emitsEvent() (gas: 255299)
[PASS] test_refreshPremium_fuzz_positiveDeltas(uint256,int256,int256,int256,bool) (runs: 5000, μ: 476301, ~: 479904)
[PASS] test_refreshPremium_fuzz_withAccrual(uint256,uint256,uint256,uint256) (runs: 5000, μ: 544799, ~: 550770)
[PASS] test_refreshPremium_maxRiskPremiumThreshold() (gas: 894293)
[PASS] test_refreshPremium_negativeDeltas(int256,int256) (runs: 5000, μ: 472764, ~: 473141)
[PASS] test_refreshPremium_negativeDeltas_withAccrual(uint256,uint256) (runs: 5000, μ: 531875, ~: 541108)
[PASS] test_refreshPremium_pausedSpokesAllowed() (gas: 112111)
[PASS] test_refreshPremium_revertsWith_InvalidPremiumChange_RiskPremiumThresholdExceeded_DecreasingPremium() (gas: 867955)
[PASS] test_refreshPremium_revertsWith_SpokeNotActive() (gas: 57695)
[PASS] test_refreshPremium_riskPremiumThreshold() (gas: 916302)
[PASS] test_refreshPremium_spokePremiumUpdateIsContained() (gas: 734640)
Suite result: ok. 11 passed; 0 failed; 0 skipped; finished in 24.68s (24.66s 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, μ: 547127, ~: 547287)
[PASS] test_accrueLiquidityFee_fuzz_maxLiquidityFee_with_premium_multiple_users(uint256,uint256,uint256,uint256,uint256) (runs: 5000, μ: 806814, ~: 806812)
[PASS] test_accrueLiquidityFee_maxLiquidityFee_multi_spoke() (gas: 741224737)
[PASS] test_accrueLiquidityFee_maxLiquidityFee_multi_user() (gas: 285872479)
[PASS] test_accrueLiquidityFee_maxLiquidityFee_with_premium() (gas: 547606)
Logs:
  Bound result 500000000000000000000
  Bound result 5000
  Bound result 34560000
  Bound result 2

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

Ran 7 tests for tests/unit/Spoke/Spoke.AccrueLiquidityFee.t.sol:SpokeAccrueLiquidityFeeTest
[PASS] test_accrueLiquidityFee() (gas: 839859)
[PASS] test_accrueLiquidityFee_NoActionTaken() (gas: 92527)
[PASS] test_accrueLiquidityFee_NoInterest_OnlySupply(uint40) (runs: 5000, μ: 235749, ~: 235722)
[PASS] test_accrueLiquidityFee_exact() (gas: 840535)
[PASS] test_accrueLiquidityFee_fuzz_BorrowAmountAndSkipTime(uint256,uint40) (runs: 5000, μ: 945709, ~: 970645)
[PASS] test_accrueLiquidityFee_maxLiquidityFee() (gas: 545311)
[PASS] test_accrueLiquidityFee_setUsingAsCollateral() (gas: 918447)
Suite result: ok. 7 passed; 0 failed; 0 skipped; finished in 22.51s (22.49s CPU time)

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

[PASS] test_remove_all_with_interest() (gas: 357700)
[PASS] test_remove_fuzz(uint256,uint256) (runs: 5000, μ: 195959, ~: 195763)
[PASS] test_remove_fuzz_all_liquidity_with_interest(uint256,uint256) (runs: 5000, μ: 402586, ~: 403283)
[PASS] test_remove_fuzz_multi_spoke(uint256,uint256) (runs: 5000, μ: 273532, ~: 273683)
[PASS] test_remove_fuzz_multi_spoke_with_interest(uint256,uint256,uint256,uint256) (runs: 5000, μ: 406778, ~: 407770)
[PASS] test_remove_revertsWith_InsufficientLiquidity() (gas: 170057)
[PASS] test_remove_revertsWith_InsufficientLiquidity_exceeding_added_amount() (gas: 141063)
[PASS] test_remove_revertsWith_InsufficientLiquidity_zero_added() (gas: 20745)
[PASS] test_remove_revertsWith_InvalidAddress() (gas: 15718)
[PASS] test_remove_revertsWith_InvalidAmount() (gas: 17819)
[PASS] test_remove_revertsWith_SpokeNotActive() (gas: 59784)
[PASS] test_remove_revertsWith_SpokePaused() (gas: 59890)
[PASS] test_remove_revertsWith_underflow_exceeding_added_amount() (gas: 174003)
[PASS] test_remove_revertsWtih_underflow_one_extra_wei() (gas: 363411)
Suite result: ok. 15 passed; 0 failed; 0 skipped; finished in 29.42s (29.40s CPU time)

Ran 6 tests for tests/unit/Hub/Hub.ReportDeficit.t.sol:HubReportDeficitTest
[PASS] test_reportDeficit_fuzz_revertsWith_SurplusDeficitReported(uint256,uint256,uint256,uint256) (runs: 5000, μ: 161018, ~: 161033)
[PASS] test_reportDeficit_fuzz_with_premium(uint256,uint256,uint256,uint256) (runs: 5000, μ: 678369, ~: 679171)
[PASS] test_reportDeficit_revertsWith_InvalidAmount() (gas: 18212)
[PASS] test_reportDeficit_revertsWith_SpokeNotActive(address) (runs: 5000, μ: 26657, ~: 26657)
[PASS] test_reportDeficit_surplus_drawn_revertsWith_SurplusDeficitReported() (gas: 196169)
[PASS] test_reportDeficit_with_premium() (gas: 677768)
Logs:
  Bound result 10000000000
  Bound result 31536000
  Bound result 5000000000
  Bound result 0

Suite result: ok. 6 passed; 0 failed; 0 skipped; finished in 14.98s (14.96s CPU time)

Ran 21 tests for tests/unit/Hub/Hub.Restore.t.sol:HubRestoreTest
[PASS] test_restore_full_amount_with_interest() (gas: 370171)
Logs:
  Bound result 1000000000000000000000
  Bound result 500000000000000000000
  Bound result 31536000

[PASS] test_restore_full_amount_with_interest_and_premium() (gas: 671908)
Logs:
  Bound result 100000000000000000000
  Bound result 50000000000000000000
  Bound result 31536000
  Bound result 1

[PASS] test_restore_fuzz_full_amount_with_interest(uint256,uint256,uint256) (runs: 5000, μ: 371319, ~: 371504)
[PASS] test_restore_fuzz_full_amount_with_interest_and_premium(uint256,uint256,uint256,uint256) (runs: 5000, μ: 664710, ~: 673267)
[PASS] test_restore_fuzz_revertsWith_SurplusAmountRestored_with_interest(uint256,uint256,uint256) (runs: 5000, μ: 249111, ~: 250093)
[PASS] test_restore_fuzz_revertsWith_SurplusAmountRestored_with_interest_and_premium(uint256,uint256,uint256,uint256) (runs: 5000, μ: 649793, ~: 650703)
[PASS] test_restore_one_share_delta_increase_revertsWith_InvalidPremiumChange() (gas: 244345)
[PASS] test_restore_partial_drawn() (gas: 322185)
[PASS] test_restore_partial_same_block() (gas: 317467)
[PASS] test_restore_premiumDeltas_twoWeiIncrease_realizedDelta() (gas: 241943)
[PASS] test_restore_revertsWith_InvalidAmount_zero() (gas: 46922)
[PASS] test_restore_revertsWith_InvalidPremiumChange_premiumIncrease() (gas: 200721)
[PASS] test_restore_revertsWith_InvalidPremiumChange_premiumSharesIncrease() (gas: 200719)
[PASS] test_restore_revertsWith_SpokeNotActive_whenPaused() (gas: 159324)
[PASS] test_restore_revertsWith_SpokePaused() (gas: 86898)
[PASS] test_restore_revertsWith_SurplusAmountRestored() (gas: 350386)
[PASS] test_restore_revertsWith_SurplusAmountRestored_with_interest() (gas: 248782)
Logs:
  Bound result 100000000000000000000
  Bound result 50000000000000000000
  Bound result 15768000

[PASS] test_restore_revertsWith_SurplusAmountRestored_with_interest_and_premium() (gas: 648906)
Logs:
  Bound result 100000000000000000000
  Bound result 50000000000000000000
  Bound result 31536000
  Bound result 1

[PASS] test_restore_revertsWith_underflow_offsetIncrease() (gas: 200729)
[PASS] test_restore_tooMuchDrawn_revertsWith_SurplusAmountRestored() (gas: 230731)
[PASS] test_restore_when_asset_frozen() (gas: 421101)
Suite result: ok. 21 passed; 0 failed; 0 skipped; finished in 19.97s (19.95s CPU time)

Ran 1 test for tests/unit/Hub/Hub.Rounding.t.sol:HubRoundingTest
[PASS] test_sharePriceWithMultipleDonations() (gas: 670344353)
Suite result: ok. 1 passed; 0 failed; 0 skipped; finished in 3.30s (3.28s CPU time)

Ran 8 tests for tests/unit/Hub/Hub.Sweep.t.sol:HubSweepTest
[PASS] test_sweep() (gas: 489336)
Logs:
  Bound result 1000000000000000000000
  Bound result 1000000000000000000000

[PASS] test_sweep_does_not_impact_utilization(uint256,uint256) (runs: 5000, μ: 654313, ~: 655658)
[PASS] test_sweep_fuzz(uint256,uint256) (runs: 5000, μ: 489847, ~: 489860)
[PASS] test_sweep_revertsWith_AssetNotListed() (gas: 12362)
[PASS] test_sweep_revertsWith_InsufficientLiquidity() (gas: 236132)
[PASS] test_sweep_revertsWith_InvalidAmount() (gas: 104308)
[PASS] test_sweep_revertsWith_OnlyReinvestmentController(address) (runs: 5000, μ: 94572, ~: 94572)
[PASS] test_sweep_revertsWith_OnlyReinvestmentController_init() (gas: 40244)
Suite result: ok. 8 passed; 0 failed; 0 skipped; finished in 17.75s (17.72s CPU time)

Ran 7 tests for tests/unit/Hub/Hub.TransferShares.t.sol:HubTransferSharesTest
[PASS] test_transferShares() (gas: 173342)
Logs:
  Bound result 1000000000000000000000
  Bound result 1000000000000000000000

[PASS] test_transferShares_fuzz(uint256,uint256) (runs: 5000, μ: 176770, ~: 176927)
[PASS] test_transferShares_fuzz_revertsWith_underflow_spoke_added_shares_exceeded(uint256) (runs: 5000, μ: 144904, ~: 144630)
[PASS] test_transferShares_revertsWith_AddCapExceeded() (gas: 188440)
[PASS] test_transferShares_revertsWith_SpokeNotActive() (gas: 169736)
[PASS] test_transferShares_revertsWith_SpokePaused() (gas: 172095)
[PASS] test_transferShares_zeroShares_revertsWith_InvalidShares() (gas: 22464)
Suite result: ok. 7 passed; 0 failed; 0 skipped; finished in 6.51s (6.50s 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, μ: 1089387, ~: 1089536)
[PASS] test_borrow_fuzz_rounding_effect_inflated_ex_rate(uint256,uint256,uint256) (runs: 5000, μ: 1468690, ~: 1468827)
[PASS] test_borrow_fuzz_rounding_effect_shares(uint256,uint256) (runs: 5000, μ: 1124781, ~: 1124552)
[PASS] test_borrow_rounding_effect_multiple_actions() (gas: 1174829)
[PASS] test_borrow_rounding_effect_shares() (gas: 1123767)
Logs:
  Bound result 5000000000000000000
  Bound result 94608000

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

Ran 6 tests for tests/unit/Hub/HubAccrueInterest.t.sol:HubAccrueInterestTest
[PASS] test_accrueInterest_NoActionTaken() (gas: 43921)
[PASS] test_accrueInterest_NoInterest_NoDebt(uint40) (runs: 5000, μ: 369480, ~: 369394)
[PASS] test_accrueInterest_NoInterest_OnlyAdd(uint40) (runs: 5000, μ: 193250, ~: 193197)
[PASS] test_accrueInterest_fuzz_BorrowAmountAndElapsed(uint256,uint40) (runs: 5000, μ: 274442, ~: 274093)
[PASS] test_accrueInterest_fuzz_BorrowAmountRateAndElapsed(uint256,uint256,uint40) (runs: 5000, μ: 385544, ~: 385379)
[PASS] test_accrueInterest_fuzz_BorrowAndWait(uint40) (runs: 5000, μ: 273198, ~: 273112)
Suite result: ok. 6 passed; 0 failed; 0 skipped; finished in 23.71s (23.69s CPU time)

Ran 60 tests for tests/unit/HubConfigurator.t.sol:HubConfiguratorTest
[PASS] test_addAsset_fuzz(bool,address,uint8,address,uint256,uint16,uint32,uint32,uint32) (runs: 5000, μ: 919415, ~: 919971)
[PASS] test_addAsset_fuzz_revertsWith_InvalidAssetDecimals(bool,address,uint8,address,uint256,address) (runs: 5000, μ: 57686, ~: 57669)
[PASS] test_addAsset_fuzz_revertsWith_OwnableUnauthorizedAccount(address) (runs: 5000, μ: 31175, ~: 31175)
[PASS] test_addAsset_revertsWith_InvalidAddress_irStrategy() (gas: 50957)
[PASS] test_addAsset_revertsWith_InvalidAddress_underlying() (gas: 50856)
[PASS] test_addAsset_revertsWith_InvalidLiquidityFee() (gas: 823020)
[PASS] test_addAsset_reverts_invalidIrData() (gas: 44715)
[PASS] test_addSpoke() (gas: 126303)
[PASS] test_addSpokeToAssets() (gas: 222751)
[PASS] test_addSpokeToAssets_revertsWith_MismatchedConfigs() (gas: 24758)
[PASS] test_addSpokeToAssets_revertsWith_OwnableUnauthorizedAccount() (gas: 17149)
[PASS] test_addSpoke_revertsWith_OwnableUnauthorizedAccount() (gas: 16882)
[PASS] test_deactivateAsset() (gas: 158692)
[PASS] test_deactivateAsset_revertsWith_OwnableUnauthorizedAccount() (gas: 17966)
[PASS] test_deactivateSpoke() (gas: 156015)
[PASS] test_deactivateSpoke_revertsWith_OwnableUnauthorizedAccount() (gas: 18016)
[PASS] test_freezeAsset() (gas: 233347)
[PASS] test_freezeAsset_revertsWith_OwnableUnauthorizedAccount() (gas: 18029)
[PASS] test_freezeSpoke() (gas: 249254)
[PASS] test_freezeSpoke_revertsWith_OwnableUnauthorizedAccount() (gas: 18105)
[PASS] test_pauseAsset() (gas: 158702)
[PASS] test_pauseAsset_revertsWith_OwnableUnauthorizedAccount() (gas: 17986)
[PASS] test_pauseSpoke() (gas: 156006)
[PASS] test_pauseSpoke_revertsWith_OwnableUnauthorizedAccount() (gas: 18037)
[PASS] test_updateFeeConfig_Scenario() (gas: 335698)
Logs:
  Bound result 0
  Bound result 1800
  Bound result 0
  Bound result 400
  Bound result 0
  Bound result 0

[PASS] test_updateFeeConfig_fuzz(uint256,uint16,address) (runs: 5000, μ: 185969, ~: 186204)
[PASS] test_updateFeeConfig_fuzz_revertsWith_OwnableUnauthorizedAccount(address) (runs: 5000, μ: 17683, ~: 17683)
[PASS] test_updateFeeConfig_revertsWith_InvalidAddress_spoke() (gas: 50125)
[PASS] test_updateFeeConfig_revertsWith_InvalidLiquidityFee() (gas: 52222)
[PASS] test_updateFeeReceiver_Scenario() (gas: 214425)
[PASS] test_updateFeeReceiver_WithdrawFromOldSpoke() (gas: 983771)
[PASS] test_updateFeeReceiver_correctAccruals() (gas: 1018524)
[PASS] test_updateFeeReceiver_fuzz(address) (runs: 5000, μ: 179912, ~: 179912)
[PASS] test_updateFeeReceiver_fuzz_revertsWith_OwnableUnauthorizedAccount(address) (runs: 5000, μ: 17314, ~: 17314)
[PASS] test_updateFeeReceiver_revertsWith_InvalidAddress_spoke() (gas: 54794)
[PASS] test_updateFeeReceiver_revertsWith_SpokeAlreadyListed() (gas: 86334)
[PASS] test_updateInterestRateData() (gas: 71870)
[PASS] test_updateInterestRateData_revertsWith_OwnableUnauthorizedAccount() (gas: 19216)
[PASS] test_updateInterestRateStrategy() (gas: 93719)
[PASS] test_updateInterestRateStrategy_fuzz_revertsWith_OwnableUnauthorizedAccount(address) (runs: 5000, μ: 28677, ~: 28677)
[PASS] test_updateInterestRateStrategy_revertsWith_InterestRateStrategyReverts() (gas: 76714)
[PASS] test_updateInterestRateStrategy_revertsWith_InvalidAddress_irStrategy() (gas: 66375)
[PASS] test_updateInterestRateStrategy_revertsWith_InvalidInterestRateStrategy() (gas: 66921)
[PASS] test_updateLiquidityFee_fuzz(uint256,uint16) (runs: 5000, μ: 86525, ~: 86766)
[PASS] test_updateLiquidityFee_revertsWith_InvalidLiquidityFee() (gas: 54755)
[PASS] test_updateLiquidityFee_revertsWith_OwnableUnauthorizedAccount() (gas: 16611)
[PASS] test_updateReinvestmentController() (gas: 101621)
[PASS] test_updateReinvestmentController_fuzz_revertsWith_OwnableUnauthorizedAccount(address) (runs: 5000, μ: 17205, ~: 17205)
[PASS] test_updateSpokeActive() (gas: 84294)
[PASS] test_updateSpokeActive_revertsWith_OwnableUnauthorizedAccount() (gas: 20241)
[PASS] test_updateSpokeCaps() (gas: 64465)
[PASS] test_updateSpokeCaps_revertsWith_OwnableUnauthorizedAccount() (gas: 20216)
[PASS] test_updateSpokeDrawCap() (gas: 64185)
[PASS] test_updateSpokeDrawCap_revertsWith_OwnableUnauthorizedAccount() (gas: 20201)
[PASS] test_updateSpokePaused() (gas: 87274)
[PASS] test_updateSpokePaused_revertsWith_OwnableUnauthorizedAccount() (gas: 20308)
[PASS] test_updateSpokeRiskPremiumThreshold() (gas: 64238)
[PASS] test_updateSpokeRiskPremiumThreshold_revertsWith_OwnableUnauthorizedAccount() (gas: 20268)
[PASS] test_updateSpokeSupplyCap() (gas: 64242)
[PASS] test_updateSpokeSupplyCap_revertsWith_OwnableUnauthorizedAccount() (gas: 20235)
Suite result: ok. 60 passed; 0 failed; 0 skipped; finished in 10.43s (10.41s CPU time)

Ran 2 tests for tests/invariant/HubInvariant.t.sol:HubInvariant
[SKIP] invariant_exchangeRateMonotonicallyIncreasing() (runs: 1, calls: 1, reverts: 1)
[SKIP] invariant_reserveTotalAssets() (runs: 1, calls: 1, reverts: 1)
Suite result: ok. 0 passed; 0 failed; 2 skipped; finished in 2.83ms (608.53µs CPU time)

Ran 9 tests for tests/unit/KeyValueList.t.sol:KeyValueListTest
[PASS] test_add_unique() (gas: 325391)
[PASS] test_fuzz_add(uint256,uint256) (runs: 5000, μ: 200007, ~: 201361)
[PASS] test_fuzz_add_unique(uint256,uint256) (runs: 5000, μ: 236482, ~: 235413)
[PASS] test_fuzz_get(uint256[]) (runs: 5000, μ: 413030, ~: 411058)
[PASS] test_fuzz_get_uninitialized(uint256[]) (runs: 5000, μ: 263153, ~: 252829)
[PASS] test_fuzz_get_uninitialized_sorted(uint256[]) (runs: 5000, μ: 204969, ~: 185290)
[PASS] test_fuzz_sortByKey(uint256[]) (runs: 5000, μ: 463572, ~: 454152)
[PASS] test_fuzz_sortByKey_length(uint256) (runs: 5000, μ: 203690, ~: 204084)
[PASS] test_fuzz_sortByKey_with_collision(uint256[]) (runs: 5000, μ: 547974, ~: 538598)
Suite result: ok. 9 passed; 0 failed; 0 skipped; finished in 74.21s (74.21s 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)) (runs: 5000, μ: 30486, ~: 30423)
[PASS] test_calculateDebtToLiquidate_fuzz_AmountAdjustedDueToDust((uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256)) (runs: 5000, μ: 32225, ~: 32335)
[PASS] test_calculateDebtToLiquidate_fuzz_ImpossibleToAdjustForDust((uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256)) (runs: 5000, μ: 34380, ~: 34352)
Suite result: ok. 3 passed; 0 failed; 0 skipped; finished in 3.34s (3.32s 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, μ: 22950, ~: 23005)
[PASS] test_calculateDebtToTargetHealthFactor_NoPrecisionLoss() (gas: 25235)
[PASS] test_calculateDebtToTargetHealthFactor_PrecisionLoss() (gas: 15209)
[PASS] test_calculateDebtToTargetHealthFactor_UnitPrice() (gas: 25168)
[PASS] test_calculateDebtToTargetHealthFactor_fuzz_NoRevert((uint256,uint256,uint256,uint256,uint256,uint256,uint256)) (runs: 5000, μ: 20008, ~: 20063)
[PASS] test_calculateDebtToTargetHealthFactor_fuzz_revertsWith_DivisionByZero_ZeroAssetPrice((uint256,uint256,uint256,uint256,uint256,uint256,uint256)) (runs: 5000, μ: 22707, ~: 22762)
[PASS] test_calculateDebtToTargetHealthFactor_revertsWith_ArithmeticError_TargetHealthFactorLessThanHealthFactor((uint256,uint256,uint256,uint256,uint256,uint256,uint256)) (runs: 5000, μ: 22790, ~: 22845)
Suite result: ok. 7 passed; 0 failed; 0 skipped; finished in 2.75s (2.73s CPU time)

Ran 16 tests for tests/unit/libraries/LiquidationLogic/LiquidationLogic.EvaluateDeficit.t.sol:LiquidationLogicEvaluateDeficitTest
[PASS] test_evaluateDeficit_CRE_SCCM_DRE_BRCM() (gas: 9025)
[PASS] test_evaluateDeficit_CRE_SCCM_DRE_BRCO() (gas: 8993)
[PASS] test_evaluateDeficit_CRE_SCCM_DRN_BRCM() (gas: 9014)
[PASS] test_evaluateDeficit_CRE_SCCM_DRN_BRCO() (gas: 8981)
[PASS] test_evaluateDeficit_CRE_SCCO_DRE_BRCM() (gas: 9007)
[PASS] test_evaluateDeficit_CRE_SCCO_DRE_BRCO() (gas: 9074)
[PASS] test_evaluateDeficit_CRE_SCCO_DRN_BRCM() (gas: 9039)
[PASS] test_evaluateDeficit_CRE_SCCO_DRN_BRCO() (gas: 9027)
[PASS] test_evaluateDeficit_CRN_SCCM_DRE_BRCM() (gas: 9027)
[PASS] test_evaluateDeficit_CRN_SCCM_DRE_BRCO() (gas: 9016)
[PASS] test_evaluateDeficit_CRN_SCCM_DRN_BRCM() (gas: 8950)
[PASS] test_evaluateDeficit_CRN_SCCM_DRN_BRCO() (gas: 8983)
[PASS] test_evaluateDeficit_CRN_SCCO_DRE_BRCM() (gas: 8960)
[PASS] test_evaluateDeficit_CRN_SCCO_DRE_BRCO() (gas: 9017)
[PASS] test_evaluateDeficit_CRN_SCCO_DRN_BRCM() (gas: 8968)
[PASS] test_evaluateDeficit_CRN_SCCO_DRN_BRCO() (gas: 9046)
Suite result: ok. 16 passed; 0 failed; 0 skipped; finished in 18.13ms (929.27µs CPU time)

Ran 3 tests for tests/unit/libraries/LiquidationLogic/LiquidationLogic.LiquidateCollateral.t.sol:LiquidationLogicLiquidateCollateralTest
[PASS] test_liquidateCollateral_fuzz(uint256,uint256) (runs: 5000, μ: 271970, ~: 272532)
[PASS] test_liquidateCollateral_fuzz_revertsWith_ArithmeticUnderflow(uint256,uint256) (runs: 5000, μ: 100776, ~: 100578)
[PASS] test_liquidateCollateral_fuzz_revertsWith_InvalidAmount(uint256) (runs: 5000, μ: 105422, ~: 105340)
Suite result: ok. 3 passed; 0 failed; 0 skipped; finished in 3.82s (3.80s CPU time)

Ran 4 tests for tests/unit/libraries/LiquidationLogic/LiquidationLogic.LiquidateDebt.t.sol:LiquidationLogicLiquidateDebtTest
[PASS] test_liquidateDebt_fuzz(uint256) (runs: 5000, μ: 187632, ~: 187632)
[PASS] test_liquidateDebt_revertsWith_ArithmeticUnderflow() (gas: 152235)
[PASS] test_liquidateDebt_revertsWith_InsufficientAllowance() (gas: 158487)
[PASS] test_liquidateDebt_revertsWith_InsufficientBalance() (gas: 203102)
Suite result: ok. 4 passed; 0 failed; 0 skipped; finished in 2.37s (2.35s CPU time)

Ran 4 tests for tests/unit/libraries/LiquidationLogic/LiquidationLogic.LiquidateUser.t.sol:LiquidationLogicLiquidateUserTest
[PASS] test_liquidateUser() (gas: 359377)
[PASS] test_liquidateUser_revertsWith_InvalidDebtToCover() (gas: 75086)
[PASS] test_liquidateUser_revertsWith_MustNotLeaveDust_Collateral() (gas: 111299)
[PASS] test_liquidateUser_revertsWith_MustNotLeaveDust_Debt() (gas: 120646)
Suite result: ok. 4 passed; 0 failed; 0 skipped; finished in 23.46ms (1.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: 5000, μ: 893596, ~: 893664)
[PASS] test_borrow_fuzz_revertsWith_HealthFactorBelowThreshold_multiple_colls(uint256,uint256) (runs: 5000, μ: 881045, ~: 881669)
[PASS] test_borrow_fuzz_revertsWith_HealthFactorBelowThreshold_multiple_colls_with_interest(uint256,uint256,uint256) (runs: 5000, μ: 914591, ~: 915033)
[PASS] test_borrow_fuzz_revertsWith_HealthFactorBelowThreshold_multiple_debts(uint256,uint256) (runs: 5000, μ: 1095648, ~: 1095772)
[PASS] test_borrow_fuzz_revertsWith_HealthFactorBelowThreshold_multiple_debts_with_interest(uint256,uint256,uint256) (runs: 5000, μ: 1132803, ~: 1132837)
[PASS] test_borrow_fuzz_revertsWith_HealthFactorBelowThreshold_with_interest(uint256,uint256) (runs: 5000, μ: 678332, ~: 678045)
[PASS] test_borrow_revertsWith_HealthFactorBelowThreshold() (gas: 647873)
[PASS] test_borrow_revertsWith_HealthFactorBelowThreshold_collateral_price_drop_weth() (gas: 887746)
[PASS] test_borrow_revertsWith_HealthFactorBelowThreshold_multiple_colls() (gas: 875269)
[PASS] test_borrow_revertsWith_HealthFactorBelowThreshold_multiple_colls_collateral_price_drop_dai() (gas: 1124168)
[PASS] test_borrow_revertsWith_HealthFactorBelowThreshold_multiple_colls_collateral_price_drop_weth() (gas: 1124212)
[PASS] test_borrow_revertsWith_HealthFactorBelowThreshold_multiple_colls_with_interest() (gas: 910322)
[PASS] test_borrow_revertsWith_HealthFactorBelowThreshold_multiple_debts() (gas: 1088815)
[PASS] test_borrow_revertsWith_HealthFactorBelowThreshold_multiple_debts_with_interest() (gas: 1125331)
[PASS] test_borrow_revertsWith_HealthFactorBelowThreshold_with_interest() (gas: 673317)
[PASS] test_fuzz_borrow_revertsWith_HealthFactorBelowThreshold_multiple_colls_collateral_price_drop_dai(uint256,uint256,uint256) (runs: 5000, μ: 1128446, ~: 1128925)
[PASS] test_fuzz_borrow_revertsWith_HealthFactorBelowThreshold_multiple_colls_collateral_price_drop_weth(uint256,uint256,uint256) (runs: 5000, μ: 1128468, ~: 1128947)
Suite result: ok. 17 passed; 0 failed; 0 skipped; finished in 133.86s (133.84s CPU time)

Ran 8 tests for tests/unit/libraries/LiquidationLogic/LiquidationLogic.LiquidationAmounts.t.sol:LiquidationLogicLiquidationAmountsTest
[PASS] test_calculateLiquidationAmounts_EnoughCollateral() (gas: 15304)
[PASS] test_calculateLiquidationAmounts_InsufficientCollateral() (gas: 15595)
[PASS] test_calculateLiquidationAmounts_fuzz_EnoughCollateral_CollateralDust((uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256)) (runs: 5000, μ: 57516, ~: 56992)
[PASS] test_calculateLiquidationAmounts_fuzz_EnoughCollateral_NoCollateralDust((uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256)) (runs: 5000, μ: 56390, ~: 56466)
[PASS] test_calculateLiquidationAmounts_fuzz_EnoughCollateral_NoDebtLeft((uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256)) (runs: 5000, μ: 74903, ~: 74867)
[PASS] test_calculateLiquidationAmounts_fuzz_InsufficientCollateral((uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256)) (runs: 5000, μ: 60269, ~: 60147)
[PASS] test_calculateLiquidationAmounts_fuzz_revertsWith_MustNotLeaveDust_Collateral((uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256)) (runs: 5000, μ: 56836, ~: 56772)
[PASS] test_calculateLiquidationAmounts_fuzz_revertsWith_MustNotLeaveDust_Debt((uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256)) (runs: 5000, μ: 70342, ~: 70276)
Suite result: ok. 8 passed; 0 failed; 0 skipped; finished in 17.96s (17.94s CPU time)

Ran 4 tests for tests/unit/libraries/LiquidationLogic/LiquidationLogic.LiquidationBonus.t.sol:LiquidationLogicLiquidationBonusTest
[PASS] test_calculateLiquidationBonus_MinBonusDueToRounding() (gas: 9360)
[PASS] test_calculateLiquidationBonus_PartialBonus() (gas: 9381)
[PASS] test_calculateLiquidationBonus_fuzz_ConstantBonus(uint256,uint256,uint256,uint256) (runs: 5000, μ: 17248, ~: 17178)
[PASS] test_calculateLiquidationBonus_fuzz_MaxBonus(uint256,uint256,uint256,uint256) (runs: 5000, μ: 19586, ~: 19506)
Suite result: ok. 4 passed; 0 failed; 0 skipped; finished in 958.66ms (938.36ms CPU time)

Ran 13 tests for tests/unit/libraries/LiquidationLogic/LiquidationLogic.ValidateLiquidationCall.t.sol:LiquidationLogicValidateLiquidationCallTest
[PASS] test_validateLiquidationCall() (gas: 33279)
[PASS] test_validateLiquidationCall_revertsWith_CannotReceiveShares() (gas: 151180)
[PASS] test_validateLiquidationCall_revertsWith_CollateralCannotBeLiquidated_NotUsingAsCollateral() (gas: 37654)
[PASS] test_validateLiquidationCall_revertsWith_CollateralCannotBeLiquidated_ZeroCollateralFactor() (gas: 31978)
[PASS] test_validateLiquidationCall_revertsWith_HealthFactorNotBelowThreshold() (gas: 36729)
[PASS] test_validateLiquidationCall_revertsWith_InvalidDebtToCover() (gas: 31638)
[PASS] test_validateLiquidationCall_revertsWith_ReserveNotBorrowed() (gas: 31853)
[PASS] test_validateLiquidationCall_revertsWith_ReserveNotListed_ZeroCollateralHub() (gas: 31713)
[PASS] test_validateLiquidationCall_revertsWith_ReserveNotListed_ZeroDebtHub() (gas: 31770)
[PASS] test_validateLiquidationCall_revertsWith_ReserveNotSupplied() (gas: 31820)
[PASS] test_validateLiquidationCall_revertsWith_ReservePaused_CollateralPaused() (gas: 36604)
[PASS] test_validateLiquidationCall_revertsWith_ReservePaused_DebtPaused() (gas: 36687)
[PASS] test_validateLiquidationCall_revertsWith_SelfLiquidation() (gas: 38572)
Suite result: ok. 13 passed; 0 failed; 0 skipped; finished in 18.44ms (1.33ms CPU time)

Ran 26 tests for tests/unit/MathUtils.t.sol:MathUtilsTest
[PASS] test_add_edge_cases() (gas: 4854)
[PASS] test_add_negative_operand(uint256,int256) (runs: 5000, μ: 9388, ~: 9626)
[PASS] test_add_positive_operand(uint256,int256) (runs: 5000, μ: 4013, ~: 4010)
[PASS] test_calculateLinearInterest() (gas: 4467)
[PASS] test_calculateLinearInterest_add_edge() (gas: 5043)
[PASS] test_calculateLinearInterest_edge_cases() (gas: 16815)
Logs:
  Bound result 0
  Bound result 1
  Bound result 864000000
  Bound result 864000000

[PASS] test_calculateLinearInterest_reverts_on_past_timestamp(uint40) (runs: 5000, μ: 7698, ~: 7550)
[PASS] test_constants() (gas: 3167)
[PASS] test_fuzz_calculateLinearInterest(uint96,uint40,uint256) (runs: 5000, μ: 8695, ~: 8996)
[PASS] test_fuzz_mulDivDown(uint256,uint256,uint256) (runs: 5000, μ: 3581, ~: 3634)
[PASS] test_fuzz_mulDivUp(uint256,uint256,uint256) (runs: 5000, μ: 3667, ~: 3781)
[PASS] test_min(uint256,uint256) (runs: 5000, μ: 3338, ~: 3339)
[PASS] test_mulDivDown_NoRemainder() (gas: 3302)
[PASS] test_mulDivDown_RevertOnDivByZero() (gas: 3147)
[PASS] test_mulDivDown_RevertOnOverflow() (gas: 3181)
[PASS] test_mulDivDown_WithRemainder() (gas: 3236)
[PASS] test_mulDivDown_ZeroAOrB() (gas: 3768)
[PASS] test_mulDivUp_NoRemainder() (gas: 3306)
[PASS] test_mulDivUp_RevertOnDivByZero() (gas: 3102)
[PASS] test_mulDivUp_RevertOnOverflow() (gas: 3160)
[PASS] test_mulDivUp_WithRemainder() (gas: 3305)
[PASS] test_mulDivUp_ZeroAOrB() (gas: 3884)
[PASS] test_signedSub(uint256,uint256) (runs: 5000, μ: 8705, ~: 8661)
[PASS] test_uncheckedAdd(uint256,uint256) (runs: 5000, μ: 3416, ~: 3408)
[PASS] test_uncheckedExp(uint256,uint256) (runs: 5000, μ: 11416, ~: 7256)
[PASS] test_uncheckedSub(uint256,uint256) (runs: 5000, μ: 3435, ~: 3518)
Suite result: ok. 26 passed; 0 failed; 0 skipped; finished in 1.47s (1.47s CPU time)

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

[PASS] test_borrowNative_fuzz(uint256) (runs: 5000, μ: 630814, ~: 630634)
[PASS] test_borrowNative_revertsWith_InvalidAmount() (gas: 32814)
[PASS] test_borrowNative_revertsWith_NotNativeWrappedAsset() (gas: 32889)
[PASS] test_borrowNative_revertsWith_SpokeNotRegistered() (gas: 25320)
[PASS] test_constructor() (gas: 1059124)
[PASS] test_constructor_revertsWith_InvalidAddress() (gas: 65422)
[PASS] test_fallback_revertsWith_UnsupportedAction() (gas: 17427)
[PASS] test_receive_revertsWith_UnsupportedAction() (gas: 17212)
[PASS] test_repayNative() (gas: 750847)
Logs:
  Bound result 5000000000000000000

[PASS] test_repayNative_excessAmount() (gas: 633307)
[PASS] test_repayNative_fuzz(uint256) (runs: 5000, μ: 750450, ~: 751482)
[PASS] test_repayNative_fuzz_withInterest(uint256,uint256) (runs: 5000, μ: 643513, ~: 638105)
[PASS] test_repayNative_revertsWith_InvalidAmount() (gas: 33177)
[PASS] test_repayNative_revertsWith_NativeAmountMismatch() (gas: 30659)
[PASS] test_repayNative_revertsWith_NotNativeWrappedAsset() (gas: 39866)
[PASS] test_repayNative_revertsWith_SpokeNotRegistered() (gas: 39286)
[PASS] test_supplyAndCollateralNative() (gas: 305576)
Logs:
  Bound result 100000000000000000000

[PASS] test_supplyAndCollateralNative_fuzz(uint256) (runs: 5000, μ: 305785, ~: 305515)
[PASS] test_supplyNative() (gas: 253108)
Logs:
  Bound result 100000000000000000000

[PASS] test_supplyNative_fuzz(uint256) (runs: 5000, μ: 253450, ~: 253180)
[PASS] test_supplyNative_revertsWith_InvalidAmount() (gas: 33142)
[PASS] test_supplyNative_revertsWith_NativeAmountMismatch() (gas: 30390)
[PASS] test_supplyNative_revertsWith_NotNativeWrappedAsset() (gas: 39829)
[PASS] test_supplyNative_revertsWith_SpokeNotRegistered() (gas: 39197)
[PASS] test_withdrawNative() (gas: 281625)
Logs:
  Bound result 100000000000000000000

[PASS] test_withdrawNative_fuzz(uint256) (runs: 5000, μ: 281601, ~: 281675)
[PASS] test_withdrawNative_fuzz_allBalance(uint256) (runs: 5000, μ: 232559, ~: 232366)
[PASS] test_withdrawNative_fuzz_allBalanceWithInterest(uint256,uint256) (runs: 5000, μ: 598086, ~: 598081)
[PASS] test_withdrawNative_revertsWith_InvalidAmount() (gas: 32900)
[PASS] test_withdrawNative_revertsWith_NotNativeWrappedAsset() (gas: 32844)
[PASS] test_withdrawNative_revertsWith_SpokeNotRegistered() (gas: 25408)
Suite result: ok. 32 passed; 0 failed; 0 skipped; finished in 66.05s (66.04s CPU time)

Ran 4 tests for tests/unit/NoncesKeyed.t.sol:NoncesKeyedTest
[PASS] test_useCheckedNonce_monotonic(bytes32) (runs: 5000, μ: 16229, ~: 16229)
[PASS] test_useCheckedNonce_revertsWith_InvalidAccountNonce(bytes32) (runs: 5000, μ: 107533, ~: 107533)
[PASS] test_useNonce_monotonic(bytes32) (runs: 5000, μ: 17035, ~: 17035)
[PASS] test_useNonce_zeroKey_monotonic(bytes32) (runs: 5000, μ: 16983, ~: 16983)
Suite result: ok. 4 passed; 0 failed; 0 skipped; finished in 4.58s (4.58s CPU time)

Ran 10 tests for tests/unit/PercentageMath.t.sol:PercentageMathTests
[PASS] test_constants() (gas: 8664)
[PASS] test_fromBpsDown() (gas: 9678)
[PASS] test_percentDiv() (gas: 15222)
[PASS] test_percentDivUp_ge_value(uint256,uint256) (runs: 5000, μ: 15283, ~: 15509)
[PASS] test_percentDivUp_le_value(uint256,uint256) (runs: 5000, μ: 15668, ~: 15662)
[PASS] test_percentDiv_fuzz(uint256,uint256) (runs: 5000, μ: 12884, ~: 13012)
[PASS] test_percentMul() (gas: 15116)
[PASS] test_percentMulUp_ge_value(uint256,uint256) (runs: 5000, μ: 15651, ~: 15645)
[PASS] test_percentMulUp_le_value(uint256,uint256) (runs: 5000, μ: 15286, ~: 15512)
[PASS] test_percentMul_fuzz(uint256,uint256) (runs: 5000, μ: 11766, ~: 12247)
Suite result: ok. 10 passed; 0 failed; 0 skipped; finished in 1.43s (1.43s CPU time)

Ran 29 tests for tests/unit/libraries/PositionStatusMap.t.sol:PositionStatusMapTest
[PASS] test_bucketId() (gas: 8971)
[PASS] test_collateralCount() (gas: 110158)
[PASS] test_collateralCount(uint256) (runs: 5000, μ: 2068368, ~: 1864098)
[PASS] test_collateralCount_ignoresInvalidBits() (gas: 124482)
[PASS] test_constants() (gas: 44966)
[PASS] test_fls() (gas: 545261)
[PASS] test_fromBitId(uint256,uint256) (runs: 5000, μ: 14104, ~: 14336)
[PASS] test_fuzz_setBorrowing(uint256,bool) (runs: 5000, μ: 22353, ~: 32140)
[PASS] test_fuzz_setUseAsCollateral(uint256,bool) (runs: 5000, μ: 22449, ~: 32236)
[PASS] test_getBucketWord(uint256) (runs: 5000, μ: 14489, ~: 14489)
[PASS] test_isUsingAsCollateralOrBorrowing_slot0() (gas: 108801)
[PASS] test_isUsingAsCollateralOrBorrowing_slot1() (gas: 44065)
[PASS] test_isolateBorrowing(uint256) (runs: 5000, μ: 162282, ~: 162282)
[PASS] test_isolateBorrowingUntil(uint256,uint256) (runs: 5000, μ: 154764, ~: 154662)
[PASS] test_isolateCollateral(uint256) (runs: 5000, μ: 162044, ~: 162044)
[PASS] test_isolateCollateralUntil(uint256,uint256) (runs: 5000, μ: 154743, ~: 154641)
[PASS] test_isolateUntil(uint256,uint256) (runs: 5000, μ: 143621, ~: 143619)
[PASS] test_next(uint256) (runs: 5000, μ: 20427, ~: 20328)
[PASS] test_nextBorrowing(uint256) (runs: 5000, μ: 18219, ~: 18289)
[PASS] test_nextBorrowing_continuous() (gas: 63845326)
[PASS] test_nextCollateral(uint256) (runs: 5000, μ: 18109, ~: 17716)
[PASS] test_nextCollateral_continuous() (gas: 64381718)
[PASS] test_next_continuous() (gas: 91795620)
[PASS] test_popCount(bytes32) (runs: 5000, μ: 38133, ~: 38133)
[PASS] test_setBorrowing_slot0() (gas: 44129)
[PASS] test_setBorrowing_slot1() (gas: 44166)
[PASS] test_setUseAsCollateral_slot0() (gas: 44203)
[PASS] test_setUseAsCollateral_slot1() (gas: 44185)
[PASS] test_setters_use_correct_slot(uint256) (runs: 5000, μ: 22195, ~: 22195)
Suite result: ok. 29 passed; 0 failed; 0 skipped; finished in 101.02s (101.02s 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: 5000, μ: 2177359, ~: 2187143)
[PASS] test_borrow_fuzz_single_spoke_multi_reserves(uint256,uint256,uint256,uint256) (runs: 5000, μ: 2389586, ~: 2397949)
[PASS] test_borrow_fuzz_single_spoke_multi_reserves_multi_user(uint256,uint256,uint256,uint256) (runs: 5000, μ: 2767366, ~: 2775377)
[PASS] test_borrow_fuzz_skip_borrow(uint256,uint256,uint256) (runs: 5000, μ: 1080349, ~: 1080152)
[PASS] test_borrow_skip_borrow() (gas: 1079337)
Logs:
  Bound result 10000000000000000000
  Bound result 20000000000000000000
  Bound result 31536000

[PASS] test_userAccountData_does_not_include_zero_cf_collateral() (gas: 1199414)
Suite result: ok. 6 passed; 0 failed; 0 skipped; finished in 180.54s (180.53s CPU time)

Ran 5 tests for tests/unit/Rescuable.t.sol:RescuableTest
[PASS] test_constructor() (gas: 12654)
[PASS] test_rescueNative_fuzz(uint256) (runs: 5000, μ: 33695, ~: 33370)
[PASS] test_rescueNative_revertsWith_OnlyRescueGuardian() (gas: 11400)
[PASS] test_rescueToken_fuzz(uint256) (runs: 5000, μ: 209621, ~: 209387)
[PASS] test_rescueToken_revertsWith_OnlyRescueGuardian() (gas: 183212)
Suite result: ok. 5 passed; 0 failed; 0 skipped; finished in 3.47s (3.46s CPU time)

Ran 10 tests for tests/unit/misc/SignatureGateway/SignatureGateway.Constants.t.sol:SignatureGatewayConstantsTest
[PASS] test_DOMAIN_SEPARATOR() (gas: 2102520)
[PASS] test_borrow_typeHash() (gas: 9874)
[PASS] test_constructor() (gas: 53857)
[PASS] test_eip712Domain() (gas: 2108085)
[PASS] test_repay_typeHash() (gas: 9975)
[PASS] test_setUsingAsCollateral_typeHash() (gas: 9943)
[PASS] test_supply_typeHash() (gas: 9945)
[PASS] test_updateUserDynamicConfig_typeHash() (gas: 10045)
[PASS] test_updateUserRiskPremium_typeHash() (gas: 9876)
[PASS] test_withdraw_typeHash() (gas: 9919)
Suite result: ok. 10 passed; 0 failed; 0 skipped; finished in 26.69ms (1.91ms CPU time)

Ran 5 tests for tests/unit/misc/SignatureGateway/SignatureGateway.PermitReserve.t.sol:SignatureGatewayPermitReserveTest
[PASS] test_permitReserve() (gas: 104990)
[PASS] test_permitReserve_forwards_correct_call() (gas: 52113)
[PASS] test_permitReserve_ignores_permit_reverts() (gas: 40969)
[PASS] test_permitReserve_revertsWith_ReserveNotListed() (gas: 30890)
[PASS] test_permitReserve_revertsWith_SpokeNotRegistered() (gas: 29451)
Suite result: ok. 5 passed; 0 failed; 0 skipped; finished in 19.16ms (1.48ms CPU time)

Ran 2 tests for tests/unit/misc/SignatureGateway/SignatureGateway.Reverts.InsufficientAllowance.t.sol:SignatureGateway_InsufficientAllowance_Test
[PASS] test_repayWithSig_revertsWith_TransferFromFailed_on_InsufficientAllowance() (gas: 462069)
[PASS] test_supplyWithSig_revertsWith_TransferFromFailed_on_InsufficientAllowance() (gas: 84603)
Suite result: ok. 2 passed; 0 failed; 0 skipped; finished in 19.52ms (1.99ms CPU time)

Ran 14 tests for tests/unit/Spoke/Spoke.Borrow.Validation.t.sol:SpokeBorrowValidationTest
[PASS] test_borrow_fuzz_revertsWith_DrawCapExceeded(uint256,uint40) (runs: 5000, μ: 107991, ~: 108015)
[PASS] test_borrow_fuzz_revertsWith_DrawCapExceeded_due_to_interest(uint256) (runs: 5000, μ: 690088, ~: 690377)
[PASS] test_borrow_fuzz_revertsWith_InsufficientLiquidity(uint256,uint256) (runs: 5000, μ: 294900, ~: 294676)
[PASS] test_borrow_fuzz_revertsWith_InvalidAmount(uint256) (runs: 5000, μ: 32615, ~: 32672)
[PASS] test_borrow_fuzz_revertsWith_ReserveFrozen(uint256,uint256) (runs: 5000, μ: 69403, ~: 69200)
[PASS] test_borrow_fuzz_revertsWith_ReserveNotBorrowable(uint256,uint256) (runs: 5000, μ: 69616, ~: 69413)
[PASS] test_borrow_fuzz_revertsWith_ReserveNotListed(uint256,uint256) (runs: 5000, μ: 26063, ~: 25806)
[PASS] test_borrow_fuzz_revertsWith_ReservePaused(uint256,uint256) (runs: 5000, μ: 69238, ~: 69035)
[PASS] test_borrow_revertsWith_InsufficientLiquidity() (gas: 294543)
Logs:
  Bound result 10000000000000000000

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

[PASS] test_borrow_revertsWith_ReserveFrozen() (gas: 70806)
Logs:
  Bound result 2
  Bound result 1

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

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

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

Suite result: ok. 14 passed; 0 failed; 0 skipped; finished in 15.10s (15.08s CPU time)

Ran 2 tests for tests/unit/Spoke/Spoke.Borrow.t.sol:SpokeBorrowTest
[PASS] test_borrow() (gas: 1042075)
[PASS] test_borrow_fuzz_amounts(uint256,uint256) (runs: 5000, μ: 1038879, ~: 1038930)
Suite result: ok. 2 passed; 0 failed; 0 skipped; finished in 25.99s (25.97s CPU time)

Ran 21 tests for tests/unit/misc/SignatureGateway/SignatureGateway.Reverts.InvalidSignature.t.sol:SignatureGatewayInvalidSignatureTest
[PASS] test_borrowWithSig_revertsWith_InvalidAccountNonce(bytes32) (runs: 5000, μ: 190113, ~: 190113)
[PASS] test_borrowWithSig_revertsWith_InvalidSignature_dueTo_ExpiredDeadline() (gas: 38516)
[PASS] test_borrowWithSig_revertsWith_InvalidSignature_dueTo_InvalidSigner() (gas: 36958)
[PASS] test_repayWithSig_revertsWith_InvalidAccountNonce(bytes32) (runs: 5000, μ: 190069, ~: 190069)
[PASS] test_repayWithSig_revertsWith_InvalidSignature_dueTo_ExpiredDeadline() (gas: 38449)
[PASS] test_repayWithSig_revertsWith_InvalidSignature_dueTo_InvalidSigner() (gas: 37024)
[PASS] test_setUsingAsCollateralWithSig_revertsWith_InvalidAccountNonce(bytes32) (runs: 5000, μ: 233692, ~: 233692)
[PASS] test_setUsingAsCollateralWithSig_revertsWith_InvalidSignature_dueTo_ExpiredDeadline() (gas: 38477)
[PASS] test_setUsingAsCollateralWithSig_revertsWith_InvalidSignature_dueTo_InvalidSigner() (gas: 37073)
[PASS] test_supplyWithSig_revertsWith_InvalidAccountNonce(bytes32) (runs: 5000, μ: 190132, ~: 190132)
[PASS] test_supplyWithSig_revertsWith_InvalidSignature_dueTo_ExpiredDeadline() (gas: 38494)
[PASS] test_supplyWithSig_revertsWith_InvalidSignature_dueTo_InvalidSigner() (gas: 36989)
[PASS] test_updateUserDynamicConfigWithSig_revertsWith_InvalidAccountNonce(bytes32) (runs: 5000, μ: 67897, ~: 67897)
[PASS] test_updateUserDynamicConfigWithSig_revertsWith_InvalidSignatureDueTo_InvalidSigner() (gas: 25626)
[PASS] test_updateUserDynamicConfigWithSig_revertsWith_InvalidSignature_dueTo_ExpiredDeadline() (gas: 27058)
[PASS] test_updateUserRiskPremiumWithSig_revertsWith_InvalidAccountNonce(bytes32) (runs: 5000, μ: 67940, ~: 67940)
[PASS] test_updateUserRiskPremiumWithSig_revertsWith_InvalidSignatureDueTo_InvalidSigner() (gas: 25631)
[PASS] test_updateUserRiskPremiumWithSig_revertsWith_InvalidSignature_dueTo_ExpiredDeadline() (gas: 27146)
[PASS] test_withdrawWithSig_revertsWith_InvalidAccountNonce(bytes32) (runs: 5000, μ: 190066, ~: 190066)
[PASS] test_withdrawWithSig_revertsWith_InvalidSignature_dueTo_ExpiredDeadline() (gas: 38536)
[PASS] test_withdrawWithSig_revertsWith_InvalidSignature_dueTo_InvalidSigner() (gas: 37022)
Suite result: ok. 21 passed; 0 failed; 0 skipped; finished in 43.86s (43.84s CPU time)

Ran 24 tests for tests/unit/Spoke/Spoke.Config.t.sol:SpokeConfigTest
[PASS] test_addReserve() (gas: 390184)
[PASS] test_addReserve_fuzz_revertsWith_AssetNotListed() (gas: 245624)
[PASS] test_addReserve_revertsWith_InvalidAddress_hub() (gas: 5981570)
[PASS] test_addReserve_revertsWith_InvalidAddress_oracle() (gas: 6018664)
[PASS] test_addReserve_revertsWith_InvalidAssetId() (gas: 33171)
[PASS] test_addReserve_revertsWith_ReserveExists() (gas: 374737)
[PASS] test_spoke_deploy() (gas: 4915767)
[PASS] test_spoke_deploy_revertsWith_InvalidOracleDecimals() (gas: 46409)
[PASS] test_spoke_deploy_reverts_on_InvalidConstructorInput() (gas: 43803)
[PASS] test_updateLiquidationConfig_fuzz_liqBonusConfig((uint128,uint64,uint16)) (runs: 5000, μ: 52155, ~: 52143)
[PASS] test_updateLiquidationConfig_fuzz_revertsWith_InvalidLiquidationConfig_healthFactorForMaxBonus((uint128,uint64,uint16)) (runs: 5000, μ: 37812, ~: 37949)
[PASS] test_updateLiquidationConfig_fuzz_revertsWith_InvalidLiquidationConfig_liquidationBonusFactor((uint128,uint64,uint16)) (runs: 5000, μ: 37380, ~: 37159)
[PASS] test_updateLiquidationConfig_fuzz_targetHealthFactor(uint128) (runs: 5000, μ: 46864, ~: 47159)
[PASS] test_updateLiquidationConfig_liqBonusConfig() (gas: 51102)
Logs:
  Bound result 900000000000000000
  Bound result 1000
  Bound result 1000000000000000000

[PASS] test_updateLiquidationConfig_revertsWith_InvalidLiquidationConfig_healthFactorForMaxBonus() (gas: 36462)
Logs:
  Bound result 1000000000000000000
  Bound result 1000
  Bound result 1000000000000000000

[PASS] test_updateLiquidationConfig_revertsWith_InvalidLiquidationConfig_liquidationBonusFactor() (gas: 36256)
Logs:
  Bound result 900000000000000000
  Bound result 10001
  Bound result 1000000000000000000

[PASS] test_updateLiquidationConfig_targetHealthFactor() (gas: 46442)
Logs:
  Bound result 1000000000000000001

[PASS] test_updateReserveConfig() (gas: 53882)
[PASS] test_updateReserveConfig_fuzz((bool,bool,bool,uint24)) (runs: 5000, μ: 55299, ~: 55127)
[PASS] test_updateReserveConfig_revertsWith_InvalidCollateralRisk() (gas: 39603)
[PASS] test_updateReserveConfig_revertsWith_ReserveNotListed() (gas: 36252)
[PASS] test_updateReservePriceSource() (gas: 240092)
[PASS] test_updateReservePriceSource_revertsWith_AccessManagedUnauthorized(address) (runs: 5000, μ: 31103, ~: 31103)
[PASS] test_updateReservePriceSource_revertsWith_ReserveNotListed() (gas: 34277)
Suite result: ok. 24 passed; 0 failed; 0 skipped; finished in 3.87s (3.86s 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, μ: 13902, ~: 13902)
[PASS] test_repayWithSig_revertsWith_SpokeNotRegistered((address,uint256,uint256,address,uint256,uint256)) (runs: 5000, μ: 13902, ~: 13902)
[PASS] test_setUsingAsCollateralWithSig_revertsWith_SpokeNotRegistered((address,uint256,bool,address,uint256,uint256)) (runs: 5000, μ: 13903, ~: 13903)
[PASS] test_supplyWithSig_revertsWith_SpokeNotRegistered((address,uint256,uint256,address,uint256,uint256)) (runs: 5000, μ: 13900, ~: 13900)
[PASS] test_updateUserDynamicConfigWithSig_revertsWith_SpokeNotRegistered((address,address,uint256,uint256)) (runs: 5000, μ: 14114, ~: 14114)
[PASS] test_updateUserRiskPremiumWithSig_revertsWith_SpokeNotRegistered((address,address,uint256,uint256)) (runs: 5000, μ: 14114, ~: 14114)
[PASS] test_withdrawWithSig_revertsWith_SpokeNotRegistered((address,uint256,uint256,address,uint256,uint256)) (runs: 5000, μ: 13967, ~: 13967)
Suite result: ok. 7 passed; 0 failed; 0 skipped; finished in 7.16s (7.13s 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: 80480)
[PASS] test_repayWithSig_revertsWith_Unauthorized() (gas: 113070)
[PASS] test_setUsingAsCollateralWithSig_revertsWith_Unauthorized() (gas: 73090)
[PASS] test_supplyWithSig_revertsWith_Unauthorized() (gas: 140887)
[PASS] test_updateUserDynamicConfigWithSig_revertsWith_Unauthorized() (gas: 82686)
[PASS] test_updateUserRiskPremiumWithSig_revertsWith_Unauthorized() (gas: 82561)
[PASS] test_withdrawWithSig_revertsWith_Unauthorized() (gas: 80603)
Suite result: ok. 7 passed; 0 failed; 0 skipped; finished in 21.72ms (4.09ms 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: 78279)
[PASS] test_repayWithSig_revertsWith_Unauthorized() (gas: 110869)
[PASS] test_setUsingAsCollateralWithSig_revertsWith_Unauthorized() (gas: 70889)
[PASS] test_supplyWithSig_revertsWith_Unauthorized() (gas: 138686)
[PASS] test_updateUserDynamicConfigWithSig_revertsWith_Unauthorized() (gas: 80485)
[PASS] test_updateUserRiskPremiumWithSig_revertsWith_Unauthorized() (gas: 80360)
[PASS] test_withdrawWithSig_revertsWith_Unauthorized() (gas: 78402)
Suite result: ok. 7 passed; 0 failed; 0 skipped; finished in 21.35ms (4.04ms CPU time)

Ran 11 tests for tests/unit/misc/SignatureGateway/SignatureGateway.t.sol:SignatureGatewayTest
[PASS] test_borrowWithSig() (gas: 803298)
[PASS] test_renouncePositionManagerRole() (gas: 26829)
[PASS] test_renouncePositionManagerRole_revertsWith_OnlyOwner() (gas: 18352)
[PASS] test_repayWithSig() (gas: 794679)
[PASS] test_setSelfAsUserPositionManagerWithSig() (gas: 294238)
[PASS] test_setUsingAsCollateralWithSig() (gas: 635619)
[PASS] test_supplyWithSig() (gas: 587321)
[PASS] test_updateUserDynamicConfigWithSig() (gas: 306776)
[PASS] test_updateUserRiskPremiumWithSig() (gas: 884922)
[PASS] test_useNonce_monotonic(bytes32) (runs: 5000, μ: 16886, ~: 16886)
[PASS] test_withdrawWithSig() (gas: 584442)
Suite result: ok. 11 passed; 0 failed; 0 skipped; finished in 435.93ms (418.46ms CPU time)

Ran 3 tests for tests/unit/Spoke/Spoke.Access.t.sol:SpokeAccessTest
[PASS] testAccess_change_authority() (gas: 2612648)
[PASS] testAccess_hub_functions_callable_by_spokes() (gas: 60...*[Comment body truncated]*

@github-actions
Copy link

github-actions bot commented Oct 18, 2025

♻️ Forge Gas Snapshots

Path Value
snapshots/Spoke.Investigation.json
borrow 31692080
liquidationCall 33494385
🔕 Unchanged
Path Value
snapshots/Hub.Operations.json
add 118,313
draw 120,582
eliminateDeficit: full 59,772
eliminateDeficit: partial 69,348
mintFeeShares 82,887
payFee 69,103
refreshPremium 70,157
remove: full 76,677
remove: partial 81,324
reportDeficit 112,891
restore: full 91,259
restore: partial 99,873
transferShares 67,904
snapshots/NativeTokenGateway.Operations.json
borrowNative 226,950
repayNative 240,607
supplyAsCollateralNative 184,580
supplyNative 137,591
withdrawNative: full 125,655
withdrawNative: partial 136,868
snapshots/SignatureGateway.Operations.json
borrowWithSig 215,130
repayWithSig 241,641
setSelfAsUserPositionManagerWithSig 75,492
setUsingAsCollateralWithSig 124,443
supplyWithSig 154,197
updateUserDynamicConfigWithSig 62,659
updateUserRiskPremiumWithSig 61,404
withdrawWithSig 131,680
snapshots/Spoke.Getters.json
getUserAccountData: supplies: 0, borrows: 0 11,681
getUserAccountData: supplies: 1, borrows: 0 48,456
getUserAccountData: supplies: 2, borrows: 0 79,959
getUserAccountData: supplies: 2, borrows: 1 100,232
getUserAccountData: supplies: 2, borrows: 2 118,456
snapshots/Spoke.Operations.ZeroRiskPremium.json
borrow: first 187,733
borrow: second action, same reserve 167,705
liquidationCall (receiveShares): full 262,664
liquidationCall (receiveShares): partial 290,260
liquidationCall: full 287,411
liquidationCall: partial 297,607
permitReserve + repay (multicall) 223,433
permitReserve + supply (multicall) 172,653
permitReserve + supply + enable collateral (multicall) 261,166
repay: full 153,130
repay: partial 176,738
setUserPositionManagerWithSig: disable 44,896
setUserPositionManagerWithSig: enable 68,925
supply + enable collateral (multicall) 184,504
supply: 0 borrows, collateral disabled 122,716
supply: 0 borrows, collateral enabled 152,391
supply: 1 borrow 127,705
supply: second action, same reserve 135,291
updateUserDynamicConfig: 1 collateral 73,487
updateUserDynamicConfig: 2 collaterals 87,983
updateUserRiskPremium: 1 borrow 94,746
updateUserRiskPremium: 2 borrows 103,274
usingAsCollateral: 0 borrows, enable 78,231
usingAsCollateral: 1 borrow, disable 105,017
usingAsCollateral: 1 borrow, enable 118,415
usingAsCollateral: 2 borrows, disable 125,782
usingAsCollateral: 2 borrows, enable 139,180
withdraw: 0 borrows, full 128,210
withdraw: 0 borrows, partial 132,901
withdraw: 1 borrow, partial 160,550
withdraw: 2 borrows, partial 181,304
withdraw: non collateral 111,398
snapshots/Spoke.Operations.json
borrow: first 257,816
borrow: second action, same reserve 200,788
liquidationCall (receiveShares): full 262,664
liquidationCall (receiveShares): partial 290,260
liquidationCall: full 287,411
liquidationCall: partial 297,607
permitReserve + repay (multicall) 256,742
permitReserve + supply (multicall) 172,653
permitReserve + supply + enable collateral (multicall) 325,777
repay: full 152,587
repay: partial 210,047
setUserPositionManagerWithSig: disable 44,896
setUserPositionManagerWithSig: enable 68,925
supply + enable collateral (multicall) 184,504
supply: 0 borrows, collateral disabled 122,716
supply: 0 borrows, collateral enabled 152,391
supply: 1 borrow 127,705
supply: second action, same reserve 135,291
updateUserDynamicConfig: 1 collateral 73,487
updateUserDynamicConfig: 2 collaterals 87,983
updateUserRiskPremium: 1 borrow 161,628
updateUserRiskPremium: 2 borrows 226,221
usingAsCollateral: 0 borrows, enable 78,231
usingAsCollateral: 1 borrow, disable 156,074
usingAsCollateral: 1 borrow, enable 185,297
usingAsCollateral: 2 borrows, disable 223,079
usingAsCollateral: 2 borrows, enable 268,127
withdraw: 0 borrows, full 128,210
withdraw: 0 borrows, partial 132,901
withdraw: 1 borrow, partial 224,929
withdraw: 2 borrows, partial 307,747
withdraw: non collateral 111,398

Comment on lines +35 to +38
assertLe(
spoke1.getUserAccountData(alice).healthFactor,
spoke1.HEALTH_FACTOR_LIQUIDATION_THRESHOLD()
);
Copy link
Member

Choose a reason for hiding this comment

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

run test with isolate and snapshot gas taken by this pls

@CheyenneAtapour CheyenneAtapour changed the title feat: OOG Test test: Gas snapshot worst case liquidation Nov 12, 2025
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