# reentrancy attack during mint() function in Position contract which can lead to removing of the other user's limit orders or stealing contract funds because initId is set low value

Position.mint() calls _safeMint before updating limit-order and initId state, letting a reentrant onERC721Received cancel others' limit orders or inflate position profit.

- Payout: Contest reward
- Severity: high
- Program: Tigris Trade
- Credited: unforgiven
- Disclosed: 2023-02-17
- Write-up quality: 8/10
- Original: https://github.com/code-423n4/2022-12-tigris-findings/issues/400
- Library page: https://bugbountylibrary.com/r/c4%3A2022-12-tigris%3AH-07
- Tags: domain:web3 impact:funds-loss impact:integrity kind:contest platform:code4rena sev:high tech:evm tech:solidity technique:chained technique:source-review vuln:accounting-error vuln:reentrancy

**Target:** Position/Trading contracts (ERC721 mint flow)
**Root cause:** mint() performs _safeMint external call before writing _limitOrders/_limitOrderIndexes/initId/_openPositions, violating check-effect-interaction; reentrant calls observe zeroed/unset state.
**Steps:**
1. Attacker contract calls `initiateLimitOrder()`; Position.mint assigns newTokenID=ID1 and calls `_safeMint(attacker, ID1)`.
2. In `onERC721Received`, `_limitOrderIndexes[asset][ID1]` is still 0 and ID1 not yet pushed to `_limitOrders`.
3. Reenter `cancelLimitOrder(ID1)` (no checkDelay); it calls `Position.burn(ID1)`.
4. burn() reads index 0 and removes `_limitOrders[asset][0]`, which belongs to another user.
5. Return to mint(); it pushes the already-burned ID1 into `_limitOrders`, leaving broken storage.
6. Alt: `initiateMarketOrder(lowMargin)` then reenter `addToPosition(ID1, bigMargin)`; addToPosition sets initId from new margin, then mint overwrites initId with low initial value, inflating accInterest/pnl payout on close.
**How found:** Code reading of mint() noting _safeMint external call precedes all storage writes for _limitOrders/initId; recognized classic CEI violation and traced which reentrant entrypoints (cancelLimitOrder, addToPosition) lack delay checks and read the unset state.
**Exploitation:** Attacker deploys a contract implementing onERC721Received that reenters Trading during mint: either cancelLimitOrder to delete a victim's limit order at index 0, or addToPosition to desync initId so accrued interest and payout are overstated, then closes the position to drain contract funds.
**Escalation:** Chaining mint reentrancy with addToPosition bypasses _checkDelay (both are opens) to amplify position size while keeping initId artificially low, maximizing overstated profit.
**Insight:** When an ERC721/ERC1155 _safeMint or hook fires mid-function, enumerate every state variable written after it and every external entrypoint that reads those variables without a delay/lock — index-0 defaults and unset initId are prime corruption targets.
