Omniscia Bolide Finance Audit
Storage Code Style Findings
Storage Code Style Findings
SEG-01C: Generic Typographic Mistakes
| Type | Severity | Location |
|---|---|---|
| Code Style | ![]() | Storage.sol:L75-L87, L93, L470, L564, L625, L669, L678, L696 |
Description:
The referenced lines contain typographical mistakes (i.e. private variable without an underscore prefix) or generic documentational errors (i.e. copy-paste) that should be corrected.
Example:
75mapping(uint256 => EarnBLID) private earnBLID;76uint256 private countEarns;77uint256 private countTokens;78mapping(uint256 => address) private tokens;79mapping(address => uint256) private tokenBalance;80mapping(address => address) private oracles;81mapping(address => bool) private tokensAdd;82mapping(address => DepositStruct) private deposits;83mapping(address => uint256) private tokenDeposited;84mapping(address => int256) private tokenTime;85uint256 private reserveBLID;86address private logicContract;87address private BLID;Recommendation:
We advise them to be corrected enhancing the legibility of the codebase.
Alleviation (fcd1a542d2d7b23c561a73199ec91be0a8f0a340):
The Bolide Finance team has re-styled their code to properly prefix private functions with an underscore (_), however, the public yet prefixed functions as well as the private contract variables have remained untouched. As the Bolide Finance team has stated that they plan to address these in a future version, we consider the exhibit adequately dealt with.
SEG-02C: Inefficient Loop Limit Evaluations
| Type | Severity | Location |
|---|---|---|
| Gas Optimization | ![]() | Storage.sol:L172, L434, L452, L491, L512, L536 |
Description:
The linked for loops evaluate their limit inefficiently on each iteration.
Example:
172for (uint256 i = 0; i < countEarns_; i++) {Recommendation:
We advise the statements within the for loop limits to be relocated outside to a local variable declaration that is consequently utilized for the evaluations to significantly reduce the codebase's gas cost. We should note the same optimization is applicable for storage reads present in those limits as they are newly read on each iteration (i.e. length members of arrays in storage).
Alleviation (fcd1a542d2d7b23c561a73199ec91be0a8f0a340):
All referenced for loop iterators that are still applicable to the codebase have been adequately optimized in unchecked code blocks as advised.
SEG-03C: Inefficient mapping Lookups
| Type | Severity | Location |
|---|---|---|
| Gas Optimization | ![]() | Storage.sol:L471, L472, L636, L637, L642, L783, L784 |
Description:
The linked statements perform key-based lookup operations on mapping declarations from storage multiple times for the same key redundantly.
Example:
635if (depositor.tokenTime[address(0)] == 0) {636 depositor.iterate = countEarns;637 depositor.depositIterate[token] = countEarns;638 depositor.tokenTime[address(0)] = 1;639 depositor.tokenTime[token] += int256(block.timestamp * (amountExp18));640} else {641 interestFee(accountAddress);642 if (depositor.depositIterate[token] == countEarns) {Recommendation:
As the lookups internally perform an expensive keccak256 operation, we advise the lookups to be cached wherever possible to a single local declaration that either holds the value of the mapping in case of primitive types or holds a storage pointer to the struct contained.
Alleviation (fcd1a542d2d7b23c561a73199ec91be0a8f0a340):
The referenced lines of code have been optimized to the fullest extent possible as advised.
SEG-04C: Inexistent Error Message
| Type | Severity | Location |
|---|---|---|
| Code Style | ![]() | Storage.sol:L183, L445 |
Description:
The linked require check has no error message explicitly defined.
Example:
183require(_token != address(0) && _oracles != address(0));Recommendation:
We advise one to be set so to increase the legibility of the codebase and aid in validating the require check's condition.
Alleviation (fcd1a542d2d7b23c561a73199ec91be0a8f0a340):
Error codes have been adequately introduced to both referenced require checks as advised.
SEG-05C: Non-Descriptive Function Name
| Type | Severity | Location |
|---|---|---|
| Code Style | ![]() | Storage.sol:L169 |
Description:
The updateAccumulatedRewardsPerShare function is meant to be invoked once for a particular token which is not clearly depicted in the function's name.
Example:
169function updateAccumulatedRewardsPerShare(address token) external onlyOwner {170 require(accumulatedRewardsPerShare[token][0] == 0, "E7");171 uint256 countEarns_ = countEarns;172 for (uint256 i = 0; i < countEarns_; i++) {173 updateAccumulatedRewardsPerShareById(token, i);174 }175}Recommendation:
We advise it to be renamed to initializeAccumulatedRewardsPerShare, clearly indicating that the function is meant to be invoked once for a particular token.
Alleviation (fcd1a542d2d7b23c561a73199ec91be0a8f0a340):
The function was removed from the codebase instead as it was assessed as deprecated by the Bolide Finance team, rendering this exhibit inapplicable.
SEG-06C: Redundant Unconditional Execution of Statements
| Type | Severity | Location |
|---|---|---|
| Gas Optimization | ![]() | Storage.sol:L273-L288 |
Description:
The interestFee function is significantly inefficient if the balanceUser is yielded as 0.
Example:
273function interestFee(address accountAddress) public {274 uint256 balanceUser = balanceEarnBLID(accountAddress);275 require(reserveBLID >= balanceUser, "E5");276 IERC20Upgradeable(BLID).safeTransfer(accountAddress, balanceUser);277 DepositStruct storage depositor = deposits[accountAddress];278 depositor.balanceBLID = balanceUser;279 depositor.iterate = countEarns;280 //unchecked is used because a check was made in require281 unchecked {282 depositor.balanceBLID = 0;283 reserveBLID -= balanceUser;284 }285
286 emit UpdateBLIDBalance(reserveBLID);287 emit InterestFee(accountAddress, balanceUser);288}Recommendation:
We advise the code to instead only update the depositor.iterate to countEarns if balanceUser is 0, avoiding the increased gas cost involved in all other operations in such a case as they are ineffectual.
Alleviation (fcd1a542d2):
The code was incorrectly optimized as our recommended course of action was not applied. We advised that the depositor.iterate is properly updated to countEarns outside the conditional evaluating the balanceUser. We strongly advise the code to be corrected as it can presently cause misbehaviours.
Alleviation (c2c03f7731):
The code was corrected per our initial recommendation, updating only the value of iterate if balanceUser evaluates to zero.
SEG-07C: Relocation of Statements
| Type | Severity | Location |
|---|---|---|
| Gas Optimization | ![]() | Storage.sol:L240, L242-L243, L245, L247, L250 |
Description:
The referenced statements are performed identically in all clauses of the if structure they are located in.
Example:
238if (amountExp18 > tokenBalance[token]) {239 ILogicContract(logicContract).returnToken(amount, token);240 interestFee(msg.sender);241 IERC20Upgradeable(token).safeTransferFrom(logicContract, msg.sender, amount);242 tokenDeposited[token] -= amountExp18;243 tokenTime[token] -= int256(block.timestamp * (amountExp18));244} else {245 interestFee(msg.sender);246 IERC20Upgradeable(token).safeTransfer(msg.sender, amount);247 tokenTime[token] -= int256(block.timestamp * (amountExp18));248
249 tokenBalance[token] -= amountExp18;250 tokenDeposited[token] -= amountExp18;251}Recommendation:
We advise them to be relocated outside the if structure, optimizing the gas cost and legibility of the codebase.
Alleviation (fcd1a542d2d7b23c561a73199ec91be0a8f0a340):
The code of withdraw was greatly simplified my relocating the common statements outside their respective conditionals as advised.
SEG-08C: Repetitive Value Literal
| Type | Severity | Location |
|---|---|---|
| Code Style | ![]() | Storage.sol:L483, L635, L638 |
Description:
The linked value literal is repeated across the codebase multiple times.
Example:
483if (depositor.tokenTime[address(0)] == 0 || countEarns == 0) {Recommendation:
We advise it to be set to a constant variable instead optimizing the legibility of the codebase.
Alleviation (fcd1a542d2d7b23c561a73199ec91be0a8f0a340):
The address(0) literal has been relocated to a contract-level constant declaration labelled as ZERO_ADDRESS, optimizing the legibility of the codebase.
SEG-09C: Variable Optimization
| Type | Severity | Location |
|---|---|---|
| Gas Optimization | ![]() | Storage.sol:L408 |
Description:
The referenced statement utilizes the logicContract storage variable while having validated that the caller of the function (i.e. msg.sender) is equivalent to the said value.
Example:
401function returnToken(uint256 amount, address token)402 external403 isLogicContract(msg.sender)404 isUsedToken(token)405{406 uint8 decimals = AggregatorV3Interface(token).decimals();407 uint256 amountExp18 = amount * 10**(18 - decimals);408 IERC20Upgradeable(token).safeTransferFrom(logicContract, address(this), amount);409 tokenBalance[token] = tokenBalance[token] + amountExp18;410
411 emit UpdateTokenBalance(tokenBalance[token], token);412 emit ReturnToken(token, amountExp18);413}Recommendation:
We advise the msg.sender to be utilized directly instead, optimizing the code's gas cost.
Alleviation (fcd1a542d2d7b23c561a73199ec91be0a8f0a340):
The safeTransferFrom function execution was optimized by passing in msg.sender instead of logicContract as advised.
