Skip to content

feat : config Payload for Governance V3#1234

Open
Kogaroshi wants to merge 26 commits intomainfrom
feat/config-engine-payload
Open

feat : config Payload for Governance V3#1234
Kogaroshi wants to merge 26 commits intomainfrom
feat/config-engine-payload

Conversation

@Kogaroshi
Copy link
Contributor

Add a new Config Engine & Payload to be compatible with Governance V3 via aave-helpers.

To be updated to have a more granular list or Roles & config functions based on #1047


import {IAaveV4ConfigEngine} from 'src/config-engine/interfaces/IAaveV4ConfigEngine.sol';
import {IAccessManager} from 'src/dependencies/openzeppelin/IAccessManager.sol';
import {Roles} from 'src/libraries/types/Roles.sol';
Copy link
Member

Choose a reason for hiding this comment

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

these roles are not final atm unfortunately, we need to decide a strategy asap bc one selector can only belong to one role

Copy link
Contributor

Choose a reason for hiding this comment

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

i think something as granular as possible helps that ie minimize the number of selectors per role. That allows us more flexibility later, if we have stewards that only need a small number of selectors. So we can build complex roles out of a combination of granular roles.

This will be better than grouping too many selectors together into a single role, and later having to redefine them and needing to update all existing admins.

Copy link
Member

@DhairyaSethi DhairyaSethi Feb 28, 2026

Choose a reason for hiding this comment

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

So we can build complex roles out of a combination of granular roles.

how? we cannot group roles together, right? or are you just saying the actor needing this will just be assigned all roles or smth

Copy link
Contributor Author

Choose a reason for hiding this comment

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

currently decided to remove the Roles from that logic, as it was increase a lot the Engine & Payload codesize. Instead we have just the generic methods, and we can have an helper contract to generate the IAaveV4ConfigEngine.RoleMembership & such with preset roleIds based on our defined Role list.

Copy link
Contributor

Choose a reason for hiding this comment

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

the actor needing this will just be assigned all roles or smth

yes

function executeHubAssetListings(IAaveV4ConfigEngine.AssetListing[] calldata listings) external {
uint256 length = listings.length;
for (uint256 i; i < length; ++i) {
if (listings[i].decimals == 0) {
Copy link
Member

Choose a reason for hiding this comment

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

maybe we do this through an engine flag? dynamic/static maybe

@github-actions
Copy link

github-actions bot commented Feb 27, 2026

Forge Build Sizes

Contract Runtime Size (B) Initcode Size (B) Runtime Margin (B) Initcode Margin (B)
AaveV4ConfigEngine 9,066 9,094 15,510 40,058
AaveV4PayloadSize 11,229 11,402 13,347 37,750
AccessManagerEngine 4,165 4,217 20,411 44,935
EngineFlags 44 94 24,532 49,058
EngineFlagsHarness 339 367 24,237 48,785
HubEngine 13,109 13,161 11,467 35,991
MinimalAaveV4Payload 11,229 11,402 13,347 37,750
PositionManagerEngine 1,021 1,073 23,555 48,079
SpokeEngine 8,730 8,782 15,846 40,370
TokenizationSpokeDeployer 22,822 22,874 1,754 26,278
🔕 Unchanged
Contract Runtime Size (B) Initcode Size (B) Runtime Margin (B) Initcode Margin (B)
AaveOracle 2,396 2,529 22,180 46,623
AccessManager 12,985 14,210 11,591 34,942
AccessManagerEnumerable 16,917 18,756 7,659 30,396
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,626 2,811 21,950 46,341
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
ConfigPermissionsMap 44 94 24,532 49,058
ConfigPermissionsWrapper 1,001 1,029 23,575 48,123
ConfigPositionManager 12,937 13,491 11,639 35,661
Constants 499 551 24,077 48,601
Create2Utils 134 184 24,442 48,968
DeployUtils 44 94 24,532 49,058
DeployWrapper 3,330 3,358 21,246 45,794
ECDSA 44 94 24,532 49,058
ECDSA.spoke 16 44 24,560 49,108
EIP712Hash (src/position-manager/libraries/EIP712Hash.sol) 771 823 23,805 48,329
EIP712Hash (src/spoke/libraries/EIP712Hash.sol) 441 493 24,135 48,659
EIP712Hash.spoke 491 521 24,085 48,631
EIP712Types 44 94 24,532 49,058
ERC1967Proxy 135 891 24,441 48,261
ERC1967Utils 44 94 24,532 49,058
EnumerableSet 44 94 24,532 49,058
EnumerableSet.hub 16 44 24,560 49,108
Errors 44 94 24,532 49,058
ExtSloadWrapper 394 422 24,182 48,730
GiverPositionManager 6,614 6,889 17,962 42,263
Hashes 44 94 24,532 49,058
Hub 23,538 23,735 1,038 25,417
HubConfigurator 13,833 14,067 10,743 35,085
KeyValueList 44 94 24,532 49,058
KeyValueList.spoke 16 44 24,560 49,108
KeyValueListWrapper 957 985 23,619 48,167
LibBit 44 94 24,532 49,058
LibBit.spoke 16 44 24,560 49,108
LiquidationLogic 12,519 12,571 12,057 36,581
LiquidationLogic.spoke 9,835 9,867 14,741 39,285
LiquidationLogicWrapper 18,611 18,785 5,965 30,367
LowLevelCall 44 94 24,532 49,058
Math 44 94 24,532 49,058
Math.hub 16 44 24,560 49,108
Math.spoke 16 44 24,560 49,108
MathUtils 44 94 24,532 49,058
MathUtils.hub 16 44 24,560 49,108
MathUtils.spoke 16 44 24,560 49,108
MockERC1271Wallet 828 962 23,748 48,190
MockERC20 2,540 3,006 22,036 46,146
MockNoncesKeyed 858 886 23,718 48,266
MockPriceFeed 538 1,187 24,038 47,965
MockReentrantCaller 882 1,083 23,694 48,069
MockSkimSpoke 1,116 1,275 23,460 47,877
NativeTokenGateway 8,685 9,102 15,891 40,050
NoncesKeyed 644 672 23,932 48,480
NoncesKeyed.spoke 387 413 24,189 48,739
Panic 44 94 24,532 49,058
Panic.hub 16 44 24,560 49,108
Panic.spoke 16 44 24,560 49,108
PercentageMath 44 94 24,532 49,058
PercentageMath.hub 16 44 24,560 49,108
PercentageMath.spoke 16 44 24,560 49,108
PercentageMathWrapper 632 660 23,944 48,492
PositionManagerBaseWrapper 4,998 5,273 19,578 43,879
PositionManagerNoMulticall 4,934 5,209 19,642 43,943
PositionStatusMap 44 94 24,532 49,058
PositionStatusMap.spoke 16 44 24,560 49,108
PositionStatusMapWrapper 3,341 3,369 21,235 45,783
Premium 44 94 24,532 49,058
Premium.hub 16 44 24,560 49,108
Premium.spoke 16 44 24,560 49,108
ProxyAdmin 1,320 1,556 23,256 47,596
RescuableWrapper 908 1,042 23,668 48,110
ReserveFlagsMap 44 94 24,532 49,058
ReserveFlagsMap.spoke 16 44 24,560 49,108
ReserveFlagsMapWrapper 928 956 23,648 48,196
Roles 218 269 24,358 48,883
SafeCast 44 94 24,532 49,058
SafeCast.hub 16 44 24,560 49,108
SafeCast.spoke 16 44 24,560 49,108
SafeERC20 44 94 24,532 49,058
SafeERC20.hub 16 44 24,560 49,108
SafeERC20.spoke 16 44 24,560 49,108
SharesMath 44 94 24,532 49,058
SharesMath.hub 16 44 24,560 49,108
SignatureChecker 44 94 24,532 49,058
SignatureChecker.spoke 16 44 24,560 49,108
SignatureGateway 12,107 12,648 12,469 36,504
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,825 12,059 12,751 37,093
SpokeInstance 24,291 25,098 285 24,054
SpokeUtils 96 146 24,480 49,006
SpokeUtils.spoke 71 99 24,505 49,053
SpokeUtilsWrapper 1,827 1,855 22,749 47,297
StorageSlot 44 94 24,532 49,058
StorageSlot.hub 16 44 24,560 49,108
StorageSlot.spoke 16 44 24,560 49,108
TakerPositionManager 10,996 11,550 13,580 37,602
TestnetERC20 3,649 4,525 20,927 44,627
Time 44 94 24,532 49,058
TokenizationSpokeInstance 13,627 14,953 10,949 34,199
TransientSlot 44 94 24,532 49,058
TransientSlot.spoke 16 44 24,560 49,108
TransparentUpgradeableProxy 1,419 4,078 23,157 45,074
TreasurySpokeInstance 4,004 4,218 20,572 44,934
UserPositionUtils 44 94 24,532 49,058
UserPositionUtils.spoke 16 44 24,560 49,108
UserPositionUtilsWrapper (tests/mocks/UserPositionDebtWrapper.sol) 3,263 3,291 21,313 45,861
UserPositionUtilsWrapper (tests/mocks/UserPositionUtilsWrapper.sol) 3,263 3,291 21,313 45,861
Utils 44 94 24,532 49,058
WETH9 2,148 2,614 22,428 46,538
WadRayMath 44 94 24,532 49,058
WadRayMath.hub 16 44 24,560 49,108
WadRayMath.spoke 16 44 24,560 49,108
WadRayMathWrapper 1,514 1,542 23,062 47,610

@github-actions
Copy link

github-actions bot commented Feb 27, 2026

♻️ Forge Gas Snapshots

🔕 Unchanged
Path Value
snapshots/ConfigPositionManager.Operations.json
renounceCanUpdateUserDynamicConfigPermission 27,748
renounceCanUpdateUserRiskPremiumPermission 27,682
renounceCanUpdateUsingAsCollateralPermission 27,705
renounceGlobalPermission 27,663
setCanSetUsingAsCollateralPermission 49,848
setCanUpdateUserDynamicConfigPermission 49,870
setCanUpdateUserRiskPremiumPermission 49,870
setGlobalPermission 49,822
setUsingAsCollateralOnBehalfOf 72,503
updateUserDynamicConfigOnBehalfOf 50,433
updateUserRiskPremiumOnBehalfOf 131,974
snapshots/GiverPositionManager.Operations.json
repayOnBehalfOf 167,904
supplyOnBehalfOf 136,911
snapshots/Hub.Operations.json
add 86,692
add: with transfer 107,989
draw 104,148
eliminateDeficit: full 72,579
eliminateDeficit: partial 82,184
mintFeeShares 82,741
payFee 70,805
refreshPremium 70,362
remove: full 75,596
remove: partial 80,734
reportDeficit 111,925
restore: full 76,552
restore: full - with transfer 169,161
restore: partial 85,262
restore: partial - with transfer 143,242
transferShares 69,619
snapshots/NativeTokenGateway.Operations.json
borrowNative 232,042
repayNative 166,511
supplyAsCollateralNative 160,195
supplyNative 135,794
withdrawNative: full 125,572
withdrawNative: partial 136,764
snapshots/PositionManagerBase.Operations.json
setSelfAsUserPositionManagerWithSig 75,029
snapshots/SignatureGateway.Operations.json
borrowWithSig 215,467
repayWithSig 186,703
setSelfAsUserPositionManagerWithSig 75,126
setUsingAsCollateralWithSig 85,380
supplyWithSig 151,980
updateUserDynamicConfigWithSig 63,113
updateUserRiskPremiumWithSig 61,995
withdrawWithSig 130,797
snapshots/Spoke.Getters.json
getUserAccountData: supplies: 0, borrows: 0 13,014
getUserAccountData: supplies: 1, borrows: 0 51,132
getUserAccountData: supplies: 2, borrows: 0 84,514
getUserAccountData: supplies: 2, borrows: 1 106,572
getUserAccountData: supplies: 2, borrows: 2 127,538
snapshots/Spoke.Operations.ZeroRiskPremium.json
borrow: first 193,708
borrow: second action, same reserve 173,574
liquidationCall (receiveShares): full 305,343
liquidationCall (receiveShares): partial 304,761
liquidationCall (reportDeficit): full 370,494
liquidationCall: full 322,971
liquidationCall: partial 322,389
permitReserve + repay (multicall) 164,565
permitReserve + supply (multicall) 146,745
permitReserve + supply + enable collateral (multicall) 161,196
repay: full 123,903
repay: partial 128,861
setUserPositionManagersWithSig: disable 46,772
setUserPositionManagersWithSig: enable 68,684
supply + enable collateral (multicall) 141,398
supply: 0 borrows, collateral disabled 122,835
supply: 0 borrows, collateral enabled 105,806
supply: second action, same reserve 105,735
updateUserDynamicConfig: 1 collateral 76,251
updateUserDynamicConfig: 2 collaterals 92,825
updateUserRiskPremium: 1 borrow 99,069
updateUserRiskPremium: 2 borrows 108,749
usingAsCollateral: 0 borrows, enable 59,616
usingAsCollateral: 1 borrow, disable 109,113
usingAsCollateral: 1 borrow, enable 42,504
usingAsCollateral: 2 borrows, disable 132,368
usingAsCollateral: 2 borrows, enable 42,516
withdraw: 0 borrows, full 129,650
withdraw: 0 borrows, partial 134,546
withdraw: 1 borrow, partial 163,306
withdraw: 2 borrows, partial 179,570
withdraw: non collateral 105,891
snapshots/Spoke.Operations.json
borrow: first 262,632
borrow: second action, same reserve 205,498
liquidationCall (receiveShares): full 337,376
liquidationCall (receiveShares): partial 336,794
liquidationCall (reportDeficit): full 362,694
liquidationCall: full 355,004
liquidationCall: partial 354,422
permitReserve + repay (multicall) 162,036
permitReserve + supply (multicall) 146,745
permitReserve + supply + enable collateral (multicall) 161,196
repay: full 117,982
repay: partial 137,340
setUserPositionManagersWithSig: disable 46,772
setUserPositionManagersWithSig: enable 68,684
supply + enable collateral (multicall) 141,398
supply: 0 borrows, collateral disabled 122,835
supply: 0 borrows, collateral enabled 105,806
supply: second action, same reserve 105,735
updateUserDynamicConfig: 1 collateral 76,251
updateUserDynamicConfig: 2 collaterals 92,825
updateUserRiskPremium: 1 borrow 152,417
updateUserRiskPremium: 2 borrows 202,668
usingAsCollateral: 0 borrows, enable 59,616
usingAsCollateral: 1 borrow, disable 162,458
usingAsCollateral: 1 borrow, enable 42,504
usingAsCollateral: 2 borrows, disable 234,283
usingAsCollateral: 2 borrows, enable 42,516
withdraw: 0 borrows, full 129,650
withdraw: 0 borrows, partial 134,546
withdraw: 1 borrow, partial 214,149
withdraw: 2 borrows, partial 262,020
withdraw: non collateral 105,891
snapshots/TakerPositionManager.Operations.json
approveBorrow 49,802
approveBorrowWithSig 65,684
approveWithdraw 49,833
approveWithdrawWithSig 65,660
borrowOnBehalfOf 312,136
renounceBorrowAllowance 27,924
renounceWithdrawAllowance 28,000
withdrawOnBehalfOf: full 120,697
withdrawOnBehalfOf: partial 130,671
snapshots/TokenizationSpoke.Operations.json
deposit 113,234
depositWithSig 124,138
mint 112,915
mintWithSig 123,782
permit 62,766
redeem: on behalf, full 90,886
redeem: on behalf, partial 113,607
redeem: self, full 88,874
redeem: self, partial 108,074
redeemWithSig 123,456
withdraw: on behalf, full 91,302
withdraw: on behalf, partial 114,127
withdraw: self, full 89,394
withdraw: self, partial 108,594
withdrawWithSig 123,987

@github-actions
Copy link

github-actions bot commented Feb 27, 2026

🌈 Test Results
No files changed, compilation skipped

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

Ran 4 tests for tests/unit/libraries/LiquidationLogic/LiquidationLogic.ExecuteLiquidation.t.sol:LiquidationLogicExecuteLiquidationTest
[PASS] test_executeLiquidation() (gas: 371989)
[PASS] test_executeLiquidation_revertsWith_InvalidDebtToCover() (gas: 81007)
[PASS] test_executeLiquidation_revertsWith_MustNotLeaveDust_Collateral() (gas: 144721)
[PASS] test_executeLiquidation_revertsWith_MustNotLeaveDust_Debt() (gas: 145273)
Suite result: ok. 4 passed; 0 failed; 0 skipped; finished in 33.52ms (1.54ms CPU time)

Ran 9 tests for tests/gas/Hub.Operations.gas.t.sol:HubOperations_Gas_Tests
[PASS] test_add() (gas: 270108)
[PASS] test_deficit() (gas: 1308440)
[PASS] test_draw() (gas: 418553)
[PASS] test_mintFeeShares() (gas: 499923)
[PASS] test_payFee_transferShares() (gas: 934789)
[PASS] test_refreshPremium() (gas: 636095)
[PASS] test_remove() (gas: 310664)
[PASS] test_restore() (gas: 877812)
[PASS] test_restore_with_transfer() (gas: 878477)
Suite result: ok. 9 passed; 0 failed; 0 skipped; finished in 66.69ms (7.23ms CPU time)

Ran 19 tests for tests/unit/AaveOracle.t.sol:AaveOracleTest
[PASS] test_constructor() (gas: 15306)
[PASS] test_decimals() (gas: 8313)
[PASS] test_fuzz_constructor(uint8) (runs: 5000, μ: 16712, ~: 17038)
Logs:
  Bound result 1

[PASS] test_getReservePrice() (gas: 46772)
[PASS] test_getReservePrice_revertsWith_InvalidPrice() (gas: 44558)
[PASS] test_getReservePrice_revertsWith_InvalidSource() (gas: 10876)
[PASS] test_getReservePrices() (gas: 76731)
[PASS] test_getReservePrices_revertsWith_InvalidSource() (gas: 48897)
[PASS] test_getReserveSource() (gas: 47161)
[PASS] test_setReserveSource() (gas: 44226)
[PASS] test_setReserveSource_revertsWith_InvalidPrice() (gas: 97405)
[PASS] test_setReserveSource_revertsWith_InvalidSource() (gas: 17138)
[PASS] test_setReserveSource_revertsWith_InvalidSourceDecimals() (gas: 16953)
[PASS] test_setReserveSource_revertsWith_OnlySpoke() (gas: 12996)
[PASS] test_setReserveSource_revertsWith_OracleMismatch() (gas: 5029298)
[PASS] test_setSpoke() (gas: 5057662)
[PASS] test_setSpoke_revertsWith_InvalidAddress() (gas: 10914)
[PASS] test_setSpoke_revertsWith_OnlyDeployer(address) (runs: 5000, μ: 13485, ~: 13485)
[PASS] test_setSpoke_revertsWith_SpokeAlreadySet() (gas: 15102)
Suite result: ok. 19 passed; 0 failed; 0 skipped; finished in 1.08s (1.05s CPU time)

Ran 22 tests for tests/config-engine/AaveV4Payload.EmptyReturns.t.sol:AaveV4PayloadEmptyReturnsTest
[PASS] test_accessManagerRoleMemberships_returnsEmpty() (gas: 8912)
[PASS] test_accessManagerRoleUpdates_returnsEmpty() (gas: 8929)
[PASS] test_accessManagerTargetAdminDelayUpdates_returnsEmpty() (gas: 8976)
[PASS] test_accessManagerTargetFunctionRoleUpdates_returnsEmpty() (gas: 8973)
[PASS] test_hubAssetCapsResets_returnsEmpty() (gas: 9003)
[PASS] test_hubAssetConfigUpdates_returnsEmpty() (gas: 8930)
[PASS] test_hubAssetDeactivations_returnsEmpty() (gas: 9003)
[PASS] test_hubAssetHalts_returnsEmpty() (gas: 8957)
[PASS] test_hubAssetListings_returnsEmpty() (gas: 8929)
[PASS] test_hubSpokeCapsResets_returnsEmpty() (gas: 8915)
[PASS] test_hubSpokeConfigUpdates_returnsEmpty() (gas: 8974)
[PASS] test_hubSpokeDeactivations_returnsEmpty() (gas: 8915)
[PASS] test_hubSpokeToAssetsAdditions_returnsEmpty() (gas: 9018)
[PASS] test_minimalPayload_execute_noReverts() (gas: 8182)
[PASS] test_positionManagerRoleRenouncements_returnsEmpty() (gas: 8955)
[PASS] test_positionManagerSpokeRegistrations_returnsEmpty() (gas: 8933)
[PASS] test_spokeDynamicReserveConfigAdditions_returnsEmpty() (gas: 8933)
[PASS] test_spokeDynamicReserveConfigUpdates_returnsEmpty() (gas: 8929)
[PASS] test_spokeLiquidationConfigUpdates_returnsEmpty() (gas: 8930)
[PASS] test_spokePositionManagerUpdates_returnsEmpty() (gas: 8974)
[PASS] test_spokeReserveConfigUpdates_returnsEmpty() (gas: 8976)
[PASS] test_spokeReserveListings_returnsEmpty() (gas: 8909)
Suite result: ok. 22 passed; 0 failed; 0 skipped; finished in 11.29ms (712.07µs CPU time)

Ran 3 tests for tests/unit/libraries/LiquidationLogic/LiquidationLogic.LiquidateCollateral.t.sol:LiquidationLogicLiquidateCollateralTest
[PASS] test_liquidateCollateral_fuzz(uint256,uint256,bool) (runs: 5000, μ: 204164, ~: 189010)
Logs:
  Bound result 101
  Bound result 69

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

Ran 4 tests for tests/unit/libraries/LiquidationLogic/LiquidationLogic.LiquidateDebt.t.sol:LiquidationLogicLiquidateDebtTest
[PASS] test_liquidateDebt_fuzz(uint256) (runs: 5000, μ: 228386, ~: 218588)
[PASS] test_liquidateDebt_revertsWith_ArithmeticUnderflow() (gas: 106091)
[PASS] test_liquidateDebt_revertsWith_InsufficientAllowance() (gas: 115525)
[PASS] test_liquidateDebt_revertsWith_InsufficientBalance() (gas: 177141)
Suite result: ok. 4 passed; 0 failed; 0 skipped; finished in 3.51s (3.47s CPU time)

Ran 4 tests for tests/unit/libraries/LiquidationLogic/LiquidationLogic.LiquidateUser.t.sol:LiquidationLogicLiquidateUserTest
[PASS] test_liquidateUser() (gas: 373076)
[PASS] test_liquidateUser_revertsWith_InvalidDebtToCover() (gas: 73786)
[PASS] test_liquidateUser_revertsWith_MustNotLeaveDust_Collateral() (gas: 141518)
[PASS] test_liquidateUser_revertsWith_MustNotLeaveDust_Debt() (gas: 146111)
Suite result: ok. 4 passed; 0 failed; 0 skipped; finished in 34.93ms (1.71ms CPU time)

Ran 43 tests for tests/config-engine/AaveV4Payload.t.sol:AaveV4PayloadTest
[PASS] test_configEngine_immutable() (gas: 10563)
[PASS] test_constructor_revertsOnZeroAddress() (gas: 45226)
[PASS] test_execute_accessManagerAction_delegatesCorrectly() (gas: 317870)
[PASS] test_execute_accessManagerRoleMemberships_revoke() (gas: 6981826)
[PASS] test_execute_accessManagerRoleUpdates() (gas: 619090)
[PASS] test_execute_accessManagerTargetAdminDelayUpdates() (gas: 260221)
[PASS] test_execute_accessManagerTargetFunctionRoleUpdates() (gas: 476982)
[PASS] test_execute_emptyArraysSkipped() (gas: 388413)
[PASS] test_execute_emptyPayload_noReverts() (gas: 147874)
[PASS] test_execute_hookOrdering() (gas: 149985)
[PASS] test_execute_hubAction_delegatesCorrectly() (gas: 385785)
[PASS] test_execute_hubAssetCapsResets() (gas: 386235)
[PASS] test_execute_hubAssetConfigUpdates_feeOnly() (gas: 562885)
[PASS] test_execute_hubAssetConfigUpdates_interestRateOnly() (gas: 456459)
[PASS] test_execute_hubAssetConfigUpdates_reinvestmentOnly() (gas: 468467)
[PASS] test_execute_hubAssetConfigUpdates_twoAssets_feeOnly() (gas: 726306)
[PASS] test_execute_hubAssetConfigUpdates_twoAssets_mixedFields() (gas: 730602)
[PASS] test_execute_hubAssetDeactivations() (gas: 7028902)
[PASS] test_execute_hubAssetHalts_multiElement() (gas: 576391)
[PASS] test_execute_hubAssetListings() (gas: 733836)
[PASS] test_execute_hubSpokeCapsResets() (gas: 367879)
[PASS] test_execute_hubSpokeConfigUpdates_capsOnly() (gas: 454986)
[PASS] test_execute_hubSpokeConfigUpdates_riskPremiumThresholdOnly() (gas: 455154)
[PASS] test_execute_hubSpokeConfigUpdates_statusOnly() (gas: 451331)
[PASS] test_execute_hubSpokeDeactivations() (gas: 367488)
[PASS] test_execute_hubSpokeToAssetsAdditions() (gas: 6398926)
[PASS] test_execute_multipleActions_allExecuted() (gas: 713935)
[PASS] test_execute_multipleActions_revertsIfOneInvalid() (gas: 428569)
[PASS] test_execute_positionManagerRoleRenouncements() (gas: 1609457)
[PASS] test_execute_positionManagerSpokeRegistrations() (gas: 256298)
[PASS] test_execute_revertsWith_UnderlyingAlreadyListed_propagatesFromEngine() (gas: 336694)
[PASS] test_execute_spokeAction_delegatesCorrectly() (gas: 313157)
[PASS] test_execute_spokeDynamicReserveConfigAdditions() (gas: 390209)
[PASS] test_execute_spokeDynamicReserveConfigUpdates() (gas: 421172)
[PASS] test_execute_spokeLiquidationConfigUpdates() (gas: 341503)
[PASS] test_execute_spokePositionManagerUpdates() (gas: 313114)
[PASS] test_execute_spokeReserveConfigUpdates() (gas: 548786)
[PASS] test_execute_spokeReserveListings() (gas: 929479)
[PASS] test_fuzz_execute_hubAssetConfigUpdates_feeOnly(uint256) (runs: 5000, μ: 474084, ~: 474796)
Logs:
  Bound result 4978

[PASS] test_fuzz_execute_hubSpokeConfigUpdates_capsOnly(uint256,uint256) (runs: 5000, μ: 459283, ~: 459965)
Logs:
  Bound result 521561012887
  Bound result 100

[PASS] test_fuzz_execute_spokeDynamicReserveConfigUpdates(uint256,uint256,uint256) (runs: 5000, μ: 427739, ~: 428363)
Logs:
  Bound result 7889
  Bound result 10659
  Bound result 5827

[PASS] test_fuzz_execute_spokeLiquidationConfigUpdates(uint256) (runs: 5000, μ: 347594, ~: 347749)
Logs:
  Bound result 340282366920938463462374610555812179593

[PASS] test_fuzz_execute_spokeReserveConfigUpdates(uint256) (runs: 5000, μ: 484723, ~: 485194)
Logs:
  Bound result 28010

Suite result: ok. 43 passed; 0 failed; 0 skipped; finished in 8.83s (8.82s CPU time)

Ran 21 tests for tests/config-engine/AccessManagerEngine.t.sol:AccessManagerEngineTest
[PASS] test_executeRoleMemberships_grant() (gas: 113334)
[PASS] test_executeRoleMemberships_grant_revert() (gas: 46524)
[PASS] test_executeRoleMemberships_multipleMemberships() (gas: 264832)
[PASS] test_executeRoleMemberships_revoke() (gas: 94266)
[PASS] test_executeRoleMemberships_revoke_revert() (gas: 46275)
[PASS] test_executeRoleUpdates_adminOnly() (gas: 190772)
[PASS] test_executeRoleUpdates_allFields() (gas: 217492)
[PASS] test_executeRoleUpdates_grantDelayOnly() (gas: 59287)
[PASS] test_executeRoleUpdates_guardianOnly() (gas: 56931)
[PASS] test_executeRoleUpdates_labelOnly() (gas: 30693)
[PASS] test_executeRoleUpdates_noneChanged() (gas: 19430)
[PASS] test_executeRoleUpdates_revert_admin() (gas: 42159)
[PASS] test_executeTargetAdminDelayUpdates() (gas: 55325)
[PASS] test_executeTargetAdminDelayUpdates_revert() (gas: 42391)
[PASS] test_executeTargetFunctionRoleUpdates() (gas: 299190)
[PASS] test_executeTargetFunctionRoleUpdates_revert() (gas: 48595)
[PASS] test_fuzz_executeRoleMemberships_grant(uint64,address,uint32) (runs: 5000, μ: 169930, ~: 172629)
[PASS] test_fuzz_executeRoleMemberships_revoke(uint64,address) (runs: 5000, μ: 140060, ~: 142230)
[PASS] test_fuzz_executeRoleUpdates_allFields(uint64,uint64,uint64,uint32) (runs: 5000, μ: 252914, ~: 258729)
[PASS] test_fuzz_executeTargetAdminDelayUpdates(address,uint32) (runs: 5000, μ: 50139, ~: 50139)
[PASS] test_fuzz_executeTargetFunctionRoleUpdates(address,bytes4,uint64) (runs: 5000, μ: 243766, ~: 260409)
Suite result: ok. 21 passed; 0 failed; 0 skipped; finished in 4.28s (4.26s CPU time)

Ran 10 tests for tests/unit/Spoke/Spoke.DynamicConfig.Triggers.t.sol:SpokeDynamicConfigTriggersTest
[PASS] test_borrow_triggers_dynamicConfigUpdate() (gas: 1343937)
[PASS] test_liquidate_does_not_trigger_dynamicConfigUpdate() (gas: 1623026)
[PASS] test_repay_does_not_trigger_dynamicConfigUpdate() (gas: 901074)
[PASS] test_supply_does_not_trigger_dynamicConfigUpdate() (gas: 1118825)
[PASS] test_updateUserDynamicConfig_doesHFCheck() (gas: 789347)
[PASS] test_updateUserDynamicConfig_reverts_when_not_authorized(address) (runs: 5000, μ: 1275886, ~: 1275886)
[PASS] test_updateUserDynamicConfig_triggers_dynamicConfigUpdate() (gas: 725736)
[PASS] test_updateUserDynamicConfig_updatesRP() (gas: 1292104)
[PASS] test_usingAsCollateral_triggers_dynamicConfigUpdate() (gas: 1370863)
[PASS] test_withdraw_triggers_dynamicConfigUpdate() (gas: 1373609)
Suite result: ok. 10 passed; 0 failed; 0 skipped; finished in 28.39s (28.35s CPU time)

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

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

[PASS] test_payFee_revertsWith_InvalidShares() (gas: 20356)
[PASS] test_payFee_revertsWith_SpokeNotActive() (gas: 61390)
[PASS] test_payFee_revertsWith_underflow_added_shares_exceeded() (gas: 135493)
[PASS] test_payFee_revertsWith_underflow_added_shares_exceeded_with_interest() (gas: 636899)
Suite result: ok. 6 passed; 0 failed; 0 skipped; finished in 29.55s (29.52s CPU time)

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

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

[PASS] test_grantRole() (gas: 315933)
[PASS] test_grantRole_fuzz(uint64,uint256) (runs: 5000, μ: 921716, ~: 920059)
Logs:
  Bound result 8

[PASS] test_renounceRole() (gas: 321091)
[PASS] test_renounceRole_shouldNotTrack() (gas: 24510)
[PASS] test_revokeRole() (gas: 323262)
[PASS] test_revokeRole_shouldNotTrack() (gas: 33158)
[PASS] test_setRoleAdmin_fuzz_trackAdminRoles_multipleRoles_multipleAdmins(uint256) (runs: 5000, μ: 2127299, ~: 2196726)
Logs:
  Bound result 12

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

[PASS] test_setRoleAdmin_trackAdminOfRoles() (gas: 606166)
[PASS] test_setRoleAdmin_trackAdminOfRoles_changeAdminRole() (gas: 577193)
[PASS] test_setRoleAdmin_trackAdminRoles() (gas: 602394)
[PASS] test_setRoleAdmin_trackRolesAndTrackAdminRoles() (gas: 378260)
[PASS] test_setRoleGuardian_trackRoles() (gas: 262021)
[PASS] test_setTargetFunctionRole() (gas: 489773)
[PASS] test_setTargetFunctionRole_multipleTargets() (gas: 1181595)
[PASS] test_setTargetFunctionRole_removeTarget() (gas: 1018326)
[PASS] test_setTargetFunctionRole_skipAddPublicRole() (gas: 206355)
[PASS] test_setTargetFunctionRole_skipAddToAdminRole() (gas: 34319)
[PASS] test_setTargetFunctionRole_withReplace() (gas: 672090)
Suite result: ok. 21 passed; 0 failed; 0 skipped; finished in 22.73s (22.73s CPU time)

Ran 22 tests for tests/unit/AssetInterestRateStrategy.t.sol:AssetInterestRateStrategyTest
[PASS] test_calculateInterestRate_AtMaxUtilization() (gas: 24621)
Logs:
  Bound result 10000
  Bound result 778565440757296803935461404101

[PASS] test_calculateInterestRate_AtOptimalPoint() (gas: 24281)
Logs:
  Bound result 2000
  Bound result 778565440757296803935461404101

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

[PASS] test_calculateInterestRate_RightToOptimalPoint(uint256) (runs: 5000, μ: 25300, ~: 25349)
Logs:
  Bound result 8137
  Bound result 252173843969976304268974536488

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

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

[PASS] test_calculateInterestRate_revertsWith_InterestRateDataNotSet() (gas: 11203)
[PASS] test_deploy_revertsWith_InvalidAddress() (gas: 3724)
[PASS] test_getBaseDrawnRate() (gas: 14746)
[PASS] test_getInterestRateData() (gas: 19268)
[PASS] test_getMaxDrawnRate() (gas: 15234)
[PASS] test_getOptimalUsageRatio() (gas: 14727)
[PASS] test_getRateGrowthAfterOptimal() (gas: 14791)
[PASS] test_getRateGrowthBeforeOptimal() (gas: 14791)
[PASS] test_maxDrawnRate() (gas: 8314)
[PASS] test_maxOptimalRatio() (gas: 8357)
[PASS] test_minOptimalRatio() (gas: 8299)
[PASS] test_setInterestRateData() (gas: 68942)
[PASS] test_setInterestRateData_revertsWith_InvalidMaxDrawnRate() (gas: 41762)
[PASS] test_setInterestRateData_revertsWith_InvalidOptimalUsageRatio() (gas: 42403)
[PASS] test_setInterestRateData_revertsWith_InvalidRateData() (gas: 35291)
[PASS] test_setInterestRateData_revertsWith_OnlyHub() (gas: 23502)
Suite result: ok. 22 passed; 0 failed; 0 skipped; finished in 1.22s (1.21s CPU time)

Ran 6 tests for tests/unit/position-manager/libraries/ConfigPermissions.t.sol:ConfigPermissionsTests
[PASS] test_constants() (gas: 12052)
[PASS] test_getConfigPermissionValues(uint8) (runs: 5000, μ: 13682, ~: 13682)
[PASS] test_setCanSetUsingAsCollateral_fuzz(uint8,bool) (runs: 5000, μ: 10623, ~: 10611)
[PASS] test_setCanUpdateUserDynamicConfig_fuzz(uint8,bool) (runs: 5000, μ: 10602, ~: 10590)
[PASS] test_setCanUpdateUserRiskPremium_fuzz(uint8,bool) (runs: 5000, μ: 10612, ~: 10600)
[PASS] test_setFullPermissions_fuzz(bool) (runs: 5000, μ: 13124, ~: 13134)
Suite result: ok. 6 passed; 0 failed; 0 skipped; finished in 1.14s (1.14s CPU time)

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

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

[PASS] test_calculateLiquidationAmounts_fuzz_EnoughCollateral_NoDebtLeft((address,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256)) (runs: 5000, μ: 259220, ~: 247786)
Logs:
  Bound result 305647192271866193
  Bound result 8596
  Bound result 375151818457824964
  Bound result 10660
  Bound result 18
  Bound result 3
  Bound result 10650
  Bound result 2
  Bound result 1320660900608901589
  Bound result 375151818457824964
  Bound result 2459529247883382
  Bound result 14
  Bound result 688868459503709026022276783765
  Bound result 35620419098526773228444064473
  Bound result 30663477167
  Bound result 40658186962
  Bound result 3642834413111126
  Bound result 12
  Bound result 6498
  Bound result 945630876467233914863016616547
  Bound result 0
  Bound result 3
  Bound result 10650
  Bound result 2
  Bound result 1320660900608901589
  Bound result 375151818457824964
  Bound result 2459529247883382
  Bound result 14
  Bound result 688868459503709026022276783765
  Bound result 35620419098526773228444064473
  Bound result 30663477167
  Bound result 40658186962
  Bound result 2459529247883382
  Bound result 678767
  Bound result 945630876467233914863016616547
  Bound result 688868459503709026022276783765

[PASS] test_calculateLiquidationAmounts_fuzz_InsufficientCollateral((address,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256)) (runs: 5000, μ: 245462, ~: 234045)
Logs:
  Bound result 536323747572635991
  Bound result 8821
  Bound result 167428388216330120
  Bound result 12139
  Bound result 13
  Bound result 370841240239815723006874948364222203766882024204480741969488896071
  Bound result 12139
  Bound result 6818
  Bound result 1609899181137382928
  Bound result 167428388216330120
  Bound result 4998819065787094
  Bound result 10
  Bound result 9158186690
  Bound result 47694844283046329925766589039
  Bound result 916739
  Bound result 1645628
  Bound result 1802713722704116
  Bound result 11
  Bound result 9999
  Bound result 130976932456558579856965198961
  Bound result 4
  Bound result 888631
  Bound result 9158186690

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

[PASS] test_calculateLiquidationAmounts_fuzz_revertsWith_MustNotLeaveDust_Debt((address,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256)) (runs: 5000, μ: 251036, ~: 239642)
Logs:
  Bound result 305647192271866193
  Bound result 8596
  Bound result 375151818457824964
  Bound result 10660
  Bound result 18
  Bound result 3
  Bound result 10650
  Bound result 2
  Bound result 1320660900608901589
  Bound result 375151818457824964
  Bound result 2459529247883382
  Bound result 14
  Bound result 688868459503709026022276783765
  Bound result 35620419098526773228444064473
  Bound result 30663477167
  Bound result 40658186962
  Bound result 3642834413111126
  Bound result 12
  Bound result 6498
  Bound result 945630876467233914863016616547
  Bound result 0
  Bound result 3
  Bound result 10650
  Bound result 2
  Bound result 1320660900608901589
  Bound result 375151818457824964
  Bound result 2459529247883382
  Bound result 14
  Bound result 688868459503709026022276783765
  Bound result 35620419098526773228444064473
  Bound result 30663477167
  Bound result 40658186962
  Bound result 2459529247883382
  Bound result 678767

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

Ran 4 tests for tests/unit/libraries/LiquidationLogic/LiquidationLogic.LiquidationBonus.t.sol:LiquidationLogicLiquidationBonusTest
[PASS] test_calculateLiquidationBonus_MinBonusDueToRounding() (gas: 12488)
[PASS] test_calculateLiquidationBonus_PartialBonus() (gas: 12509)
[PASS] test_calculateLiquidationBonus_fuzz_ConstantBonus(uint256,uint256,uint256,uint256) (runs: 5000, μ: 20337, ~: 20128)
Logs:
  Bound result 10567
  Bound result 2974
  Bound result 10000000000000000
  Bound result 14444

[PASS] test_calculateLiquidationBonus_fuzz_MaxBonus(uint256,uint256,uint256,uint256) (runs: 5000, μ: 23282, ~: 23072)
Logs:
  Bound result 10567
  Bound result 2974
  Bound result 10000000000000000
  Bound result 14444
  Bound result 5456

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

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

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

[PASS] test_reclaim_fullAmount() (gas: 616734)
[PASS] test_reclaim_fuzz(uint256,uint256,uint256) (runs: 5000, μ: 635970, ~: 635227)
Logs:
  Bound result 615514462186775432459
  Bound result 571193127101173104469
  Bound result 564283877115702805413

[PASS] test_reclaim_multipleSweepsAndReclaims() (gas: 725320)
[PASS] test_reclaim_revertsWith_AssetNotListed() (gas: 13093)
[PASS] test_reclaim_revertsWith_InsufficientTransferred() (gas: 438036)
[PASS] test_reclaim_revertsWith_InsufficientTransferred_noSwept() (gas: 102540)
[PASS] test_reclaim_revertsWith_InvalidAmount_zero() (gas: 92710)
[PASS] test_reclaim_revertsWith_OnlyReinvestmentController(address) (runs: 5000, μ: 93593, ~: 93593)
[PASS] test_reclaim_revertsWith_OnlyReinvestmentController_init() (gas: 40516)
[PASS] test_reclaim_revertsWith_underflow_exceedsSwept_afterSweep() (gas: 601387)
Suite result: ok. 11 passed; 0 failed; 0 skipped; finished in 16.76s (16.73s CPU time)

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

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

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

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

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

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

[PASS] test_uncheckedAdd(uint256,uint256) (runs: 5000, μ: 3447, ~: 3438)
[PASS] test_uncheckedExp(uint256,uint256) (runs: 5000, μ: 12422, ~: 9712)
[PASS] test_uncheckedSub(uint256,uint256) (runs: 5000, μ: 3445, ~: 3526)
[PASS] test_zeroFloorSub(uint256,uint256) (runs: 5000, μ: 3289, ~: 3254)
Suite result: ok. 29 passed; 0 failed; 0 skipped; finished in 3.08s (3.07s CPU time)

Ran 21 tests for tests/unit/Spoke/Spoke.DynamicConfig.t.sol:SpokeDynamicConfigTest
[PASS] test_addDynamicReserveConfig() (gas: 79168)
[PASS] test_addDynamicReserveConfig_fuzz_revertsWith_InvalidCollateralFactorAndMaxLiquidationBonus_incompatible(uint16,uint32) (runs: 5000, μ: 46201, ~: 46371)
Logs:
  Bound result 9010
  Bound result 11100

[PASS] test_addDynamicReserveConfig_once() (gas: 507896)
[PASS] test_addDynamicReserveConfig_revertsWith_AccessManagedUnauthorized(address) (runs: 5000, μ: 45477, ~: 45477)
[PASS] test_addDynamicReserveConfig_revertsWith_InvalidCollateralFactorAndMaxLiquidationBonus_collateralFactor() (gas: 57132)
[PASS] test_addDynamicReserveConfig_revertsWith_InvalidCollateralFactorAndMaxLiquidationBonus_liquidationBonus() (gas: 40351)
[PASS] test_addDynamicReserveConfig_revertsWith_InvalidLiquidationFee() (gas: 40880)
[PASS] test_addDynamicReserveConfig_revertsWith_MaximumDynamicConfigKeyReached() (gas: 43340)
[PASS] test_addDynamicReserveConfig_revertsWith_ReserveNotListed() (gas: 28219)
[PASS] test_fuzz_addDynamicReserveConfig_spaced_dup_updates(bytes32) (runs: 5000, μ: 414514, ~: 444892)
[PASS] test_fuzz_addDynamicReserveConfig_trailing_order(bytes32) (runs: 5000, μ: 395681, ~: 428957)
[PASS] test_offboardReserve_existing_borrows_remain_unaffected() (gas: 1126571)
[PASS] test_updateDynamicReserveConfig() (gas: 1714385)
[PASS] test_updateDynamicReserveConfig_fuzz_revertsWith_InvalidCollateralFactorAndMaxLiquidationBonus(uint16,uint32) (runs: 5000, μ: 56769, ~: 56939)
Logs:
  Bound result 9010
  Bound result 11100

[PASS] test_updateDynamicReserveConfig_revertsWith_AccessManagedUnauthorized(address) (runs: 5000, μ: 45501, ~: 45501)
[PASS] test_updateDynamicReserveConfig_revertsWith_DynamicConfigKeyUninitialized() (gas: 48968)
[PASS] test_updateDynamicReserveConfig_revertsWith_InvalidCollateralFactor() (gas: 49948)
[PASS] test_updateDynamicReserveConfig_revertsWith_InvalidCollateralFactorAndMaxLiquidationBonus_collateralFactor() (gas: 50704)
[PASS] test_updateDynamicReserveConfig_revertsWith_InvalidCollateralFactorAndMaxLiquidationBonus_liquidationBonus() (gas: 50852)
[PASS] test_updateDynamicReserveConfig_revertsWith_InvalidLiquidationFee() (gas: 51423)
[PASS] test_updateDynamicReserveConfig_revertsWith_ReserveNotListed() (gas: 28635)
Suite result: ok. 21 passed; 0 failed; 0 skipped; finished in 22.51s (22.48s CPU time)

Ran 5 tests for tests/gas/Spoke.Getters.gas.t.sol:SpokeGetters_Gas_Tests
[PASS] test_getUserAccountData() (gas: 23594)
[PASS] test_getUserAccountData_oneSupplies() (gas: 285291)
[PASS] test_getUserAccountData_twoSupplies() (gas: 521822)
[PASS] test_getUserAccountData_twoSupplies_oneBorrows() (gas: 1051246)
[PASS] test_getUserAccountData_twoSupplies_twoBorrows() (gas: 1619782)
Suite result: ok. 5 passed; 0 failed; 0 skipped; finished in 49.97ms (4.46ms CPU time)

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

[PASS] test_getLiquidationBonus_fuzz_configured(uint256,uint256,uint16,uint64) (runs: 5000, μ: 99622, ~: 99990)
Logs:
  Bound result 3
  Bound result 12828
  Bound result 1800
  Bound result 941575929182936874

[PASS] test_getLiquidationBonus_fuzz_notConfigured(uint256,uint256) (runs: 5000, μ: 77598, ~: 77823)
Logs:
  Bound result 4
  Bound result 100

[PASS] test_getLiquidationBonus_notConfigured() (gas: 78811)
Logs:
  Bound result 2
  Bound result 1000000000000000000

[PASS] test_premiumRayGetters() (gas: 1539405)
[PASS] test_protocol_getters() (gas: 288396)
Suite result: ok. 6 passed; 0 failed; 0 skipped; finished in 2.63s (2.60s CPU time)

Ran 4 tests for tests/unit/Spoke/Liquidations/Spoke.LiquidationCall.Dust.t.sol:SpokeLiquidationCallDustTest
[PASS] test_collateralDust_min_debtToTarget() (gas: 17747613)
[PASS] test_debtToCover_exceeds_collateralValue() (gas: 17736024)
[PASS] test_dustColl_allowed() (gas: 17596716)
[PASS] test_dustDebt_allowed() (gas: 17727290)
Suite result: ok. 4 passed; 0 failed; 0 skipped; finished in 54.63ms (22.39ms CPU time)

Ran 14 tests for tests/unit/Spoke/Liquidations/Spoke.LiquidationCall.Scenarios.t.sol:SpokeLiquidationCallScenariosTest
[PASS] test_liquidationCall_revertsWith_ReentrancyGuardReentrantCall_hubRefreshPremium() (gas: 25955719)
[PASS] test_liquidationCall_revertsWith_ReentrancyGuardReentrantCall_hubRemove() (gas: 25827962)
[PASS] test_liquidationCall_revertsWith_ReentrancyGuardReentrantCall_hubReportDeficit() (gas: 25939081)
[PASS] test_liquidationCall_revertsWith_ReentrancyGuardReentrantCall_hubRestore() (gas: 25903368)
[PASS] test_liquidationCall_scenario1() (gas: 3848874)
[PASS] test_liquidationCall_scenario2() (gas: 3857200)
[PASS] test_liquidationCall_scenario3() (gas: 3263193)
[PASS] test_liquidationCall_scenario4() (gas: 27490834)
[PASS] test_liquidationCall_scenario5() (gas: 3400829)
[PASS] test_liquidationCall_scenario6() (gas: 2237622)
[PASS] test_liquidationCall_scenario7() (gas: 2981560)
[PASS] test_liquidationCall_scenario8() (gas: 2207108)
[PASS] test_scenario_halted_asset() (gas: 26575755)
[PASS] test_scenario_halted_asset_with_deficit() (gas: 26419921)
Suite result: ok. 14 passed; 0 failed; 0 skipped; finished in 175.10ms (142.22ms CPU time)

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

[PASS] test_refreshPremium_fuzz_withAccrual(uint256,uint256,uint256,uint256) (runs: 5000, μ: 467716, ~: 476864)
Logs:
  Bound result 1635356462
  Bound result 13361
  Bound result 10000000000000000
  Bound result 269438908366791257524913374246

[PASS] test_refreshPremium_haltedSpokesAllowed() (gas: 121430)
[PASS] test_refreshPremium_maxRiskPremiumThreshold() (gas: 897881)
[PASS] test_refreshPremium_negativeDeltas(uint256) (runs: 5000, μ: 460143, ~: 460729)
Logs:
  Bound result 3124043968137

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

[PASS] test_refreshPremium_revertsWith_InvalidPremiumChange_NonZeroRestoredPremiumRay() (gas: 853291)
[PASS] test_refreshPremium_revertsWith_InvalidPremiumChange_RiskPremiumThresholdExceeded_DecreasingPremium() (gas: 874603)
[PASS] test_refreshPremium_revertsWith_SpokeNotActive() (gas: 58921)
[PASS] test_refreshPremium_riskPremiumThreshold() (gas: 920059)
[PASS] test_refreshPremium_spokePremiumUpdateIsContained() (gas: 710944)
Suite result: ok. 12 passed; 0 failed; 0 skipped; finished in 20.76s (20.73s CPU time)

Ran 26 tests for tests/unit/position-manager/ConfigPositionManager/ConfigPositionManager.Permit.t.sol:ConfigPositionManagerPermitTest
[PASS] test_DOMAIN_SEPARATOR() (gas: 5688)
[PASS] test_eip712Domain() (gas: 10941)
[PASS] test_setCanSetUsingAsCollateralPermissionPermit_typeHash() (gas: 9951)
[PASS] test_setCanSetUsingAsCollateralPermissionWithSig_fuzz(address,bool) (runs: 5000, μ: 158444, ~: 157614)
[PASS] test_setCanSetUsingAsCollateralPermissionWithSig_revertsWith_InvalidAccountNonce(bytes32) (runs: 5000, μ: 144916, ~: 142519)
[PASS] test_setCanSetUsingAsCollateralPermissionWithSig_revertsWith_InvalidSignature_dueTo_ExpiredDeadline() (gas: 28199)
[PASS] test_setCanSetUsingAsCollateralPermissionWithSig_revertsWith_InvalidSignature_dueTo_InvalidSigner() (gas: 32591)
[PASS] test_setCanSetUsingAsCollateralPermissionWithSig_revertsWith_SpokeNotRegistered() (gas: 61515)
[PASS] test_setCanUpdateUserDynamicConfigPermissionPermit_typeHash() (gas: 9863)
[PASS] test_setCanUpdateUserDynamicConfigPermissionWithSig_fuzz(address,bool) (runs: 5000, μ: 158450, ~: 157620)
[PASS] test_setCanUpdateUserDynamicConfigPermissionWithSig_revertsWith_InvalidAccountNonce(bytes32) (runs: 5000, μ: 144938, ~: 142541)
[PASS] test_setCanUpdateUserDynamicConfigPermissionWithSig_revertsWith_InvalidSignature_dueTo_ExpiredDeadline() (gas: 28190)
[PASS] test_setCanUpdateUserDynamicConfigPermissionWithSig_revertsWith_InvalidSignature_dueTo_InvalidSigner() (gas: 32571)
[PASS] test_setCanUpdateUserDynamicConfigPermissionWithSig_revertsWith_SpokeNotRegistered() (gas: 61528)
[PASS] test_setCanUpdateUserRiskPremiumPermissionPermit_typeHash() (gas: 9949)
[PASS] test_setCanUpdateUserRiskPremiumPermissionWithSig_fuzz(address,bool) (runs: 5000, μ: 158427, ~: 157597)
[PASS] test_setCanUpdateUserRiskPremiumPermissionWithSig_revertsWith_InvalidAccountNonce(bytes32) (runs: 5000, μ: 144873, ~: 142476)
[PASS] test_setCanUpdateUserRiskPremiumPermissionWithSig_revertsWith_InvalidSignature_dueTo_ExpiredDeadline() (gas: 28189)
[PASS] test_setCanUpdateUserRiskPremiumPermissionWithSig_revertsWith_InvalidSignature_dueTo_InvalidSigner() (gas: 32560)
[PASS] test_setCanUpdateUserRiskPremiumPermissionWithSig_revertsWith_SpokeNotRegistered() (gas: 61460)
[PASS] test_setGlobalPermissionPermit_typeHash() (gas: 9957)
[PASS] test_setGlobalPermissionWithSig_fuzz(address,bool) (runs: 5000, μ: 162700, ~: 162066)
[PASS] test_setGlobalPermissionWithSig_revertsWith_InvalidAccountNonce(bytes32) (runs: 5000, μ: 144899, ~: 142502)
[PASS] test_setGlobalPermissionWithSig_revertsWith_InvalidSignature_dueTo_ExpiredDeadline() (gas: 28176)
[PASS] test_setGlobalPermissionWithSig_revertsWith_InvalidSignature_dueTo_InvalidSigner() (gas: 32532)
[PASS] test_setGlobalPermissionWithSig_revertsWith_SpokeNotRegistered() (gas: 61468)
Suite result: ok. 26 passed; 0 failed; 0 skipped; finished in 49.98s (49.95s CPU time)

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

[PASS] test_remove_all_with_interest() (gas: 361850)
[PASS] test_remove_fuzz(uint256,uint256) (runs: 5000, μ: 204531, ~: 204587)
Logs:
  Bound result 4
  Bound result 100

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

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

[PASS] test_remove_fuzz_multi_spoke_with_interest(uint256,uint256,uint256,uint256) (runs: 5000, μ: 412554, ~: 413053)
Logs:
  Bound result 5240
  Bound result 12757
  Bound result 14746
  Bound result 584511984

[PASS] test_remove_revertsWith_InsufficientLiquidity() (gas: 155153)
[PASS] test_remove_revertsWith_InsufficientLiquidity_exceeding_added_amount() (gas: 144250)
[PASS] test_remove_revertsWith_InsufficientLiquidity_zero_added() (gas: 21376)
[PASS] test_remove_revertsWith_InvalidAddress() (gas: 16471)
[PASS] test_remove_revertsWith_InvalidAmount() (gas: 18628)
[PASS] test_remove_revertsWith_SpokeHalted() (gas: 61971)
[PASS] test_remove_revertsWith_SpokeNotActive() (gas: 61880)
[PASS] test_remove_revertsWith_underflow_exceeding_added_amount() (gas: 178890)
[PASS] test_remove_revertsWtih_underflow_one_extra_wei() (gas: 354295)
Suite result: ok. 15 passed; 0 failed; 0 skipped; finished in 31.99s (31.96s CPU time)

Ran 39 tests for tests/unit/position-manager/ConfigPositionManager/ConfigPositionManager.t.sol:ConfigPositionManagerTest
[PASS] test_multicall() (gas: 84518)
[PASS] test_renounceCanUpdateUserDynamicConfigPermission() (gas: 41286)
[PASS] test_renounceCanUpdateUserDynamicConfigPermission_revertsWith_SpokeNotRegistered() (gas: 17489)
[PASS] test_renounceCanUpdateUserRiskPremiumPermission() (gas: 41198)
[PASS] test_renounceCanUpdateUserRiskPremiumPermission_revertsWith_SpokeNotRegistered() (gas: 17380)
[PASS] test_renounceCanUpdateUsingAsCollateralPermission() (gas: 41215)
[PASS] test_renounceCanUpdateUsingAsCollateralPermission_revertsWith_SpokeNotRegistered() (gas: 17402)
[PASS] test_renounceGlobalPermission() (gas: 42252)
[PASS] test_renounceGlobalPermission_revertsWith_SpokeNotRegistered() (gas: 17423)
[PASS] test_setCanSetUsingAsCollateralPermission() (gas: 54009)
[PASS] test_setCanSetUsingAsCollateralPermission_remove() (gas: 41304)
[PASS] test_setCanSetUsingAsCollateralPermission_revertsWith_InvalidAddress_zeroDelegatee() (gas: 17885)
[PASS] test_setCanSetUsingAsCollateralPermission_revertsWith_SpokeNotRegistered() (gas: 17497)
[PASS] test_setCanUpdateUserDynamicConfigPermission() (gas: 54032)
[PASS] test_setCanUpdateUserDynamicConfigPermission_remove() (gas: 41359)
[PASS] test_setCanUpdateUserDynamicConfigPermission_revertsWith_InvalidAddress_zeroDelegatee() (gas: 17937)
[PASS] test_setCanUpdateUserDynamicConfigPermission_revertsWith_SpokeNotRegistered() (gas: 17561)
[PASS] test_setCanUpdateUserRiskPremiumPermission() (gas: 54033)
[PASS] test_setCanUpdateUserRiskPremiumPermission_remove() (gas: 41341)
[PASS] test_setCanUpdateUserRiskPremiumPermission_revertsWith_InvalidAddress_zeroDelegatee() (gas: 17916)
[PASS] test_setCanUpdateUserRiskPremiumPermission_revertsWith_SpokeNotRegistered() (gas: 17542)
[PASS] test_setGlobalPermission() (gas: 55612)
[PASS] test_setGlobalPermission_removeAllPermissions() (gas: 42393)
[PASS] test_setGlobalPermission_removePreviousPermissions() (gas: 46538)
[PASS] test_setGlobalPermission_revertsWith_InvalidAddress_zeroDelegatee() (gas: 17869)
[PASS] test_setGlobalPermission_revertsWith_SpokeNotRegistered() (gas: 17540)
[PASS] test_setGlobalPermission_setThenRemove() (gas: 50008)
[PASS] test_setUsingAsCollateralOnBehalfOf_fuzz_withGlobalPermission(uint256,bool) (runs: 5000, μ: 105691, ~: 110529)
Logs:
  Bound result 2

[PASS] test_setUsingAsCollateralOnBehalfOf_fuzz_withPermission(uint256,bool) (runs: 5000, μ: 105751, ~: 110589)
Logs:
  Bound result 2

[PASS] test_setUsingAsCollateralOnBehalfOf_revertsWith_CallerNotAllowed() (gas: 22151)
[PASS] test_setUsingAsCollateralOnBehalfOf_revertsWith_SpokeNotRegistered() (gas: 17584)
[PASS] test_updateUserDynamicConfigOnBehalfOf_revertsWith_CallerNotAllowed() (gas: 19908)
[PASS] test_updateUserDynamicConfigOnBehalfOf_revertsWith_SpokeNotRegistered() (gas: 17422)
[PASS] test_updateUserDynamicConfigOnBehalfOf_withGlobalPermission() (gas: 69720)
[PASS] test_updateUserDynamicConfigOnBehalfOf_withPermission() (gas: 69822)
[PASS] test_updateUserRiskPremiumOnBehalfOf_revertsWith_CallerNotAllowed() (gas: 19909)
[PASS] test_updateUserRiskPremiumOnBehalfOf_revertsWith_SpokeNotRegistered() (gas: 17469)
[PASS] test_updateUserRiskPremiumOnBehalfOf_withGlobalPermission() (gas: 809271)
[PASS] test_updateUserRiskPremiumOnBehalfOf_withPermission() (gas: 809284)
Suite result: ok. 39 passed; 0 failed; 0 skipped; finished in 12.72s (12.70s CPU time)

Ran 11 tests for tests/config-engine/EngineFlags.t.sol:EngineFlagsTest
[PASS] test_constants() (gas: 6195)
[PASS] test_fromBool_false_returnsDisabled() (gas: 8477)
[PASS] test_fromBool_true_returnsEnabled() (gas: 8448)
[PASS] test_fuzz_fromBool(bool) (runs: 5000, μ: 8652, ~: 8657)
[PASS] test_fuzz_toBool_revertsOnInvalid(uint256) (runs: 5000, μ: 9145, ~: 9145)
[PASS] test_fuzz_toBool_revertsOnInvalidValue(uint256) (runs: 5000, μ: 9203, ~: 9203)
[PASS] test_roundtrip_toBool_fromBool() (gas: 11271)
[PASS] test_toBool_one_returnsTrue() (gas: 8431)
[PASS] test_toBool_revertsOnInvalidValue() (gas: 8710)
[PASS] test_toBool_revertsOnMax() (gas: 8719)
[PASS] test_toBool_zero_returnsFalse() (gas: 8493)
Suite result: ok. 11 passed; 0 failed; 0 skipped; finished in 416.37ms (414.81ms CPU time)

Ran 7 tests for tests/unit/Hub/Hub.ReportDeficit.t.sol:HubReportDeficitTest
[PASS] test_reportDeficit_fuzz_revertsWith_SurplusDrawnDeficitReported(uint256) (runs: 5000, μ: 220029, ~: 220462)
Logs:
  Bound result 3124043968137

[PASS] test_reportDeficit_fuzz_revertsWith_SurplusPremiumRayDeficitReported(uint256) (runs: 5000, μ: 221054, ~: 221487)
Logs:
  Bound result 3124043968137

[PASS] test_reportDeficit_fuzz_with_premium(uint256,uint256,uint256,uint256) (runs: 5000, μ: 677694, ~: 678447)
Logs:
  Bound result 5441
  Bound result 2063
  Bound result 663
  Bound result 10000000000000000

[PASS] test_reportDeficit_halted() (gas: 265181)
[PASS] test_reportDeficit_revertsWith_InvalidAmount() (gas: 22783)
[PASS] test_reportDeficit_revertsWith_SpokeNotActive(address) (runs: 5000, μ: 33938, ~: 33938)
[PASS] test_reportDeficit_with_premium() (gas: 676807)
Logs:
  Bound result 10000000000
  Bound result 31536000
  Bound result 5000000000
  Bound result 0

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

Ran 41 tests for tests/unit/position-manager/NativeTokenGateway.t.sol:NativeTokenGatewayTest
[PASS] test_borrowNative() (gas: 667531)
Logs:
  Bound result 5000000000000000000

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

[PASS] test_borrowNative_revertsWith_InvalidAmount() (gas: 32444)
[PASS] test_borrowNative_revertsWith_NotNativeWrappedAsset() (gas: 32519)
[PASS] test_borrowNative_revertsWith_ReentrancyGuardReentrantCall_hubDraw() (gas: 283143)
[PASS] test_borrowNative_revertsWith_ReentrancyGuardReentrantCall_spokeBorrow() (gas: 271222)
[PASS] test_borrowNative_revertsWith_SpokeNotRegistered() (gas: 25378)
[PASS] test_constructor() (gas: 12675)
[PASS] test_constructor_revertsWith_InvalidAddress() (gas: 5958)
[PASS] test_fallback_revertsWith_UnsupportedAction() (gas: 17595)
[PASS] test_multicall_revertsWith_UnsupportedAction() (gas: 11265)
[PASS] test_receive_revertsWith_UnsupportedAction() (gas: 17408)
[PASS] test_repayNative() (gas: 759989)
Logs:
  Bound result 5000000000000000000

[PASS] test_repayNative_excessAmount() (gas: 668542)
[PASS] test_repayNative_fuzz(uint256) (runs: 5000, μ: 755821, ~: 760570)
Logs:
  Bound result 3124043968137

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

[PASS] test_repayNative_revertsWith_InvalidAmount() (gas: 32481)
[PASS] test_repayNative_revertsWith_NativeAmountMismatch() (gas: 30002)
[PASS] test_repayNative_revertsWith_NotNativeWrappedAsset() (gas: 39249)
[PASS] test_repayNative_revertsWith_ReentrancyGuardReentrantCall_hubRestore() (gas: 326265)
[PASS] test_repayNative_revertsWith_ReentrancyGuardReentrantCall_spokeRepay() (gas: 303321)
[PASS] test_repayNative_revertsWith_SpokeNotRegistered() (gas: 38722)
[PASS] test_supplyAndCollateralNative() (gas: 333564)
Logs:
  Bound result 100000000000000000000

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

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

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

[PASS] test_supplyNative_revertsWith_InvalidAmount() (gas: 32457)
[PASS] test_supplyNative_revertsWith_NativeAmountMismatch() (gas: 29986)
[PASS] test_supplyNative_revertsWith_NotNativeWrappedAsset() (gas: 39237)
[PASS] test_supplyNative_revertsWith_ReentrancyGuardReentrantCall_hubAdd() (gas: 374260)
[PASS] test_supplyNative_revertsWith_ReentrancyGuardReentrantCall_spokeSupply() (gas: 336151)
[PASS] test_supplyNative_revertsWith_SpokeNotRegistered() (gas: 38734)
[PASS] test_withdrawNative() (gas: 331913)
Logs:
  Bound result 100000000000000000000

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

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

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

[PASS] test_withdrawNative_revertsWith_InvalidAmount() (gas: 32475)
[PASS] test_withdrawNative_revertsWith_NotNativeWrappedAsset() (gas: 32508)
[PASS] test_withdrawNative_revertsWith_ReentrancyGuardReentrantCall_hubRemove() (gas: 300006)
[PASS] test_withdrawNative_revertsWith_ReentrancyGuardReentrantCall_spokeWithdraw() (gas: 271196)
[PASS] test_withdrawNative_revertsWith_SpokeNotRegistered() (gas: 25345)
Suite result: ok. 41 passed; 0 failed; 0 skipped; finished in 80.52s (80.50s CPU time)

Ran 3 tests for tests/unit/NoncesKeyed.t.sol:NoncesKeyedTest
[PASS] test_useCheckedNonce_monotonic(bytes32) (runs: 5000, μ: 12902, ~: 12902)
[PASS] test_useCheckedNonce_revertsWith_InvalidAccountNonce(bytes32) (runs: 5000, μ: 95279, ~: 94374)
[PASS] test_useNonce_monotonic(bytes32) (runs: 5000, μ: 13570, ~: 13570)
Suite result: ok. 3 passed; 0 failed; 0 skipped; finished in 4.03s (4.03s CPU time)

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

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

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

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

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

Ran 17 tests for tests/unit/position-manager/PositionManagerBase.t.sol:PositionManagerBaseTest
[PASS] test_constructor() (gas: 17209)
[PASS] test_getReserveUnderlying_fuzz(uint256) (runs: 5000, μ: 36891, ~: 36947)
Logs:
  Bound result 2

[PASS] test_getReserveUnderlying_revertsWith_ReserveNotListed() (gas: 25763)
[PASS] test_multicall() (gas: 73158)
[PASS] test_multicall_atomicity_on_revert() (gas: 48181)
[PASS] test_multicall_revertsWith_UnsupportedAction() (gas: 11243)
[PASS] test_permitReserveUnderlying() (gas: 128765)
[PASS] test_permitReserveUnderlying_forwards_correct_call() (gas: 78195)
[PASS] test_permitReserveUnderlying_ignores_permit_reverts() (gas: 67273)
[PASS] test_permitReserveUnderlying_revertsWith_ReserveNotListed() (gas: 58153)
[PASS] test_registerSpoke_fuzz(address) (runs: 5000, μ: 41640, ~: 41640)
[PASS] test_registerSpoke_revertsWith_InvalidAddress() (gas: 13087)
[PASS] test_registerSpoke_revertsWith_OwnableUnauthorizedAccount() (gas: 15935)
[PASS] test_registerSpoke_unregister() (gas: 36116)
[PASS] test_renouncePositionManagerRole() (gas: 65242)
[PASS] test_renouncePositionManagerRole_revertsWith_OwnableUnauthorizedAccount() (gas: 74572)
[PASS] test_setSelfAsUserPositionManagerWithSig() (gas: 131425)
Suite result: ok. 17 passed; 0 failed; 0 skipped; finished in 1.05s (1.02s CPU time)

Ran 3 tests for tests/unit/Hub/Hub.Rescue.t.sol:HubRescueTest
[PASS] test_cannot_rescue_liquidity_fee_reverts_with_InsufficientTransferred() (gas: 264896)
[PASS] test_rescue_fuzz_with_interest(uint256,uint256) (runs: 5000, μ: 507016, ~: 506972)
Logs:
  Bound result 351500639
  Bound result 1256746

[PASS] test_rescue_scenario_fuzz(uint256) (runs: 5000, μ: 446545, ~: 446336)
Logs:
  Bound result 3124043968137

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

Ran 10 tests for tests/unit/position-manager/libraries/PositionManagerEIP712Hash.t.sol:PositionManagerEIP712HashTest
[PASS] test_constants() (gas: 13419)
[PASS] test_hash_borrow_fuzz((address,uint256,uint256,address,uint256,uint256)) (runs: 5000, μ: 6712, ~: 6712)
[PASS] test_hash_creditDelegation_fuzz((address,uint256,address,address,uint256,uint256,uint256)) (runs: 5000, μ: 4810, ~: 4810)
[PASS] test_hash_repay_fuzz((address,uint256,uint256,address,uint256,uint256)) (runs: 5000, μ: 6690, ~: 6690)
[PASS] test_hash_setUsingAsCollateral_fuzz((address,uint256,bool,address,uint256,uint256)) (runs: 5000, μ: 7171, ~: 7171)
[PASS] test_hash_supply_fuzz((address,uint256,uint256,address,uint256,uint256)) (runs: 5000, μ: 6711, ~: 6711)
[PASS] test_hash_updateUserDynamicConfig_fuzz((address,address,uint256,uint256)) (runs: 5000, μ: 6349, ~: 6349)
[PASS] test_hash_updateUserRiskPremium_fuzz((address,address,uint256,uint256)) (runs: 5000, μ: 6370, ~: 6370)
[PASS] test_hash_withdrawPermit_fuzz((address,uint256,address,address,uint256,uint256,uint256)) (runs: 5000, μ: 4832, ~: 4832)
[PASS] test_hash_withdraw_fuzz((address,uint256,uint256,address,uint256,uint256)) (runs: 5000, μ: 6689, ~: 6689)
Suite result: ok. 10 passed; 0 failed; 0 skipped; finished in 5.85s (5.85s CPU time)

Ran 6 tests for tests/config-engine/PositionManagerEngine.t.sol:PositionManagerEngineTest
[PASS] test_executePositionManagerRoleRenouncements() (gas: 140024)
[PASS] test_executePositionManagerRoleRenouncements_revert() (gas: 1079520)
[PASS] test_executePositionManagerSpokeRegistrations() (gas: 51256)
[PASS] test_executePositionManagerSpokeRegistrations_deregister() (gas: 42523)
[PASS] test_executePositionManagerSpokeRegistrations_revert() (gas: 1077395)
[PASS] test_fuzz_executePositionManagerSpokeRegistrations(bool) (runs: 5000, μ: 38321, ~: 28527)
Suite result: ok. 6 passed; 0 failed; 0 skipped; finished in 400.06ms (384.17ms CPU time)

Ran 11 tests for tests/gas/PositionManagers.Operations.gas.t.sol:ConfigPositionManager_Gas_Tests
[PASS] test_renounceCanUpdateUserDynamicConfigPermission() (gas: 93331)
[PASS] test_renounceCanUpdateUserRiskPremiumPermission() (gas: 93308)
[PASS] test_renounceCanUpdateUsingAsCollateralPermission() (gas: 93243)
[PASS] test_renounceGlobalPermission() (gas: 93180)
[PASS] test_setCanSetUsingAsCollateralPermission() (gas: 69240)
[PASS] test_setCanUpdateUserDynamicConfigPermission() (gas: 69259)
[PASS] test_setCanUpdateUserRiskPremiumPermission() (gas: 69282)
[PASS] test_setGlobalPermission() (gas: 69173)
[PASS] test_setUsingAsCollateralOnBehalfOf_fuzz_withGlobalPermission() (gas: 145058)
[PASS] test_updateUserDynamicConfigOnBehalfOf_withGlobalPermission() (gas: 120767)
[PASS] test_updateUserRiskPremiumOnBehalfOf_withGlobalPermission() (gas: 713857)
Suite result: ok. 11 passed; 0 failed; 0 skipped; finished in 47.55ms (2.20ms CPU time)

Ran 2 tests for tests/gas/PositionManagers.Operations.gas.t.sol:GiverPositionManager_Gas_Tests
[PASS] test_repayOnBehalfOf() (gas: 919766)
[PASS] test_supplyOnBehalfOf() (gas: 282870)
Suite result: ok. 2 passed; 0 failed; 0 skipped; finished in 47.79ms (1.74ms CPU time)

Ran 1 test for tests/gas/PositionManagers.Operations.gas.t.sol:PositionManager_Gas_Tests
[PASS] test_setSelfAsUserPositionManagerWithSig() (gas: 215923)
Suite result: ok. 1 passed; 0 failed; 0 skipped; finished in 45.34ms (775.01µs CPU time)

Ran 8 tests for tests/gas/PositionManagers.Operations.gas.t.sol:TakerPositionManager_Gas_Tests
[PASS] test_approveWithdraw() (gas: 69195)
[PASS] test_approveWithdrawWithSig() (gas: 155438)
[PASS] test_borrowOnBehalfOf() (gas: 763831)
[PASS] test_creditDelegation() (gas: 69162)
[PASS] test_delegateCreditWithSig() (gas: 155432)
[PASS] test_renounceCreditDelegation() (gas: 93655)
[PASS] test_renounceWithdrawAllowance() (gas: 93762)
[PASS] test_withdrawOnBehalfOf() (gas: 584219)
Suite result: ok. 8 passed; 0 failed; 0 skipped; finished in 48.10ms (3.44ms CPU time)

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

[PASS] test_restore_full_amount_with_interest_and_premium() (gas: 677404)
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, μ: 365357, ~: 365451)
Logs:
  Bound result 615514462186775432459
  Bound result 571193127101173104469
  Bound result 173721804

[PASS] test_restore_fuzz_full_amount_with_interest_and_premium(uint256,uint256,uint256,uint256) (runs: 5000, μ: 668125, ~: 679465)
Logs:
  Bound result 12168
  Bound result 4632
  Bound result 64000000
  Bound result 74

[PASS] test_restore_fuzz_revertsWith_SurplusDrawnRestored_with_interest(uint256,uint256,uint256) (runs: 5000, μ: 243453, ~: 244624)
Logs:
  Bound result 615514462186775432459
  Bound result 571193127101173104469
  Bound result 173721804

[PASS] test_restore_fuzz_revertsWith_SurplusDrawnRestored_with_interest_and_premium(uint256,uint256,uint256,uint256) (runs: 5000, μ: 642047, ~: 642302)
Logs:
  Bound result 12168
  Bound result 4632
  Bound result 64000000
  Bound result 74

[PASS] test_restore_one_share_delta_increase_revertsWith_InvalidPremiumChange() (gas: 211618)
[PASS] test_restore_partial_drawn() (gas: 322405)
[PASS] test_restore_partial_same_block() (gas: 322531)
[PASS] test_restore_premiumDeltas_twoWeiIncrease_realizedDelta() (gas: 232328)
[PASS] test_restore_revertsWith_InsufficientTransferred() (gas: 252128)
[PASS] test_restore_revertsWith_InvalidAmount_zero() (gas: 58090)
[PASS] test_restore_revertsWith_InvalidPremiumChange_premiumIncrease() (gas: 218581)
[PASS] test_restore_revertsWith_InvalidPremiumChange_premiumSharesIncrease() (gas: 218581)
[PASS] test_restore_revertsWith_SpokeHalted() (gas: 99279)
[PASS] test_restore_revertsWith_SpokeNotActive_whenPaused() (gas: 181407)
[PASS] test_restore_revertsWith_SurplusDrawnRestored() (gas: 358172)
[PASS] test_restore_revertsWith_SurplusDrawnRestored_with_interest() (gas: 243249)
Logs:
  Bound result 100000000000000000000
  Bound result 50000000000000000000
  Bound result 15768000

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

[PASS] test_restore_revertsWith_SurplusPremiumRayRestored() (gas: 508498)
[PASS] test_restore_revertsWith_underflow_offsetIncrease() (gas: 227438)
[PASS] test_restore_tooMuchDrawn_revertsWith_SurplusDrawnRestored() (gas: 213936)
[PASS] test_restore_when_asset_caps_reset() (gas: 435330)
Suite result: ok. 23 passed; 0 failed; 0 skipped; finished in 19.21s (19.18s CPU time)

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

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

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

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

Ran 5 tests for tests/gas/Gateways.Operations.gas.t.sol:NativeTokenGateway_Gas_Tests
[PASS] test_borrowNative() (gas: 924794)
[PASS] test_repayNative() (gas: 992785)
[PASS] test_supplyAndCollateralNative() (gas: 305250)
[PASS] test_supplyNative() (gas: 286691)
[PASS] test_withdrawNative() (gas: 508792)
Suite result: ok. 5 passed; 0 failed; 0 skipped; finished in 49.68ms (4.26ms CPU time)

Ran 8 tests for tests/gas/Gateways.Operations.gas.t.sol:SignatureGateway_Gas_Tests
[PASS] test_borrowWithSig() (gas: 748631)
[PASS] test_repayWithSig() (gas: 955129)
[PASS] test_setSelfAsUserPositionManagerWithSig() (gas: 209293)
[PASS] test_setUsingAsCollateralWithSig() (gas: 289353)
[PASS] test_supplyWithSig() (gas: 434276)
[PASS] test_updateUserDynamicConfigWithSig() (gas: 145250)
[PASS] test_updateUserRiskPremiumWithSig() (gas: 143115)
[PASS] test_withdrawWithSig() (gas: 409926)
Suite result: ok. 8 passed; 0 failed; 0 skipped; finished in 53.99ms (8.21ms CPU time)

Ran 4 tests for tests/unit/Hub/Hub.Skim.t.sol:HubSkimTest
[PASS] test_skimAdd_fuzz_donationAfterAdd(uint256,uint256,uint256) (runs: 5000, μ: 228214, ~: 228282)
Logs:
  Bound result 3
  Bound result 18470873395738003579119570309
  Bound result 446067553769140138733721804

[PASS] test_skimAdd_fuzz_donationBeforeAdd(uint256,uint256,uint256) (runs: 5000, μ: 228246, ~: 228314)
Logs:
  Bound result 3
  Bound result 18470873395738003579119570309
  Bound result 446067553769140138733721804

[PASS] test_skimAdd_fuzz_wrongSpokeTransfer(uint256,uint256,uint256) (runs: 5000, μ: 217339, ~: 217278)
Logs:
  Bound result 3
  Bound result 18132171100462486213502917929
  Bound result 446067553769140138733721804

[PASS] test_skimRestore_fuzz_liquidityDonation(uint256,uint256,uint256) (runs: 5000, μ: 269452, ~: 270838)
Logs:
  Bound result 3
  Bound result 18470873395738003579119570309
  Bound result 446067553769140138733721804

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

Ran 12 tests for tests/unit/position-manager/GiverPositionManager.t.sol:GiverPositionManagerTest
[PASS] test_multicall() (gas: 334903)
[PASS] test_repayOnBehalfOf() (gas: 640360)
Logs:
  Bound result 50000000000000000000

[PASS] test_repayOnBehalfOf_fuzz(uint256) (runs: 5000, μ: 637573, ~: 640655)
Logs:
  Bound result 3124043968137

[PASS] test_repayOnBehalfOf_fuzz_withInterest(uint256,uint256) (runs: 5000, μ: 571410, ~: 567797)
Logs:
  Bound result 900000068691281935000
  Bound result 25920101

[PASS] test_repayOnBehalfOf_maxRepay() (gas: 561613)
[PASS] test_repayOnBehalfOf_maxRepay_revertsWith_InvalidRepayAmount() (gas: 483216)
[PASS] test_repayOnBehalfOf_revertsWith_ReserveNotListed() (gas: 32366)
[PASS] test_repayOnBehalfOf_revertsWith_SpokeNotRegistered() (gas: 28744)
[PASS] test_supplyOnBehalfOf() (gas: 296643)
Logs:
  Bound result 100000000000000000000

[PASS] test_supplyOnBehalfOf_fuzz(uint256) (runs: 5000, μ: 296905, ~: 296693)
Logs:
  Bound result 3124043968137

[PASS] test_supplyOnBehalfOf_revertsWith_ReserveNotListed() (gas: 32405)
[PASS] test_supplyOnBehalfOf_revertsWith_SpokeNotRegistered() (gas: 28794)
Suite result: ok. 12 passed; 0 failed; 0 skipped; finished in 33.09s (33.06s CPU time)

Ran 6 tests for tests/unit/Hub/Hub.Access.t.sol:HubAccessTest
[PASS] test_change_authority() (gas: 206679)
[PASS] test_change_role_responsibility() (gas: 121287)
[PASS] test_hub_access_manager_exposure() (gas: 13439)
[PASS] test_hub_admin_access() (gas: 1350370)
[PASS] test_migrate_role_responsibility() (gas: 709202)
[PASS] test_setInterestRateData_access() (gas: 102610)
Suite result: ok. 6 passed; 0 failed; 0 skipped; finished in 29.33ms (3.89ms CPU time)

Ran 10 tests for tests/unit/Hub/Hub.SpokeConfig.t.sol:HubSpokeConfigTest
[PASS] test_add_active_halted_scenarios() (gas: 300448)
[PASS] test_draw_active_halted_scenarios() (gas: 304372)
[PASS] test_eliminateDeficit_active_halted_scenarios() (gas: 829470)
[PASS] test_mintFeeShares_active_halted_scenarios() (gas: 813892)
[PASS] test_payFeeShares_active_halted_scenarios() (gas: 366014)
[PASS] test_refreshPremium_active_halted_scenarios() (gas: 267080)
[PASS] test_remove_active_halted_scenarios() (gas: 316268)
[PASS] test_repor...*[Comment body truncated]*

@Kogaroshi Kogaroshi changed the title Config Payload for Governance V3 feat : config Payload for Governance V3 Mar 4, 2026
/// @author Aave Labs
/// @notice Interface for the Aave V4 Config Engine, defining all structs and engine method signatures.
/// The engine is stateless and invoked via delegatecall from payload contracts.
/// All numeric fields in config structs use uint256 so that type(uint256).max can serve as
Copy link
Contributor

Choose a reason for hiding this comment

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

can we use this sentinel like that though? Like for example, what if we want to go from a non-inf addCap to inf addCap? Then we'd pass type(uint256).max but that wouldn't actually change the addCap as desired. I think similar behavior for some other configs that use this value as a sentinel, no?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

we could modify the sentinel value to type(uint256).max - 1, so we can pass infinite value in those case, wdyt ?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Copy link
Contributor

Choose a reason for hiding this comment

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

in v3 they use more random/exotic vals for the sentinel like type(uint256).max - 42, which is more unlikely to be used. We could do similar (ie more random), although max-1 is prob also not super likely

https://github.com/aave-dao/aave-v3-origin/blob/1e3d70c4151a94166ebc59e2eaa4aff6e6ba6978/src/contracts/extensions/v3-config-engine/EngineFlags.sol#L7

Comment on lines +27 to +28
/// @dev Expected to be called by a governance executor. No on-chain access control is applied;
/// the caller is responsible for authorization. Idempotency is not guaranteed.
Copy link
Contributor

@CheyenneAtapour CheyenneAtapour Mar 11, 2026

Choose a reason for hiding this comment

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

why is no access control applied on-chain exactly?

Copy link
Contributor

Choose a reason for hiding this comment

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

just that it gets applied at the time of execution, rather than separately validating access control here?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes, try to say that we do not verify the needed roles are given before executing the actions of the Payload, and Executor will need all the required Roles for the complete execution beforehand.
And that we rely on the Configurators & contracts access control directly.

);
}

if (listings[i].tokenization.addCap > 0) {
Copy link
Contributor

@yan-man yan-man Mar 12, 2026

Choose a reason for hiding this comment

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

hm do you think that we would ever deploy a tokenization spoke with addCap of 0 legitimately (ie just to launch with), maybe we can base this on name or symbol or somethign else like another engine flag

Copy link
Contributor Author

Choose a reason for hiding this comment

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

In that case, we'd need a new bool in the struct to know if we want to deploy it, wdyt @DhairyaSethi ?

Copy link
Member

Choose a reason for hiding this comment

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

yes we want to deploy w 0 addCap for coverage

Copy link
Contributor Author

Choose a reason for hiding this comment

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

}

if (listings[i].tokenization.addCap > 0) {
_deployAndRegisterTokenizationSpoke(listings[i]);
Copy link
Contributor

Choose a reason for hiding this comment

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

also tbh it is a little weird to have the hub engine be deploying a spoke here. ig it depends on framing, do we see tokenization spoke as an inherent part of the hub? perhaps this can be in the spoke engine and we call it from there

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Imo the Spoke Engine is for Spoke.sol & SpokeConfigurator.sol, and the TokenizationSpoke is more of a "periphery" of an asset on the Hub, hence why it was here (and also because we only need deploy + call a config on the Hub here, so made more sense there as well).

/// read-modify-write via updateInterestRateData.
/// Reinvestment: address set → updateReinvestmentController.
/// @param updates The asset config updates to execute.
function executeHubAssetConfigUpdates(
Copy link
Contributor

Choose a reason for hiding this comment

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

any reason you wanted to name it this way instead of executeHubUpdateAssetConfig and executeHubAddSpokeToAssets below? but i also dont think we need to have the "Hub" part in these fns given it's the HubEngine

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The Hub part in the name is because that method is in IAaveV4ConfigEngine.
As for the naming, it was to show that we have a list of updates (and additions), ant not only one, but open to other names here.

@Kogaroshi Kogaroshi marked this pull request as ready for review March 13, 2026 09:25
Copilot AI review requested due to automatic review settings March 13, 2026 09:26
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Introduces a new Aave V4 “Config Engine” + base payload abstraction intended to standardize governance payload construction (Governance V3 compatible via aave-helpers), with comprehensive unit tests and supporting mocks/docs.

Changes:

  • Adds AaveV4Payload (base governance payload) and AaveV4ConfigEngine with hub/spoke/access-manager/position-manager action execution.
  • Implements sub-engines as libraries (HubEngine, SpokeEngine, AccessManagerEngine, PositionManagerEngine) plus sentinel flags (EngineFlags) and deterministic tokenization-spoke deployment (TokenizationSpokeDeployer).
  • Adds extensive Foundry tests and mocks, plus documentation/diagram for the config-engine architecture.

Reviewed changes

Copilot reviewed 27 out of 28 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
tests/mocks/config-engine/MockSpokeReader.sol Mock spoke reader for reserve ID + dynamic config reads (incl forced revert).
tests/mocks/config-engine/MockSpokeConfigurator.sol Mock spoke configurator emitting events / configurable reverts for spoke actions.
tests/mocks/config-engine/MockPositionManager.sol Mock position manager emitting events / configurable reverts.
tests/mocks/config-engine/MockInterestRateStrategy.sol Mock IR strategy storage + getter for IR data reads.
tests/mocks/config-engine/MockHubConfigurator.sol Mock hub configurator emitting events / configurable reverts for hub actions.
tests/mocks/config-engine/MockHub.sol Mock hub exposing assetId/config/decimals + max cap reads.
tests/mocks/config-engine/MockAccessManager.sol Mock OZ AccessManager for role/target configuration tests.
tests/mocks/config-engine/AaveV4PayloadWrapper.sol Test payload implementation with setters + hook tracking.
tests/mocks/config-engine/AaveV4PayloadSize.sol Minimal payload to measure bytecode size impact.
tests/config-engine/SpokeEngine.t.sol Unit tests for SpokeEngine behavior and sentinel handling.
tests/config-engine/PositionManagerEngine.t.sol Unit tests for PositionManagerEngine behavior and reverts.
tests/config-engine/HubEngine.t.sol Unit tests for HubEngine incl tokenization spoke deployment + validation.
tests/config-engine/EngineFlags.t.sol Unit tests for sentinel constants + bool conversion helpers.
tests/config-engine/BaseConfigEngine.t.sol Shared test setup + helpers for single-item arrays/default structs.
tests/config-engine/AccessManagerEngine.t.sol Unit tests for AccessManagerEngine role/target updates + reverts.
tests/config-engine/AaveV4Payload.t.sol Integration-style tests asserting payload delegates into engine correctly.
tests/config-engine/AaveV4Payload.EmptyReturns.t.sol Tests that the base payload’s default empty-return getters are no-ops.
src/config-engine/libraries/TokenizationSpokeDeployer.sol CREATE2 deployment + precomputation for TokenizationSpoke proxies via Safe factory.
src/config-engine/libraries/SpokeEngine.sol Spoke-side configuration execution (reserve listing/config/liquidation/dynamic config/PM updates).
src/config-engine/libraries/PositionManagerEngine.sol Position-manager execution helpers (spoke registration + role renouncement).
src/config-engine/libraries/HubEngine.sol Hub-side configuration execution (asset listing/config updates/spoke registration/caps/status + tokenization).
src/config-engine/libraries/EngineFlags.sol Sentinel values and uint256↔bool helpers for partial updates.
src/config-engine/libraries/AccessManagerEngine.sol AccessManager execution helpers (membership, role updates, selector roles, admin delays).
src/config-engine/interfaces/IAaveV4ConfigEngine.sol Public interface defining structs and engine method signatures.
src/config-engine/README.md High-level documentation of engine usage, action categories, and execution model.
src/config-engine/AaveV4Payload.sol Base payload contract that gathers overrides and delegatecalls the engine.
src/config-engine/AaveV4ConfigEngine.sol Engine entrypoint that routes calls into the sub-engine libraries.
resources/config-engine.svg Architecture diagram showing call/delegatecall flow across executor/payload/engine/sub-engines.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

You can also share your feedback on Copilot code review. Take the survey.

@linear
Copy link

linear bot commented Mar 17, 2026

Copilot AI review requested due to automatic review settings March 17, 2026 08:58
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Adds an Aave V4 “config engine” + payload base contract intended for governance payload authors (Gov v3 / aave-helpers compatibility), consolidating common Hub/Spoke/AccessManager/PositionManager admin operations behind a struct-driven, sentinel-based interface.

Changes:

  • Introduces AaveV4Payload, AaveV4ConfigEngine, and action libraries (Hub/Spoke/AccessManager/PositionManager) plus EngineFlags sentinels.
  • Adds deterministic CREATE2 tokenization spoke deployment utilities (TokenizationSpokeDeployer) and corresponding hub listing support.
  • Adds a comprehensive test suite for each engine area and payload delegatecall behavior, plus README + diagram.

Reviewed changes

Copilot reviewed 21 out of 22 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
tests/unit/AccessManagerEnumerable.t.sol Fixes a small comment typo (“Default”).
tests/mocks/config-engine/AaveV4PayloadWrapper.sol Test wrapper payload exposing setters/getters to drive payload execution tests.
tests/mocks/config-engine/AaveV4PayloadSize.sol Minimal contract to measure AaveV4Payload size.
tests/config-engine/BaseConfigEngine.t.sol Shared test harness to deploy/seed hubs/spokes/configurators/roles.
tests/config-engine/EngineFlags.t.sol Unit tests for sentinel/flag helpers.
tests/config-engine/HubEngine.t.sol HubEngine behavior tests (listings, updates, tokenization, caps, halts, etc.).
tests/config-engine/SpokeEngine.t.sol SpokeEngine behavior tests (reserve listing/config, liquidation, dynamic config, PM updates).
tests/config-engine/PositionManagerEngine.t.sol PositionManagerEngine behavior tests (spoke registration, role renouncement).
tests/config-engine/AccessManagerEngine.t.sol AccessManagerEngine behavior tests (memberships, role updates, target roles/delays).
tests/config-engine/AaveV4Payload.t.sol End-to-end payload delegatecall execution tests across all action categories.
tests/config-engine/AaveV4Payload.EmptyReturns.t.sol Verifies base payload defaults return empty arrays and execute safely.
src/config-engine/libraries/EngineFlags.sol Adds sentinel constants + bool conversions for partial updates.
src/config-engine/interfaces/IAaveV4ConfigEngine.sol Defines structs + engine method surface for payloads/engine libs.
src/config-engine/libraries/AccessManagerEngine.sol Role membership/config/target role/delay execution logic.
src/config-engine/libraries/PositionManagerEngine.sol Position manager spoke registration + user role renouncement execution logic.
src/config-engine/libraries/SpokeEngine.sol Reserve listing/config updates, liquidation config updates, dynamic config updates, PM updates.
src/config-engine/libraries/HubEngine.sol Asset listing/config updates, spoke config updates, tokenization spoke deployment/registration, halts/deactivations/resets.
src/config-engine/libraries/TokenizationSpokeDeployer.sol Deterministic Safe Singleton Factory CREATE2 deploy + address precomputation for tokenization spokes.
src/config-engine/AaveV4Payload.sol Abstract payload base contract that delegatecalls the engine.
src/config-engine/AaveV4ConfigEngine.sol Engine entrypoints delegating to the action libraries.
src/config-engine/README.md High-level documentation for usage, sentinels, and ordering.
resources/config-engine.svg Architecture diagram for payload → engine → sub-engines/external calls.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

You can also share your feedback on Copilot code review. Take the survey.

Copilot AI review requested due to automatic review settings March 18, 2026 15:34

This comment was marked as off-topic.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants