-
Notifications
You must be signed in to change notification settings - Fork 0
Description
Energetic Peanut Crab
Medium
Unverified Swap Data Enables Fee Bypass Through Destination Address Manipulation
Summary
The DeBank swap router protocol contains vulnerability where users can bypass protocol fees by manipulating the destination address in unverified swap data parameters. The DexSwap contract accepts arbitrary data parameters without validation, allowing malicious users to redirect swapped tokens directly to themselves while avoiding fee collection mechanisms.
Root Cause
The vulnerability stems from the lack of validation for the data parameter in the SwapParams struct. The DexSwap::_swap() function accepts user-provided data without verification and passes it directly to adapter contracts, enabling users to manipulate swap execution to redirect tokens and avoid fee deductions.
struct SwapParams {
string aggregatorId;
address fromToken;
uint256 fromTokenAmount;
address toToken;
uint256 minAmountOut;
uint256 feeRate;
bool feeOnFromToken;
address feeReceiver;
>> bytes data; // Unverified user input
}
function _swap(SwapParams memory params) internal {
Adapter storage adapter = adapters[params.aggregatorId];
// 1. check params
_validateSwapParams(params, adapter);
uint256 feeAmount;
uint256 receivedAmount;
// 2. charge fee on fromToken if needed
if (params.feeOnFromToken) {
(params.fromTokenAmount, feeAmount) = _chargeFee(
params.fromToken, params.feeOnFromToken, params.fromTokenAmount, params.feeRate, params.feeReceiver
);
}
// 3. transfer fromToken
if (params.fromToken != UniversalERC20.ETH) {
IERC20(params.fromToken).safeTransferFrom(msg.sender, address(spender), params.fromTokenAmount);
}
// 4. execute swap with unverified data
{
uint256 balanceBefore = IERC20(params.toToken).universalBalanceOf(address(this));
spender.swap{value: params.fromToken == UniversalERC20.ETH ? params.fromTokenAmount : 0}(
adapter.addr,
abi.encodeWithSelector(
>> adapter.selector, params.fromToken, params.toToken, msg.sender, params.data // Unverified data
)
);
receivedAmount = IERC20(params.toToken).universalBalanceOf(address(this)) - balanceBefore;
}
}The _validateSwapParams() function only performs basic checks but does not validate the content or structure of the data parameter, allowing users to craft malicious swap data that encodes the destination address as themselves.
Internal pre-conditions
External pre-conditions
Attack Path
- User analyzes adapter contract implementations to understand data encoding patterns
- User crafts malicious
dataparameter that:- Encodes the destination address as themselves instead of DexSwap
- Sets
params.feeOnFromToken = falseto avoid input fee collection - Sets
params.minAmountOut = 0to bypass slippage protection
- User submits swap transaction with manipulated
dataparameter - DexSwap accepts the unverified data and executes the swap
- Swapped tokens are transferred directly to the user instead of DexSwap
- Slippage check passes due to
minAmountOut = 0 - Fee collection is bypassed due to
feeOnFromToken = false - Protocol fees are completely avoided
Impact
Users can completely bypass protocol fees by manipulating swap data to redirect tokens directly to themselves, leading to significant revenue loss for the DeBank protocol. This creates an unfair advantage for malicious users while legitimate users continue to pay fees, undermining the protocol's economic model and sustainability.
Mitigation
Implement comprehensive data validation mechanisms.