Skip to content

Commit 07bdc21

Browse files
committed
🔒 exa: require initialize call before initialize2
1 parent 6006846 commit 07bdc21

3 files changed

Lines changed: 56 additions & 42 deletions

File tree

.gas-snapshot

Lines changed: 42 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ DebtManagerTest:testFloatingToFixedRollHigherThanAvailableLiquidityWithSlippage(
4949
DebtManagerTest:testFloatingToFixedRollHigherThanAvailableLiquidityWithSlippageWithThreePools() (gas: 2818426)
5050
DebtManagerTest:testFloatingToFixedRollWithAccurateSlippage() (gas: 1732739)
5151
DebtManagerTest:testFloatingToFixedRollWithAccurateSlippageWithPreviousPosition() (gas: 1954939)
52-
DebtManagerTest:testFuzzRolls(uint8[4],uint8[4],uint256[4],uint40[4],uint8[4]) (runs: 256, μ: 8031714, ~: 8129987)
52+
DebtManagerTest:testFuzzRolls(uint8[4],uint8[4],uint256[4],uint40[4],uint8[4]) (runs: 256, μ: 7911792, ~: 7969725)
5353
DebtManagerTest:testLateFixedRoll() (gas: 1454770)
5454
DebtManagerTest:testLateFixedRollWithThreeLoops() (gas: 2043936)
5555
DebtManagerTest:testLateFixedToFloatingRoll() (gas: 1449634)
@@ -100,26 +100,27 @@ DebtRollerTest:test_rollFixed_reverts_whenNotMarket() (gas: 49047)
100100
DebtRollerTest:test_rollFixed_rolls() (gas: 1100854)
101101
DebtRollerTest:test_rollFixed_rolls_partial() (gas: 1140051)
102102
EXATest:test_burn_burnsAndEmitsCrosschainBurn() (gas: 149890)
103-
EXATest:test_burn_reverts_whenCallerLacksBridgeRole() (gas: 69277)
103+
EXATest:test_burn_reverts_whenCallerLacksBridgeRole() (gas: 69255)
104104
EXATest:test_crosschainBurn_burnsAndEmitsCrosschainBurn() (gas: 149888)
105105
EXATest:test_crosschainBurn_reverts_whenCallerLacksBridgeRole() (gas: 69268)
106-
EXATest:test_crosschainMint_mintsAndEmitsCrosschainMint() (gas: 103234)
106+
EXATest:test_crosschainMint_mintsAndEmitsCrosschainMint() (gas: 103300)
107107
EXATest:test_crosschainMint_reverts_whenCallerLacksBridgeRole() (gas: 69277)
108-
EXATest:test_initialize2_grantsAdminRole() (gas: 30356)
109-
EXATest:test_initialize2_reverts_whenAdminIsZeroAddress() (gas: 5633722)
110-
EXATest:test_initialize2_reverts_whenCalledByNotProxyAdmin() (gas: 3392762)
111-
EXATest:test_initialize2_reverts_whenCalledTwice() (gas: 2290266)
112-
EXATest:test_initialize_reverts_whenCalledByNotProxyAdmin() (gas: 3284161)
113-
EXATest:test_initialize_reverts_whenCalledOnImplementation() (gas: 2261057)
108+
EXATest:test_initialize2_grantsAdminRole() (gas: 30379)
109+
EXATest:test_initialize2_reverts_whenAdminIsZeroAddress() (gas: 5661254)
110+
EXATest:test_initialize2_reverts_whenCalledBeforeInitialize() (gas: 3313044)
111+
EXATest:test_initialize2_reverts_whenCalledByNotProxyAdmin() (gas: 3406504)
112+
EXATest:test_initialize2_reverts_whenCalledTwice() (gas: 2304030)
113+
EXATest:test_initialize_reverts_whenCalledByNotProxyAdmin() (gas: 3297925)
114+
EXATest:test_initialize_reverts_whenCalledOnImplementation() (gas: 2274821)
114115
EXATest:test_initialize_reverts_whenCalledTwice() (gas: 38964)
115116
EXATest:test_initialize_setsNameSymbolAndSupply() (gas: 55624)
116-
EXATest:test_initialize_succeeds_whenProxyAlreadyDeployedAndUpgradedWithCall() (gas: 5654939)
117-
EXATest:test_initialize_totalSupplyIsZero_whenNotOptimism() (gas: 3396691)
117+
EXATest:test_initialize_succeeds_whenProxyAlreadyDeployedAndUpgradedWithCall() (gas: 5682459)
118+
EXATest:test_initialize_totalSupplyIsZero_whenNotOptimism() (gas: 3410455)
118119
EXATest:test_mint_mintsAndEmitsCrosschainMint() (gas: 103345)
119120
EXATest:test_mint_reverts_whenCallerLacksBridgeRole() (gas: 69342)
120-
EXATest:test_supportsInterface_returnsFalse_forInvalidInterface() (gas: 15813)
121+
EXATest:test_supportsInterface_returnsFalse_forInvalidInterface() (gas: 15791)
121122
EXATest:test_supportsInterface_returnsTrue_forIAccessControl() (gas: 15793)
122-
EXATest:test_supportsInterface_returnsTrue_forIERC165() (gas: 15815)
123+
EXATest:test_supportsInterface_returnsTrue_forIERC165() (gas: 15793)
123124
EXATest:test_supportsInterface_returnsTrue_forIERC7802() (gas: 15661)
124125
EscrowedEXATest:testCancelExternalStreams() (gas: 398267)
125126
EscrowedEXATest:testCancelExternalStreamsWithesEXACancel() (gas: 1137424)
@@ -193,18 +194,18 @@ IntegrationPreviewerTest:test_fixedRepayPosition_beforeMaturity() (gas: 579991)
193194
IntegrationPreviewerTest:test_fixedRepayPosition_maxUint() (gas: 79468)
194195
IntegrationPreviewerTest:test_fixedRepayPosition_saturatedFallback() (gas: 63069)
195196
IntegrationPreviewerTest:test_healthFactor() (gas: 463879)
196-
IntegrationPreviewerTest:test_previewDeposit_(uint256) (runs: 256, μ: 1590621, ~: 1594531)
197+
IntegrationPreviewerTest:test_previewDeposit_(uint256) (runs: 256, μ: 1590152, ~: 1594077)
197198
IntegrationPreviewerTest:test_previewHealthFactor() (gas: 5805369)
198-
IntegrationPreviewerTest:test_previewWithdraw_(uint256) (runs: 256, μ: 1650006, ~: 1654116)
199+
IntegrationPreviewerTest:test_previewWithdraw_(uint256) (runs: 256, μ: 1649487, ~: 1653259)
199200
InterestRateModelTest:testFixedBorrowRate() (gas: 2088868)
200201
InterestRateModelTest:testFixedRateRevertAlreadyMatured() (gas: 2083135)
201202
InterestRateModelTest:testFixedRateRevertUtilizationExceeded() (gas: 2097203)
202203
InterestRateModelTest:testFloatingBorrowRate() (gas: 2082456)
203-
InterestRateModelTest:testFuzzFixedRateGrowth(uint256,uint256,uint256,uint256) (runs: 256, μ: 2109079, ~: 2105195)
204-
InterestRateModelTest:testFuzzFixedRateTimeSensitivity(uint256,uint256,uint256) (runs: 256, μ: 2117002, ~: 2117161)
205-
InterestRateModelTest:testFuzzReferenceLegacyRateFixed(uint32,uint256,uint256[2],uint256[2],uint256,uint256,uint256) (runs: 256, μ: 12911661, ~: 13132845)
206-
InterestRateModelTest:testFuzzReferenceRateFixed(uint256,uint256,uint256,uint256,uint256,uint256,(uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,int256,uint256,uint256)) (runs: 256, μ: 2384608, ~: 2386846)
207-
InterestRateModelTest:testFuzzReferenceRateFloating(uint256,uint256,(uint256,uint256,uint256,uint256,uint256,uint256,uint256)) (runs: 256, μ: 2324354, ~: 2324970)
204+
InterestRateModelTest:testFuzzFixedRateGrowth(uint256,uint256,uint256,uint256) (runs: 256, μ: 2109043, ~: 2105195)
205+
InterestRateModelTest:testFuzzFixedRateTimeSensitivity(uint256,uint256,uint256) (runs: 256, μ: 2116971, ~: 2117161)
206+
InterestRateModelTest:testFuzzReferenceLegacyRateFixed(uint32,uint256,uint256[2],uint256[2],uint256,uint256,uint256) (runs: 256, μ: 12879393, ~: 13130335)
207+
InterestRateModelTest:testFuzzReferenceRateFixed(uint256,uint256,uint256,uint256,uint256,uint256,(uint256,uint256,uint256,uint256,uint256,uint256,uint256,uint256,int256,uint256,uint256)) (runs: 256, μ: 2384148, ~: 2386756)
208+
InterestRateModelTest:testFuzzReferenceRateFloating(uint256,uint256,(uint256,uint256,uint256,uint256,uint256,uint256,uint256)) (runs: 256, μ: 2324223, ~: 2324917)
208209
InterestRateModelTest:testMinTimeToMaturity() (gas: 2107232)
209210
InterestRateModelTest:testRevertMaxUtilizationLowerThanWad() (gas: 268402)
210211
MarketTest:testAccountLiquidityAdjustedDebt() (gas: 654335)
@@ -359,7 +360,7 @@ PoolLibTest:testAtomicDepositBorrowRepayWithdraw() (gas: 45922)
359360
PoolLibTest:testBackupBorrow() (gas: 33624)
360361
PoolLibTest:testEarningsAccrual() (gas: 38952)
361362
PoolLibTest:testEarningsDistribution() (gas: 32679)
362-
PoolLibTest:testFuzzAddRemoveAll(uint8[12]) (runs: 256, μ: 104449, ~: 105534)
363+
PoolLibTest:testFuzzAddRemoveAll(uint8[12]) (runs: 256, μ: 105431, ~: 107158)
363364
PoolLibTest:testMaturityRangeLimit() (gas: 7866)
364365
PoolLibTest:testMaturityRangeTooWide() (gas: 11656)
365366
PreviewerTest:testAccountsReturningAccurateAmounts() (gas: 1686539)
@@ -538,8 +539,8 @@ StakedEXATest:invariantNoDuplicatedReward() (runs: 10, calls: 5000, reverts: 0)
538539
StakedEXATest:invariantRewardsUpOnly() (runs: 10, calls: 5000, reverts: 0)
539540
StakedEXATest:invariantShareValueIsOne() (runs: 10, calls: 5000, reverts: 0)
540541
StakedEXATest:testAlreadyListedError() (gas: 43677)
541-
StakedEXATest:testAvgIndex(uint256[3],uint256[2]) (runs: 256, μ: 1316807, ~: 1370333)
542-
StakedEXATest:testAvgStartTime(uint256[3],uint256[2]) (runs: 256, μ: 1244873, ~: 1298399)
542+
StakedEXATest:testAvgIndex(uint256[3],uint256[2]) (runs: 256, μ: 1294619, ~: 1319773)
543+
StakedEXATest:testAvgStartTime(uint256[3],uint256[2]) (runs: 256, μ: 1222685, ~: 1247839)
543544
StakedEXATest:testBalanceOfDeposit(uint80) (runs: 256, μ: 331886, ~: 339807)
544545
StakedEXATest:testBalanceOfWithdraw(uint256) (runs: 256, μ: 82393, ~: 82407)
545546
StakedEXATest:testCanChangeRewardsDurationWhenDisabled() (gas: 176331)
@@ -548,12 +549,12 @@ StakedEXATest:testClaimAndUnstake() (gas: 1622618)
548549
StakedEXATest:testClaimAndWithdrawAfterRefTime() (gas: 1029325)
549550
StakedEXATest:testClaimBeforeFirstHarvest() (gas: 527334)
550551
StakedEXATest:testDepositClaimsRewardsToReceiver() (gas: 1121108)
551-
StakedEXATest:testDepositEvent(uint256) (runs: 256, μ: 335230, ~: 334978)
552-
StakedEXATest:testDepositShouldClaim(uint256[2],uint32) (runs: 256, μ: 815900, ~: 754868)
552+
StakedEXATest:testDepositEvent(uint256) (runs: 256, μ: 335220, ~: 334966)
553+
StakedEXATest:testDepositShouldClaim(uint256[2],uint32) (runs: 256, μ: 815531, ~: 754868)
553554
StakedEXATest:testDepositToAnotherWithAllowance() (gas: 375284)
554555
StakedEXATest:testDepositToAnotherWithoutAllowanceShouldFail() (gas: 121959)
555-
StakedEXATest:testDepositWithdrawAvgStartTimeAndIndex(uint256[3],uint256,uint256[5]) (runs: 256, μ: 1883981, ~: 1904719)
556-
StakedEXATest:testEarnedWithTime(uint256) (runs: 256, μ: 86109, ~: 86314)
556+
StakedEXATest:testDepositWithdrawAvgStartTimeAndIndex(uint256[3],uint256,uint256[5]) (runs: 256, μ: 1858235, ~: 1902168)
557+
StakedEXATest:testEarnedWithTime(uint256) (runs: 256, μ: 86053, ~: 86314)
557558
StakedEXATest:testEmergencyAdminCanPauseNotUnpause() (gas: 175029)
558559
StakedEXATest:testFinishDistributionEmitEvent() (gas: 240752)
559560
StakedEXATest:testFinishDistributionLetsClaimUnclaimed() (gas: 1784865)
@@ -564,9 +565,9 @@ StakedEXATest:testGrantRevokeEmergencyAdmin() (gas: 117824)
564565
StakedEXATest:testGrantRevokePauser() (gas: 117836)
565566
StakedEXATest:testHandlerClaim(uint8) (runs: 256, μ: 485340, ~: 485340)
566567
StakedEXATest:testHandlerDeposit(uint80) (runs: 256, μ: 1231152, ~: 1263054)
567-
StakedEXATest:testHandlerHarvest(uint64) (runs: 256, μ: 403155, ~: 411143)
568-
StakedEXATest:testHandlerNotifyRewardAmount(uint64) (runs: 256, μ: 143611, ~: 136610)
569-
StakedEXATest:testHandlerSetDuration(uint32) (runs: 256, μ: 189027, ~: 218699)
568+
StakedEXATest:testHandlerHarvest(uint64) (runs: 256, μ: 401537, ~: 411143)
569+
StakedEXATest:testHandlerNotifyRewardAmount(uint64) (runs: 256, μ: 144811, ~: 136620)
570+
StakedEXATest:testHandlerSetDuration(uint32) (runs: 256, μ: 189476, ~: 218699)
570571
StakedEXATest:testHandlerSetMarket() (gas: 144553)
571572
StakedEXATest:testHandlerWithdraw(uint256) (runs: 256, μ: 102852, ~: 102866)
572573
StakedEXATest:testHarvestAmountWithReducedAllowance() (gas: 184605)
@@ -577,13 +578,13 @@ StakedEXATest:testHarvestWhenFinished() (gas: 326352)
577578
StakedEXATest:testHarvestX() (gas: 180952)
578579
StakedEXATest:testHarvestZero() (gas: 255436)
579580
StakedEXATest:testInitialValues() (gas: 196483)
580-
StakedEXATest:testInsufficientBalanceError(uint256) (runs: 256, μ: 63928, ~: 64151)
581+
StakedEXATest:testInsufficientBalanceError(uint256) (runs: 256, μ: 63990, ~: 64151)
581582
StakedEXATest:testMaxRewardsGasConsumption() (gas: 144674963)
582583
StakedEXATest:testMultipleClaimsVsOne() (gas: 21936440)
583584
StakedEXATest:testMultipleHarvests() (gas: 284083)
584-
StakedEXATest:testNoRewardsAfterPeriod(uint256) (runs: 256, μ: 1809576, ~: 1804391)
585+
StakedEXATest:testNoRewardsAfterPeriod(uint256) (runs: 256, μ: 1810466, ~: 1816281)
585586
StakedEXATest:testNotPausingRoleError() (gas: 39124)
586-
StakedEXATest:testNotifyRewardAmount(uint256,uint256) (runs: 256, μ: 155634, ~: 155564)
587+
StakedEXATest:testNotifyRewardAmount(uint256,uint256) (runs: 256, μ: 155628, ~: 155564)
587588
StakedEXATest:testNotifyRewardWithUnderlyingAsset() (gas: 460608)
588589
StakedEXATest:testOnlyAdminEnableReward() (gas: 1297302)
589590
StakedEXATest:testOnlyAdminFinishDistribution() (gas: 213640)
@@ -601,13 +602,13 @@ StakedEXATest:testPenaltyThresholdRange() (gas: 36989)
601602
StakedEXATest:testPermitAndDeposit() (gas: 452146)
602603
StakedEXATest:testPermitFailKeepsFlow() (gas: 484480)
603604
StakedEXATest:testRemoveDepositAllowance() (gas: 466913)
604-
StakedEXATest:testResetDepositAfterRefTime(uint256) (runs: 256, μ: 1033243, ~: 1032994)
605-
StakedEXATest:testRewardAmountNotifiedEvent(uint256) (runs: 256, μ: 105537, ~: 105281)
605+
StakedEXATest:testResetDepositAfterRefTime(uint256) (runs: 256, μ: 1033225, ~: 1032994)
606+
StakedEXATest:testRewardAmountNotifiedEvent(uint256) (runs: 256, μ: 105537, ~: 105269)
606607
StakedEXATest:testRewardNotListedError() (gas: 1177184)
607-
StakedEXATest:testRewardPaidEvent(uint256,uint256) (runs: 256, μ: 810177, ~: 854316)
608-
StakedEXATest:testRewardsAmounts(uint256) (runs: 256, μ: 1707501, ~: 1707275)
608+
StakedEXATest:testRewardPaidEvent(uint256,uint256) (runs: 256, μ: 802090, ~: 854267)
609+
StakedEXATest:testRewardsAmounts(uint256) (runs: 256, μ: 1707472, ~: 1707275)
609610
StakedEXATest:testRewardsDurationSetEvent(uint40) (runs: 256, μ: 52170, ~: 52149)
610-
StakedEXATest:testSetDuration(uint256,uint40) (runs: 256, μ: 65920, ~: 64453)
611+
StakedEXATest:testSetDuration(uint256,uint40) (runs: 256, μ: 65763, ~: 64441)
611612
StakedEXATest:testSetMarketAddressZero() (gas: 36979)
612613
StakedEXATest:testSetMarketOnlyAdmin() (gas: 1345554)
613614
StakedEXATest:testSetMaxRewardsTokensExceeded() (gas: 111958823)
@@ -619,12 +620,12 @@ StakedEXATest:testSetSavingsZeroAddressError() (gas: 37006)
619620
StakedEXATest:testTotalSupplyDeposit(uint80) (runs: 256, μ: 331272, ~: 339193)
620621
StakedEXATest:testTotalSupplyWithdraw(uint256) (runs: 256, μ: 81753, ~: 81767)
621622
StakedEXATest:testUntransferable(uint80) (runs: 256, μ: 339593, ~: 348672)
622-
StakedEXATest:testWithdrawEvent(uint256) (runs: 256, μ: 483397, ~: 483158)
623+
StakedEXATest:testWithdrawEvent(uint256) (runs: 256, μ: 483383, ~: 483140)
623624
StakedEXATest:testWithdrawRewardUnderlyingAsset() (gas: 456617)
624625
StakedEXATest:testWithdrawRewardsOnlyAdmin() (gas: 242200)
625626
StakedEXATest:testWithdrawRewardsOnlyReward() (gas: 1177174)
626-
StakedEXATest:testWithdrawSameAmountRewardsShouldEqual(uint256,uint256) (runs: 256, μ: 1064623, ~: 1107850)
627-
StakedEXATest:testWithdrawWithRewards(uint256) (runs: 256, μ: 895615, ~: 895376)
627+
StakedEXATest:testWithdrawSameAmountRewardsShouldEqual(uint256,uint256) (runs: 256, μ: 1057664, ~: 1107782)
628+
StakedEXATest:testWithdrawWithRewards(uint256) (runs: 256, μ: 895601, ~: 895358)
628629
StakedEXATest:testZeroRateError() (gas: 58274)
629630
StakingPreviewerTest:testAllClaimable() (gas: 769205)
630631
StakingPreviewerTest:testAllClaimed() (gas: 818952)

contracts/periphery/EXA.sol

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ contract EXA is ERC20VotesUpgradeable, AccessControlUpgradeable, IERC7802 {
3232
function initialize2(address admin_) external reinitializer(2) {
3333
if (msg.sender != StorageSlotUpgradeable.getAddressSlot(ADMIN_SLOT).value) revert NotProxyAdmin();
3434
if (admin_ == address(0)) revert ZeroAddress();
35+
if (bytes(symbol()).length == 0) revert NotInitialized();
3536

3637
__AccessControl_init();
3738
_grantRole(DEFAULT_ADMIN_ROLE, admin_);
@@ -73,5 +74,6 @@ contract EXA is ERC20VotesUpgradeable, AccessControlUpgradeable, IERC7802 {
7374
}
7475
}
7576

77+
error NotInitialized();
7678
error NotProxyAdmin();
7779
error ZeroAddress();

test/EXA.t.sol

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import { IAccessControl } from "@openzeppelin/contracts/access/IAccessControl.so
1111
import { IERC165 } from "@openzeppelin/contracts/utils/introspection/IERC165.sol";
1212
import { IERC7802 } from "@openzeppelin/contracts/interfaces/draft-IERC7802.sol";
1313

14-
import { EXA, NotProxyAdmin, ZeroAddress } from "../contracts/periphery/EXA.sol";
14+
import { EXA, NotInitialized, NotProxyAdmin, ZeroAddress } from "../contracts/periphery/EXA.sol";
1515

1616
contract EXATest is Test {
1717
EXA internal exa;
@@ -127,6 +127,17 @@ contract EXATest is Test {
127127
assertTrue(exa.hasRole(exa.DEFAULT_ADMIN_ROLE(), admin));
128128
}
129129

130+
function test_initialize2_reverts_whenCalledBeforeInitialize() external {
131+
ProxyAdmin proxyAdmin_ = new ProxyAdmin();
132+
address implementation = address(new EXA());
133+
ITransparentUpgradeableProxy proxy_ = ITransparentUpgradeableProxy(
134+
payable(address(new TransparentUpgradeableProxy(implementation, address(proxyAdmin_), "")))
135+
);
136+
137+
vm.expectRevert(NotInitialized.selector);
138+
proxyAdmin_.upgradeAndCall(proxy_, implementation, abi.encodeCall(EXA.initialize2, (admin)));
139+
}
140+
130141
function test_initialize2_reverts_whenCalledTwice() external {
131142
EXA implementation = new EXA();
132143

0 commit comments

Comments
 (0)