# Incorrect flow of adding liquidity in UlyssesRouter.sol

UlyssesRouter.addLiquidity pulls tokens from the router itself, so a user's pre-transferred tokens can be stolen by anyone calling addLiquidity first.

- Payout: Contest reward
- Severity: high
- Program: Maia DAO Ecosystem
- Credited: T1MOH
- Disclosed: 2023-09-18
- Write-up quality: 6/10
- Original: https://github.com/code-423n4/2023-05-maia-findings/issues/201
- Library page: https://bugbountylibrary.com/r/c4%3A2023-05-maia%3AH-30
- Tags: domain:web3 impact:funds-loss kind:contest platform:code4rena sev:high tech:evm tech:solidity technique:source-review vuln:access-control vuln:business-logic

**Target:** UlyssesRouter.sol addLiquidity / UlyssesERC4626 deposit
**Root cause:** addLiquidity assumes tokens were pre-sent to the stateless router and calls deposit which does safeTransferFrom(msg.sender=router), so any caller can consume tokens sitting in the router.
**Steps:**
1. User transfers tokens to UlyssesRouter in tx1 (non-atomic).
2. Attacker calls `addLiquidity(amount, minOutput, poolId)` in tx2.
3. Router's deposit does `asset.safeTransferFrom(router, pool, amount)` using the victim's tokens.
4. Shares are minted to attacker (msg.sender) via `_mint(receiver, shares)`.
5. Victim's tokens are lost; attacker gains pool shares.
**How found:** Recognized that AMM routers should be stateless; noticed addLiquidity relies on a prior separate transfer to the router, making the deposit non-atomic and stealable.
**Exploitation:** Attacker monitors the mempool for a user's token transfer to the router, then front-runs/calls addLiquidity to deposit the victim's tokens and receive the shares.
**Insight:** Check whether router/aggregator contracts hold token balances between calls; any deposit that pulls from the router's own balance instead of the user is front-runnable.
