Grouped Transfer Bug: How the Proposed Fix Works
The proposed fix adds up the entries that share a token id, so 40 + 40 counts as 80. Was it merged, and what else could you do?

IN 30 SECONDS
A cumulative per-id check is a fix that adds up every batch entry sharing a token id, then compares that running total with both the raw balance and the unfrozen amount. PR #2045 proposes it for the ERC-7943 reference code; it was unmerged on 7 October 2026.
KEY TAKEAWAYS · 3
- With PR #2045 applied, the batch of 40 + 40 on one id is refused at the second entry, before any debit.
- On 7 October 2026, the PR was open, unmerged and unreviewed, and issue #1814 was still open.
- Any fix must make the check see the total per id. A balance check after the debit is a backstop, not a replacement.
On this page
A worked example: the same batch, before and after the fix
IN SHORT With PR #2045 applied, the same batch is refused at the second entry: the check now adds up entries that share an id.
WORDS TO KNOW
- Regression test
- A test that replays a bug once it is fixed, so the bug can never come back unnoticed.
- Pull request
- A proposed change to a project’s code, open for review. It changes nothing until someone merges it.
- Self-transfer
- A transfer where the sender and the receiver are the same account.
A WORKED EXAMPLE
REFUSEDPR #2045 applied: id 1 twice, 40 each
INPUT
- Balance
- 100
- Frozen
- 60
- Batch
- id 1 twice: 40 + 40
WHAT HAPPENS
- First entry: the running total for id 1 is 40, within the 40 unfrozen.
- Second entry: the running total for id 1 is now 80, over the 40 unfrozen.
- The call fails (it reverts) before any debit.
OUTPUT
- Moved
- 0
- Balance / frozen
- 100 / 60
BYPASSEDReference contract before the fix, same batch
INPUT
- Batch
- id 1 twice: 40 + 40
WHAT HAPPENS
- Each entry is checked against the same 40 unfrozen: both pass.
- Only then are both entries debited: 80 in total.
OUTPUT
- Moved
- 80
- Balance / frozen
- 20 / 60
ITEM GET
Add up per id
These are the PR’s reproduction numbers, not made-up ones. Unfixed, the bypass is bounded: toward another account, never more than the raw balance, and each entry must fit the 40 unfrozen. But any whitelisted holder can use it, with no special role.
A Regression test A test that replays a bug once it is fixed, so the bug can never come back unnoticed. See the glossary replays this exact batch. It passes once the PR’s changes are applied.
Coming up next: So has this fix been merged yet?
Where issue #1814 and PR #2045 stand
IN SHORT On 7 October 2026, the fix sat in an open pull request with no reviews, and the issue was still open.
STEP BY STEP
Step 1. Final. The commit “Update ERC-7943: Move to Final” lands on the ERC’s text.
- Final The commit “Update ERC-7943: Move to Final” lands on the ERC’s text.
- Reported @MavenRain opens an issue, a public bug report, on the repeated-id bypass in uRWA1155, with a proof of concept.
- Redirected A contributor recommends posting on the ERC’s thread on Ethereum Magicians, the standards forum.
- Fix proposed @Kshot3000 opens PR #2045: it fixes the transfer and burn branches (a burn destroys tokens) and adds three regression tests.
- Still open The PR is open and unmerged, with no reviews. The bot lists one author review and two editor reviews as required. The issue is still open too.
IN PLAIN WORDS
Four ways to close the gap
IN SHORT Any fix has to make the check see the total per id, and every option has a trade-off.
I like the check after the debit as a second line of defense. On holder transfers that start at or above the frozen amount, it asserts directly that frozen tokens stay put.
WATCH OUT
A freeze may exceed the balance: then holder transfers must not widen that gap. Forced transfers and privileged burns follow their own rule. If they spend frozen tokens, they update the frozen amount and emit Frozen before the transfer event.
In OpenZeppelin v5, ERC-1155 runs _update before the receiver check, the call that asks a receiving contract to accept the tokens. So a check at the end of _update comes first.
WATCH OUT
I ran the stage 4 test for this post, not on client code. The post-check version passed two of its three tests. PR #2045 passed all three, self-transfers included.
So keep the aggregate check and treat the post-check as a backstop.
Sources: ERCs issue #1814, ERCs PR #2045 (open as of 7 Oct 2026).
STAGE CLEAR
What you now know
- Where the fix stood on 7 October 2026: open, unmerged, with no reviews.
- Why a check after the debit can back the fix up but can’t replace it.
Check yourself
Tap or click a question to see the answer.
You reject every batch that repeats an id. Is the 40 + 40 trick closed, and what does it cost you?
Closed: each entry is then its id’s total. The cost is refusing batches that ERC-1155 itself allows.
Former CTO of Integra. Named author (1 of 5) of ERC-3643, first author of ERC-6960, co-author of ERC-7410, and co-author of ERC-8203, which is still a draft. Building production AI and regulated Web3 systems.
Have a project to ship or a role to fill?
Discuss your project or roleFollow the engineering notes
Get new articles on production AI and smart contracts by email.