Skip to content

feat: naive strongly typed sig batcher#1127

Open
DhairyaSethi wants to merge 2 commits into
feat/permit2from
feat/sig-batch
Open

feat: naive strongly typed sig batcher#1127
DhairyaSethi wants to merge 2 commits into
feat/permit2from
feat/sig-batch

Conversation

@DhairyaSethi

@DhairyaSethi DhairyaSethi commented Jan 20, 2026

Copy link
Copy Markdown
Member

dynamically builds typestring at runtime based on input

todo opts:

  • execute individual action alongside building the typestring to save on loops
  • OR the final loop for executing actions can be a multicall
  • tstore map/mem fixed array for actionId to action lookup

@github-actions

github-actions Bot commented Jan 20, 2026

Copy link
Copy Markdown

Forge Build Sizes

Contract Runtime Size (B) Initcode Size (B) Runtime Margin (B) Initcode Margin (B)
EIP712Hash (src/position-manager/libraries/EIP712Hash.sol) ↑86% (+380) 821 ↑77% (+380) 873 ↓2% (-380) 23,755 ↓1% (-380) 48,279
JsonBindings ↑89% (+11479) 24,314 ↑89% (+11479) 24,366 ↓98% (-11479) 262 ↓32% (-11479) 24,786
SignatureGateway ↑54% (+7421) 21,132 ↑52% (+7421) 21,777 ↓68% (-7421) 3,444 ↓21% (-7421) 27,375
BatchEIP712 44 94 24,532 49,058
🔕 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,709 2,894 21,867 46,258
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 427 479 24,149 48,673
Create2Utils 134 184 24,442 48,968
DeployUtils 44 94 24,532 49,058
DeployWrapper 6,773 6,801 17,803 42,351
ECDSA 44 94 24,532 49,058
ECDSA.spoke 16 44 24,560 49,108
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
GatewayBaseWrapper 2,400 2,675 22,176 46,477
Hashes 44 94 24,532 49,058
Hub 24,425 24,622 151 24,530
HubConfigurator 13,133 13,406 11,443 35,746
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 7,942 7,994 16,634 41,158
LiquidationLogic.spoke 5,603 5,635 18,973 43,517
LiquidationLogicWrapper 13,706 13,880 10,870 35,272
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 775 803 23,801 48,349
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,168 6,585 18,408 42,567
NoncesKeyed 561 589 24,015 48,563
NoncesKeyed.spoke 323 349 24,253 48,803
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,102 3,130 21,474 46,022
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 1,075 1,103 23,501 48,049
Roles 153 203 24,423 48,949
SafeCast 44 94 24,532 49,058
SafeCast.hub 16 44 24,560 49,108
SafeCast.spoke 16 44 24,560 49,108
SafeERC20 44 94 24,532 49,058
SafeERC20.hub 16 44 24,560 49,108
SafeERC20.spoke 16 44 24,560 49,108
SharesMath 44 94 24,532 49,058
SharesMath.hub 16 44 24,560 49,108
SignatureChecker 44 94 24,532 49,058
SignatureChecker.spoke 16 44 24,560 49,108
SlotDerivation 44 94 24,532 49,058
SlotDerivation.hub 16 44 24,560 49,108
SlotDerivation.spoke 16 44 24,560 49,108
SpokeConfigurator 11,354 11,627 13,222 37,525
SpokeInstance 24,195 24,927 381 24,225
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
UserPositionDebt 44 94 24,532 49,058
UserPositionDebt.spoke 16 44 24,560 49,108
UserPositionDebtWrapper 3,259 3,287 21,317 45,865
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,394 1,422 23,182 47,730

@github-actions

github-actions Bot commented Jan 20, 2026

Copy link
Copy Markdown

♻️ Forge Gas Snapshots

Path Value
snapshots/SignatureGateway.BatchOperations.json
executeBatchWithSig: 1 action (supply) 157175
executeBatchWithSig: 2 actions (borrow+repay) 280312
executeBatchWithSig: 2 actions (supply+setCollateral) 166211
executeBatchWithSig: 2 actions (supply+withdraw) 206224
executeBatchWithSig: 3 actions (supply+setCollateral+withdraw) 234576
executeBatchWithSig: 5 actions 436224
snapshots/SignatureGateway.Operations.json
borrowWithSig ↑0% (+455) 213,302
repayWithPermit2 ↑0% (+486) 213,547
repayWithSig ↑0% (+558) 186,958
setSelfAsUserPositionManagerWithSig ↓0% (-25) 75,407
setUsingAsCollateralWithSig ↑0% (+304) 85,689
supplyWithPermit2 ↑2% (+3959) 176,929
supplyWithSig ↑0% (+422) 152,347
updateUserDynamicConfigWithSig ↑1% (+406) 63,485
updateUserRiskPremiumWithSig ↑1% (+383) 62,466
withdrawWithSig ↑0% (+355) 130,956
🔕 Unchanged
Path Value
snapshots/Hub.Operations.json
add 86,624
add: with transfer 107,921
draw 104,105
eliminateDeficit: full 58,850
eliminateDeficit: partial 68,453
mintFeeShares 82,661
payFee 70,814
refreshPremium 70,367
remove: full 75,357
remove: partial 80,495
reportDeficit 111,875
restore: full 76,533
restore: full - with transfer 169,118
restore: partial 85,255
restore: partial - with transfer 143,235
transferShares 69,588
snapshots/NativeTokenGateway.Operations.json
borrowNative 227,621
repayNative 166,091
supplyAsCollateralNative 159,972
supplyNative 135,681
withdrawNative: full 125,318
withdrawNative: partial 136,447
snapshots/Spoke.Getters.json
getUserAccountData: supplies: 0, borrows: 0 12,919
getUserAccountData: supplies: 1, borrows: 0 49,208
getUserAccountData: supplies: 2, borrows: 0 80,783
getUserAccountData: supplies: 2, borrows: 1 100,194
getUserAccountData: supplies: 2, borrows: 2 118,951
snapshots/Spoke.Operations.ZeroRiskPremium.json
borrow: first 189,248
borrow: second action, same reserve 169,197
liquidationCall (receiveShares): full 294,964
liquidationCall (receiveShares): partial 294,682
liquidationCall: full 304,249
liquidationCall: partial 303,967
permitReserve + repay (multicall) 164,333
permitReserve + supply (multicall) 146,622
permitReserve + supply + enable collateral (multicall) 161,025
repay: full 123,692
repay: partial 128,662
setUserPositionManagersWithSig: disable 47,350
setUserPositionManagersWithSig: enable 69,262
supply + enable collateral (multicall) 141,205
supply: 0 borrows, collateral disabled 122,745
supply: 0 borrows, collateral enabled 105,716
supply: second action, same reserve 105,645
updateUserDynamicConfig: 1 collateral 74,527
updateUserDynamicConfig: 2 collaterals 89,432
updateUserRiskPremium: 1 borrow 94,760
updateUserRiskPremium: 2 borrows 103,895
usingAsCollateral: 0 borrows, enable 59,556
usingAsCollateral: 1 borrow, disable 104,875
usingAsCollateral: 1 borrow, enable 42,444
usingAsCollateral: 2 borrows, disable 125,971
usingAsCollateral: 2 borrows, enable 42,456
withdraw: 0 borrows, full 127,660
withdraw: 0 borrows, partial 132,346
withdraw: 1 borrow, partial 158,728
withdraw: 2 borrows, partial 172,834
withdraw: non collateral 105,615
snapshots/Spoke.Operations.json
borrow: first 258,151
borrow: second action, same reserve 201,100
liquidationCall (receiveShares): full 326,972
liquidationCall (receiveShares): partial 326,690
liquidationCall: full 336,257
liquidationCall: partial 335,975
permitReserve + repay (multicall) 161,850
permitReserve + supply (multicall) 146,622
permitReserve + supply + enable collateral (multicall) 161,025
repay: full 117,771
repay: partial 137,141
setUserPositionManagersWithSig: disable 47,350
setUserPositionManagersWithSig: enable 69,262
supply + enable collateral (multicall) 141,205
supply: 0 borrows, collateral disabled 122,745
supply: 0 borrows, collateral enabled 105,716
supply: second action, same reserve 105,645
updateUserDynamicConfig: 1 collateral 74,527
updateUserDynamicConfig: 2 collaterals 89,432
updateUserRiskPremium: 1 borrow 148,084
updateUserRiskPremium: 2 borrows 197,791
usingAsCollateral: 0 borrows, enable 59,556
usingAsCollateral: 1 borrow, disable 158,199
usingAsCollateral: 1 borrow, enable 42,444
usingAsCollateral: 2 borrows, disable 227,867
usingAsCollateral: 2 borrows, enable 42,456
withdraw: 0 borrows, full 127,660
withdraw: 0 borrows, partial 132,346
withdraw: 1 borrow, partial 209,550
withdraw: 2 borrows, partial 255,263
withdraw: non collateral 105,615

@github-actions

github-actions Bot commented Jan 20, 2026

Copy link
Copy Markdown
🌈 Test Results
No files changed, compilation skipped

Ran 6 tests for tests/unit/Spoke/Spoke.SetUsingAsCollateral.t.sol:SpokeConfigTest
[PASS] test_setUsingAsCollateral() (gas: 310803)
[PASS] test_setUsingAsCollateral_collateralStatusUnchanged() (gas: 466968)
[PASS] test_setUsingAsCollateral_revertsWith_ReentrancyGuardReentrantCall() (gas: 763065)
[PASS] test_setUsingAsCollateral_revertsWith_ReserveFrozen() (gas: 106916)
[PASS] test_setUsingAsCollateral_revertsWith_ReserveNotListed() (gas: 22995)
[PASS] test_setUsingAsCollateral_revertsWith_ReservePaused() (gas: 64216)
Suite result: ok. 6 passed; 0 failed; 0 skipped; finished in 43.51ms (5.79ms CPU time)

Ran 4 tests for tests/gas/Spoke.Operations.Liquidation.gas.t.sol:SpokeOperations_Liquidation_Gas_Tests
[PASS] test_liquidation_full() (gas: 355873)
[PASS] test_liquidation_partial() (gas: 355635)
[PASS] test_liquidation_receiveShares_full() (gas: 346629)
[PASS] test_liquidation_receiveShares_partial() (gas: 346369)
Suite result: ok. 4 passed; 0 failed; 0 skipped; finished in 59.94ms (4.11ms CPU time)

Ran 4 tests for tests/gas/Spoke.Operations.Liquidation.gas.t.sol:SpokeOperations_Liquidation_ZeroRiskPremium_Gas_Tests
[PASS] test_liquidation_full() (gas: 326092)
[PASS] test_liquidation_partial() (gas: 325854)
[PASS] test_liquidation_receiveShares_full() (gas: 316848)
[PASS] test_liquidation_receiveShares_partial() (gas: 316588)
Suite result: ok. 4 passed; 0 failed; 0 skipped; finished in 42.33ms (3.58ms CPU time)

Ran 9 tests for tests/gas/Spoke.Operations.gas.t.sol:SpokeOperations_Basic_ZeroRiskPremium_Gas_Tests
[PASS] test_borrow() (gas: 1087268)
[PASS] test_multicall_ops() (gas: 1319539)
[PASS] test_repay() (gas: 775693)
[PASS] test_setUserPositionManagersWithSig() (gas: 313293)
[PASS] test_supply() (gas: 541326)
[PASS] test_updateRiskPremium() (gas: 937610)
[PASS] test_updateUserDynamicConfig() (gas: 587390)
[PASS] test_usingAsCollateral() (gas: 1083610)
[PASS] test_withdraw() (gas: 1580467)
Suite result: ok. 9 passed; 0 failed; 0 skipped; finished in 50.64ms (14.60ms CPU time)

Ran 9 tests for tests/gas/Spoke.Operations.gas.t.sol:SpokeOperations_Gas_Tests
[PASS] test_borrow() (gas: 1320548)
[PASS] test_multicall_ops() (gas: 1402028)
[PASS] test_repay() (gas: 866422)
[PASS] test_setUserPositionManagersWithSig() (gas: 308761)
[PASS] test_supply() (gas: 538528)
[PASS] test_updateRiskPremium() (gas: 1309531)
[PASS] test_updateUserDynamicConfig() (gas: 582858)
[PASS] test_usingAsCollateral() (gas: 1464733)
[PASS] test_withdraw() (gas: 1939621)
Suite result: ok. 9 passed; 0 failed; 0 skipped; finished in 53.12ms (17.16ms CPU time)

Ran 4 tests for tests/unit/Spoke/Spoke.PermitReserve.t.sol:SpokePermitReserveTest
[PASS] test_permitReserve() (gas: 88258)
[PASS] test_permitReserve_forwards_correct_call() (gas: 35570)
[PASS] test_permitReserve_ignores_permit_reverts() (gas: 24418)
[PASS] test_permitReserve_revertsWith_ReserveNotListedIn() (gas: 22950)
Suite result: ok. 4 passed; 0 failed; 0 skipped; finished in 20.86ms (1.08ms CPU time)

Ran 20 tests for tests/unit/AaveOracle.t.sol:AaveOracleTest
[PASS] test_DECIMALS() (gas: 8326)
[PASS] test_constructor() (gas: 641047)
[PASS] test_description() (gas: 12039)
[PASS] test_fuzz_constructor(uint8) (runs: 5000, μ: 642513, ~: 642835)
[PASS] test_getReservePrice() (gas: 48787)
[PASS] test_getReservePrice_revertsWith_InvalidPrice() (gas: 48043)
[PASS] test_getReservePrice_revertsWith_InvalidSource() (gas: 10894)
[PASS] test_getReservePrices() (gas: 80715)
[PASS] test_getReservePrices_revertsWith_InvalidSource() (gas: 50926)
[PASS] test_getReserveSource() (gas: 48957)
[PASS] test_setReserveSource() (gas: 45999)
[PASS] test_setReserveSource_revertsWith_InvalidPrice() (gas: 102778)
[PASS] test_setReserveSource_revertsWith_InvalidSource() (gas: 17224)
[PASS] test_setReserveSource_revertsWith_InvalidSourceDecimals() (gas: 17072)
[PASS] test_setReserveSource_revertsWith_OnlySpoke() (gas: 13021)
[PASS] test_setReserveSource_revertsWith_OracleMismatch() (gas: 6254448)
[PASS] test_setSpoke() (gas: 5659870)
[PASS] test_setSpoke_revertsWith_InvalidAddress() (gas: 10870)
[PASS] test_setSpoke_revertsWith_OnlyDeployer(address) (runs: 5000, μ: 13397, ~: 13397)
[PASS] test_setSpoke_revertsWith_SpokeAlreadySet() (gas: 15081)
Suite result: ok. 20 passed; 0 failed; 0 skipped; finished in 664.15ms (815.87ms CPU time)

Ran 17 tests for tests/unit/AccessManagerEnumerable.t.sol:AccessManagerEnumerableTest
[PASS] test_getRoleMembers_fuzz(uint256,uint256) (runs: 5000, μ: 1981469, ~: 1980367)
[PASS] test_getRoleTargetSelectors_fuzz(uint256,uint256) (runs: 5000, μ: 1528827, ~: 1527966)
[PASS] test_grantRole() (gas: 315886)
[PASS] test_grantRole_fuzz(uint64,uint256) (runs: 5000, μ: 923275, ~: 919753)
[PASS] test_revokeRole() (gas: 323138)
[PASS] test_setRoleAdmin_fuzz_trackAdminRoles_multipleRoles_multipleAdmins(uint256) (runs: 5000, μ: 2070563, ~: 1926994)
[PASS] test_setRoleAdmin_fuzz_trackRolesAndTrackAdminRoles_multipleRoles(uint256) (runs: 5000, μ: 1962501, ~: 1899754)
[PASS] test_setRoleAdmin_trackAdminOfRoles() (gas: 606131)
[PASS] test_setRoleAdmin_trackAdminOfRoles_changeAdminRole() (gas: 577217)
[PASS] test_setRoleAdmin_trackAdminRoles() (gas: 602311)
[PASS] test_setRoleAdmin_trackRolesAndTrackAdminRoles() (gas: 378311)
[PASS] test_setRoleGuardian_trackRoles() (gas: 263932)
[PASS] test_setTargetFunctionRole() (gas: 414440)
[PASS] test_setTargetFunctionRole_multipleTargets() (gas: 1103911)
[PASS] test_setTargetFunctionRole_removeTarget() (gas: 894967)
[PASS] test_setTargetFunctionRole_skipAddToAdminRole() (gas: 30940)
[PASS] test_setTargetFunctionRole_withReplace() (gas: 549104)
Suite result: ok. 17 passed; 0 failed; 0 skipped; finished in 22.62s (36.45s CPU time)

Ran 32 tests for tests/unit/misc/BatchEIP712.t.sol:BatchEIP712Test
[PASS] test_buildBatchTypeHash_matchesKeccak() (gas: 11446)
[PASS] test_buildBatchTypeString_allActionsAlphabeticalOrder() (gas: 17110)
[PASS] test_buildBatchTypeString_borrowRepay() (gas: 7963)
[PASS] test_buildBatchTypeString_duplicateActions() (gas: 9061)
[PASS] test_buildBatchTypeString_singleBorrow() (gas: 6250)
[PASS] test_buildBatchTypeString_singleRepay() (gas: 6323)
[PASS] test_buildBatchTypeString_singleSetUsingAsCollateral() (gas: 6352)
[PASS] test_buildBatchTypeString_singleSupply() (gas: 6213)
[PASS] test_buildBatchTypeString_singleUpdateUserDynamicConfig() (gas: 6416)
[PASS] test_buildBatchTypeString_singleUpdateUserRiskPremium() (gas: 6383)
[PASS] test_buildBatchTypeString_singleWithdraw() (gas: 6269)
[PASS] test_buildBatchTypeString_supplyWithdraw() (gas: 7826)
[PASS] test_constants_borrowParamsTypehash() (gas: 3581)
[PASS] test_constants_repayParamsTypehash() (gas: 3561)
[PASS] test_constants_setUsingAsCollateralParamsTypehash() (gas: 3538)
[PASS] test_constants_supplyParamsTypehash() (gas: 3561)
[PASS] test_constants_updateUserDynamicConfigParamsTypehash() (gas: 3558)
[PASS] test_constants_updateUserRiskPremiumParamsTypehash() (gas: 3560)
[PASS] test_constants_withdrawParamsTypehash() (gas: 3536)
[PASS] test_hashAction_borrow_fuzz((address,uint256,uint256)) (runs: 5000, μ: 5281, ~: 5281)
[PASS] test_hashAction_repay_fuzz((address,uint256,uint256)) (runs: 5000, μ: 5332, ~: 5332)
[PASS] test_hashAction_revertsOnInvalidActionType() (gas: 5048)
[PASS] test_hashAction_setUsingAsCollateral_fuzz((address,uint256,bool)) (runs: 5000, μ: 5412, ~: 5412)
[PASS] test_hashAction_supply_fuzz((address,uint256,uint256)) (runs: 5000, μ: 5223, ~: 5223)
[PASS] test_hashAction_updateUserDynamicConfig_fuzz((address)) (runs: 5000, μ: 5033, ~: 5033)
[PASS] test_hashAction_updateUserRiskPremium_fuzz((address)) (runs: 5000, μ: 5057, ~: 5057)
[PASS] test_hashAction_withdraw_fuzz((address,uint256,uint256)) (runs: 5000, μ: 5276, ~: 5276)
[PASS] test_hashBatch_borrowRepay_fuzz((address,uint256,uint256),(address,uint256,uint256),address,uint256,uint256) (runs: 5000, μ: 19058, ~: 19058)
[PASS] test_hashBatch_duplicateSupply_fuzz((address,uint256,uint256),(address,uint256,uint256),address,uint256,uint256) (runs: 5000, μ: 17870, ~: 17870)
[PASS] test_hashBatch_singleSupply_fuzz((address,uint256,uint256),address,uint256,uint256) (runs: 5000, μ: 12631, ~: 12631)
[PASS] test_hashBatch_supplyWithdraw_fuzz((address,uint256,uint256),(address,uint256,uint256),address,uint256,uint256) (runs: 5000, μ: 18753, ~: 18753)
[PASS] test_hashBatch_threeActions_fuzz((address,uint256,uint256),(address,uint256,uint256),(address,uint256,bool),address,uint256,uint256) (runs: 5000, μ: 25421, ~: 25421)
Suite result: ok. 32 passed; 0 failed; 0 skipped; finished in 13.02s (13.02s 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: 5000, μ: 696863, ~: 697844)
[PASS] test_supply() (gas: 302883)
[PASS] test_supply_does_not_update_risk_premium() (gas: 1656271)
[PASS] test_supply_fuzz_amounts(uint256) (runs: 5000, μ: 427214, ~: 426883)
[PASS] test_supply_fuzz_index_increase_no_premium(uint256,uint256,uint256,uint256) (runs: 5000, μ: 663888, ~: 664138)
[PASS] test_supply_fuzz_index_increase_with_premium(uint256,uint256,uint256,uint256) (runs: 5000, μ: 760308, ~: 760430)
[PASS] test_supply_fuzz_revertsWith_ERC20InsufficientBalance(uint256) (runs: 5000, μ: 62033, ~: 61747)
[PASS] test_supply_index_increase_no_premium() (gas: 862780)
[PASS] test_supply_index_increase_with_premium() (gas: 920274)
[PASS] test_supply_revertsWith_ERC20InsufficientAllowance() (gas: 39612)
[PASS] test_supply_revertsWith_InvalidSupplyAmount() (gas: 42365)
[PASS] test_supply_revertsWith_ReentrancyGuardReentrantCall() (gas: 278470)
[PASS] test_supply_revertsWith_ReserveFrozen() (gas: 64356)
[PASS] test_supply_revertsWith_ReserveNotListed() (gas: 22869)
[PASS] test_supply_revertsWith_ReservePaused() (gas: 64260)
Suite result: ok. 15 passed; 0 failed; 0 skipped; finished in 49.06s (91.15s CPU time)

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

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

Ran 32 tests for tests/unit/misc/EIP712Hash.t.sol:EIP712HashTest
[PASS] test_constants_borrowParamsTypehash() (gas: 3580)
[PASS] test_constants_borrowTypehash() (gas: 3560)
[PASS] test_constants_positionManagerUpdateTypehash() (gas: 3559)
[PASS] test_constants_repayParamsTypehash() (gas: 3538)
[PASS] test_constants_repayTypehash() (gas: 3580)
[PASS] test_constants_setUserPositionManagersTypehash() (gas: 3558)
[PASS] test_constants_setUsingAsCollateralParamsTypehash() (gas: 3538)
[PASS] test_constants_setUsingAsCollateralTypehash() (gas: 3536)
[PASS] test_constants_supplyParamsTypehash() (gas: 3582)
[PASS] test_constants_supplyTypehash() (gas: 3537)
[PASS] test_constants_updateUserDynamicConfigParamsTypehash() (gas: 3535)
[PASS] test_constants_updateUserDynamicConfigTypehash() (gas: 3536)
[PASS] test_constants_updateUserRiskPremiumParamsTypehash() (gas: 3559)
[PASS] test_constants_updateUserRiskPremiumTypehash() (gas: 3537)
[PASS] test_constants_withdrawParamsTypehash() (gas: 3580)
[PASS] test_constants_withdrawTypehash() (gas: 3561)
[PASS] test_hash_borrowAction_fuzz((address,uint256,uint256,(address,uint256,uint256))) (runs: 5000, μ: 5325, ~: 5325)
[PASS] test_hash_borrowParams_fuzz((address,uint256,uint256)) (runs: 5000, μ: 4617, ~: 4617)
[PASS] test_hash_positionManagerUpdate_fuzz((address,bool)) (runs: 5000, μ: 4733, ~: 4733)
[PASS] test_hash_repayAction_fuzz((address,uint256,uint256,(address,uint256,uint256))) (runs: 5000, μ: 5302, ~: 5302)
[PASS] test_hash_repayParams_fuzz((address,uint256,uint256)) (runs: 5000, μ: 4598, ~: 4598)
[PASS] test_hash_setUserPositionManagers_fuzz((address,(address,bool)[],uint256,uint256)) (runs: 5000, μ: 178055, ~: 176527)
[PASS] test_hash_setUsingAsCollateralAction_fuzz((address,uint256,uint256,(address,uint256,bool))) (runs: 5000, μ: 5501, ~: 5501)
[PASS] test_hash_setUsingAsCollateralParams_fuzz((address,uint256,bool)) (runs: 5000, μ: 4873, ~: 4873)
[PASS] test_hash_supplyAction_fuzz((address,uint256,uint256,(address,uint256,uint256))) (runs: 5000, μ: 5326, ~: 5326)
[PASS] test_hash_supplyParams_fuzz((address,uint256,uint256)) (runs: 5000, μ: 4618, ~: 4618)
[PASS] test_hash_updateUserDynamicConfigAction_fuzz((address,uint256,uint256,(address))) (runs: 5000, μ: 5107, ~: 5107)
[PASS] test_hash_updateUserDynamicConfigParams_fuzz((address)) (runs: 5000, μ: 4448, ~: 4448)
[PASS] test_hash_updateUserRiskPremiumAction_fuzz((address,uint256,uint256,(address))) (runs: 5000, μ: 5106, ~: 5106)
[PASS] test_hash_updateUserRiskPremiumParams_fuzz((address)) (runs: 5000, μ: 4425, ~: 4425)
[PASS] test_hash_withdrawAction_fuzz((address,uint256,uint256,(address,uint256,uint256))) (runs: 5000, μ: 5283, ~: 5283)
[PASS] test_hash_withdrawParams_fuzz((address,uint256,uint256)) (runs: 5000, μ: 4620, ~: 4620)
Suite result: ok. 32 passed; 0 failed; 0 skipped; finished in 18.78s (18.78s CPU time)

Ran 8 tests for tests/unit/misc/GatewayBase.t.sol:GatewayBaseTest
[PASS] test_constructor() (gas: 17151)
[PASS] test_registerSpoke_fuzz(address) (runs: 5000, μ: 41629, ~: 41629)
[PASS] test_registerSpoke_revertsWith_InvalidAddress() (gas: 13119)
[PASS] test_registerSpoke_revertsWith_OwnableUnauthorizedAccount() (gas: 13791)
[PASS] test_registerSpoke_unregister() (gas: 36076)
[PASS] test_renouncePositionManagerRole() (gas: 65227)
[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 343.75ms (323.59ms CPU time)

Ran 5 tests for tests/gas/Gateways.Operations.gas.t.sol:NativeTokenGateway_Gas_Tests
[PASS] test_borrowNative() (gas: 915702)
[PASS] test_repayNative() (gas: 987507)
[PASS] test_supplyAndCollateralNative() (gas: 304937)
[PASS] test_supplyNative() (gas: 286516)
[PASS] test_withdrawNative() (gas: 507906)
Suite result: ok. 5 passed; 0 failed; 0 skipped; finished in 38.95ms (4.11ms CPU time)

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

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

[PASS] test_calculateInterestRate_LeftToKinkPoint(uint256) (runs: 5000, μ: 24228, ~: 24372)
[PASS] test_calculateInterestRate_RightToKinkPoint(uint256) (runs: 5000, μ: 25367, ~: 25411)
[PASS] test_calculateInterestRate_ZeroDebtZeroLiquidity() (gas: 18783)
Logs:
  Bound result 0

[PASS] test_calculateInterestRate_fuzz_ZeroDebt(uint256) (runs: 5000, μ: 19081, ~: 18834)
[PASS] test_calculateInterestRate_revertsWith_InterestRateDataNotSet() (gas: 11225)
[PASS] test_deploy_revertsWith_InvalidAddress() (gas: 36272)
[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 33.17s (33.35s CPU time)

Ran 6 tests for tests/gas/Gateways.Operations.gas.t.sol:SignatureGatewayBatch_Gas_Tests
[PASS] test_executeBatchWithSig_borrowRepay() (gas: 1072655)
[PASS] test_executeBatchWithSig_fiveActions() (gas: 1546190)
[PASS] test_executeBatchWithSig_singleSupply() (gas: 481357)
[PASS] test_executeBatchWithSig_supplyAndSetCollateral() (gas: 552409)
[PASS] test_executeBatchWithSig_supplyWithdraw() (gas: 634601)
[PASS] test_executeBatchWithSig_threeActions() (gas: 746755)
Suite result: ok. 6 passed; 0 failed; 0 skipped; finished in 46.32ms (11.16ms CPU time)

Ran 2 tests for tests/gas/Gateways.Operations.gas.t.sol:SignatureGatewayPermit2_Gas_Tests
[PASS] test_repayWithPermit2() (gas: 969966)
[PASS] test_supplyWithPermit2() (gas: 452750)
Suite result: ok. 2 passed; 0 failed; 0 skipped; finished in 37.48ms (2.86ms CPU time)

Ran 8 tests for tests/gas/Gateways.Operations.gas.t.sol:SignatureGateway_Gas_Tests
[PASS] test_borrowWithSig() (gas: 748905)
[PASS] test_repayWithSig() (gas: 983970)
[PASS] test_setSelfAsUserPositionManagerWithSig() (gas: 210375)
[PASS] test_setUsingAsCollateralWithSig() (gas: 295057)
[PASS] test_supplyWithSig() (gas: 468540)
[PASS] test_updateUserDynamicConfigWithSig() (gas: 146588)
[PASS] test_updateUserRiskPremiumWithSig() (gas: 144530)
[PASS] test_withdrawWithSig() (gas: 417214)
Suite result: ok. 8 passed; 0 failed; 0 skipped; finished in 42.54ms (8.04ms CPU time)

Ran 6 tests for tests/unit/Hub/Hub.Access.t.sol:HubAccessTest
[PASS] test_change_authority() (gas: 2867083)
[PASS] test_change_role_responsibility() (gas: 121132)
[PASS] test_hub_access_manager_exposure() (gas: 13427)
[PASS] test_hub_admin_access() (gas: 1365850)
[PASS] test_migrate_role_responsibility() (gas: 781111)
[PASS] test_setInterestRateData_access() (gas: 102489)
Suite result: ok. 6 passed; 0 failed; 0 skipped; finished in 23.56ms (3.66ms CPU time)

Ran 8 tests for tests/unit/Spoke/Spoke.Upgradeable.t.sol:SpokeUpgradeableTest
[PASS] test_implementation_constructor_fuzz(uint64) (runs: 5000, μ: 6614530, ~: 6614530)
[PASS] test_proxy_constructor_fuzz(uint64) (runs: 5000, μ: 7394248, ~: 7394241)
[PASS] test_proxy_constructor_fuzz_revertsWith_InvalidInitialization(uint64) (runs: 5000, μ: 13978449, ~: 13978442)
[PASS] test_proxy_constructor_revertsWith_InvalidAddress() (gas: 5090285)
[PASS] test_proxy_constructor_revertsWith_InvalidInitialization_ZeroRevision() (gas: 6671293)
[PASS] test_proxy_reinitialization_fuzz(uint64) (runs: 5000, μ: 15125999, ~: 15125983)
[PASS] test_proxy_reinitialization_revertsWith_CallerNotProxyAdmin() (gas: 12375393)
[PASS] test_proxy_reinitialization_revertsWith_InvalidAddress() (gas: 12375952)
Suite result: ok. 8 passed; 0 failed; 0 skipped; finished in 19.08s (33.05s CPU time)

Ran 6 tests for tests/unit/Spoke/Spoke.UserAccountData.t.sol:SpokeUserAccountDataTest
[PASS] test_userAccountData_scenario1() (gas: 499421)
[PASS] test_userAccountData_scenario2() (gas: 560274)
[PASS] test_userAccountData_scenario3() (gas: 560523)
[PASS] test_userAccountData_scenario4() (gas: 835342)
[PASS] test_userAccountData_scenario5() (gas: 717686)
[PASS] test_userAccountData_scenario6() (gas: 688089)
Suite result: ok. 6 passed; 0 failed; 0 skipped; finished in 27.38ms (4.42ms CPU time)

Ran 6 tests for tests/unit/Hub/Hub.EliminateDeficit.t.sol:HubEliminateDeficitTest
[PASS] test_eliminateDeficit(uint256) (runs: 5000, μ: 642202, ~: 642202)
[PASS] test_eliminateDeficit_allowSpokePaused() (gas: 421578)
[PASS] test_eliminateDeficit_fuzz_revertsWith_ArithmeticUnderflow_CallerSpokeNoFunds(uint256) (runs: 5000, μ: 335338, ~: 335338)
[PASS] test_eliminateDeficit_fuzz_revertsWith_callerSpokeNotActive(address) (runs: 5000, μ: 29920, ~: 29920)
[PASS] test_eliminateDeficit_revertsWith_InvalidAmount_ZeroAmountNoDeficit() (gas: 20547)
[PASS] test_eliminateDeficit_revertsWith_InvalidAmount_ZeroAmountWithDeficit() (gas: 333170)
Suite result: ok. 6 passed; 0 failed; 0 skipped; finished in 15.70s (15.68s CPU time)

Ran 6 tests for tests/unit/Hub/Hub.MintFeeShares.t.sol:HubMintFeeSharesTest
[PASS] test_mintFeeShares() (gas: 310124)
[PASS] test_mintFeeShares_noFees() (gas: 365611)
[PASS] test_mintFeeShares_noShares() (gas: 291681)
[PASS] test_mintFeeShares_revertsWith_AccessManagedUnauthorized() (gas: 24115)
[PASS] test_mintFeeShares_revertsWith_AssetNotListed() (gas: 27529)
[PASS] test_mintFeeShares_revertsWith_SpokeNotActive() (gas: 242098)
Suite result: ok. 6 passed; 0 failed; 0 skipped; finished in 23.83ms (3.87ms CPU time)

Ran 9 tests for tests/gas/Hub.Operations.gas.t.sol:HubOperations_Gas_Tests
[PASS] test_add() (gas: 269972)
[PASS] test_deficit() (gas: 1172996)
[PASS] test_draw() (gas: 418374)
[PASS] test_mintFeeShares() (gas: 499664)
[PASS] test_payFee_transferShares() (gas: 966958)
[PASS] test_refreshPremium() (gas: 633170)
[PASS] test_remove() (gas: 310118)
[PASS] test_restore() (gas: 877564)
[PASS] test_restore_with_transfer() (gas: 878229)
Suite result: ok. 9 passed; 0 failed; 0 skipped; finished in 42.70ms (6.66ms CPU time)

Ran 6 tests for tests/unit/Hub/Hub.PayFee.t.sol:HubPayFeeTest
[PASS] test_payFee_fuzz(uint256,uint256) (runs: 5000, μ: 702322, ~: 702467)
[PASS] test_payFee_fuzz_with_interest(uint256,uint256,uint256) (runs: 5000, μ: 702767, ~: 703135)
[PASS] test_payFee_revertsWith_InvalidShares() (gas: 20348)
[PASS] test_payFee_revertsWith_SpokeNotActive() (gas: 61205)
[PASS] test_payFee_revertsWith_underflow_added_shares_exceeded() (gas: 138371)
[PASS] test_payFee_revertsWith_underflow_added_shares_exceeded_with_interest() (gas: 642346)
Suite result: ok. 6 passed; 0 failed; 0 skipped; finished in 25.17s (25.15s CPU time)

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

[PASS] test_reclaim_fullAmount() (gas: 654276)
[PASS] test_reclaim_fuzz(uint256,uint256,uint256) (runs: 5000, μ: 675306, ~: 674519)
[PASS] test_reclaim_multipleSweepsAndReclaims() (gas: 780976)
[PASS] test_reclaim_revertsWith_AssetNotListed() (gas: 13126)
[PASS] test_reclaim_revertsWith_InvalidAmount_zero() (gas: 92375)
[PASS] test_reclaim_revertsWith_OnlyReinvestmentController(address) (runs: 5000, μ: 93192, ~: 93192)
[PASS] test_reclaim_revertsWith_OnlyReinvestmentController_init() (gas: 40425)
[PASS] test_reclaim_revertsWith_underflow_exceedsSwept() (gas: 97867)
[PASS] test_reclaim_revertsWith_underflow_exceedsSwept_afterSweep() (gas: 456723)
Suite result: ok. 10 passed; 0 failed; 0 skipped; finished in 14.91s (14.89s CPU time)

Ran 12 tests for tests/unit/Hub/Hub.RefreshPremium.t.sol:HubRefreshPremiumTest
[PASS] test_refreshPremium_emitsEvent() (gas: 254285)
[PASS] test_refreshPremium_fuzz_positiveDeltas(uint256,int256,int256) (runs: 5000, μ: 465604, ~: 470125)
[PASS] test_refreshPremium_fuzz_withAccrual(uint256,uint256,uint256,uint256) (runs: 5000, μ: 528946, ~: 535921)
[PASS] test_refreshPremium_maxRiskPremiumThreshold() (gas: 885599)
[PASS] test_refreshPremium_negativeDeltas(uint256) (runs: 5000, μ: 456787, ~: 457362)
[PASS] test_refreshPremium_negativeDeltas_withAccrual(uint256) (runs: 5000, μ: 525704, ~: 525920)
[PASS] test_refreshPremium_pausedSpokesAllowed() (gas: 121075)
[PASS] test_refreshPremium_revertsWith_InvalidPremiumChange_NonZeroRestoredPremiumRay() (gas: 841357)
[PASS] test_refreshPremium_revertsWith_InvalidPremiumChange_RiskPremiumThresholdExceeded_DecreasingPremium() (gas: 862507)
[PASS] test_refreshPremium_revertsWith_SpokeNotActive() (gas: 58757)
[PASS] test_refreshPremium_riskPremiumThreshold() (gas: 907705)
[PASS] test_refreshPremium_spokePremiumUpdateIsContained() (gas: 704841)
Suite result: ok. 12 passed; 0 failed; 0 skipped; finished in 20.99s (20.97s CPU time)

Ran 7 tests for tests/unit/Spoke/Spoke.AccrueInterest.t.sol:SpokeAccrueInterestTest
[PASS] test_accrueInterest_NoActionTaken() (gas: 132400)
[PASS] test_accrueInterest_NoInterest_NoDebt(uint40) (runs: 5000, μ: 627609, ~: 627445)
[PASS] test_accrueInterest_NoInterest_OnlySupply(uint40) (runs: 5000, μ: 249410, ~: 249392)
[PASS] test_accrueInterest_TenPercentRp(uint256,uint40) (runs: 5000, μ: 576595, ~: 576972)
[PASS] test_accrueInterest_fuzz_BorrowAmountAndSkipTime(uint256,uint40) (runs: 5000, μ: 535330, ~: 535782)
[PASS] test_accrueInterest_fuzz_RPBorrowAndSkipTime((uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256),uint40) (runs: 5000, μ: 3835456, ~: 3851631)
[PASS] test_accrueInterest_fuzz_RatesRPBorrowAndSkipTime((uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256),(uint96,uint96,uint96,uint96),uint40) (runs: 5000, μ: 3905027, ~: 3920953)
Suite result: ok. 7 passed; 0 failed; 0 skipped; finished in 191.50s (191.48s CPU time)

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

[PASS] test_remove_all_with_interest() (gas: 366363)
[PASS] test_remove_fuzz(uint256,uint256) (runs: 5000, μ: 206340, ~: 206291)
[PASS] test_remove_fuzz_all_liquidity_with_interest(uint256,uint256) (runs: 5000, μ: 417170, ~: 417417)
[PASS] test_remove_fuzz_multi_spoke(uint256,uint256) (runs: 5000, μ: 287103, ~: 287219)
[PASS] test_remove_fuzz_multi_spoke_with_interest(uint256,uint256,uint256,uint256) (runs: 5000, μ: 419826, ~: 420326)
[PASS] test_remove_revertsWith_InsufficientLiquidity() (gas: 157978)
[PASS] test_remove_revertsWith_InsufficientLiquidity_exceeding_added_amount() (gas: 147067)
[PASS] test_remove_revertsWith_InsufficientLiquidity_zero_added() (gas: 21306)
[PASS] test_remove_revertsWith_InvalidAddress() (gas: 16413)
[PASS] test_remove_revertsWith_InvalidAmount() (gas: 18525)
[PASS] test_remove_revertsWith_SpokeNotActive() (gas: 61694)
[PASS] test_remove_revertsWith_SpokePaused() (gas: 61676)
[PASS] test_remove_revertsWith_underflow_exceeding_added_amount() (gas: 184546)
[PASS] test_remove_revertsWtih_underflow_one_extra_wei() (gas: 362276)
Suite result: ok. 15 passed; 0 failed; 0 skipped; finished in 30.16s (30.14s 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, μ: 536190, ~: 536340)
[PASS] test_accrueLiquidityFee_fuzz_maxLiquidityFee_with_premium_multiple_users(uint256,uint256,uint256,uint256,uint256) (runs: 5000, μ: 787441, ~: 787526)
[PASS] test_accrueLiquidityFee_maxLiquidityFee_multi_spoke() (gas: 642589341)
[PASS] test_accrueLiquidityFee_maxLiquidityFee_multi_user() (gas: 256387842)
[PASS] test_accrueLiquidityFee_maxLiquidityFee_with_premium() (gas: 536502)
Logs:
  Bound result 500000000000000000000
  Bound result 5000
  Bound result 34560000
  Bound result 2

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

Ran 7 tests for tests/unit/Hub/Hub.ReportDeficit.t.sol:HubReportDeficitTest
[PASS] test_reportDeficit_fuzz_revertsWith_SurplusDrawnDeficitReported(uint256) (runs: 5000, μ: 217848, ~: 217560)
[PASS] test_reportDeficit_fuzz_revertsWith_SurplusPremiumRayDeficitReported(uint256) (runs: 5000, μ: 218806, ~: 218518)
[PASS] test_reportDeficit_fuzz_with_premium(uint256,uint256,uint256,uint256) (runs: 5000, μ: 669744, ~: 670667)
[PASS] test_reportDeficit_paused() (gas: 264951)
[PASS] test_reportDeficit_revertsWith_InvalidAmount() (gas: 24838)
[PASS] test_reportDeficit_revertsWith_SpokeNotActive(address) (runs: 5000, μ: 33829, ~: 33829)
[PASS] test_reportDeficit_with_premium() (gas: 669246)
Logs:
  Bound result 10000000000
  Bound result 31536000
  Bound result 5000000000
  Bound result 0

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

Ran 21 tests for tests/unit/Spoke/Spoke.Withdraw.HealthFactor.t.sol:SpokeWithdrawHealthFactorTest
[PASS] test_unsetCollateral_fuzz_revertsWith_HealthFactorBelowThreshold(uint256) (runs: 5000, μ: 757562, ~: 757274)
[PASS] test_withdraw_fuzz_revertsWith_HealthFactorBelowThreshold_interest_increase(uint256,uint256) (runs: 5000, μ: 649784, ~: 650260)
[PASS] test_withdraw_fuzz_revertsWith_HealthFactorBelowThreshold_multiple_colls(uint256,uint256) (runs: 5000, μ: 875443, ~: 875765)
[PASS] test_withdraw_fuzz_revertsWith_HealthFactorBelowThreshold_multiple_colls_price_drop_dai(uint256,uint256,uint256) (runs: 5000, μ: 1158737, ~: 1159487)
[PASS] test_withdraw_fuzz_revertsWith_HealthFactorBelowThreshold_multiple_colls_price_drop_weth(uint256,uint256,uint256) (runs: 5000, μ: 1159326, ~: 1159504)
[PASS] test_withdraw_fuzz_revertsWith_HealthFactorBelowThreshold_multiple_colls_with_interest(uint256,uint256) (runs: 5000, μ: 927778, ~: 928755)
[PASS] test_withdraw_fuzz_revertsWith_HealthFactorBelowThreshold_multiple_debts(uint256,uint256) (runs: 5000, μ: 995419, ~: 995272)
[PASS] test_withdraw_fuzz_revertsWith_HealthFactorBelowThreshold_multiple_debts_price_drop(uint256,uint256,uint256) (runs: 5000, μ: 1265987, ~: 1266176)
[PASS] test_withdraw_fuzz_revertsWith_HealthFactorBelowThreshold_multiple_debts_with_interest(uint256,uint256,uint256) (runs: 5000, μ: 1031102, ~: 1031259)
[PASS] test_withdraw_fuzz_revertsWith_HealthFactorBelowThreshold_price_drop(uint256,uint256) (runs: 5000, μ: 885372, ~: 885472)
[PASS] test_withdraw_fuzz_revertsWith_HealthFactorBelowThreshold_singleBorrow(uint256) (runs: 5000, μ: 616196, ~: 615962)
[PASS] test_withdraw_revertsWith_HealthFactorBelowThreshold_interest_increase() (gas: 644990)
[PASS] test_withdraw_revertsWith_HealthFactorBelowThreshold_multiple_colls() (gas: 871216)
[PASS] test_withdraw_revertsWith_HealthFactorBelowThreshold_multiple_colls_price_drop_dai() (gas: 1153336)
[PASS] test_withdraw_revertsWith_HealthFactorBelowThreshold_multiple_colls_price_drop_weth() (gas: 1153338)
[PASS] test_withdraw_revertsWith_HealthFactorBelowThreshold_multiple_colls_with_interest() (gas: 923777)
[PASS] test_withdraw_revertsWith_HealthFactorBelowThreshold_multiple_debts() (gas: 990370)
[PASS] test_withdraw_revertsWith_HealthFactorBelowThreshold_multiple_debts_price_drop() (gas: 1259619)
[PASS] test_withdraw_revertsWith_HealthFactorBelowThreshold_multiple_debts_with_interest() (gas: 1024995)
[PASS] test_withdraw_revertsWith_HealthFactorBelowThreshold_price_drop() (gas: 880246)
[PASS] test_withdraw_revertsWith_HealthFactorBelowThreshold_singleBorrow() (gas: 617249)
Suite result: ok. 21 passed; 0 failed; 0 skipped; finished in 156.46s (288.69s CPU time)

Ran 7 tests for tests/unit/Spoke/Spoke.AccrueLiquidityFee.t.sol:SpokeAccrueLiquidityFeeTest
[PASS] test_accrueLiquidityFee() (gas: 857660)
[PASS] test_accrueLiquidityFee_NoActionTaken() (gas: 121564)
[PASS] test_accrueLiquidityFee_NoInterest_OnlySupply(uint40) (runs: 5000, μ: 244539, ~: 244486)
[PASS] test_accrueLiquidityFee_exact() (gas: 863439)
[PASS] test_accrueLiquidityFee_fuzz_BorrowAmountAndSkipTime(uint256,uint40) (runs: 5000, μ: 932618, ~: 954501)
[PASS] test_accrueLiquidityFee_maxLiquidityFee() (gas: 542408)
[PASS] test_accrueLiquidityFee_setUsingAsCollateral() (gas: 889781)
Suite result: ok. 7 passed; 0 failed; 0 skipped; finished in 19.38s (19.36s CPU time)

Ran 3 tests for tests/unit/Hub/Hub.Rescue.t.sol:HubRescueTest
[PASS] test_cannot_rescue_liquidity_fee_reverts_with_InsufficientTransferred() (gas: 273385)
[PASS] test_rescue_fuzz_with_interest(uint256,uint256) (runs: 5000, μ: 512690, ~: 512654)
[PASS] test_rescue_scenario_fuzz(uint256) (runs: 5000, μ: 452315, ~: 452108)
Suite result: ok. 3 passed; 0 failed; 0 skipped; finished in 17.77s (17.75s CPU time)

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

[PASS] test_restore_full_amount_with_interest_and_premium() (gas: 669203)
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, μ: 361702, ~: 361788)
[PASS] test_restore_fuzz_full_amount_with_interest_and_premium(uint256,uint256,uint256,uint256) (runs: 5000, μ: 659432, ~: 671144)
[PASS] test_restore_fuzz_revertsWith_SurplusDrawnRestored_with_interest(uint256,uint256,uint256) (runs: 5000, μ: 243288, ~: 244502)
[PASS] test_restore_fuzz_revertsWith_SurplusDrawnRestored_with_interest_and_premium(uint256,uint256,uint256,uint256) (runs: 5000, μ: 634199, ~: 634394)
[PASS] test_restore_one_share_delta_increase_revertsWith_InvalidPremiumChange() (gas: 211474)
[PASS] test_restore_partial_drawn() (gas: 321716)
[PASS] test_restore_partial_same_block() (gas: 321892)
[PASS] test_restore_premiumDeltas_twoWeiIncrease_realizedDelta() (gas: 232177)
[PASS] test_restore_revertsWith_InsufficientTransferred() (gas: 251950)
[PASS] test_restore_revertsWith_InvalidAmount_zero() (gas: 55102)
[PASS] test_restore_revertsWith_InvalidPremiumChange_premiumIncrease() (gas: 218439)
[PASS] test_restore_revertsWith_InvalidPremiumChange_premiumSharesIncrease() (gas: 218438)
[PASS] test_restore_revertsWith_SpokeNotActive_whenPaused() (gas: 169045)
[PASS] test_restore_revertsWith_SpokePaused() (gas: 96095)
[PASS] test_restore_revertsWith_SurplusDrawnRestored() (gas: 360819)
[PASS] test_restore_revertsWith_SurplusDrawnRestored_with_interest() (gas: 243105)
Logs:
  Bound result 100000000000000000000
  Bound result 50000000000000000000
  Bound result 15768000

[PASS] test_restore_revertsWith_SurplusDrawnRestored_with_interest_and_premium() (gas: 632476)
Logs:
  Bound result 100000000000000000000
  Bound result 50000000000000000000
  Bound result 31536000
  Bound result 1

[PASS] test_restore_revertsWith_SurplusPremiumRayRestored() (gas: 526536)
[PASS] test_restore_revertsWith_underflow_offsetIncrease() (gas: 227317)
[PASS] test_restore_tooMuchDrawn_revertsWith_SurplusDrawnRestored() (gas: 216814)
[PASS] test_restore_when_asset_frozen() (gas: 425565)
Suite result: ok. 23 passed; 0 failed; 0 skipped; finished in 18.41s (18.39s CPU time)

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

Ran 5 tests for tests/unit/Spoke/Spoke.Withdraw.Scenario.t.sol:SpokeWithdrawScenarioTest
[PASS] test_withdraw_fuzz_all_liquidity_with_interest_multi_user((uint256,uint256,uint256,uint256,uint256[2],uint256)) (runs: 5000, μ: 865280, ~: 865309)
[PASS] test_withdraw_fuzz_partial_full_with_interest(uint256,uint256,uint256,uint40) (runs: 5000, μ: 709804, ~: 709852)
[PASS] test_withdraw_round_trip_deposit_withdraw(uint256,uint256,address,uint256) (runs: 5000, μ: 412393, ~: 412356)
[PASS] test_withdraw_round_trip_withdraw_deposit(uint256,uint256,uint256,address,uint256) (runs: 5000, μ: 433065, ~: 432381)
[PASS] test_withdraw_underwater_reserve_not_collateral() (gas: 813847)
Suite result: ok. 5 passed; 0 failed; 0 skipped; finished in 55.18s (78.45s CPU time)

Ran 6 tests for tests/unit/Spoke/Spoke.Withdraw.Validation.t.sol:SpokeWithdrawValidationTest
[PASS] test_withdraw_fuzz_revertsWith_InsufficientLiquidity_with_debt(uint256,uint256,uint256,uint256,uint256) (runs: 5000, μ: 428592, ~: 428814)
[PASS] test_withdraw_fuzz_revertsWith_InsufficientSupply_zero_supplied(uint256) (runs: 5000, μ: 54855, ~: 54568)
[PASS] test_withdraw_revertsWith_InsufficientLiquidity_with_debt() (gas: 425268)
[PASS] test_withdraw_revertsWith_InvalidAmount_zero_supplied() (gas: 51188)
[PASS] test_withdraw_revertsWith_ReserveNotListed() (gas: 22387)
[PASS] test_withdraw_revertsWith_ReservePaused() (gas: 63845)
Suite result: ok. 6 passed; 0 failed; 0 skipped; finished in 5.70s (6.41s 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, μ: 1038825, ~: 1038945)
[PASS] test_borrow_fuzz_rounding_effect_inflated_ex_rate(uint256,uint256,uint256) (runs: 5000, μ: 1409200, ~: 1409289)
[PASS] test_borrow_fuzz_rounding_effect_shares(uint256,uint256) (runs: 5000, μ: 1081472, ~: 1081226)
[PASS] test_borrow_rounding_effect_multiple_actions() (gas: 1140221)
[PASS] test_borrow_rounding_effect_shares() (gas: 1080488)
Logs:
  Bound result 5000000000000000000
  Bound result 94608000

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

Ran 11 tests for tests/unit/misc/SignatureGateway/SignatureGateway.t.sol:SignatureGatewayTest
[PASS] test_borrowWithSig() (gas: 793384)
[PASS] test_renouncePositionManagerRole() (gas: 27535)
[PASS] test_renouncePositionManagerRole_revertsWith_OnlyOwner() (gas: 18157)
[PASS] test_repayWithSig() (gas: 796747)
[PASS] test_setSelfAsUserPositionManagerWithSig() (gas: 309191)
[PASS] test_setUsingAsCollateralWithSig() (gas: 607012)
[PASS] test_supplyWithSig() (gas: 586934)
[PASS] test_updateUserDynamicConfigWithSig() (gas: 319869)
[PASS] test_updateUserRiskPremiumWithSig() (gas: 893457)
[PASS] test_useNonce_monotonic(bytes32) (runs: 5000, μ: 13435, ~: 13435)
[PASS] test_withdrawWithSig() (gas: 586963)
Suite result: ok. 11 passed; 0 failed; 0 skipped; finished in 288.28s (288.26s CPU time)

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

Ran 1 test for tests/unit/Spoke/Spoke.AccrueInterest.Scenario.t.sol:SpokeAccrueInterestScenarioTest
[SKIP: pending rft] test_accrueInterest_fuzz_RPBorrowAndSkipTime_twoActions((uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256),uint40) (runs: 0, μ: 0, ~: 0)
Suite result: ok. 0 passed; 0 failed; 1 skipped; finished in 24.72ms (4.12ms CPU time)

Ran 4 tests for tests/unit/Hub/Hub.Skim.t.sol:HubSkimTest
[PASS] test_skimAdd_fuzz_donationAfterAdd(uint256,uint256,uint256) (runs: 5000, μ: 227273, ~: 227284)
[PASS] test_skimAdd_fuzz_donationBeforeAdd(uint256,uint256,uint256) (runs: 5000, μ: 227305, ~: 227316)
[PASS] test_skimAdd_fuzz_wrongSpokeTransfer(uint256,uint256,uint256) (runs: 5000, μ: 216399, ~: 216340)
[PASS] test_skimRestore_fuzz_liquidityDonation(uint256,uint256,uint256) (runs: 5000, μ: 271858, ~: 273268)
Suite result: ok. 4 passed; 0 failed; 0 skipped; finished in 27.44s (27.42s CPU time)

Ran 10 tests for tests/unit/Hub/Hub.SpokeConfig.t.sol:HubSpokeConfigTest
[PASS] test_add_active_paused_scenarios() (gas: 302089)
[PASS] test_draw_active_paused_scenarios() (gas: 303048)
[PASS] test_eliminateDeficit_active_paused_scenarios() (gas: 653418)
[PASS] test_mintFeeShares_active_paused_scenarios() (gas: 835071)
[PASS] test_payFeeShares_active_paused_scenarios() (gas: 359839)
[PASS] test_refreshPremium_active_paused_scenarios() (gas: 265802)
[PASS] test_remove_active_paused_scenarios() (gas: 317589)
[PASS] test_reportDeficit_active_paused_scenarios() (gas: 443613)
[PASS] test_restore_active_paused_scenarios() (gas: 353725)
[PASS] test_transferShares_fuzz_active_paused_scenarios(bool,bool,bool,bool) (runs: 5000, μ: 212578, ~: 212584)
Suite result: ok. 10 passed; 0 failed; 0 skipped; finished in 4.03s (4.01s 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: 5000, μ: 1202545, ~: 1207399)
[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: 5000, μ: 2002815, ~: 1973710)
[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: 5000, μ: 5899605, ~: 5899975)
[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: 5000, μ: 4182294, ~: 4182497)
[PASS] test_repay_partial_then_max() (gas: 680765)
[PASS] test_repay_round_trip_borrow_repay(uint256,uint256,uint40,address,uint256) (runs: 5000, μ: 858738, ~: 861459)
[PASS] test_repay_round_trip_repay_borrow(uint256,uint256,uint256,uint40,address,uint256) (runs: 5000, μ: 939300, ~: 948196)
[PASS] test_repay_two_users_repay_same_reserve((uint256,uint256,uint256,uint256,uint256,uint256,address),(uint256,uint256,uint256,uint256,uint256,uint256,address),uint256) (runs: 5000, μ: 1448517, ~: 1476599)
Suite result: ok. 8 passed; 0 failed; 0 skipped; finished in 300.66s (300.64s CPU time)

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

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

[PASS] test_sweep_does_not_impact_utilization(uint256,uint256) (runs: 5000, μ: 628826, ~: 630119)
[PASS] test_sweep_fuzz(uint256,uint256) (runs: 5000, μ: 482906, ~: 482905)
[PASS] test_sweep_revertsWith_AssetNotListed() (gas: 12581)
[PASS] test_sweep_revertsWith_InsufficientLiquidity() (gas: 219260)
[PASS] test_sweep_revertsWith_InvalidAmount() (gas: 103393)
[PASS] test_sweep_revertsWith_OnlyReinvestmentController(address) (runs: 5000, μ: 93572, ~: 93572)
[PASS] test_sweep_revertsWith_OnlyReinvestmentController_init() (gas: 39925)
Suite result: ok. 8 passed; 0 failed; 0 skipped; finished in 18.28s (18.26s CPU time)

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

[PASS] test_transferShares_fuzz(uint256,uint256) (runs: 5000, μ: 194032, ~: 194229)
[PASS] test_transferShares_fuzz_revertsWith_underflow_spoke_added_shares_exceeded(uint256) (runs: 5000, μ: 150978, ~: 150690)
[PASS] test_transferShares_revertsWith_AddCapExceeded() (gas: 194839)
[PASS] test_transferShares_revertsWith_SpokeNotActive() (gas: 177490)
[PASS] test_transferShares_revertsWith_SpokePaused() (gas: 179662)
[PASS] test_transferShares_zeroShares_revertsWith_InvalidShares() (gas: 22559)
Suite result: ok. 7 passed; 0 failed; 0 skipped; finished in 7.56s (7.54s CPU time)

Ran 19 tests for tests/unit/Hub/Hub.Add.t.sol:HubAddTest
[PASS] test_add_AddCapReachedButNotExceeded_rounding() (gas: 664082)
[PASS] test_add_fuzz_AddCapReachedButNotExceeded(uint40) (runs: 5000, μ: 157555, ~: 157512)
[PASS] test_add_fuzz_multi_asset_multi_spoke(uint256,uint256,uint256) (runs: 5000, μ: 331170, ~: 331291)
[PASS] test_add_fuzz_revertsWith_AddCapExceeded(uint40) (runs: 5000, μ: 112173, ~: 112130)
[PASS] test_add_fuzz_revertsWith_AddCapExceeded_due_to_interest(uint40,uint256,uint256) (runs: 5000, μ: 266078, ~: 265935)
[PASS] test_add_fuzz_revertsWith_InvalidShares_due_to_index(uint256,uint256,uint256) (runs: 5000, μ: 223429, ~: 223634)
[PASS] test_add_fuzz_single_asset(uint256,address,uint256) (runs: 5000, μ: 341716, ~: 341748)
[PASS] test_add_fuzz_single_spoke_multi_add(uint256,uint256) (runs: 5000, μ: 798875, ~: 798910)
[PASS] test_add_multi_add_minimal_shares() (gas: 320018)
[PASS] test_add_revertsWith_AmountDowncastOverflow() (gas: 359810)
[PASS] test_add_revertsWith_InsufficientTransferred() (gas: 64480)
[PASS] test_add_revertsWith_InvalidAmount() (gas: 13619)
[PASS] test_add_revertsWith_InvalidShares() (gas: 222924)
[PASS] test_add_revertsWith_SharesDowncastOverflow() (gas: 224170)
[PASS] test_add_revertsWith_SpokeNotActive() (gas: 99533)
[PASS] test_add_revertsWith_SpokePaused() (gas: 99540)
[PASS] test_add_single_asset() (gas: 329572)
Logs:
  Bound result 2
  Bound result 100000000000000000000

[PASS] test_add_with_increased_index() (gas: 300274)
[PASS] test_add_with_increased_index_with_premium() (gas: 678484)
Suite result: ok. 19 passed; 0 failed; 0 skipped; finished in 265.29s (302.75s CPU time)

Ran 14 tests for tests/unit/Spoke/Spoke.Withdraw.t.sol:SpokeWithdrawTest
[PASS] test_fuzz_withdraw_effect_on_ex_rates(uint256,uint256) (runs: 5000, μ: 724709, ~: 726745)
[PASS] test_withdraw_all_liquidity() (gas: 237344)
[PASS] test_withdraw_all_liquidity_with_interest_no_premium() (gas: 792792)
[PASS] test_withdraw_all_liquidity_with_interest_with_premium() (gas: 799421)
[PASS] test_withdraw_fuzz_all_elapsed_with_interest(uint256,uint256,uint40) (runs: 5000, μ: 658053, ~: 657944)
[PASS] test_withdraw_fuzz_all_greater_than_supplied(uint256) (runs: 5000, μ: 240366, ~: 240163)
[PASS] test_withdraw_fuzz_all_liquidity_with_interest_no_premium((uint256,uint256,uint256,uint256,uint256)) (runs: 5000, μ: 852189, ~: 852645)
[PASS] test_withdraw_fuzz_all_liquidity_with_interest_with_premium((uint256,uint256,uint256,uint256,uint256)) (runs: 5000, μ: 863558, ~: 863695)
[PASS] test_withdraw_fuzz_all_with_interest(uint256,uint256) (runs: 5000, μ: 669335, ~: 669325)
[PASS] test_withdraw_fuzz_suppliedAmount(uint256) (runs: 5000, μ: 240279, ~: 240076)
[PASS] test_withdraw_max_greater_than_supplied() (gas: 220868)
[PASS] test_withdraw_revertsWith_ReentrancyGuardReentrantCall_hubRefreshPremium() (gas: 652161)
[PASS] test_withdraw_revertsWith_ReentrancyGuardReentrantCall_hubRemove() (gas: 401883)
[PASS] test_withdraw_same_block() (gas: 242616)
Suite result: ok. 14 passed; 0 failed; 0 skipped; finished in 74.55s (125.19s CPU time)

Ran 49 tests for tests/unit/SpokeConfigurator.t.sol:SpokeConfiguratorTest
[PASS] test_addCollateralFactor() (gas: 113402)
[PASS] test_addCollateralFactor_revertsWith_OwnableUnauthorizedAccount() (gas: 17832)
[PASS] test_addDynamicReserveConfig() (gas: 95409)
[PASS] test_addDynamicReserveConfig_revertsWith_OwnableUnauthorizedAccount() (gas: 18103)
[PASS] test_addLiquidationBonus_revertsWith_OwnableUnauthorizedAccount() (gas: 17863)
[PASS] test_addLiquidationFee() (gas: 113380)
[PASS] test_addLiquidationFee_revertsWith_OwnableUnauthorizedAccount() (gas: 17778)
[PASS] test_addMaxLiquidationBonus() (gas: 113439)
[PASS] test_addReserve() (gas: 441929)
[PASS] test_addReserve_revertsWith_MaximumReservesReached() (gas: 273165)
[PASS] test_addReserve_revertsWith_OwnableUnauthorizedAccount() (gas: 18874)
[PASS] test_freezeAllReserves() (gas: 200066)
[PASS] test_freezeAllReserves_revertsWith_OwnableUnauthorizedAccount() (gas: 15611)
[PASS] test_pauseAllReserves() (gas: 199968)
[PASS] test_pauseAllReserves_revertsWith_OwnableUnauthorizedAccount() (gas: 15568)
[PASS] test_updateBorrowable() (gas: 93707)
[PASS] test_updateBorrowable_revertsWith_OwnableUnauthorizedAccount() (gas: 17770)
[PASS] test_updateCollateralFactor() (gas: 69696)
[PASS] test_updateCollateralFactor_revertsWith_OwnableUnauthorizedAccount() (gas: 17910)
[PASS] test_updateCollateralRisk() (gas: 69524)
[PASS] test_updateCollateralRisk_revertsWith_OwnableUnauthorizedAccount() (gas: 17810)
[PASS] test_updateDynamicReserveConfig() (gas: 180474)
[PASS] test_updateDynamicReserveConfig_revertsWith_OwnableUnauthorizedAccount() (gas: 18170)
[PASS] test_updateFrozen() (gas: 96650)
[PASS] test_updateFrozen_revertsWith_OwnableUnauthorizedAccount() (gas: 17858)
[PASS] test_updateHealthFactorForMaxBonus() (gas: 59149)
[PASS] test_updateHealthFactorForMaxBonus_revertsWith_OwnableUnauthorizedAccount() (gas: 15645)
[PASS] test_updateLiquidatable() (gas: 93798)
[PASS] test_updateLiquidatable_revertsWith_OwnableUnauthorizedAccount() (gas: 17836)
[PASS] test_updateLiquidationBonusFactor() (gas: 62010)
[PASS] test_updateLiquidationBonusFactor_revertsWith_OwnableUnauthorizedAccount() (gas: 15601)
[PASS] test_updateLiquidationConfig() (gas: 56821)
[PASS] test_updateLiquidationConfig_revertsWith_OwnableUnauthorizedAccount() (gas: 15904)
[PASS] test_updateLiquidationFee() (gas: 69737)
[PASS] test_updateLiquidationFee_revertsWith_OwnableUnauthorizedAccount() (gas: 17890)
[PASS] test_updateLiquidationTargetHealthFactor() (gas: 61937)
[PASS] test_updateLiquidationTargetHealthFactor_revertsWith_OwnableUnauthorizedAccount() (gas: 15669)
[PASS] test_updateMaxLiquidationBonus() (gas: 69714)
[PASS] test_updateMaxLiquidationBonus_revertsWith_OwnableUnauthorizedAccount() (gas: 17847)
[PASS] test_updateMaxReserves() (gas: 42285)
[PASS] test_updateMaxReserves_revertsWith_OwnableUnauthorizedAccount() (gas: 15593)
[PASS] test_updatePaused() (gas: 96521)
[PASS] test_updatePaused_revertsWith_OwnableUnauthorizedAccount() (gas: 17835)
[PASS] test_updatePositionManager() (gas: 62474)
[PASS] test_updatePositionManager_revertsWith_OwnableUnauthorizedAccount() (gas: 15742)
[PASS] test_updateReceiveSharesEnabled() (gas: 93717)
[PASS] test_updateReceiveSharesEnabled_revertsWith_OwnableUnauthorizedAccount() (gas: 17812)
[PASS] test_updateReservePriceSource() (gas: 271369)
[PASS] test_updateReservePriceSource_revertsWith_OwnableUnauthorizedAccount() (gas: 17812)
Suite result: ok. 49 passed; 0 failed; 0 skipped; finished in 34.42ms (13.32ms CPU time)

Ran 24 tests for tests/unit/Spoke/Spoke.Config.t.sol:SpokeConfigTest
[PASS] test_addReserve() (gas: 418784)
[PASS] test_addReserve_fuzz_revertsWith_AssetNotListed() (gas: 285800)
[PASS] test_addReserve_revertsWith_InvalidAddress_hub() (gas: 6435179)
[PASS] test_addReserve_revertsWith_InvalidAddress_oracle() (gas: 6493380)
[PASS] test_addReserve_revertsWith_InvalidAssetId() (gas: 32930)
[PASS] test_addReserve_revertsWith_ReserveExists() (gas: 397633)
[PASS] test_spoke_deploy() (gas: 5006135)
[PASS] test_spoke_deploy_reverts_on_InvalidConstructorInput() (gas: 1522785)
[PASS] test_spoke_deploy_reverts_on_InvalidOracleDecimals() (gas: 1525029)
[PASS] test_updateLiquidationConfig_fuzz_liqBonusConfig((uint128,uint64,uint16)) (runs: 5000, μ: 52865, ~: 52931)
[PASS] test_updateLiquidationConfig_fuzz_revertsWith_InvalidLiquidationConfig_healthFactorForMaxBonus((uint128,uint64,uint16)) (runs: 5000, μ: 36865, ~: 37115)
[PASS] test_updateLiquidationConfig_fuzz_revertsWith_InvalidLiquidationConfig_liquidationBonusFactor((uint128,uint64,uint16)) (runs: 5000, μ: 36663, ~: 36418)
[PASS] test_updateLiquidationConfig_fuzz_targetHealthFactor(uint128) (runs: 5000, μ: 46880, ~: 47183)
[PASS] test_updateLiquidationConfig_liqBonusConfig() (gas: 51951)
Logs:
  Bound result 900000000000000000
  Bound result 1000
  Bound result 1000000000000000000

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

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

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

[PASS] test_updateReserveConfig() (gas: 55923)
[PASS] test_updateReserveConfig_fuzz((uint24,bool,bool,bool,bool,bool)) (runs: 5000, μ: 57006, ~: 56835)
[PASS] test_updateReserveConfig_revertsWith_InvalidCollateralRisk() (gas: 40298)
[PASS] test_updateReserveConfig_revertsWith_ReserveNotListed() (gas: 36808)
[PASS] test_updateReservePriceSource() (gas: 261406)
[PASS] test_updateReservePriceSource_revertsWith_AccessManagedUnauthorized(address) (runs: 5000, μ: 30987, ~: 30987)
[PASS] test_updateReservePriceSource_revertsWith_ReserveNotListed() (gas: 34767)
Suite result: ok. 24 passed; 0 failed; 0 skipped; finished in 4.03s (4.00s CPU time)

Ran 10 tests for tests/unit/Spoke/Spoke.DynamicConfig.Triggers.t.sol:SpokeDynamicConfigTriggersTest
[PASS] test_borrow_triggers_dynamicConfigUpdate() (gas: 1323395)
[PASS] test_liquidate_does_not_trigger_dynamicConfigUpdate() (gas: 1606650)
[PASS] test_repay_does_not_trigger_dynamicConfigUpdate() (gas: 895783)
[PASS] test_supply_does_not_trigger_dynamicConfigUpdate() (gas: 1081513)
[PASS] test_updateUserDynamicConfig_doesHFCheck() (gas: 785179)
[PASS] test_updateUserDynamicConfig_reverts_when_not_authorized(address) (runs: 5000, μ: 1251853, ~: 1251853)
[PASS] test_updateUserDynamicConfig_triggers_dynamicConfigUpdate() (gas: 715461)
[PASS] test_updateUserDynamicConfig_updatesRP() (gas: 1282904)
[PASS] test_usingAsCollateral_triggers_dynamicConfigUpdate() (gas: 1351925)
[PASS] test_withdraw_triggers_dynamicConfigUpdate() (gas: 1361352)
Suite result: ok. 10 passed; 0 failed; 0 skipped; finished in 27.68s (27.65s CPU time)

Ran 8 tests for tests/unit/UnitPriceFeed.t.sol:UnitPriceFeedTest
[PASS] testDECIMALS() (gas: 8305)
[PASS] test_constructor_revertsWith_Uint8Overflow() (gas: 37603)
[PASS] test_description() (gas: 11865)
[PASS] test_fuzz_latestRoundData(uint80) (runs: 5000, μ: 11105, ~: 11105)
[PASS] test_fuzz_latestRoundData_DifferentDecimals(uint8) (runs: 5000, μ: 225183, ~: 225416)
[PASS] test_getRoundData() (gas: 12402)
[PASS] test_getRoundData_futureRound() (gas: 12325)
[PASS] test_version() (gas: 8261)
Suite result: ok. 8 passed; 0 failed; 0 skipped; finished in 520.02ms (512.25ms CPU time)

Ran 17 tests for tests/unit/Spoke/TreasurySpoke.t.sol:TreasurySpokeTest
[PASS] test_borrow_revertsWith_UnsupportedAction() (gas: 9654)
[PASS] test_deploy_reverts_on_invalid_params() (gas: 97401)
[PASS] test_getters() (gas: 740872)
[PASS] test_initial_state() (gas: 167242)
[PASS] test_liquidationCall_revertsWith_UnsupportedAction() (gas: 10474)
[PASS] test_repay_revertsWith_UnsupportedAction() (gas: 9656)
[PASS] test_supply(uint256) (runs: 5000, μ: 124669, ~: 124458)
[PASS] test_supply_revertsWith_Unauthorized(address) (runs: 5000, μ: 16113, ~: 16113)
[PASS] test_transfer_fuzz(address,uint256,uint256) (runs: 5000, μ: 100200, ~: 101179)
[PASS] test_transfer_revertsWith_ERC20InsufficientBalance(uint256) (runs: 5000, μ: 604008, ~: 604008)
[PASS] test_transfer_revertsWith_Unauthorized(address) (runs: 5000, μ: 14826, ~: 14826)
[PASS] test_withdraw_fuzz_amount_feesOnly(uint256) (runs: 5000, μ: 787733, ~: 787445)
[PASS] test_withdraw_fuzz_amount_interestAndFees(uint256) (runs: 5000, μ: 774883, ~: 774700)
[PASS] test_withdraw_fuzz_amount_interestOnly(uint256) (runs: 5000, μ: 807639, ~: 807343)
[PASS] test_withdraw_fuzz_maxLiquidityFee(uint256,uint256,uint256) (runs: 5000, μ: 848362, ~: 848482)
[PASS] test_withdraw_maxLiquidityFee() (gas: 849216)
Logs:
  Bound result 1000000000000000000000
  Bound result 29376000
  Bound result 2

[PASS] test_withdraw_revertsWith_Unauthorized(address) (runs: 5000, μ: 16476, ~: 16476)
Suite result: ok. 17 passed; 0 failed; 0 skipped; finished in 54.96s (108.28s CPU time)

Ran 21 tests for tests/unit/Spoke/Spoke.DynamicConfig.t.sol:SpokeDynamicConfigTest
[PASS] test_addDynamicReserveConfig() (gas: 79122)
[PASS] test_addDynamicReserveConfig_fuzz_revertsWith_InvalidCollateralFactorAndMaxLiquidationBonus_incompatible(uint16,uint32) (runs: 5000, μ: 46249, ~: 46424)
[PASS] test_addDynamicReserveConfig_once() (gas: 507245)
[PASS] test_addDynamicReserveConfig_revertsWith_AccessManagedUnauthorized(address) (runs: 5000, μ: 43298, ~: 43298)
[PASS] test_addDynamicReserveConfig_revertsWith_InvalidCollateralFactorAndMaxLiquidationBonus_collateralFactor() (gas: 57244)
[PASS] test_addDynamicReserveConfig_revertsWith_InvalidCollateralFactorAndMaxLiquidationBonus_liquidationBonus() (gas: 40400)
[PASS] test_addDynamicReserveConfig_revertsWith_InvalidLiquidationFee() (gas: 40918)
[PASS] test_addDynamicReserveConfig_revertsWith_MaximumDynamicConfigKeyReached() (gas: 43454)
[PASS] test_addDynamicReserveConfig_revertsWith_ReserveNotListed() (gas: 28270)
[PASS] test_fuzz_addDynamicReserveConfig_spaced_dup_updates(bytes32) (runs: 5000, μ: 138686, ~: 138686)
[PASS] test_fuzz_addDynamicReserveConfig_trailing_order(bytes32) (runs: 5000, μ: 132988, ~: 132988)
[PASS] test_offboardReserve_existing_borrows_remain_unaffected() (gas: 1124595)
[PASS] test_updateDynamicReserveConfig() (gas: 1713825)
[PASS] test_updateDynamicReserveConfig_fuzz_revertsWith_InvalidCollateralFactorAndMaxLiquidationBonus(uint16,uint32) (runs: 5000, μ: 56733, ~: 56908)
[PASS] test_updateDynamicReserveConfig_revertsWith_AccessManagedUnauthorized(address) (runs: 5000, μ: 43322, ~: 43322)
[PASS] test_updateDynamicReserveConfig_revertsWith_ConfigKeyUninitialized() (gas: 48922)
[PASS] test_updateDynamicReserveConfig_revertsWith_InvalidCollateralFactor() (gas: 49933)
[PASS] test_updateDynamicReserveConfig_revertsWith_InvalidCollateralFactorAndMaxLiquidationBonus_collateralFactor() (gas: 50652)
[PASS] test_updateDynamicReserveConfig_revertsWith_InvalidCollateralFactorAndMaxLiquidationBonus_liquidationBonus() (gas: 50817)
[PASS] test_updateDynamicReserveConfig_revertsWith_InvalidLiquidationFee() (gas: 51377)
[PASS] test_updateDynamicReserveConfig_revertsWith_ReserveNotListed() (gas: 28599)
Suite result: ok. 21 passed; 0 failed; 0 skipped; finished in 8.80s (8.77s CPU time)

Ran 5 tests for tests/gas/Spoke.Getters.gas.t.sol:SpokeGetters_Gas_Tests
[PASS] test_getUserAccountData() (gas: 23499)
[PASS] test_getUserAccountData_oneSupplies() (gas: 283217)
[PASS] test_getUserAccountData_twoSupplies() (gas: 517791)
[PASS] test_getUserAccountData_twoSupplies_oneBorrows() (gas: 1037971)
[PASS] test_getUserAccountData_twoSupplies_twoBorrows() (gas: 1595494)
Suite result: ok. 5 passed; 0 failed; 0 skipped; finished in 41.68ms (4.33ms CPU time)

Ran 15 tests for tests/unit/WadRayMath.t.sol:WadRayMathDifferentialTests
[PASS] test_bpsToRay_fuzz(uint256) (runs: 5000, μ: 11775, ~: 12392)
[PASS] test_bpsToWad_fuzz(uint256) (runs: 5000, μ: 12030, ~: 12488)
[PASS] test_constants() (gas: 11505)
[PASS] test_fromRayUp_fuzz(uint256) (runs: 5000, μ: 11111, ~: 11138)
[PASS] test_fromWadDown_fuzz(uint256) (runs: 5000, μ: 9378, ~: 9378)
[PASS] test_fuzz_rayDiv(uint256,uint256) (runs: 5000, μ: 12477, ~: 12851)
[PASS] test_fuzz_rayMul(uint256,uint256) (runs: 5000, μ: 11627, ~: 12154)
[PASS] test_fuzz_wadDiv(uint256,uint256) (runs: 5000, μ: 12675, ~: 12983)
[PASS] test_fuzz_wadMul(uint256,uint256) (runs: 5000, μ: 11631, ~: 12177)
[PASS] test_rayDiv() (gas: 39637)
[PASS] test_rayMul() (gas: 28583)
[PASS] test_toRay_fuzz(uint256) (runs: 5000, μ: 11673, ~: 12251)
[PASS] test_toWad_fuzz(uint256) (runs: 5000, μ: 11918, ~: 12350)
[PASS] test_wadDiv() (gas: 40033)
[PASS] test_wadMul() (gas: 28400)
Suite result: ok. 15 passed; 0 failed; 0 skipped; finished in 1.95s (1.95s CPU time)

Ran 12 tests for tests/unit/libraries/UserPositionDebt.t.sol:UserPositionDebtTest
[PASS] test_applyPremiumDelta() (gas: 26057)
[PASS] test_calculatePremiumDelta() (gas: 17570)
[PASS] test_calculatePremiumRay() (gas: 19396)
[PASS] test_calculateRestoreAmount() (gas: 24248)
[PASS] test_fuzz_applyPremiumDelta((int256,int256,uint256)) (runs: 5000, μ: 34024, ~: 34090)
[PASS] test_fuzz_calculatePremiumDelta((uint256,uint256,int256,uint256,uint256,uint256,uint256)) (runs: 5000, μ: 48932, ~: 49089)
[PASS] test_fuzz_calculatePremiumRay(uint256,int256,uint256) (runs: 5000, μ: 33237, ~: 33225)
[PASS] test_fuzz_calculateRestoreAmount(uint256,uint256,int256,uint256,uint256) (runs: 5000, μ: 42419, ~: 42406)
[PASS] test_fuzz_getUserDebt_DrawnIndex(uint256,uint256,int256,uint256) (runs: 5000, μ: 39484, ~: 39482)
[PASS] test_fuzz_getUserDebt_HubAndAssetId(uint256,uint256,int256,uint256) (runs: 5000, μ: 45422, ~: 45420)
[PASS] test_getUserDebt_DrawnIndex() (gas: 23463)
[PASS] test_getUserDebt_HubAndAssetId() (gas: 30124)
Suite result: ok. 12 passed; 0 failed; 0 skipped; finished in 6.29s (9.04s CPU time)

Ran 6 tests for tests/unit/Hub/HubAccrueInterest.t.sol:HubAccrueInterestTest
[PASS] test_accrueInterest_NoActionTaken() (gas: 42540)
[PASS] test_accrueInterest_NoInterest_NoDebt(uint40) (runs: 5000, μ: 389293, ~: 389195)
[PASS] test_accrueInterest_NoInterest_OnlyAdd(uint40) (runs: 5000, μ: 206052, ~: 205992)
[PASS] test_accrueInterest_fuzz_BorrowAmountAndElapsed(uint256,uint40) (runs: 5000, μ: 270275, ~: 270173)
[PASS] test_accrueInterest_fuzz_BorrowAmountRateAndElapsed(uint256,uint256,uint40) (runs: 5000, μ: 390246, ~: 390003)
[PASS] test_accrueInterest_fuzz_BorrowAndWait(uint40) (runs: 5000, μ: 268999, ~: 268901)
Suite result: ok. 6 passed; 0 failed; 0 skipped; finished in 24.73s (24.71s CPU time)

Ran 6 tests for tests/unit/Spoke/Spoke.Getters.t.sol:SpokeGettersTest
[PASS] test_getLiquidationBonus_configured() (gas: 95206)
Logs:
  Bound result 2
  Bound result 1000000000000000000
  Bound result 4000
  Bound result 900000000000000000

[PASS] test_getLiquidationBonus_fuzz_configured(uint256,uint256,uint16,uint64) (runs: 5000, μ: 94089, ~: 94380)
[PASS] test_getLiquidationBonus_fuzz_notConfigured(uint256,uint256) (runs: 5000, μ: 71995, ~: 72222)
[PASS] test_getLiquidationBonus_notConfigured() (gas: 73210)
Logs:
  Bound result 2
  Bound result 1000000000000000000

[PASS] test_premiumRayGetters() (gas: 1537277)
[PASS] test_protocol_getters() (gas: 287172)
Suite result: ok. 6 passed; 0 failed; 0 skipped; finished in 2.21s (2.19s CPU time)

Ran 4 tests for tests/unit/Spoke/Liquidations/Spoke.LiquidationCall.Dust.t.sol:SpokeLiquidationCallDustTest
[PASS] test_collateralDust_min_debtToTarget() (gas: 9326700)
[PASS] test_debtToCover_exceeds_collateralValue() (gas: 9319169)
[PASS] test_dustColl_allowed() (gas: 9184924)
[PASS] test_dustDebt_allowed() (gas: 9314204)
Suite result: ok. 4 passed; 0 failed; 0 skipped; finished in 48.22ms (20.01ms 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, μ: 1038848, ~: 1039465)
[PASS] test_addAsset_fuzz_revertsWith_InvalidAssetDecimals(bool,address,uint8,address,uint256,address) (runs: 5000, μ: 56184, ~: 56171)
[PASS] test_addAsset_fuzz_revertsWith_OwnableUnauthorizedAccount(address) (runs: 5000, μ: 30615, ~: 30615)
[PASS] test_addAsset_revertsWith_InvalidAddress_irStrategy() (gas: 49370)
[PASS] test_addAsset_revertsWith_InvalidAddress_underlying() (gas: 49291)
[PASS] test_addAsset_revertsWith_InvalidLiquidityFee() (gas: 941193)
[PASS] test_addAsset_reverts_invalidIrData() (gas: 92849)
[PASS] test_addSpoke() (gas: 126565)
[PASS] test_addSpokeToAssets() (gas: 223560)
[PASS] test_addSpokeToAssets_revertsWith_MismatchedConfigs() (gas: 24589)
[PASS] test_addSpokeToAssets_revertsWith_OwnableUnauthorizedAccount() (gas: 16865)
[PASS] test_addSpoke_revertsWith_OwnableUnauthorizedAccount() (gas: 16642)
[PASS] test_deactivateAsset() (gas: 166873)
[PASS] test_deactivateAsset_revertsWith_OwnableUnauthorizedAccount() (gas: 17739)
[PASS] test_deactivateSpoke() (gas: 165682)
[PASS] test_deactivateSpoke_revertsWith_OwnableUnauthorizedAccount() (gas: 17807)
[PASS] test_freezeAsset() (gas: 241108)
[PASS] test_freezeAsset_revertsWith_OwnableUnauthorizedAccount() (gas: 17780)
[PASS] test_freezeSpoke() (gas: 258574)
[PASS] test_freezeSpoke_revertsWith_OwnableUnauthorizedAccount() (gas: 17763)
[PASS] test_pauseAsset() (gas: 166884)
[PASS] test_pauseAsset_revertsWith_OwnableUnauthorizedAccount() (gas: 17737)
[PASS] test_pauseSpoke() (gas: 165650)
[PASS] test_pauseSpoke_revertsWith_OwnableUnauthorizedAccount() (gas: 17806)
[PASS] test_updateFeeConfig_Scenario() (gas: 336989)
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, μ: 185792, ~: 186099)
[PASS] test_updateFeeConfig_fuzz_revertsWith_OwnableUnauthorizedAccount(address) (runs: 5000, μ: 17321, ~: 17321)
[PASS] test_updateFeeConfig_revertsWith_InvalidAddress_spoke() (gas: 50452)
[PASS] test_updateFeeConfig_revertsWith_InvalidLiquidityFee() (gas: 53617)
[PASS] test_updateFeeReceiver_Scenario() (gas: 214826)
[PASS] test_updateFeeReceiver_WithdrawFromOldSpoke() (gas: 1198275)
[PASS] test_updateFeeReceiver_correctAccruals() (gas: 1234785)
[PASS] test_updateFeeReceiver_fuzz(address) (runs: 5000, μ: 179343, ~: 179361)
[PASS] test_updateFeeReceiver_fuzz_revertsWith_OwnableUnauthorizedAccount(address) (runs: 5000, μ: 16918, ~: 16918)
[PASS] test_updateFeeReceiver_revertsWith_InvalidAddress_spoke() (gas: 55064)
[PASS] test_updateFeeReceiver_revertsWith_SpokeAlreadyListed() (gas: 85005)
[PASS] test_updateInterestRateData() (...*[Comment body truncated]*

/// @notice Minimal interface for protocol actions involving signed intents.
interface ISignatureGateway is IGatewayBase, IIntentConsumer, IMulticall {
/// @notice Action type enumeration for batch operations.
enum ActionType {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

@DhairyaSethi DhairyaSethi Jan 20, 2026

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

yes definitely next on the list to optimise decoding; im still thinking through the types given the idea that user should see exactly what they're signing, the supplemented data can be as compressed as needed

im also thinking the final loop for executing actions can be a multicall lol

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

not 100% sure for the multicall xD but yes on the rest !

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

i think we should

  • have non withSig method for this to enable cross spoke communication?
  • do something where this gateway can skim tokens as well bc rn to withdraw from one spoke & deposit to another user has to receive tokens to themselves and have allowance to pull tokens to supply to another

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

im now thinking the calldata opt really doesnt help us because we anyway need to lift the vars in memory to build the struct hash

Comment thread src/position-manager/interfaces/ISignatureGateway.sol
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants