I am developing a contract that needs to use historical Chainlink prices.
I use the following approach: The caller passes the roundId to contract, according to which we get the price data. Contract get the next roundId to make sure that the roundId is in the right time range.
Current understanding: proxyRoundId = phaseId >> x64 | aggregatorRoundId proxyRoundId - increases monotonously(+1) each new round within same phase. Increases nonmonotonically if phase change. phaseId - depends on Argregator version/implementation. When change aggregator increases phaseId(+1). aggregatorRoundId - starts from 1 and increases monotonously(+1) with each new round.
I checked the value of RoundData for oracles during the transition between phases and did not fully understand the logic of publishing RoundData.
The contract -
roundId uint80 : 18446744073709551727 => phaseId 1, aggregatorRoundId 111
answer int256 : 99939094
startedAt uint256 : 1725911063
updatedAt uint256 : 1725911063
answeredInRound uint80 : 18446744073709551727
roundId uint80 : 36893488147419103233 => phaseId 2, aggregatorRoundId 1
answer int256 : 99894945
startedAt uint256 : 1720771216
updatedAt uint256 : 1720771295
answeredInRound uint80 : 36893488147419103233
Questions:
- Why RoundData(36893488147419103233).updatedAt < RoundData(18446744073709551727).updatedAt? Based on the current understanding, the new phase should have the newest values compared to the previous one.
- I think that for this task I can try to use a binary search by roundId and check RoundData.updatedAt, but the implementation in the contract consumes a lot of gas. Do you know more effective ways to get roundId by timestamp?
- Up to what time are the rounds in the old phase updated (when is the switch to the new phase)?
- How is it optimal to search for prices based on historical data if the timestamp may overlap in different phases?
I am developing a contract that needs to use historical Chainlink prices.
I use the following approach: The caller passes the roundId to contract, according to which we get the price data. Contract get the next roundId to make sure that the roundId is in the right time range.
Current understanding: proxyRoundId = phaseId >> x64 | aggregatorRoundId proxyRoundId - increases monotonously(+1) each new round within same phase. Increases nonmonotonically if phase change. phaseId - depends on Argregator version/implementation. When change aggregator increases phaseId(+1). aggregatorRoundId - starts from 1 and increases monotonously(+1) with each new round.
I checked the value of RoundData for oracles during the transition between phases and did not fully understand the logic of publishing RoundData.
The contract - https://etherscan.io/address/0xa569d910839Ae8865Da8F8e70FfFb0cBA869F961
roundId uint80 : 18446744073709551727 => phaseId 1, aggregatorRoundId 111
answer int256 : 99939094
startedAt uint256 : 1725911063
updatedAt uint256 : 1725911063
answeredInRound uint80 : 18446744073709551727
roundId uint80 : 36893488147419103233 => phaseId 2, aggregatorRoundId 1
answer int256 : 99894945
startedAt uint256 : 1720771216
updatedAt uint256 : 1720771295
answeredInRound uint80 : 36893488147419103233
Questions:
- Why RoundData(36893488147419103233).updatedAt < RoundData(18446744073709551727).updatedAt? Based on the current understanding, the new phase should have the newest values compared to the previous one.
- I think that for this task I can try to use a binary search by roundId and check RoundData.updatedAt, but the implementation in the contract consumes a lot of gas. Do you know more effective ways to get roundId by timestamp?
- Up to what time are the rounds in the old phase updated (when is the switch to the new phase)?
- How is it optimal to search for prices based on historical data if the timestamp may overlap in different phases?
1 Answer
Reset to default 0Here is a Pseudocode for Binary Search
function findRoundId(uint256 targetTimestamp) public view returns (uint80 roundId) {
AggregatorV3Interface aggregator = AggregatorV3Interface(AGGREGATOR_ADDRESS);
uint80 low = aggregator.firstRound();
uint80 high = aggregator.latestRound();
while (low < high) {
uint80 mid = low + (high - low) / 2;
(, , , uint256 midTimestamp, ) = aggregator.getRoundData(mid);
if (midTimestamp < targetTimestamp) {
low = mid + 1;
} else {
high = mid;
}
}
return low; // Closest round ID
}
发布者:admin,转转请注明出处:http://www.yc00.com/questions/1742296126a4417152.html
评论列表(0条)