# Using a timestamp as a key for processed messages leads to key collisions in the database

Initia opinit-bots keys processed-message DB entries by nanosecond timestamp; batches created in the same tick collide, overwriting/deleting pending txs so a restarted executor skips critical Cosmos broadcasts.

- Payout: Contest reward
- Severity: medium
- Program: Initia
- Credited: RadiantLabs
- Disclosed: 2025-04-10
- Write-up quality: 6/10
- Original: https://code4rena.com/reports/2025-01-initia-rollup-modules#m-04
- Library page: https://bugbountylibrary.com/r/c4%3A2025-01-initia-rollup-modules%3AM-04
- Tags: domain:web3 impact:dos impact:integrity kind:contest platform:code4rena sev:medium tech:go technique:race-window technique:source-review vuln:accounting-error vuln:race-condition

**Target:** opinit-bots executor batchsubmitter / broadcaster DB persistence
**Root cause:** ProcessedMsgs.Key() derives the DB key solely from a nanosecond timestamp; MsgsToProcessedMsgs() stamps every chunk with CurrentNanoTimestamp(), so multiple batches in one loop iteration share a timestamp and thus a key.
**Steps:**
1. Read `MsgsToProcessedMsgs` in executor/batchsubmitter/batch.go: chunks of 5 msgs each get `Timestamp: types.CurrentNanoTimestamp()`
2. Note `ProcessedMsgs.Key()` returns `prefixedProcessedMsgs(MustInt64ToUint64(p.Timestamp))`
3. Queue 100 messages for one sender, call `MsgsToProcessedMsgs` -> 20 batches
4. Observe adjacent batches share Timestamp and `msgs[i].Key() == msgs[i+1].Key()`
5. `SaveProcessedMsgsBatch` overwrites and `DeleteProcessedMsgs` deletes by that shared key
**How found:** Code review of the batching/persistence path: noticed the DB key is derived only from a timestamp and that a tight loop generating many batches would reuse the same nanosecond value; confirmed with a unit test asserting key equality across batches.
**Exploitation:** Not attacker-triggered; on executor restart the collided keys mean pending processed messages are lost/overwritten, so the bot fails to resume and misses broadcasting critical Cosmos txs such as finalizing an L1->L2 token deposit.
**Insight:** When a persistence key is derived from a clock value, check whether the producer emits multiple records within one clock tick (tight loops, chunking); nanosecond timestamps are not unique identifiers on all platforms.
