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.