Numoen contest - SleepingBugs's results

Automated exchange for power perpetuals.

General Information

Platform: Code4rena

Start Date: 26/01/2023

Pot Size: $60,500 USDC

Total HM: 7

Participants: 31

Period: 6 days

Judge: berndartmueller

Total Solo HM: 3

Id: 207

League: ETH

Numoen

Findings Distribution

Researcher Performance

Rank: 22/31

Findings: 1

Award: $142.48

🌟 Selected for report: 0

šŸš€ Solo Findings: 0

Findings Information

🌟 Selected for report: CodingNameKiki

Also found by: 0xAgro, 0xSmartContract, IllIllI, Rolezn, SleepingBugs, btk, chrisdior4, matrix_0wl

Labels

bug
grade-b
QA (Quality Assurance)
Q-02

Awards

142.4841 USDC - $142.48

External Links

Low

Lack of sanity check for same value will revert

Impact

If both values are the same, operation will revert due to division by 0

Vulnerability Details

There is a call of LendgineRouter.sol#mintCallback() that calls SwapHelper#swap() that calls, for negative values (later converted in positive with - operator), function getAmountIn.

function getAmountIn(
  uint256 amountOut,
  uint256 reserveIn,
  uint256 reserveOut
)
  internal
  pure
  returns (uint256 amountIn)
{
  require(amountOut > 0, "UniswapV2Library: INSUFFICIENT_OUTPUT_AMOUNT");
  require(reserveIn > 0 && reserveOut > 0, "UniswapV2Library: INSUFFICIENT_LIQUIDITY");
  uint256 numerator = reserveIn * amountOut * 1000;
  uint256 denominator = (reserveOut - amountOut) * 997;
  amountIn = (numerator / denominator) + 1;
}

If the value is the same of reserveOut, line: uint256 denominator = (reserveOut - amountOut) * 997;

denominator will be 0 and will revert next line amountIn = (numerator / denominator) + 1;

Recommendation

Add a sanity check for not being the same values or revert in SwapHelper or in getAmountIn.

block.timestamp used as time proxy

Summary

Risk of using block.timestamp for time should be considered.

Details

block.timestamp is not an ideal proxy for time because of issues with synchronization, miner manipulation and changing block times.

This kind of issue may affect the code allowing or reverting the code before the expected deadline, modifying the normal functioning or reverting sometimes.

References

SWC ID: 116

Code Snippet

Recommendation

  • Consider the risk of using block.timestamp as time proxy and evaluate if block numbers can be used as an approximation for the application logic. Both have risks that need to be factored in.
  • Consider using an oracle for precision

Destination recipient for assets transfers may be address(0)

  function sweepToken(address token, uint256 amountMinimum, address recipient) public payable {
    uint256 balanceToken = Balance.balance(token);
    if (balanceToken < amountMinimum) revert InsufficientOutputError();

    if (balanceToken > 0) {
      SafeTransferLib.safeTransfer(token, recipient, balanceToken);
    }
  }

Description

The recipient of a transfer may be address(0), leading to losing assets

Informational

Solidity compiler optimizations can be problematic

Protocol has enabled optional compiler optimizations in Solidity. There have been several optimization bugs with security implications. Moreover, optimizations are actively being developed. Solidity compiler optimizations are disabled by default, and it is unclear how many contracts in the wild actually use them.

Therefore, it is unclear how well they are being tested and exercised. High-severity security issues due to optimization bugs have occurred in the past. A high-severity bug in the emscripten-generated solc-js compiler used by Truffle and Remix persisted until late 2018. The fix for this bug was not reported in the Solidity CHANGELOG.

Another high-severity optimization bug resulting in incorrect bit shift results was patched in Solidity 0.5.6. More recently, another bug due to the incorrect caching of keccak256 was reported. A compiler audit of Solidity from November 2018 concluded that the optional optimizations may not be safe. It is likely that there are latent bugs related to optimization and that new bugs will be introduced due to future optimizations.

It's likely there is a latent or future bug in Solidity compiler optimizations—or in the Emscripten transpilation to solc-js—causes a security vulnerability in the contracts.

Can be saved directly as bytes32

Given that is always going to be casted to bytes32 later, consider defining it directly as bytes32

  • LendgineAddress.sol#L7 71_695_300_681_742_793_458_567_320_549_603_773_755_938_496_017_772_337_363_704_152_556_600_186_974;

Max value can be used rather than 2 ** n

Rather than using 2 ** 256 or other numbers (128, 64, 32, 16, 8...), it can be used type(uint256).max (depending on the exponentiation number).

Recommendation

Consider replacing 2 ** n notation to max value.

Warning SPDX-License missing

SPDX license should be included for avoiding compiler warnings.

Recommendation

Add a SPDX License to each file

Use of hardcoded amount of days

Formula uses a hardcoded value of 365 (days) which would be wrong applied in a leap year (366 days)

Code Snippet

  • Lendgine.sol#L252 uint256 dilutionLPRequested = (FullMath.mulDiv(borrowRate, _totalLiquidityBorrowed, 1e18) * timeElapsed) / 365 days;

Recommendation

  • Consider using an oracle for this
  • Consider that that each year is like 365.25 not 365

Different versions of pragma

NOTE: None of these findings where found by 4naly3er output - NC

Some of the contracts include an unlocked pragma, e.g., pragma solidity ^0.8.0.

Locking the pragma helps ensure that contracts are not accidentally deployed using an old compiler version with unfixed bugs.

Recommendation

Lock pragmas to a specific Solidity version.

Constants should be defined rather than using magic numbers

NOTE: None of these findings where found by 4naly3er output - NC

#0 - c4-judge

2023-02-16T11:26:44Z

berndartmueller marked the issue as grade-b

AuditHub

A portfolio for auditors, a security profile for protocols, a hub for web3 security.

Built bymalatrax Ā© 2024

Auditors

Browse

Contests

Browse

Get in touch

ContactTwitter