@@ -13,6 +13,8 @@ import "../utils/Precision.sol";
1313import "../utils/Cast.sol " ;
1414import "../market/MarketUtils.sol " ;
1515
16+ import "./ConfigUtils.sol " ;
17+
1618// @title Config
1719contract Config is ReentrancyGuard , RoleModule , BasicMulticall {
1820 using EventUtils for EventUtils.AddressItems;
@@ -90,27 +92,14 @@ contract Config is ReentrancyGuard, RoleModule, BasicMulticall {
9092 uint256 priceFeedHeartbeatDuration ,
9193 uint256 stablePrice
9294 ) external onlyConfigKeeper nonReentrant {
93- if (dataStore.getAddress (Keys.priceFeedKey (token)) != address (0 )) {
94- revert Errors.PriceFeedAlreadyExistsForToken (token);
95- }
96-
97- dataStore.setAddress (Keys.priceFeedKey (token), priceFeed);
98- dataStore.setUint (Keys.priceFeedMultiplierKey (token), priceFeedMultiplier);
99- dataStore.setUint (Keys.priceFeedHeartbeatDurationKey (token), priceFeedHeartbeatDuration);
100- dataStore.setUint (Keys.stablePriceKey (token), stablePrice);
101-
102- EventUtils.EventLogData memory eventData;
103- eventData.addressItems.initItems (2 );
104- eventData.addressItems.setItem (0 , "token " , token);
105- eventData.addressItems.setItem (1 , "priceFeed " , priceFeed);
106- eventData.uintItems.initItems (3 );
107- eventData.uintItems.setItem (0 , "priceFeedMultiplier " , priceFeedMultiplier);
108- eventData.uintItems.setItem (1 , "priceFeedHeartbeatDuration " , priceFeedHeartbeatDuration);
109- eventData.uintItems.setItem (2 , "stablePrice " , stablePrice);
110- eventEmitter.emitEventLog1 (
111- "ConfigSetPriceFeed " ,
112- Cast.toBytes32 (token),
113- eventData
95+ ConfigUtils.setPriceFeed (
96+ dataStore,
97+ eventEmitter,
98+ token,
99+ priceFeed,
100+ priceFeedMultiplier,
101+ priceFeedHeartbeatDuration,
102+ stablePrice
114103 );
115104 }
116105
@@ -120,28 +109,17 @@ contract Config is ReentrancyGuard, RoleModule, BasicMulticall {
120109 uint256 dataStreamMultiplier ,
121110 uint256 dataStreamSpreadReductionFactor
122111 ) external onlyConfigKeeper nonReentrant {
123- if (dataStore.getBytes32 (Keys.dataStreamIdKey (token)) != bytes32 (0 )) {
124- revert Errors.DataStreamIdAlreadyExistsForToken (token);
125- }
126-
127- _validateRange (Keys.DATA_STREAM_SPREAD_REDUCTION_FACTOR, abi.encode (token), dataStreamSpreadReductionFactor);
128-
129- dataStore.setBytes32 (Keys.dataStreamIdKey (token), feedId);
130- dataStore.setUint (Keys.dataStreamMultiplierKey (token), dataStreamMultiplier);
131- dataStore.setUint (Keys.dataStreamSpreadReductionFactorKey (token), dataStreamSpreadReductionFactor);
132112
133- EventUtils.EventLogData memory eventData;
134- eventData.addressItems.initItems (1 );
135- eventData.addressItems.setItem (0 , "token " , token);
136- eventData.bytes32Items.initItems (1 );
137- eventData.bytes32Items.setItem (0 , "feedId " , feedId);
138- eventData.uintItems.initItems (2 );
139- eventData.uintItems.setItem (0 , "dataStreamMultiplier " , dataStreamMultiplier);
140- eventData.uintItems.setItem (1 , "dataStreamSpreadReductionFactor " , dataStreamSpreadReductionFactor);
141- eventEmitter.emitEventLog1 (
142- "ConfigSetDataStream " ,
143- Cast.toBytes32 (token),
144- eventData
113+ ConfigUtils.setDataStream (
114+ dataStore,
115+ eventEmitter,
116+ token,
117+ feedId,
118+ dataStreamMultiplier,
119+ dataStreamSpreadReductionFactor,
120+ MAX_ALLOWED_MAX_FUNDING_FACTOR_PER_SECOND,
121+ MAX_ALLOWED_FUNDING_INCREASE_FACTOR_PER_SECOND,
122+ MAX_ALLOWED_FUNDING_DECREASE_FACTOR_PER_SECOND
145123 );
146124 }
147125
@@ -151,26 +129,13 @@ contract Config is ReentrancyGuard, RoleModule, BasicMulticall {
151129 uint256 timeKey ,
152130 uint256 factor
153131 ) external onlyConfigKeeper nonReentrant {
154- if (factor > Precision.FLOAT_PRECISION) { revert Errors.InvalidClaimableFactor (factor); }
155-
156- bytes32 key = Keys.claimableCollateralFactorKey (market, token, timeKey);
157- dataStore.setUint (key, factor);
158-
159- EventUtils.EventLogData memory eventData;
160-
161- eventData.addressItems.initItems (2 );
162- eventData.addressItems.setItem (0 , "market " , market);
163- eventData.addressItems.setItem (1 , "token " , token);
164-
165- eventData.uintItems.initItems (2 );
166- eventData.uintItems.setItem (0 , "timeKey " , timeKey);
167- eventData.uintItems.setItem (1 , "factor " , factor);
168-
169- eventEmitter.emitEventLog2 (
170- "SetClaimableCollateralFactorForTime " ,
171- Cast.toBytes32 (market),
172- Cast.toBytes32 (token),
173- eventData
132+ ConfigUtils.setClaimableCollateralFactorForTime (
133+ dataStore,
134+ eventEmitter,
135+ market,
136+ token,
137+ timeKey,
138+ factor
174139 );
175140 }
176141
@@ -181,27 +146,14 @@ contract Config is ReentrancyGuard, RoleModule, BasicMulticall {
181146 address account ,
182147 uint256 factor
183148 ) external onlyConfigKeeper nonReentrant {
184- if (factor > Precision.FLOAT_PRECISION) { revert Errors.InvalidClaimableFactor (factor); }
185-
186- bytes32 key = Keys.claimableCollateralFactorKey (market, token, timeKey, account);
187- dataStore.setUint (key, factor);
188-
189- EventUtils.EventLogData memory eventData;
190-
191- eventData.addressItems.initItems (3 );
192- eventData.addressItems.setItem (0 , "market " , market);
193- eventData.addressItems.setItem (1 , "token " , token);
194- eventData.addressItems.setItem (2 , "account " , account);
195-
196- eventData.uintItems.initItems (2 );
197- eventData.uintItems.setItem (0 , "timeKey " , timeKey);
198- eventData.uintItems.setItem (1 , "factor " , factor);
199-
200- eventEmitter.emitEventLog2 (
201- "SetClaimableCollateralFactorForAccount " ,
202- Cast.toBytes32 (market),
203- Cast.toBytes32 (token),
204- eventData
149+ ConfigUtils.setClaimableCollateralFactorForAccount (
150+ dataStore,
151+ eventEmitter,
152+ market,
153+ token,
154+ timeKey,
155+ account,
156+ factor
205157 );
206158 }
207159
@@ -210,36 +162,13 @@ contract Config is ReentrancyGuard, RoleModule, BasicMulticall {
210162 uint256 minPositionImpactPoolAmount ,
211163 uint256 positionImpactPoolDistributionRate
212164 ) external onlyConfigKeeper nonReentrant {
213- MarketUtils.distributePositionImpactPool (dataStore, eventEmitter, market);
214-
215- // Ensure the full positionImpactPoolAmount cannot be distributed in less then the minimum required time
216- uint256 positionImpactPoolAmount = MarketUtils.getPositionImpactPoolAmount (dataStore, market);
217- // positionImpactPoolDistributionRate has FLOAT_PRECISION, distributionAmount has WEI_PRECISION
218- uint256 distributionAmount = Precision.applyFactor (MIN_POSITION_IMPACT_POOL_DISTRIBUTION_TIME, positionImpactPoolDistributionRate);
219- if (positionImpactPoolAmount > 0 ) {
220- if (distributionAmount >= positionImpactPoolAmount) {
221- revert Errors.InvalidPositionImpactPoolDistributionRate (distributionAmount, positionImpactPoolAmount);
222- }
223- }
224-
225- dataStore.setUint (Keys.minPositionImpactPoolAmountKey (market), minPositionImpactPoolAmount);
226- dataStore.setUint (Keys.positionImpactPoolDistributionRateKey (market), positionImpactPoolDistributionRate);
227-
228- dataStore.setUint (Keys.positionImpactPoolDistributedAtKey (market), Chain.currentTimestamp ());
229-
230- EventUtils.EventLogData memory eventData;
231-
232- eventData.addressItems.initItems (1 );
233- eventData.addressItems.setItem (0 , "market " , market);
234-
235- eventData.uintItems.initItems (2 );
236- eventData.uintItems.setItem (0 , "minPositionImpactPoolAmount " , minPositionImpactPoolAmount);
237- eventData.uintItems.setItem (1 , "positionImpactPoolDistributionRate " , positionImpactPoolDistributionRate);
238-
239- eventEmitter.emitEventLog1 (
240- "SetPositionImpactPoolDistributionRate " ,
241- Cast.toBytes32 (market),
242- eventData
165+ ConfigUtils.setPositionImpactDistributionRate (
166+ dataStore,
167+ eventEmitter,
168+ market,
169+ minPositionImpactPoolAmount,
170+ positionImpactPoolDistributionRate,
171+ MIN_POSITION_IMPACT_POOL_DISTRIBUTION_TIME
243172 );
244173 }
245174
@@ -337,7 +266,15 @@ contract Config is ReentrancyGuard, RoleModule, BasicMulticall {
337266
338267 bytes32 fullKey = Keys.getFullKey (baseKey, data);
339268
340- _validateRange (baseKey, data, value);
269+ ConfigUtils.validateRange (
270+ dataStore,
271+ baseKey,
272+ data,
273+ value,
274+ MAX_ALLOWED_MAX_FUNDING_FACTOR_PER_SECOND,
275+ MAX_ALLOWED_FUNDING_INCREASE_FACTOR_PER_SECOND,
276+ MAX_ALLOWED_FUNDING_DECREASE_FACTOR_PER_SECOND
277+ );
341278
342279 dataStore.setUint (fullKey, value);
343280
@@ -605,155 +542,4 @@ contract Config is ReentrancyGuard, RoleModule, BasicMulticall {
605542
606543 revert Errors.InvalidBaseKey (baseKey);
607544 }
608-
609- // @dev validate that the value is within the allowed range
610- // @param baseKey the base key for the value
611- // @param value the value to be set
612- function _validateRange (bytes32 baseKey , bytes memory data , uint256 value ) internal view {
613- if (
614- baseKey == Keys.SEQUENCER_GRACE_DURATION
615- ) {
616- // 2 hours
617- if (value > 7200 ) {
618- revert Errors.ConfigValueExceedsAllowedRange (baseKey, value);
619- }
620- }
621-
622- if (
623- baseKey == Keys.MAX_FUNDING_FACTOR_PER_SECOND
624- ) {
625- if (value > MAX_ALLOWED_MAX_FUNDING_FACTOR_PER_SECOND) {
626- revert Errors.ConfigValueExceedsAllowedRange (baseKey, value);
627- }
628-
629- bytes32 minFundingFactorPerSecondKey = Keys.getFullKey (Keys.MIN_FUNDING_FACTOR_PER_SECOND, data);
630- uint256 minFundingFactorPerSecond = dataStore.getUint (minFundingFactorPerSecondKey);
631- if (value < minFundingFactorPerSecond) {
632- revert Errors.ConfigValueExceedsAllowedRange (baseKey, value);
633- }
634- }
635-
636- if (
637- baseKey == Keys.MIN_FUNDING_FACTOR_PER_SECOND
638- ) {
639- bytes32 maxFundingFactorPerSecondKey = Keys.getFullKey (Keys.MAX_FUNDING_FACTOR_PER_SECOND, data);
640- uint256 maxFundingFactorPerSecond = dataStore.getUint (maxFundingFactorPerSecondKey);
641- if (value > maxFundingFactorPerSecond) {
642- revert Errors.ConfigValueExceedsAllowedRange (baseKey, value);
643- }
644- }
645-
646- if (
647- baseKey == Keys.FUNDING_INCREASE_FACTOR_PER_SECOND
648- ) {
649- if (value > MAX_ALLOWED_FUNDING_INCREASE_FACTOR_PER_SECOND) {
650- revert Errors.ConfigValueExceedsAllowedRange (baseKey, value);
651- }
652- }
653-
654- if (
655- baseKey == Keys.FUNDING_DECREASE_FACTOR_PER_SECOND
656- ) {
657- if (value > MAX_ALLOWED_FUNDING_DECREASE_FACTOR_PER_SECOND) {
658- revert Errors.ConfigValueExceedsAllowedRange (baseKey, value);
659- }
660- }
661-
662- if (
663- baseKey == Keys.BORROWING_FACTOR ||
664- baseKey == Keys.BASE_BORROWING_FACTOR
665- ) {
666- // 0.000005% per second, ~157% per year at 100% utilization
667- if (value > 50000000000000000000000 ) {
668- revert Errors.ConfigValueExceedsAllowedRange (baseKey, value);
669- }
670- }
671-
672- if (baseKey == Keys.ABOVE_OPTIMAL_USAGE_BORROWING_FACTOR) {
673- // 0.00001% per second, ~315% per year at 100% utilization
674- if (value > 100000000000000000000000 ) {
675- revert Errors.ConfigValueExceedsAllowedRange (baseKey, value);
676- }
677- }
678-
679- if (
680- baseKey == Keys.FUNDING_EXPONENT_FACTOR ||
681- baseKey == Keys.BORROWING_EXPONENT_FACTOR
682- ) {
683- // revert if value > 2
684- if (value > 2 * Precision.FLOAT_PRECISION) {
685- revert Errors.ConfigValueExceedsAllowedRange (baseKey, value);
686- }
687- }
688-
689- if (
690- baseKey == Keys.POSITION_IMPACT_EXPONENT_FACTOR ||
691- baseKey == Keys.SWAP_IMPACT_EXPONENT_FACTOR
692- ) {
693- // revert if value > 3
694- if (value > 3 * Precision.FLOAT_PRECISION) {
695- revert Errors.ConfigValueExceedsAllowedRange (baseKey, value);
696- }
697- }
698-
699- if (
700- baseKey == Keys.FUNDING_FACTOR ||
701- baseKey == Keys.BORROWING_FACTOR ||
702- baseKey == Keys.FUNDING_INCREASE_FACTOR_PER_SECOND ||
703- baseKey == Keys.FUNDING_DECREASE_FACTOR_PER_SECOND ||
704- baseKey == Keys.MIN_COLLATERAL_FACTOR
705- ) {
706- // revert if value > 1%
707- if (value > 1 * Precision.FLOAT_PRECISION / 100 ) {
708- revert Errors.ConfigValueExceedsAllowedRange (baseKey, value);
709- }
710- }
711-
712- if (
713- baseKey == Keys.SWAP_FEE_FACTOR ||
714- baseKey == Keys.DEPOSIT_FEE_FACTOR ||
715- baseKey == Keys.WITHDRAWAL_FEE_FACTOR ||
716- baseKey == Keys.POSITION_FEE_FACTOR ||
717- baseKey == Keys.MAX_UI_FEE_FACTOR ||
718- baseKey == Keys.ATOMIC_SWAP_FEE_FACTOR ||
719- baseKey == Keys.BUYBACK_MAX_PRICE_IMPACT_FACTOR
720- ) {
721- // revert if value > 5%
722- if (value > 5 * Precision.FLOAT_PRECISION / 100 ) {
723- revert Errors.ConfigValueExceedsAllowedRange (baseKey, value);
724- }
725- }
726-
727- if (baseKey == Keys.LIQUIDATION_FEE_FACTOR) {
728- // revert if value > 1%
729- if (value > Precision.FLOAT_PRECISION / 100 ) {
730- revert Errors.ConfigValueExceedsAllowedRange (baseKey, value);
731- }
732- }
733-
734- if (baseKey == Keys.MIN_COLLATERAL_USD) {
735- // revert if value > 10 USD
736- if (value > 10 * Precision.FLOAT_PRECISION) {
737- revert Errors.ConfigValueExceedsAllowedRange (baseKey, value);
738- }
739- }
740-
741- if (
742- baseKey == Keys.POSITION_FEE_RECEIVER_FACTOR ||
743- baseKey == Keys.SWAP_FEE_RECEIVER_FACTOR ||
744- baseKey == Keys.BORROWING_FEE_RECEIVER_FACTOR ||
745- baseKey == Keys.LIQUIDATION_FEE_RECEIVER_FACTOR ||
746- baseKey == Keys.MAX_PNL_FACTOR ||
747- baseKey == Keys.MIN_PNL_FACTOR_AFTER_ADL ||
748- baseKey == Keys.OPTIMAL_USAGE_FACTOR ||
749- baseKey == Keys.PRO_DISCOUNT_FACTOR ||
750- baseKey == Keys.BUYBACK_GMX_FACTOR ||
751- baseKey == Keys.DATA_STREAM_SPREAD_REDUCTION_FACTOR
752- ) {
753- // revert if value > 100%
754- if (value > Precision.FLOAT_PRECISION) {
755- revert Errors.ConfigValueExceedsAllowedRange (baseKey, value);
756- }
757- }
758- }
759545}
0 commit comments