The swap decoder, src/shared/uniswap.js. BALANCE_CHECK_ERC20 takes (address owner, address token, uint256 minBalance); the decoder reads the token and the minimum to set the output side and Min. received, but never reads the owner.
What happens
Calldata that ends with a BALANCE_CHECK_ERC20 of another address's balance reads Min. received with that minimum, as if it were what the user receives. The router only checks that the named owner holds at least that much; it pays nobody.
What should happen
Min. received states only what the calldata guarantees the user receives. A balance check of another address is not a guarantee to the user: the screen either names that address or does not draw Min. received from it.
Severity: major (with a swap paid to the user, the screen reads like a normal swap while stating another address's balance as what the user receives; #598 (comment))
Definition of done
A BALANCE_CHECK_ERC20 whose owner is not the user does not set Min. received.
Tests with the owner the user and another address.
Model: opus-5-5
Seen by the review of https://git.eeqj.de/sneak/AutistMask/pulls/598.
## Where
The swap decoder, `src/shared/uniswap.js`. `BALANCE_CHECK_ERC20` takes `(address owner, address token, uint256 minBalance)`; the decoder reads the token and the minimum to set the output side and `Min. received`, but never reads the owner.
## What happens
Calldata that ends with a `BALANCE_CHECK_ERC20` of another address's balance reads `Min. received` with that minimum, as if it were what the user receives. The router only checks that the named owner holds at least that much; it pays nobody.
## What should happen
`Min. received` states only what the calldata guarantees the user receives. A balance check of another address is not a guarantee to the user: the screen either names that address or does not draw `Min. received` from it.
Severity: major (with a swap paid to the user, the screen reads like a normal swap while stating another address's balance as what the user receives; https://git.eeqj.de/sneak/AutistMask/pulls/598#issuecomment-147892)
## Definition of done
- [ ] A `BALANCE_CHECK_ERC20` whose owner is not the user does not set `Min. received`.
- [ ] Tests with the owner the user and another address.
Model: opus-5-5
clawbot
self-assigned this 2026-10-19 08:37:04 +02:00
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Seen by the review of #598.
Where
The swap decoder,
src/shared/uniswap.js.BALANCE_CHECK_ERC20takes(address owner, address token, uint256 minBalance); the decoder reads the token and the minimum to set the output side andMin. received, but never reads the owner.What happens
Calldata that ends with a
BALANCE_CHECK_ERC20of another address's balance readsMin. receivedwith that minimum, as if it were what the user receives. The router only checks that the named owner holds at least that much; it pays nobody.What should happen
Min. receivedstates only what the calldata guarantees the user receives. A balance check of another address is not a guarantee to the user: the screen either names that address or does not drawMin. receivedfrom it.Severity: major (with a swap paid to the user, the screen reads like a normal swap while stating another address's balance as what the user receives; #598 (comment))
Definition of done
BALANCE_CHECK_ERC20whose owner is not the user does not setMin. received.Model: opus-5-5