Omniscia CloudFunding Audit
Manager Code Style Findings
Manager Code Style Findings
MAN-01C: Expensive Array Maintenance Operation
Type | Severity | Location |
---|---|---|
Gas Optimization | Manager.sol:L54-L65 |
Description:
The ftsoRewardManagersTmp
array is a temporary array that retains the managers that should be added after they are all identified as they need to be included in reverse order.
Example:
50function updateFtsoRewardManagers() external {51 IFtsoRewardManager lastSaved = ftsoRewardManagers[ftsoRewardManagers.length - 1];52 IFtsoRewardManager current = FlareLibrary.getFtsoRewardManager(FlareLibrary.getFtsoManager());53 if (current != lastSaved) {54 do {55 ftsoRewardManagersTmp.push(current);56 IFtsoRewardManager previous = getPreviousFtsoRewardManager(current);57 if (previous == lastSaved || address(previous) == address(0)) break;58 current = previous;59 } while (true);60 for (uint256 i = ftsoRewardManagersTmp.length; i > 0; i--) {61 IFtsoRewardManager ftsoRewardManager = ftsoRewardManagersTmp[i - 1];62 ftsoRewardManagers.push(ftsoRewardManager);63 ftsoRewardManagersTmp.pop();64 emit AddFtsoRewardManager(address(ftsoRewardManager));65 }66 }67}
Recommendation:
We advise the updateFtsoRewardManagers
function to introduce an input argument specifying the number of expected managers to add in the loop and an in-memory dynamic array to be created instead, removing the need for a very expensive storage array and optimizing the gas cost of the function significantly.
Alleviation:
The CloudFunding team has opted not to alleviate any informational or minor exhibits they disagree with, thus rendering this exhibit as acknowledged.
MAN-02C: Suboptimal Iteration of Potential New Managers
Type | Severity | Location |
---|---|---|
Gas Optimization | Manager.sol:L76-L92 |
Description:
The getFtsoRewardManagers
function currently contains additional logic handling up to 3
new reward managers, however, this is redundant as the updateFtsoRewardManagers
could be invoked instead.
Example:
69function getFtsoRewardManagers() external view returns (IFtsoRewardManager[] memory managers) {70 IFtsoRewardManager lastSaved = ftsoRewardManagers[ftsoRewardManagers.length - 1];71 IFtsoRewardManager current = FlareLibrary.getFtsoRewardManager(FlareLibrary.getFtsoManager());72 if (current == lastSaved) {73 // no changes74 managers = ftsoRewardManagers;75 } else {76 // new ftso reward manager(s), handle up to 2 new77 IFtsoRewardManager[] memory extra = new IFtsoRewardManager[](3);78 uint256 count;79 extra[count] = current;80 do {81 count++;82 require(count < extra.length, 'Update FtsoRewardManager');83 extra[count] = getPreviousFtsoRewardManager(extra[count - 1]);84 } while (extra[count] != lastSaved && address(extra[count]) != address(0));85 uint256 previousLen = ftsoRewardManagers.length;86 managers = new IFtsoRewardManager[](previousLen + count);87 for (uint256 i; i < previousLen; i++) {88 managers[i] = ftsoRewardManagers[i];89 }90 for (uint256 i; i < count; i++) {91 managers[previousLen + i] = extra[count - i - 1];92 }93 }94}
Recommendation:
We advise the updateFtsoRewardManagers
function to be invoked in an if (current != lastSaved)
block and ftsoRewardManagers
to always be yielded by the function. This will work well with the secondary optimization exhibit outlined previously as it would allow the call to be made with an argument of 3
being identical to the current implementation's logic.
Alleviation:
The CloudFunding team has opted not to alleviate any informational or minor exhibits they disagree with, thus rendering this exhibit as acknowledged.