Omniscia Bolide Finance Audit

Storage Static Analysis Findings

Storage Static Analysis Findings

SEG-01S: Inexistent Conformity to Checks-Effects-Interactions Pattern

TypeSeverityLocation
Logical FaultStorage.sol:L241, L246, L276, L304, L336, L633, L670

Description:

All referenced statements perform an external contract invocation mid-execution, breaking the CEI pattern as sensitive storage updates are performed after the external calls conclude.

Impact:

The impact of this exhibit cannot be assessed as the tokens supported by the system are unknown whilst the BLID token of the project is not within scope of the audit.

Example:

strategies/low_risk/contracts/Storage.sol
232function withdraw(uint256 amount, address token) external isUsedToken(token) whenNotPaused {
233 uint8 decimals = AggregatorV3Interface(token).decimals();
234 uint256 countEarns_ = countEarns;
235 uint256 amountExp18 = amount * 10**(18 - decimals);
236 DepositStruct storage depositor = deposits[msg.sender];
237 require(depositor.amount[token] >= amountExp18 && amount > 0, "E4");
238 if (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 }
252 if (depositor.depositIterate[token] == countEarns_) {
253 depositor.tokenTime[token] -= int256(block.timestamp * (amountExp18));
254 } else {
255 depositor.tokenTime[token] =
256 int256(depositor.amount[token] * earnBLID[countEarns_ - 1].timestamp) -
257 int256(block.timestamp * (amountExp18));
258 depositor.depositIterate[token] = countEarns_;
259 }
260 depositor.amount[token] -= amountExp18;
261
262 // Claim BoostingRewardBLID
263 _claimBoostingRewardBLIDInternal(msg.sender, true);
264
265 emit UpdateTokenBalance(tokenBalance[token], token);
266 emit Withdraw(msg.sender, token, amountExp18);
267}

Recommendation:

We advise the contract to either apply the CEI pattern in full when dealing with external tokens and potentially with the BLID token (which is not in scope and cannot be assessed) or the contract to apply re-entrancy protections across all state-mutating functions via the usage of a ReentrancyGuard such as the one by OpenZeppelin.

Alleviation (fcd1a542d2d7b23c561a73199ec91be0a8f0a340):

All referenced external interactions now properly conform to the CEI pattern as they have been relocated towards the end of a function's body after all checks have been evaluated and effects have been applied to the contract.

SEG-02S: Ineffectual Assignment

TypeSeverityLocation
Gas OptimizationStorage.sol:L278

Description:

The referenced assignment is followed by an assignment of zero to the same storage slot.

Example:

strategies/low_risk/contracts/Storage.sol
278depositor.balanceBLID = balanceUser;
279depositor.iterate = countEarns;
280//unchecked is used because a check was made in require
281unchecked {
282 depositor.balanceBLID = 0;
283 reserveBLID -= balanceUser;
284}

Recommendation:

We advise it to be safely omitted from the codebase as it is currently ineffectual.

Alleviation (fcd1a542d2d7b23c561a73199ec91be0a8f0a340):

The ineffectual assignment has been safely removed from the codebase.

SEG-03S: Multiple Top-Level Declarations

TypeSeverityLocation
Code StyleStorage.sol:L12, L16, L22

Description:

The Storage.sol file contains three separate top-level declarations in its body.

Example:

strategies/low_risk/contracts/Storage.sol
12interface ILogicContract {
13 function returnToken(uint256 amount, address token) external;
14}
15
16interface AggregatorV3Interface {
17 function decimals() external view returns (uint8);
18
19 function latestAnswer() external view returns (int256 answer);
20}
21
22contract StorageV21 is Initializable, OwnableUpgradeable, PausableUpgradeable {

Recommendation:

We advise them to be split to dedicated files that are instead imported on a need-to basis to increase the standardization of the codebase.

Alleviation (fcd1a542d2d7b23c561a73199ec91be0a8f0a340):

The two highlighted interface declarations have been relocated to their dedicated ILogicContract.sol and AggregatorV3Interface.sol files, ensuring the StorageV21 contract is the only top-level declaration of the Storage.sol file.

SEG-04S: Inexistent Sanitization of Input Addresses

TypeSeverityLocation
Input SanitizationStorage.sol:L120-L124, L130-L134, L182-L190, L196-L200, L219-L225

Description:

The linked function(s) accept address arguments yet do not properly sanitize them.

Impact:

The presence of zero-value addresses, especially in constructor implementations, can cause the contract to be permanently inoperable. These checks are advised as zero-value inputs are a common side-effect of off-chain software related bugs.

Example:

strategies/low_risk/contracts/Storage.sol
219function depositOnBehalf(
220 uint256 amount,
221 address token,
222 address accountAddress
223) external payable isUsedToken(token) whenNotPaused {
224 depositInternal(amount, token, accountAddress);
225}

Recommendation:

We advise some basic sanitization to be put in place by ensuring that each address specified is non-zero.

Alleviation (fcd1a542d2d7b23c561a73199ec91be0a8f0a340):

The address arguments of all referenced lines of code by this exhibit are now adequately sanitized as non-zero via a corresponding require check.