# EthRouter.sell, EthRouter.deposit, and EthRouter.change functions can be DOS'ed for some ERC721 tokens

EthRouter unconditionally re-calls setApprovalForAll on each sell/deposit/change; ERC721s like Axie revert on redundant approval, permanently DoSing those flows for a pool.

- Payout: Contest reward
- Severity: medium
- Program: Caviar
- Credited: rbserver
- Disclosed: 2023-05-18
- Write-up quality: 6/10
- Original: https://github.com/code-423n4/2023-04-caviar-findings/issues/776
- Library page: https://bugbountylibrary.com/r/c4%3A2023-04-caviar%3AM-05
- Tags: domain:web3 impact:dos kind:contest platform:code4rena sev:medium tech:evm tech:solidity technique:source-review vuln:dos

**Target:** EthRouter.sell/deposit/change in Caviar private pools
**Root cause:** EthRouter calls ERC721.setApprovalForAll(pool, true) on every invocation without checking existing approval; some ERC721s (Axie) revert when re-approving the same operator with the same bool.
**Steps:**
1. Alice calls `EthRouter.sell` selling 1 Axie NFT to a private pool; `setApprovalForAll(pool,true)` succeeds.
2. Alice calls `EthRouter.sell` again for another Axie to the same pool; `ERC721(nft).setApprovalForAll(pool,true)` reverts due to Axie's `require(_tokenOperator[msg.sender][_operator] != _approved)`.
3. Any user (Bob) repeating the call also reverts, permanently blocking sells/deposits/changes of that NFT to that pool.
**How found:** Code review of EthRouter's unconditional approval pattern combined with knowledge of non-standard ERC721 implementations (Axie) whose setApprovalForAll reverts on redundant approval.
**Exploitation:** No value extraction; griefing/DoS. Once the router has approved a pool for an Axie-type NFT, all subsequent sell/deposit/change calls for that NFT+pool revert, blocking legitimate users from using the router for that collection.
**Insight:** When a router/contract re-approves tokens on every call, check non-standard ERC721/ERC20 implementations (Axie, some older tokens) that revert on no-op approvals; the first call succeeds and locks out all later calls, a persistent DoS.
