You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The _swap function is designed to facilitate token exchanges through a swap contract. However, its current implementation contains several vulnerabilities that can be exploited, particularly concerning slippage logic and transaction timing.
Identified Issues
Zero Slippage Setting:
Configuring slippage to zero can cause legitimate user transactions to fail if the price changes before their transaction is processed. Check the code:
function _swap(address[] memorypath, uint256[] memoryflag) private {
uint256 amountIn_;
require(path.length-1== flag.length);
for (uint256 i; i < flag.length; i++) {
(addressinput, addressoutput) = (path[i], path[i +1]);
(uint256k, uint256j, addressswapContract) =
SmartRouterHelper.getStableInfo(stableSwapFactory, input, output, flag[i]);
if (input == ROSE) {
amountIn_ =address(this).balance;
IStableSwap(swapContract).exchange{ value: amountIn_ }(k, j, amountIn_, 0);
}
if (input != ROSE) {
amountIn_ =IERC20(input).balanceOf(address(this));
TransferHelper.safeApprove(input, swapContract, amountIn_);
// This means that anyone with enough capital can force arbitrarily large slippage by// sandwiching// transactions, close to 100%.IStableSwap(swapContract).exchange(k, j, amountIn_, 0); // @audit <-- slippage set to 0
}
Frontrunning Vulnerability:
An attacker can frontrun a legitimate user's transaction, altering the expected amountOut and causing the transaction to fail due to the check require(amountOut >= amountOutMin).
Impact:
Transaction Failures: Legitimate transactions may fail due to price fluctuations, leading to poor user experience.
Frontrunning Exploitation: Attackers can manipulate transactions, resulting transactions may fail.
Proposed Improvements
To mitigate these vulnerabilities, the following improvements are recommended for the _swap function:
Improved Code for the _swap Function
Below is an enhanced version of the _swap function that incorporates these suggestions:
function _swap(address[] memorypath, uint256[] memoryflag, uint256amountOutMin) private {
uint256 amountIn_;
require(path.length-1== flag.length, "Invalid path or flag length");
for (uint256 i; i < flag.length; i++) {
(addressinput, addressoutput) = (path[i], path[i +1]);
(uint256k, uint256j, addressswapContract) = SmartRouterHelper
.getStableInfo(stableSwapFactory, input, output, flag[i]);
if (input == ROSE) {
amountIn_ =address(this).balance;
IStableSwap(swapContract).exchange{value: amountIn_}(k, j, amountIn_, 0);
} else {
amountIn_ =IERC20(input).balanceOf(address(this));
TransferHelper.safeApprove(input, swapContract, amountIn_);
// Estimate the expected amount out before the swapuint256 estimatedAmountOut =IStableSwap(swapContract).getEstimatedAmountOut(k, j, amountIn_);
// Execute the exchange IStableSwap(swapContract).exchange(k, j, amountIn_, amountOutMin); // <- proper slippage setUp
}
}
}
Improvements in the exactInputStableSwap Function
Additionally, here is the adjusted exactInputStableSwap function to include slippage:
function exactInputStableSwap(
address[] calldatapath,
uint256[] calldataflag,
uint256amountIn,
uint256amountOutMin, // Minimum output tokens expectedaddressto
) externalpayable nonReentrant returns (uint256amountOut) {
require(!isKill, "Contract is killed");
// Perform the swap_swap(path, flag, amountOutMin); // Pass the slippage to _swap// Obtain the output amountif (dstToken == ROSE) {
amountOut =address(this).balance;
} else {
amountOut =IERC20(dstToken).balanceOf(address(this));
}
// Ensure the output amount is greater than or equal to the expected minimumrequire(amountOut >= amountOutMin, "Output amount too low"); // This line may cause the user's initial tx to fail if slippage is too high.// Adjust the destination address and execute the transferif (to == Constants.MSG_SENDER) {
to =msg.sender;
} elseif (to == Constants.ADDRESS_THIS) {
to =address(this);
}
if (to !=address(this)) {
pay(dstToken, address(this), to, amountOut);
}
emitStableExchange(msg.sender, amountIn, path[0], amountOut, path[path.length-1], to);
}
The text was updated successfully, but these errors were encountered:
Github username: @catellaTech
Twitter username: catellatech
Submission hash (on-chain): 0xca61dcbf9bfe2303ceb41e6834f39e19dad96447ea165e96693e1683e906d4fd
Severity: medium
Description:
Severity: Medium
Description:
The
_swap
function is designed to facilitate token exchanges through a swap contract. However, its current implementation contains several vulnerabilities that can be exploited, particularly concerning slippage logic and transaction timing.Identified Issues
amountOut
and causing the transaction to fail due to the checkrequire(amountOut >= amountOutMin)
.Impact:
Proposed Improvements
To mitigate these vulnerabilities, the following improvements are recommended for the
_swap
function:Improved Code for the
_swap
FunctionBelow is an enhanced version of the
_swap
function that incorporates these suggestions:Improvements in the
exactInputStableSwap
FunctionAdditionally, here is the adjusted
exactInputStableSwap
function to include slippage:The text was updated successfully, but these errors were encountered: