# BondNFTs can revert when transferred

BondNFT._transfer requires epoch[asset] equal current day, so transfers revert whenever rewards weren't distributed that day, blocking sales and collateral release.

- Payout: Contest reward
- Severity: medium
- Program: Tigris Trade
- Credited: 0xdeadbeef0x
- Disclosed: 2023-02-17
- Write-up quality: 6/10
- Original: https://github.com/code-423n4/2022-12-tigris-findings/issues/162
- Library page: https://bugbountylibrary.com/r/c4%3A2022-12-tigris%3AM-06
- Tags: domain:web3 impact:dos kind:contest platform:code4rena sev:medium tech:evm tech:solidity vuln:business-logic vuln:dos

**Target:** BondNFT ERC721 transfer / reward epoch accounting
**Root cause:** _transfer enforces `epoch[bond.asset] == block.timestamp/DAY`, but epoch only advances inside distribute(), which returns early when totalShares==0 or asset not allowed and is only called by lock/release/extend flows.
**Steps:**
1. Lock 3000 StableToken for 365 days to mint BondNFT id 1
2. Advance chain time 864000s via `evm_increaseTime` so epoch[asset] != block.timestamp/DAY
3. Call `bond.safeTransferMany(user, [1])`
4. Observe revert `Bad epoch` because no distribute() ran that day
**How found:** Read _transfer's epoch equality check against distribute(), noticed epoch only updates on lock/release/extend or claimGovFees and returns early for blacklisted/zero-share assets, then confirmed with existing Hardhat test.
**Exploitation:** Not an attack; functional DoS. Any BondNFT listed on a marketplace (e.g. OpenSea) or deposited as collateral cannot be transferred unless someone calls claimGovFees/distribute for that tigAsset the same day, so orders fail and collateral cannot be released.
**Insight:** When a transfer guard compares stored state to block.timestamp/DAY, check every path that advances that state and whether external callers (marketplaces, other protocols) will ever trigger it; lazy-updated accumulators gated on user actions create transferability DoS.
