Skip to content

Latest commit

 

History

History
80 lines (61 loc) · 4.22 KB

File metadata and controls

80 lines (61 loc) · 4.22 KB

Daring Mustard Crab

Medium

No validation is performed on _pairedOut before calculations, leading to potential silent failures

Summary

The function _tokenToPodLp() calls _tokenToPairedLpToken(_token, _amountIn), but it does not verify whether the returned value (_pairedOut) is valid before proceeding. This missing check can lead to silent failures, incorrect calculations, or unexpected behavior when _pairedOut is 0.

Severity: Medium Impact: Medium Likelihood: High

Affected Line of Code

https://github.com/sherlock-audit/2025-01-peapods-finance/blob/main/contracts/contracts/AutoCompoundingPodLp.sol#L233-L247

uint256 _pairedOut = _tokenToPairedLpToken(_token, _amountIn);
if (_pairedOut > 0) { // Missing validation before this check
    uint256 _pairedFee = (_pairedOut * protocolFee) / 1000;

Finding Description

The _tokenToPodLp() function is responsible for converting a given _token into LP tokens. It first calls _tokenToPairedLpToken() to get the paired token amount but does not verify if _pairedOut is valid before proceeding.

This missing validation introduces multiple risks:

  1. Silent Failure: If _tokenToPairedLpToken() fails or returns 0, the function continues execution instead of reverting.
  2. Incorrect Fee Calculation: If _pairedOut is 0, fee calculations still take place, leading to unnecessary operations.
  3. Potentially Stuck Funds: If _pairedOut is 0, _lpAmtOut will also be 0, but the require(_lpAmtOut >= _amountLpOutMin, "M"); statement is only executed if _pairedOut > 0, meaning the function could exit without providing LP tokens.
  4. Breaks Expected Security Guarantees: Functions that perform conversions should validate return values to prevent downstream errors.

An attacker could exploit this issue by providing a token pair with an invalid conversion path, leading to transactions completing without reverting while failing to provide LP tokens in return.

Impact Explanation

This issue has a medium impact because it can lead to loss of funds for users who expect a successful LP token conversion but instead receive nothing without a clear revert. While this does not allow direct theft of funds, it results in unexpected and undesirable behavior for protocol users.

Likelihood Explanation

The likelihood of this issue occurring is high because:

  1. The function does not validate _pairedOut, meaning any failure in _tokenToPairedLpToken() propagates silently.
  2. If _tokenToPairedLpToken() returns 0 due to an unsupported token, a liquidity issue, or an external failure, the user could lose funds without realizing why.
  3. Malicious actors could create tokens that fail to convert properly, leading to confusion and potential exploitation.

Proof of Concept

Scenario 1 – Unsupported Token Pair

  1. User calls _tokenToPodLp(someUnsupportedToken, 1000, 500, deadline).
  2. _tokenToPairedLpToken() fails to convert and returns 0.
  3. The function does not revert, and the user does not receive any LP tokens.

Scenario 2 – Malicious Token

  1. Attacker creates a token contract where _tokenToPairedLpToken() always returns 0.
  2. User unknowingly interacts with it, and the function completes without providing LP tokens.

Recommendation

To fix this issue, add a check right after _tokenToPairedLpToken() is called:

Fixed Code Snippet:

uint256 _pairedOut = _tokenToPairedLpToken(_token, _amountIn);
require(_pairedOut > 0, "Conversion failed"); // Ensure valid return value before proceeding

uint256 _pairedFee = (_pairedOut * protocolFee) / 1000;
if (_pairedFee > 0) {
    _protocolFees += _pairedFee;
    _pairedOut -= _pairedFee;
}
_lpAmtOut = _pairedLpTokenToPodLp(_pairedOut, _deadline);
require(_lpAmtOut >= _amountLpOutMin, "M");
                         OR

If want better revert messaging

uint256 _pairedOut = _tokenToPairedLpToken(_token, _amountIn);
require(_pairedOut > 0, "Conversion failed: token not paired or invalid");

Ensures _tokenToPairedLpToken() provides a valid, nonzero output before continuing. Prevents silent failures and ensures that users receive expected LP tokens or a clear revert message. Reduces unnecessary calculations when _pairedOut is 0.