Skip to content

Commit 89d62bc

Browse files
committed
fix: use fixed-length array for priceIds in req
1 parent 0e2434d commit 89d62bc

File tree

3 files changed

+26
-6
lines changed

3 files changed

+26
-6
lines changed

target_chains/ethereum/contracts/contracts/pulse/Pulse.sol

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,11 @@ abstract contract Pulse is IPulse, PulseState {
3131
req.publishTime = 1;
3232
req.callbackGasLimit = 1;
3333
req.requester = address(1);
34+
req.numPriceIds = 0;
35+
// Pre-warm the priceIds array storage
36+
for (uint8 j = 0; j < MAX_PRICE_IDS; j++) {
37+
req.priceIds[j] = bytes32(0);
38+
}
3439
}
3540
}
3641
}
@@ -41,6 +46,9 @@ abstract contract Pulse is IPulse, PulseState {
4146
uint256 callbackGasLimit
4247
) external payable override returns (uint64 requestSequenceNumber) {
4348
require(publishTime <= block.timestamp + 60, "Too far in future");
49+
if (priceIds.length > MAX_PRICE_IDS) {
50+
revert TooManyPriceIds(priceIds.length, MAX_PRICE_IDS);
51+
}
4452
requestSequenceNumber = _state.currentSequenceNumber++;
4553

4654
uint128 requiredFee = getFee(callbackGasLimit);
@@ -49,9 +57,14 @@ abstract contract Pulse is IPulse, PulseState {
4957
Request storage req = allocRequest(requestSequenceNumber);
5058
req.sequenceNumber = requestSequenceNumber;
5159
req.publishTime = publishTime;
52-
req.priceIdsHash = keccak256(abi.encode(priceIds));
5360
req.callbackGasLimit = callbackGasLimit;
5461
req.requester = msg.sender;
62+
req.numPriceIds = uint8(priceIds.length);
63+
64+
// Copy price IDs to storage
65+
for (uint8 i = 0; i < priceIds.length; i++) {
66+
req.priceIds[i] = priceIds[i];
67+
}
5568

5669
_state.accruedFeesInWei += SafeCast.toUint128(msg.value);
5770

@@ -66,10 +79,14 @@ abstract contract Pulse is IPulse, PulseState {
6679
Request storage req = findActiveRequest(sequenceNumber);
6780

6881
// Verify priceIds match
69-
bytes32 providedPriceIdsHash = keccak256(abi.encode(priceIds));
70-
bytes32 storedPriceIdsHash = req.priceIdsHash;
71-
if (providedPriceIdsHash != storedPriceIdsHash) {
72-
revert InvalidPriceIds(providedPriceIdsHash, storedPriceIdsHash);
82+
require(
83+
priceIds.length == req.numPriceIds,
84+
"Price IDs length mismatch"
85+
);
86+
for (uint8 i = 0; i < req.numPriceIds; i++) {
87+
if (priceIds[i] != req.priceIds[i]) {
88+
revert InvalidPriceIds(priceIds[i], req.priceIds[i]);
89+
}
7390
}
7491

7592
// Parse price feeds first to measure gas usage

target_chains/ethereum/contracts/contracts/pulse/PulseErrors.sol

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,3 +12,4 @@ error InvalidPriceIds(bytes32 providedPriceIdsHash, bytes32 storedPriceIdsHash);
1212
error InvalidCallbackGasLimit(uint256 requested, uint256 stored);
1313
error ExceedsMaxPrices(uint32 requested, uint32 maxAllowed);
1414
error InsufficientGas();
15+
error TooManyPriceIds(uint256 provided, uint256 maximum);

target_chains/ethereum/contracts/contracts/pulse/PulseState.sol

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,13 @@ pragma solidity ^0.8.0;
55
contract PulseState {
66
uint8 public constant NUM_REQUESTS = 32;
77
bytes1 public constant NUM_REQUESTS_MASK = 0x1f;
8+
uint8 public constant MAX_PRICE_IDS = 10;
89

910
struct Request {
1011
uint64 sequenceNumber;
1112
uint256 publishTime;
12-
bytes32 priceIdsHash;
13+
bytes32[MAX_PRICE_IDS] priceIds;
14+
uint8 numPriceIds; // Actual number of price IDs used
1315
uint256 callbackGasLimit;
1416
address requester;
1517
}

0 commit comments

Comments
 (0)