You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Issue 1 Use memory variables instead of state variables to save gas
In allocateFunds() from Project.sol, the function loops through all items in the dynamic array _changeOrderedTask using its length. However, the length is read from storage every loop, consider saving the length in memory and using that in the for loop
Additionally, this applies for looping up to taskCount
Consider rewriting to:
function allocateFunds() publicoverride {
// Max amount out times this loop will run// This is to ensure the transaction do not run out of gas (max gas limit)uint256 _maxLoop =50;
// Difference of totalLent and totalAllocated is what can be used to allocate new tasksuint256 _costToAllocate = totalLent - totalAllocated;
// Bool if max loop limit is exceededbool _exceedLimit;
// Local instance of lastAllocatedChangeOrderTask. To save gas.uint256 i = lastAllocatedChangeOrderTask;
// Local instance of lastAllocatedTask. To save gas.uint256 j = lastAllocatedTask;
uint256 _taskCount = taskCount;
uint256 length = _changeOrderedTask.length;
// Initialize empty array in which allocated tasks will be added.uint256[] memory _tasksAllocated =newuint256[](
_taskCount - j + length - i
);
// Number of times a loop has run.uint256 _loopCount;
/// CHANGE ORDERED TASK FUNDING ///// Any tasks added to _changeOrderedTask will be allocated firstif (length >0) {
// Loop from lastAllocatedChangeOrderTask to _changeOrderedTask length (until _maxLoop)for (; i < length; i++) {
// Local instance of task cost. To save gas.uint256 _taskCost = tasks[_changeOrderedTask[i]].cost;
// If _maxLoop limit is reached then stop loopingif (_loopCount >= _maxLoop) {
_exceedLimit =true;
break;
}
// If there is enough funds to allocate this taskif (_costToAllocate >= _taskCost) {
// Reduce task cost from _costToAllocate
_costToAllocate -= _taskCost;
// Mark the task as allocated
tasks[_changeOrderedTask[i]].fundTask();
// Add task to _tasksAllocated array
_tasksAllocated[_loopCount] = _changeOrderedTask[i];
// Increment loop counter
_loopCount++;
}
// If there are not enough funds to allocate this task then stop loopingelse {
break;
}
}
// If all the change ordered tasks are allocated, then delete// the changeOrderedTask array and reset lastAllocatedChangeOrderTask.if (i == length) {
lastAllocatedChangeOrderTask =0;
delete _changeOrderedTask;
}
// Else store the last allocated change order task index.else {
lastAllocatedChangeOrderTask = i;
}
}
/// TASK FUNDING ///// If lastAllocatedTask is lesser than taskCount, that means there are un-allocated tasksif (j < _taskCount) {
// Loop from lastAllocatedTask + 1 to taskCount (until _maxLoop)for (++j; j <= _taskCount; j++) {
// Local instance of task cost. To save gas.uint256 _taskCost = tasks[j].cost;
// If _maxLoop limit is reached then stop loopingif (_loopCount >= _maxLoop) {
_exceedLimit =true;
break;
}
// If there is enough funds to allocate this taskif (_costToAllocate >= _taskCost) {
// Reduce task cost from _costToAllocate
_costToAllocate -= _taskCost;
// Mark the task as allocated
tasks[j].fundTask();
// Add task to _tasksAllocated array
_tasksAllocated[_loopCount] = j;
// Increment loop counter
_loopCount++;
}
// If there are not enough funds to allocate this task then stop loopingelse {
break;
}
}
// If all pending tasks are allocated store lastAllocatedTask equal to taskCountif (j > _taskCount) {
lastAllocatedTask = _taskCount;
}
// If not all tasks are allocated store updated lastAllocatedTaskelse {
lastAllocatedTask =--j;
}
}
// If any tasks is allocated, then emit eventif (_loopCount >0) emitTaskAllocated(_tasksAllocated);
// If allocation was incomplete, then emit eventif (_exceedLimit) emitIncompleteAllocation();
// Update totalAllocated with all allocations
totalAllocated = totalLent - _costToAllocate;
}
Using tests from repo:
average gas used for allocateFunds() before fix: 63493
average gas used for allocateFunds() after fix: 63085
Average gas saved: 408
The text was updated successfully, but these errors were encountered:
Issue 1 Use memory variables instead of state variables to save gas
In
allocateFunds()
from Project.sol, the function loops through all items in the dynamic array_changeOrderedTask
using its length. However, the length is read from storage every loop, consider saving the length in memory and using that in the for loopAdditionally, this applies for looping up to
taskCount
Consider rewriting to:
Using tests from repo:
average gas used for
allocateFunds()
before fix: 63493average gas used for
allocateFunds()
after fix: 63085Average gas saved: 408
The text was updated successfully, but these errors were encountered: