sherlock-audit / 2022-10-illuminate-judging

3 stars 0 forks source link

Jeiwan - Wrong return value in the Pendle's `lend` function can cause lose of funds or excessive iPT issuance #215

Closed sherlock-admin closed 1 year ago

sherlock-admin commented 1 year ago

Jeiwan

high

Wrong return value in the Pendle's lend function can cause lose of funds or excessive iPT issuance

Summary

Wrong return value in the Pendle's lend function can cause lose of funds or excessive iPT issuance

Vulnerability Detail

The swapExactTokensForTokens function returns an array of amounts, with the first element being the input amount (IPendle.sol#L12, UniswapV2Router02.sol#L231, UniswapV2Library.sol#L65). The lend functions uses the first amount, however it must check the last output amount to ensure the correct number of tokens was swapped (Lender.sol#L546).

Impact

Lending using the Pendle's lend function will always make users lose funds or mint more iPTs than expected since the returned variable will always equal the amount variable and not the actual number of principal tokens.

Code Snippet

Lender.sol#L521;

function lend(
    uint8 pId,
    address underlying,
    uint256 maturity,
    uint256 amount,
    uint256 slippage,
    uint256 deadline
) external unpaused(underlying, maturity, pId) returns (uint256) {
    // Instantiate market and tokens
    address principal = IMarketPlace(marketPlace).token(underlying, maturity, pId);

    // Transfer funds from user to Illuminate
    Safe.transferFrom(IERC20(underlying), msg.sender, address(this), amount);

    uint256 returned;
    {
        // Add the accumulated fees to the total
        uint256 fee = amount / feenominator;
        fees[underlying] = fees[underlying] + fee;

        address[] memory path = new address[](2);
        path[0] = underlying;
        path[1] = principal;

        // Swap on the Pendle Router using the provided market and params
        returned = IPendle(pendleAddr).swapExactTokensForTokens( // @audit returned = input amount
            amount - fee,
            slippage,
            path,
            address(this),
            deadline
        )[1];
    }

    // Mint Illuminate zero coupons
    IERC5095(principalToken(underlying, maturity)).authMint(msg.sender, returned);

    emit Lend(pId, underlying, maturity, returned, amount, msg.sender);
    return returned;
}

Tool used

Manual Review

Recommendation

Consider checking the returned value of the swapExactTokensForTokens function and ensuring the correct element of the returned array is used.

sourabhmarathe commented 1 year ago

In the case of the router for Pendle, the swaps will always be directly from underlying to PT, in which case the output will be formatted [input token amount (underlying), output token amount (PT)]. As a result, the [1] will contain the number of PTs received in the swap.