Skip to content

Commit c3ec05a

Browse files
authored
Fenwick gas improvements (#761)
* Calcualte current index only once * Declare vars outside for / while loops
1 parent 48791b5 commit c3ec05a

File tree

1 file changed

+33
-15
lines changed

1 file changed

+33
-15
lines changed

src/libraries/internal/Deposits.sol

Lines changed: 33 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -40,13 +40,17 @@ library Deposits {
4040
// 2- We often need to precisely change the value in the tree, avoiding the rounding that dividing by scale(index).
4141
// This is more relevant to unscaledRemove(...), where we need to ensure the value is precisely set to 0, but we
4242
// also prefer it here for consistency.
43-
43+
44+
uint256 value;
45+
uint256 scaling;
46+
uint256 newValue;
47+
4448
while (index_ <= SIZE) {
45-
uint256 value = deposits_.values[index_];
46-
uint256 scaling = deposits_.scaling[index_];
49+
value = deposits_.values[index_];
50+
scaling = deposits_.scaling[index_];
4751

4852
// Compute the new value to be put in location index_
49-
uint256 newValue = value + unscaledAddAmount_;
53+
newValue = value + unscaledAddAmount_;
5054

5155
// Update unscaledAddAmount to propogate up the Fenwick tree
5256
// Note: we can't just multiply addAmount_ by scaling[i_] due to rounding
@@ -81,22 +85,27 @@ library Deposits {
8185
// We construct the target sumIndex_ bit by bit, from MSB to LSB. lowerIndexSum_ always maintains the sum
8286
// up to the current value of sumIndex_
8387
uint256 lowerIndexSum;
88+
uint256 curIndex;
89+
uint256 value;
90+
uint256 scaling;
91+
uint256 scaledValue;
8492

8593
while (i > 0) {
8694
// Consider if the target index is less than or greater than sumIndex_ + i
87-
uint256 value = deposits_.values[sumIndex_ + i];
88-
uint256 scaling = deposits_.scaling[sumIndex_ + i];
95+
curIndex = sumIndex_ + i;
96+
value = deposits_.values[curIndex];
97+
scaling = deposits_.scaling[curIndex];
8998

9099
// Compute sum up to sumIndex_ + i
91-
uint256 scaledValue =
100+
scaledValue =
92101
lowerIndexSum +
93102
(scaling != 0 ? (runningScale * scaling * value + 5e35) / 1e36 : Maths.wmul(runningScale, value));
94103

95104
if (scaledValue < targetSum_) {
96105
// Target value is too small, need to consider increasing sumIndex_ still
97-
if (sumIndex_ + i <= MAX_FENWICK_INDEX) {
106+
if (curIndex <= MAX_FENWICK_INDEX) {
98107
// sumIndex_+i is in range of Fenwick prices. Target index has this bit set to 1.
99-
sumIndex_ += i;
108+
sumIndex_ = curIndex;
100109
lowerIndexSum = scaledValue;
101110
}
102111
} else {
@@ -227,23 +236,26 @@ library Deposits {
227236

228237
// Used to terminate loop. We don't need to consider final 0 bits of sumIndex_
229238
uint256 indexLSB = lsb(sumIndex_);
239+
uint256 curIndex;
230240

231241
while (j >= indexLSB) {
242+
curIndex = index + j;
243+
232244
// Skip considering indices outside bounds of Fenwick tree
233-
if (index + j > SIZE) continue;
245+
if (curIndex > SIZE) continue;
234246

235247
// We are considering whether to include node index + j in the sum or not. Either way, we need to scaling[index + j],
236248
// either to increment sum_ or to accumulate in runningScale
237-
uint256 scaled = deposits_.scaling[index + j];
249+
uint256 scaled = deposits_.scaling[curIndex];
238250

239251
if (sumIndex_ & j != 0) {
240252
// node index + j of tree is included in sum
241-
uint256 value = deposits_.values[index + j];
253+
uint256 value = deposits_.values[curIndex];
242254

243255
// Accumulate in sum_, recall that scaled==0 means that the scale factor is actually 1
244256
sum_ += scaled != 0 ? (runningScale * scaled * value + 5e35) / 1e36 : Maths.wmul(runningScale, value);
245257
// Build up index bit by bit
246-
index += j;
258+
index = curIndex;
247259

248260
// terminate if we've already matched sumIndex_
249261
if (index == sumIndex_) break;
@@ -352,9 +364,15 @@ library Deposits {
352364
// 2- We may already have computed the scale factor, so we can avoid duplicate traversal
353365

354366
unscaledDepositValue_ = deposits_.values[index_];
367+
uint256 curIndex;
368+
uint256 value;
369+
uint256 scaling;
370+
355371
while (j & index_ == 0) {
356-
uint256 value = deposits_.values[index_ - j];
357-
uint256 scaling = deposits_.scaling[index_ - j];
372+
curIndex = index_ - j;
373+
374+
value = deposits_.values[curIndex];
375+
scaling = deposits_.scaling[curIndex];
358376

359377
unscaledDepositValue_ -= scaling != 0 ? Maths.wmul(scaling, value) : value;
360378
j = j << 1;

0 commit comments

Comments
 (0)