NaN XE fee for withdrawals
annybs opened this issue · comments
There is a critical problem in AccountPanel where props are reused across multiple inner "views" in a way that breaks fee calculation for withdrawals, both visually and in the actual withdrawal.
The same data.amount
prop is bound to three inputs: here, here, and here. In turn, the data.amount
prop is watched here:
wallet/src/components/AccountPanel.vue
Line 1319 in d152ef8
This means that whenever data.amount
is updated by any of the three inputs, both of these component methods are invoked, causing the fee to be recalculated - twice:
wallet/src/components/AccountPanel.vue
Line 1327 in d152ef8
wallet/src/components/AccountPanel.vue
Line 1334 in d152ef8
data.fee
is itself bound to multiple elements (too many to list) with :value="fee"
- the key effect being that the same data.amount
and data.fee
properties are used across all inner views (and, notably, persist across them even if the modal is opened/closed).
Going back to the watch
rule: whenever the data.amount
is updated, the data.fee
property is updated twice, by calculateEdge()
and then calculateUSDC()
- with the result that the following reproduction steps will display a NaN fee:
- Open exchange modal
- Open 'Withdraw' inner view
- (optional) Select any transaction speed
- Update amount
We see NaN
because the USDC fee calculation is done second, which uses data.exchangeRate
the gas
property of which is initially undefined. As a result, the calculation fails since undefined cannot be parsed to a number.
To fix this, you can select a transaction speed again. NaN is cleared and a correct fee is shown (and subsequently used while attempting withdrawal). This works because the options are bound to only calculateEdge()
and not calculateUSDC()
:
wallet/src/components/AccountPanel.vue
Lines 1465 to 1468 in d152ef8
Another way to "fix" this (although improperly) is through the following reproduction steps:
- Open exchange modal
- Open 'Sell' inner view
- Cancel and reopen exchange modal
- Open 'Withdraw' inner view
Now, you can update amount before or after transaction speed, it doesn't matter. This works because opening the 'Sell' view updates the exchangeRate object with actual values, allowing the calculation to work.
Of course, these steps don't actually solve the problem, because you still see the USDC fee, which is likely to differ from the EDGE withdrawal fee. So, an unknowing user might follow these steps, and then inadvertently attempt to create a withdrawal transaction with an incorrect fee.
Fundamentally, the problem here is misappropriation of shared props for multiple different uses, and the optimal solution here is to isolate each inner view of the modal into its own component, using its own properties. A quicker fix might be just to define separate properties for each view within the AccountPanel component. However, the component is already complex enough as it is, and I think the larger task of refactoring is warranted in the circumstances.
Welcoming feedback from @adamkdean before I go ahead making fixes.