Huge accounting errors and losses for borrowers and liquidators if a collateral token with a non-18 decimal value is used. The oracle contract won't always return prices in 18 decimals.
On the other side if the token decimals aren't 18 (let's say 6 like the DAI stablecoin) price will be in 30 decimals and the 1 ether constant will remove extra value. Decimals will be 6 * 18 / 30 = 3 which will reduce the liquidator reward by 50%.
This issue also happens in other parts of the contract where the 1 ether constant is used. It's also used to compute collateral value so wrong calculations can also lead to undeserved liquidation leading to losses for borrowers.
Lines of code
https://github.com/code-423n4/2022-10-inverse/blob/3e81f0f5908ea99b36e6ab72f13488bbfe622183/src/Oracle.sol#L88 https://github.com/code-423n4/2022-10-inverse/blob/3e81f0f5908ea99b36e6ab72f13488bbfe622183/src/Market.sol#L326 https://github.com/code-423n4/2022-10-inverse/blob/3e81f0f5908ea99b36e6ab72f13488bbfe622183/src/Market.sol#L597
Vulnerability details
Impact
Huge accounting errors and losses for borrowers and liquidators if a collateral token with a non-18 decimal value is used. The oracle contract won't always return prices in 18 decimals.
Proof of Concept
The oracle returns the price in a normalized way equal to 36 - TokenDecimals. https://github.com/code-423n4/2022-10-inverse/blob/3e81f0f5908ea99b36e6ab72f13488bbfe622183/src/Oracle.sol#L88
Let's say we're using a 6-decimal token and chainlink returns feed data in 18 decimals. The price will be something in the form of p * 10 **18.
Normalized price will be p*10*18 10 (36-18-6) = p 10 (18+12) = p 10(30) = p *10(36-tokenDecimals)
In the liquidate function the 1 ether constant is used to avoid accounting for decimals twice when multiplying by price. https://github.com/code-423n4/2022-10-inverse/blob/3e81f0f5908ea99b36e6ab72f13488bbfe622183/src/Market.sol#L597 If the Token decimals are 18 the price will be in 18 decimals and 1 ether will cancel the decimals as intended.
On the other side if the token decimals aren't 18 (let's say 6 like the DAI stablecoin) price will be in 30 decimals and the 1 ether constant will remove extra value. Decimals will be 6 * 18 / 30 = 3 which will reduce the liquidator reward by 50%.
This issue also happens in other parts of the contract where the 1 ether constant is used. It's also used to compute collateral value so wrong calculations can also lead to undeserved liquidation leading to losses for borrowers.
https://github.com/code-423n4/2022-10-inverse/blob/3e81f0f5908ea99b36e6ab72f13488bbfe622183/src/Market.sol#L326
Tools Used
Recommended Mitigation Steps
Don't assume token has 18 decimals. Use token decimals to do calculations instead of the ether constant.