# Unable to transfer fee reserve assets to treasury

Sign error in Notional's _redeemAndTransfer makes withdrawPrimeCash return non-positive, so the require always reverts, blocking fee reserve transfers to treasury and NOTE staker rewards.

- Payout: Contest reward
- Severity: high
- Program: Notional
- Credited: xiaoming90 + 0xleastwood
- Disclosed: 2023-03-09
- Write-up quality: 6/10
- Original: https://github.com/sherlock-audit/2023-03-notional-judging/issues/190
- Library page: https://bugbountylibrary.com/r/sherlock%3A2023-03-notional%3AH-5
- Tags: domain:web3 impact:dos impact:funds-loss kind:contest platform:sherlock sev:high tech:solidity technique:source-review vuln:accounting-error vuln:business-logic

**Target:** TreasuryAction._redeemAndTransfer / TokenHandler.withdrawPrimeCash (Solidity contracts)
**Root cause:** withdrawPrimeCash returns a value <= 0 (amount withdrawn is negated), but _redeemAndTransfer requires actualTransferExternal > 0 without negating the return value.
**Steps:**
1. Call transferReserveToTreasury(currencyId, primeCashRedeemAmount) on TreasuryAction.
2. It calls _redeemAndTransfer, which calls TokenHandler.withdrawPrimeCash(treasuryManagerContract, currencyId, primeCashRedeemAmount.neg(), primeRate, true).
3. withdrawPrimeCash returns a value <= 0.
4. require(actualTransferExternal > 0) fails, reverting the whole transfer.
**How found:** Code reading of TreasuryAction._redeemAndTransfer and TokenHandler.withdrawPrimeCash: noticed the return value is always <= 0 while the caller requires > 0, so the path always reverts.
**Insight:** When a helper returns a signed amount, check the sign convention against every caller's require/if guard; a single missing .neg() on a return value silently bricks an entire admin path.
