decrementWeightUntilFree can be optimized by using _userGauges[user].at(i) and _userGauges[user].length() directly instead of storing _userGauges[user].values() as gaugeList and calling gaugeList.length and gaugeList[i].
Implementation:
function _decrementWeightUntilFree(address user, uint256 weight) internal {
uint256 userFreeWeight = balanceOf[user] - getUserWeight[user];
// early return if already free
if (userFreeWeight >= weight) return;
uint32 currentCycle = _getGaugeCycleEnd();
// cache totals for batch updates
uint112 userFreed;
uint112 totalFreed;
// Loop through all user gauges, live and deprecated
//address[] memory gaugeList = _userGauges[user].values();
// Free gauges until through entire list or under weight
uint256 size = _userGauges[user].length();
//uint256 size = gaugeList.length;
for (uint256 i = 0; i < size && (userFreeWeight + totalFreed) < weight; ) {
//address gauge = gaugeList[i];
address gauge = _userGauges[user].at(i);
uint112 userGaugeWeight = getUserGaugeWeight[user][gauge];
if (userGaugeWeight != 0) {
// If the gauge is live (not deprecated), include its weight in the total to remove
if (!_deprecatedGauges.contains(gauge)) {
totalFreed += userGaugeWeight;
}
userFreed += userGaugeWeight;
_decrementGaugeWeight(user, gauge, userGaugeWeight, currentCycle);
unchecked {
i++;
}
}
}
getUserWeight[user] -= userFreed;
_writeGaugeWeight(_totalWeight, _subtract, totalFreed, currentCycle);
}
Gas testing function:
function testGasGauge() public {
token.mint(address(this), 100e18);
token.setMaxGauges(5);
uint160 i = 1; // address 0 causes reverts
while (i < 3) {
token.addGauge(address(i));
token.incrementGauge(address(i), 50e18);
i++;
}
startMeasuringGas("transfer call");
token.transfer(address(1000000), 1);
stopMeasuringGas();
}
decrementWeightUntilFree
can be optimized by using_userGauges[user].at(i)
and_userGauges[user].length()
directly instead of storing_userGauges[user].values()
asgaugeList
and callinggaugeList.length
andgaugeList[i]
.Implementation:
Gas testing function: