Numoen contest - Deivitto'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: 14/31

Findings: 2

Award: $578.85

Gas:
grade-b

🌟 Selected for report: 0

🚀 Solo Findings: 0

Findings Information

🌟 Selected for report: RaymondFam

Also found by: 0xhacksmithh, Deivitto, peakbolt, rvierdiiev

Labels

bug
2 (Med Risk)
satisfactory
duplicate-263

Awards

533.4249 USDC - $533.42

External Links

Lines of code

https://github.com/code-423n4/2023-01-numoen/blob/2ad9a73d793ea23a25a381faadc86ae0c8cb5913/src/periphery/LendgineRouter.sol#L11 https://github.com/code-423n4/2023-01-numoen/blob/2ad9a73d793ea23a25a381faadc86ae0c8cb5913/src/periphery/LendgineRouter.sol#L228 https://github.com/code-423n4/2023-01-numoen/blob/2ad9a73d793ea23a25a381faadc86ae0c8cb5913/src/core/Pair.sol#L102 https://github.com/code-423n4/2023-01-numoen/blob/2ad9a73d793ea23a25a381faadc86ae0c8cb5913/src/core/Pair.sol#L103 https://github.com/code-423n4/2023-01-numoen/blob/2ad9a73d793ea23a25a381faadc86ae0c8cb5913/src/core/Pair.sol#L122 https://github.com/code-423n4/2023-01-numoen/blob/2ad9a73d793ea23a25a381faadc86ae0c8cb5913/src/core/Pair.sol#L123

Vulnerability details

Losses in Pair and LendgineRouter can be generated if used with ERC20 Tokens with fee on transfer

Summary

Some tokens (token1, token0, ...) are used over the code that can be any kind of ERC20 token. If this token includes fees on transfer, some operations will make the protocol lose value using wrong amounts.

Vulnerability Detail

There are ERC20 tokens that charge fee for every transfer() / transferFrom(). Some reference of this common issue: 1, 2, 3.

LendgineRouter#mintCallback assumes that the received amount is the same as the transfer amount, and uses it to calculate assets like collateralIn, etc. While the actual transferred amount can be lower for those tokens.

For example:

    SafeTransferLib.safeTransfer(decoded.token1, msg.sender, amount1);

    // pull the rest of tokens from the user
    uint256 collateralIn = collateralTotal - amount1 - collateralSwap;//@audit amount1 can be more than it actual is
    if (collateralIn > decoded.collateralMax) revert AmountError();

    pay(decoded.token1, decoded.payer, msg.sender, collateralIn);

Impact

Losses of assets because of wrong amounts used in tokens with fees

Code Snippet

  • LendgineRouter.sol#L117 SafeTransferLib.safeTransfer(decoded.token1, msg.sender, amount1);

  • LendgineRouter.sol#L228 SafeTransferLib.safeTransfer(decoded.token1, msg.sender, amount1);

  • Pair.sol#L102 if (amount0 > 0) SafeTransferLib.safeTransfer(token0, to, amount0);

  • Pair.sol#L103 if (amount1 > 0) SafeTransferLib.safeTransfer(token1, to, amount1);

  • Pair.sol#L122 if (amount0Out > 0) SafeTransferLib.safeTransfer(token0, to, amount0Out);

  • Pair.sol#L123 if (amount1Out > 0) SafeTransferLib.safeTransfer(token1, to, amount1Out);

Tool used

Manual Review

Recommendation

Consider comparing before and after balance to get the actual transferred amount.

#0 - c4-judge

2023-02-06T17:22:21Z

berndartmueller marked the issue as duplicate of #263

#1 - c4-judge

2023-02-16T10:56:46Z

berndartmueller marked the issue as satisfactory

Awards

45.4256 USDC - $45.43

Labels

bug
G (Gas Optimization)
grade-b
sponsor confirmed
G-01

External Links

Gas

<x> += <y> costs more gas than <x> = <x> + <y> for state variables

Using the addition operator instead of plus-equals saves gas. Same goes for other operands like -=.

Not using the named return variables when a function returns, wastes deployment gas

  • JumpRate.sol#L13 function getBorrowRate(uint256 borrowedLiquidity, uint256 totalLiquidity) public pure override returns (uint256 rate) {

  • JumpRate.sol#L32 returns (uint256 rate)

  • JumpRate.sol#L40 function utilizationRate(uint256 borrowedLiquidity, uint256 totalLiquidity) private pure returns (uint256 rate) {

internal functions only called once can be inlined to save gas

Not inlining costs 20 to 40 gas because of two extra JUMP instructions and additional stack operations needed for function calls.

newTokensOwed

  • Position.sol#L69 function newTokensOwed(Position.Info memory position, uint256 rewardPerPosition) internal pure returns (uint256) {

addDelta

abi.encode() is less gas efficient than abi.encodePacked()

Changing the abi.encode function to abi.encodePacked can save gas since the abi.encode function pads extra null bytes at the end of the call data, which is unnecessary. Also, in general, abi.encodePacked is more gas-efficient.

Duplicated require() check should be refactored

Duplicated require() / revert() checks should be refactored to a modifier or function to save gas. If it's been used for example require(addr != address(0)) or require(a > b), etc multiple times in the same contract. This can be refactored to a modifier like notZeroAddress(address a), function biggerThan(uint a, uint b), etc.

Splitting require() statements that use && saves gas

Instead of using the && operator in a single require statement to check multiple conditions, consider using multiple require statements with 1 condition per require statement (saving 3 gas per &).

Use Custom Errors

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

Source Instead of using error strings, to reduce deployment and runtime cost, you should use Custom Errors. This would save both deployment and runtime cost.

Use calldata instead of memory for function arguments that do not get mutated

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

  • SwapHelper.sol#L69 function swap(SwapType swapType, SwapParams memory params, bytes memory data) internal returns (uint256 amount) {

  • Position.sol#L69 function newTokensOwed(Position.Info memory position, uint256 rewardPerPosition) internal pure returns (uint256) {

#0 - c4-sponsor

2023-02-09T17:09:11Z

kyscott18 marked the issue as sponsor confirmed

#1 - c4-judge

2023-02-16T11:18:06Z

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