# No entry checks in crossSwap[Exact]TokensFor[Exact]Tokens

MarginRouter crossSwap functions lack caller and pair validation, letting anyone trade on Marginswap's behalf and inject self-constructed pair contracts for reentrancy.

- Payout: Audit contest
- Severity: medium
- Program: Marginswap
- Disclosed: 2021-05-03
- Write-up quality: 6/10
- Original: https://github.com/code-423n4/2021-04-marginswap-findings/issues/4
- Library page: https://bugbountylibrary.com/r/c4%3A2021-04-marginswap%3AM-03
- Tags: area:web3 domain:web3 impact:funds-loss kind:contest platform:code4rena sev:medium tech:solidity technique:source-review vuln:access-control vuln:business-logic vuln:reentrancy

**Target:** MarginRouter.sol crossSwapTokensForExactTokens / crossSwapExactTokensForTokens
**Root cause:** crossSwap functions do not restrict callers, do not validate pairs/tokens contents, and do not check array length equality; the internal isMarginTrader check passes because msg.sender is MarginRouter itself.
**Steps:**
1. Call `crossSwapExactTokensForTokens` or `crossSwapTokensForExactTokens` on MarginRouter.sol with attacker-chosen `pairs` and `tokens` arrays.
2. Supply self-constructed pair contract addresses; these are invoked via getAmountsIn/getAmountsOut and pair.swap.
3. Malicious pair code reentrantly calls back into Marginswap during the swap.
**How found:** Code review of MarginRouter.sol: noticed crossSwap functions lack caller/content/length checks, and that the isMarginTrader(msg.sender) check in registerTradeAndBorrow passes because msg.sender is MarginRouter itself.
**Exploitation:** Attacker calls the unauthenticated crossSwap functions with fully attacker-controlled pair addresses, executing arbitrary self-constructed code that reenters Marginswap and trades on its behalf, potentially draining funds.
**Escalation:** Self-constructed pair contracts enable reentrancy into Marginswap code during the swap.
**Insight:** When an external call forwards to an internal auth check, msg.sender becomes the router contract, so the check trivially passes; also treat user-supplied pair addresses as arbitrary code execution vectors via swap callbacks.

