# Re-enterable Code When Making a Deposit to Stake

RocketJoeStaking.deposit() updates user.amount and rewardDebt after _safeRJoeTransfer, so a reentrant rJoe token could repeatedly drain pending rewards.

- Payout: Audit contest
- Severity: medium
- Program: Trader Joe
- Found by: kirk-baird
- Disclosed: 2022-03-07
- Write-up quality: 6/10
- Original: https://github.com/code-423n4/2022-01-trader-joe-findings/issues/127
- Library page: https://bugbountylibrary.com/r/c4%3A2022-01-trader-joe%3AM-11
- Tags: domain:web3 impact:funds-loss kind:contest platform:code4rena sev:medium tech:evm tech:solidity technique:source-review vuln:reentrancy

**Target:** RocketJoeStaking.deposit() staking contract
**Root cause:** deposit() computes pending rewards from user.amount and user.rewardDebt, then calls _safeRJoeTransfer before updating those state variables, violating checks-effects-interactions.
**Steps:**
1. Attacker stakes so user.amount > 0 and accrues pending rewards.
2. Attacker calls `deposit(_amount)`; contract computes `pending = user.amount * accRJoePerShare / PRECISION - user.rewardDebt`.
3. Contract calls `_safeRJoeTransfer(msg.sender, pending)` before updating user.amount/rewardDebt.
4. If rJoe token relinquishes control during transfer, attacker reenters `deposit()`; pending recomputes to the same value since state is unchanged.
5. Repeat reentrancy until contract's entire rJoe balance is drained.
**How found:** Code review of deposit() ordering: noticed reward state variables updated after the external _safeRJoeTransfer call, a classic reentrancy pattern.
**Exploitation:** Requires the rJoe token to hand control flow to the attacker during transfer() (e.g. malicious/hook token); then recursive deposit() calls each pay out the same pending amount, draining the contract's rJoe balance. Not exploitable with current RocketJoeToken.
**Insight:** In staking/reward contracts, check whether reward-debt and amount updates happen after the token transfer; even a currently non-callback ERC20 is a latent reentrancy risk if the token is upgradeable or swappable.
