Open johnsaigle opened 8 months ago
@johnsaigle what's your view on this issue? What's the range of decimals and word sizes over which this issue could manifest?
I gave some examples here: https://github.com/wormhole-foundation/example-native-token-transfers/issues/266#issue-2171615766
The dominant variable is the difference between to_decimals
and from_decimals
. The greater this difference, the smaller the amount must be. Conversely, larger amounts only work if the platforms have similar numbers of decimals.
Here's some example Python you can play with to get an idea. Using uint64 because it represents Solana and many other chains. uint128
is more appropriate for Solidity though we do a lot of conversions/truncations in the codebase.
>>> int(10e18).bit_length() # This number fits in uint64
64
>>> int(2*10e18).bit_length() # this number overflows uint64
65
>>> amount = 10e6
>>> to_decimals = 18
>>> from_decimals = 6
>>> to_decimals - from_decimals
12
>>> scaling_factor = 10e12 # see the `scale()` functions in EVM and Rust implementations
>>> amount * scaling_factor
1e+20
>>> int(amount * scaling_factor).bit_length() # The amount when scaled in `trimmed_amount` overflows uint64
67
Another check we should consider adding is on the sending side, before the transfer is sent, ensuring the recipient will be able to untrim the amount to its desired decimals. The contracts know their peers' decimals, so they could perform this check before sending out. This way, the transaction would revert on the sending side, not the receiving side in case the target chain wouldn't be able to handle the amount.
Originally posted by @kcsongor in https://github.com/wormhole-foundation/example-native-token-transfers/issues/266#issuecomment-1981002675