DeFiFoundrySolidity
16,653 OP
View results
Submission Details
Severity: high
Invalid

Partial Withdrawal vs. “Claimable” Balances

Issue:

The _freeFunds function only withdraws assets from the “unexchanged” balance in the transmuter. It does not account for the “claimable” balance, which represents WETH that could be claimed, swapped, and added to the pool of withdrawable funds. This limitation results in suboptimal utilization of available assets and may lead to user dissatisfaction when withdrawals are restricted despite claimable assets being present.


Impact:

Medium to High.

  1. Incomplete Asset Utilization:

    • A significant amount of WETH in the “claimable” state may remain unclaimed, even though it could be converted into asset (e.g., alETH) and made available for withdrawals.

  2. User Confusion and Frustration:

    • Users may expect the full value of the contract’s total balance (both “unexchanged” and “claimable”) to be available for withdrawals. The current implementation might lead to unmet expectations.

  3. Inefficient Strategy Performance:

    • The strategy may fail to maximize the use of all available assets, leading to financial inefficiencies and reduced yields.


Evidence from Code:

The _freeFunds function:

function _freeFunds(uint256 _amount) internal override {
uint256 totalAvailabe = transmuter.getUnexchangedBalance(address(this));
if (_amount > totalAvailabe) {
transmuter.withdraw(totalAvailabe, address(this));
} else {
transmuter.withdraw(_amount, address(this));
}
}
  • Only utilizes getUnexchangedBalance and ignores getClaimableBalance.


Potential Attack / Problem Scenario:

  1. User Withdrawal Shortfall:

    • A user requests a withdrawal, but _freeFunds can only withdraw from the “unexchanged” balance, leaving “claimable” WETH untouched.

    • The withdrawal partially succeeds or fails, even though sufficient assets are available in the “claimable” state.

  2. Suboptimal Yield Utilization:

    • The strategy fails to convert claimable WETH into asset tokens, reducing overall performance and affecting the strategy's competitiveness.


Proposed Solution:

Modify _freeFunds to include the claimable balance in its calculations, allowing the strategy to claim WETH, swap it to asset, and increase available funds for withdrawals.


Enhanced _freeFunds Function:

function _freeFunds(uint256 _amount) internal override {
uint256 unexchanged = transmuter.getUnexchangedBalance(address(this));
uint256 claimable = transmuter.getClaimableBalance(address(this));
uint256 totalAvailable = unexchanged + claimable;
require(_amount <= totalAvailable, "Insufficient funds");
if (_amount > unexchanged) {
uint256 toClaim = _amount - unexchanged;
transmuter.claim(toClaim, address(this));
_swapClaimableToAsset(toClaim);
}
transmuter.withdraw(_amount, address(this));
}
function _swapClaimableToAsset(uint256 _amount) internal {
// Assuming router and path are predefined or dynamically selected
uint256 minOut = _getMinOutForSwap(_amount);
IVeloRouter(router).swapExactTokensForTokens(_amount, minOut, _getSwapPath(), address(this), block.timestamp);
}

Mitigation Steps:

  1. Incorporate claimable Balances:

    • Modify _freeFunds to check both unexchanged and claimable balances.

    • Include a mechanism to claim WETH and convert it to asset before attempting to satisfy withdrawal requests.

  2. Optimize Swapping Logic:

    • Use real-time pricing (e.g., oracles) to calculate minOut for swaps to ensure efficient conversions without incurring losses.

  3. Provide Accurate User Balances:

    • Update user-facing functions (e.g., availableWithdrawLimit) to include both “unexchanged” and “claimable” balances for accurate representations.


Proof of Concept (PoC):

  1. Scenario:

    • The strategy holds 100 asset in “unexchanged” balance and 50 WETH in “claimable” balance.

    • A user requests a withdrawal of 130 asset.

  2. Execution:

    • _freeFunds(130) is called.

    • The function claims 30 WETH from the “claimable” balance, swaps it to asset, and includes the 100 asset from the “unexchanged” balance.

    • The user receives the requested 130 asset.

  3. Expected Outcome:

    • Full withdrawal is successful.

    • Both “unexchanged” and “claimable” balances are utilized efficiently.


Conc:

Incorporating “claimable” balances into _freeFunds ensures that all available assets are efficiently utilized, improving the strategy’s performance and meeting user expectations. This modification enhances the strategy's robustness, avoids unnecessary user dissatisfaction, and optimizes the protocol’s financial operations.

Updates

Appeal created

inallhonesty Lead Judge 8 months ago
Submission Judgement Published
Invalidated
Reason: Design choice

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.