Normalizing decimals to 18 decimals returns the amount scaled up by a magnitude different than 18 when the original tokenDecimals are not 18 decimals #170
Incorrectly computing the magnitude of the token amounts will make that users transfer more tokens than what they really expect to transfer
Also is possible that for a good number of users it becomes impossible to even cover the wrong computed amount of tokens, thus, they won't be able to use the systems
Also using an incorrect magnitude can impact the internal accounting and balances in the system, which could lead to losses or even DoS in functions dependant on the internal accounting & balances.
Lines of code
https://github.com/code-423n4/2023-05-maia/blob/main/src/ulysses-omnichain/BranchBridgeAgent.sol#L1335-L1342
Vulnerability details
Impact
Proof of Concept
The current formula to normalize the decimals is the below one:
By doing the math we have:
_amount
is scaled up by the tokensDecimals!_amount * (10 ** _decimals) / 1 ether
[(10**8) * (10**8)] / (10**18)
===>(10**16) / (10**18)
===>10**-2
Example 2: A token that has 30 decimals:
_amount
is scaled up by the tokensDecimals!The formula:
_amount * (10 ** _decimals) / 1 ether
Substituting values:
[(10**30) * (10**30)] / (10**18)
===>(10**60) / (10**18)
===>10**42
result:
10**42
As demonstrated in the above examples, the current formula doesn't compute correctly the normalization of the decimals to 18 decimals.
Tools Used
Manual Audit
Recommended Mitigation Steps
Make sure to update the formula to normalize the decimals to 18 as follows:
return _decimals == 18 ? _amount : _amount * (10 ** _decimals) / 1 ether;
return _decimals == 18 ? _amount : _amount * 1 ether / (10 ** _decimals); }
By doing the math we have:
Example 1: A token that has 8 decimals:
_amount
is scaled up by the tokensDecimals!The formula:
_amount * 1 ether / (10 ** _decimals)
Substituting values:
[(10**8) * (10**18)] / (10**8)
===>(10**26) / (10**8)
===>10**18
result:
10**18
Example 2: A token that has 30 decimals:
_amount
is scaled up by the tokensDecimals!The formula:
_amount * 1 ether / (10 ** _decimals)
Substituting values:
[(10**30) * (10**18)] / (10**30)
===>(10**48) / (10**30)
===>10**18
result:
10**18
Assessed type
Math