There is a logic error in _convertDecimals() function which means wrapping interactions for tokens with less than 18 decimals are processed incorrectly.
The below is triggered in _convertDecimals() where the input parameter decimals is less than 18. If amountToConvert is less than shift and then convertedAmount returns 0
It ends up that only "1" will be transferred from the user to ocean. The user will keep most of their money minus "1" in the ERC20 token balances and they will also get the an amount of Ocean 1155 tokens equivalent to the amoiunt they tried to wrap.
Impact
Users can get free money when wrapping a 6 decimal token
Lines of code
https://github.com/code-423n4/2023-11-shellprotocol/blob/main/src/ocean/Ocean.sol#L1068-L1109
Vulnerability details
There is a logic error in
_convertDecimals()
function which means wrapping interactions for tokens with less than 18 decimals are processed incorrectly.The below is triggered in
_convertDecimals()
where the input parameterdecimals
is less than 18. IfamountToConvert
is less thanshift
and thenconvertedAmount
returns 0In
_determineTransferAmount
iftruncatedAmount
is > 0 a 1 will be added totransferAmount
.It ends up that only "1" will be transferred from the user to ocean. The user will keep most of their money minus "1" in the ERC20 token balances and they will also get the an amount of Ocean 1155 tokens equivalent to the amoiunt they tried to wrap.
Impact
Users can get free money when wrapping a 6 decimal token
Proof of Concept
Add this test to
TokenIntegration.js
and run:Tools Used
Hardhat Manual Review
Recommended Mitigation Steps
If user has
truncatedAmount
but it is less thanshift
do not add 1 totransferAmount
Assessed type
Error