diff --git a/src/libraries/DrawAccumulatorLib.sol b/src/libraries/DrawAccumulatorLib.sol index 4f8ef4c..024ad1c 100644 --- a/src/libraries/DrawAccumulatorLib.sol +++ b/src/libraries/DrawAccumulatorLib.sol @@ -161,56 +161,42 @@ library DrawAccumulatorLib { return 0; } - uint24 firstObservationDrawIdOccurringAtOrAfterStart; + Observation memory atOrAfterStart; if (_startDrawId <= oldestDrawId || ringBufferInfo.cardinality == 1) { - firstObservationDrawIdOccurringAtOrAfterStart = oldestDrawId; + atOrAfterStart = _accumulator.observations[oldestDrawId]; } else { - // The start must be between newest and oldest - uint24 beforeOrAtDrawId; - // binary search - ( - , - beforeOrAtDrawId, - , - firstObservationDrawIdOccurringAtOrAfterStart - ) = binarySearch( - _accumulator.drawRingBuffer, - uint16(oldestIndex), - uint16(newestIndex), - ringBufferInfo.cardinality, - _startDrawId - ); - if (beforeOrAtDrawId == _startDrawId) { - firstObservationDrawIdOccurringAtOrAfterStart = _startDrawId; + // check if the start draw has an observation, otherwise search for the earliest observation after + atOrAfterStart = _accumulator.observations[_startDrawId]; + if (atOrAfterStart.available == 0 && atOrAfterStart.disbursed == 0) { + (, , , uint24 afterOrAtDrawId) = binarySearch( + _accumulator.drawRingBuffer, + oldestIndex, + newestIndex, + ringBufferInfo.cardinality, + _startDrawId + ); + atOrAfterStart = _accumulator.observations[afterOrAtDrawId]; } } - uint24 lastObservationDrawIdOccurringAtOrBeforeEnd; + Observation memory atOrBeforeEnd; if (_endDrawId >= newestDrawId || ringBufferInfo.cardinality == 1) { - // then it must be the end - lastObservationDrawIdOccurringAtOrBeforeEnd = newestDrawId; + atOrBeforeEnd = _accumulator.observations[newestDrawId]; } else { - uint24 afterOrAtDrawId; - (, lastObservationDrawIdOccurringAtOrBeforeEnd, ,afterOrAtDrawId) = binarySearch( - _accumulator.drawRingBuffer, - uint16(oldestIndex), - uint16(newestIndex), - ringBufferInfo.cardinality, - _endDrawId - ); - if (afterOrAtDrawId == _endDrawId) { - lastObservationDrawIdOccurringAtOrBeforeEnd = _endDrawId; + // check if the end draw has an observation, otherwise search for the latest observation before + atOrBeforeEnd = _accumulator.observations[_endDrawId]; + if (atOrBeforeEnd.available == 0 && atOrBeforeEnd.disbursed == 0) { + (, uint24 beforeOrAtDrawId, , ) = binarySearch( + _accumulator.drawRingBuffer, + oldestIndex, + newestIndex, + ringBufferInfo.cardinality, + _endDrawId + ); + atOrBeforeEnd = _accumulator.observations[beforeOrAtDrawId]; } } - Observation memory atOrAfterStart = _accumulator.observations[ - firstObservationDrawIdOccurringAtOrAfterStart - ]; - - Observation memory atOrBeforeEnd = _accumulator.observations[ - lastObservationDrawIdOccurringAtOrBeforeEnd - ]; - return atOrBeforeEnd.available + atOrBeforeEnd.disbursed - atOrAfterStart.disbursed; }