@@ -11,11 +11,11 @@ import "./PulseErrors.sol";
1111abstract contract Pulse is IPulse , PulseState {
1212 function _initialize (
1313 address admin ,
14- uint128 pythFeeInWei ,
14+ uint96 pythFeeInWei ,
1515 address pythAddress ,
1616 address defaultProvider ,
1717 bool prefillRequestStorage ,
18- uint256 exclusivityPeriodSeconds
18+ uint32 exclusivityPeriodSeconds
1919 ) internal {
2020 require (admin != address (0 ), "admin is zero address " );
2121 require (pythAddress != address (0 ), "pyth is zero address " );
@@ -44,11 +44,6 @@ abstract contract Pulse is IPulse, PulseState {
4444 req.publishTime = 1 ;
4545 req.callbackGasLimit = 1 ;
4646 req.requester = address (1 );
47- req.numPriceIds = 0 ;
48- // Pre-warm the priceIds array storage
49- for (uint8 j = 0 ; j < MAX_PRICE_IDS; j++ ) {
50- req.priceIds[j] = bytes32 (0 );
51- }
5247 }
5348 }
5449 }
@@ -58,7 +53,7 @@ abstract contract Pulse is IPulse, PulseState {
5853 address provider ,
5954 uint64 publishTime ,
6055 bytes32 [] calldata priceIds ,
61- uint256 callbackGasLimit
56+ uint32 callbackGasLimit
6257 ) external payable override returns (uint64 requestSequenceNumber ) {
6358 require (
6459 _state.providers[provider].isRegistered,
@@ -77,21 +72,29 @@ abstract contract Pulse is IPulse, PulseState {
7772 }
7873 requestSequenceNumber = _state.currentSequenceNumber++ ;
7974
80- uint128 requiredFee = getFee (provider, callbackGasLimit, priceIds);
75+ uint96 requiredFee = getFee (provider, callbackGasLimit, priceIds);
8176 if (msg .value < requiredFee) revert InsufficientFee ();
8277
8378 Request storage req = allocRequest (requestSequenceNumber);
8479 req.sequenceNumber = requestSequenceNumber;
8580 req.publishTime = publishTime;
8681 req.callbackGasLimit = callbackGasLimit;
8782 req.requester = msg .sender ;
88- req.numPriceIds = uint8 (priceIds.length );
8983 req.provider = provider;
90- req.fee = SafeCast.toUint128 (msg .value - _state.pythFeeInWei);
84+ req.fee = SafeCast.toUint96 (msg .value - _state.pythFeeInWei);
9185
92- // Copy price IDs to storage
86+ // Create array with the right size
87+ req.priceIdPrefixes = new bytes8 [](priceIds.length );
88+
89+ // Copy only the first 8 bytes of each price ID to storage
9390 for (uint8 i = 0 ; i < priceIds.length ; i++ ) {
94- req.priceIds[i] = priceIds[i];
91+ // Extract first 8 bytes of the price ID
92+ bytes32 priceId = priceIds[i];
93+ bytes8 prefix;
94+ assembly {
95+ prefix := priceId
96+ }
97+ req.priceIdPrefixes[i] = prefix;
9598 }
9699 _state.accruedFeesInWei += _state.pythFeeInWei;
97100
@@ -119,12 +122,21 @@ abstract contract Pulse is IPulse, PulseState {
119122
120123 // Verify priceIds match
121124 require (
122- priceIds.length == req.numPriceIds ,
125+ priceIds.length == req.priceIdPrefixes. length ,
123126 "Price IDs length mismatch "
124127 );
125- for (uint8 i = 0 ; i < req.numPriceIds; i++ ) {
126- if (priceIds[i] != req.priceIds[i]) {
127- revert InvalidPriceIds (priceIds[i], req.priceIds[i]);
128+ for (uint8 i = 0 ; i < req.priceIdPrefixes.length ; i++ ) {
129+ // Extract first 8 bytes of the provided price ID
130+ bytes32 priceId = priceIds[i];
131+ bytes8 prefix;
132+ assembly {
133+ prefix := priceId
134+ }
135+
136+ // Compare with stored prefix
137+ if (prefix != req.priceIdPrefixes[i]) {
138+ // Now we can directly use the bytes8 prefix in the error
139+ revert InvalidPriceIds (priceIds[i], req.priceIdPrefixes[i]);
128140 }
129141 }
130142
@@ -222,31 +234,31 @@ abstract contract Pulse is IPulse, PulseState {
222234
223235 function getFee (
224236 address provider ,
225- uint256 callbackGasLimit ,
237+ uint32 callbackGasLimit ,
226238 bytes32 [] calldata priceIds
227- ) public view override returns (uint128 feeAmount ) {
228- uint128 baseFee = _state.pythFeeInWei; // Fixed fee to Pyth
239+ ) public view override returns (uint96 feeAmount ) {
240+ uint96 baseFee = _state.pythFeeInWei; // Fixed fee to Pyth
229241 // Note: The provider needs to set its fees to include the fee charged by the Pyth contract.
230242 // Ideally, we would be able to automatically compute the pyth fees from the priceIds, but the
231243 // fee computation on IPyth assumes it has the full updated data.
232- uint128 providerBaseFee = _state.providers[provider].baseFeeInWei;
233- uint128 providerFeedFee = SafeCast.toUint128 (
244+ uint96 providerBaseFee = _state.providers[provider].baseFeeInWei;
245+ uint96 providerFeedFee = SafeCast.toUint96 (
234246 priceIds.length * _state.providers[provider].feePerFeedInWei
235247 );
236- uint128 providerFeeInWei = _state.providers[provider].feePerGasInWei; // Provider's per-gas rate
248+ uint96 providerFeeInWei = _state.providers[provider].feePerGasInWei; // Provider's per-gas rate
237249 uint256 gasFee = callbackGasLimit * providerFeeInWei; // Total provider fee based on gas
238250 feeAmount =
239251 baseFee +
240252 providerBaseFee +
241253 providerFeedFee +
242- SafeCast.toUint128 (gasFee); // Total fee user needs to pay
254+ SafeCast.toUint96 (gasFee); // Total fee user needs to pay
243255 }
244256
245257 function getPythFeeInWei ()
246258 public
247259 view
248260 override
249- returns (uint128 pythFeeInWei )
261+ returns (uint96 pythFeeInWei )
250262 {
251263 pythFeeInWei = _state.pythFeeInWei;
252264 }
@@ -367,9 +379,9 @@ abstract contract Pulse is IPulse, PulseState {
367379 }
368380
369381 function registerProvider (
370- uint128 baseFeeInWei ,
371- uint128 feePerFeedInWei ,
372- uint128 feePerGasInWei
382+ uint96 baseFeeInWei ,
383+ uint96 feePerFeedInWei ,
384+ uint96 feePerGasInWei
373385 ) external override {
374386 ProviderInfo storage provider = _state.providers[msg .sender ];
375387 require (! provider.isRegistered, "Provider already registered " );
@@ -382,9 +394,9 @@ abstract contract Pulse is IPulse, PulseState {
382394
383395 function setProviderFee (
384396 address provider ,
385- uint128 newBaseFeeInWei ,
386- uint128 newFeePerFeedInWei ,
387- uint128 newFeePerGasInWei
397+ uint96 newBaseFeeInWei ,
398+ uint96 newFeePerFeedInWei ,
399+ uint96 newFeePerGasInWei
388400 ) external override {
389401 require (
390402 _state.providers[provider].isRegistered,
@@ -396,9 +408,9 @@ abstract contract Pulse is IPulse, PulseState {
396408 "Only provider or fee manager can invoke this method "
397409 );
398410
399- uint128 oldBaseFee = _state.providers[provider].baseFeeInWei;
400- uint128 oldFeePerFeed = _state.providers[provider].feePerFeedInWei;
401- uint128 oldFeePerGas = _state.providers[provider].feePerGasInWei;
411+ uint96 oldBaseFee = _state.providers[provider].baseFeeInWei;
412+ uint96 oldFeePerFeed = _state.providers[provider].feePerFeedInWei;
413+ uint96 oldFeePerGas = _state.providers[provider].feePerGasInWei;
402414 _state.providers[provider].baseFeeInWei = newBaseFeeInWei;
403415 _state.providers[provider].feePerFeedInWei = newFeePerFeedInWei;
404416 _state.providers[provider].feePerGasInWei = newFeePerGasInWei;
@@ -437,7 +449,7 @@ abstract contract Pulse is IPulse, PulseState {
437449 emit DefaultProviderUpdated (oldProvider, provider);
438450 }
439451
440- function setExclusivityPeriod (uint256 periodSeconds ) external override {
452+ function setExclusivityPeriod (uint32 periodSeconds ) external override {
441453 require (
442454 msg .sender == _state.admin,
443455 "Only admin can set exclusivity period "
@@ -447,7 +459,7 @@ abstract contract Pulse is IPulse, PulseState {
447459 emit ExclusivityPeriodUpdated (oldPeriod, periodSeconds);
448460 }
449461
450- function getExclusivityPeriod () external view override returns (uint256 ) {
462+ function getExclusivityPeriod () external view override returns (uint32 ) {
451463 return _state.exclusivityPeriodSeconds;
452464 }
453465
0 commit comments