USD1 is priced as $1 instead of being pegged to USDT
The system treats 1 USD1 = $1 instead of 1 USD1 = 1 USDT which allows arbitrage opportunities.\\nTo swap from one token to another Unitas first get's the price of the quote token and then calculates the swap result. Given that we want to swap 1 USD1 for USDT, we have USDT as the quote token:\\n```\\n        address priceQuoteToken = _getPriceQuoteToken(tokenIn, tokenOut);\\n        price = oracle.getLatestPrice(priceQuoteToken);\\n        _checkPrice(priceQuoteToken, price);\\n\\n        feeNumerator = isBuy ? pair.buyFee : pair.sellFee;\\n        feeToken = IERC20Token(priceQuoteToken == tokenIn ? tokenOut : tokenIn);\\n\\n        SwapRequest memory request;\\n        request.tokenIn = tokenIn;\\n        request.tokenOut = tokenOut;\\n        request.amountType = amountType;\\n        request.amount = amount;\\n        request.feeNumerator = feeNumerator;\\n        request.feeBase = tokenManager.SWAP_FEE_BASE();\\n        request.feeToken = address(feeToken);\\n        request.price = price;\\n        request.priceBase = 10 ** oracle.decimals();\\n        request.quoteToken = priceQuoteToken;\\n\\n        (amountIn, amountOut, fee) = _calculateSwapResult(request);\\n```\\n\\nSince `amountType == AmountType.In`, it executes _calculateSwapResultByAmountIn():\\n```\\n            // When tokenOut is feeToken, subtracts the fee after converting the amount\\n            amountOut = _convert(\\n                request.tokenIn,\\n                request.tokenOut,\\n                amountIn,\\n                MathUpgradeable.Rounding.Down,\\n                request.price,\\n                request.priceBase,\\n                request.quoteToken\\n            );\\n            fee = _getFeeByAmountWithFee(amountOut, request.feeNumerator, request.feeBase);\\n            amountOut -= fee;\\n```\\n\\nGiven that the price is 0.99e18, i.e. 1 USDT is worth $0.99, it calculates the amount of USDT we should receive as:\\n```\\n    function _convertByFromPrice(\\n        address fromToken,\\n        address toToken,\\n        uint256 fromAmount,\\n        MathUpgradeable.Rounding rounding,\\n        uint256 price,\\n        uint256 priceBase\\n    ) internal view virtual returns (uint256) {\\n        uint256 fromBase = 10 ** IERC20Metadata(fromToken).decimals();\\n        uint256 toBase = 10 ** IERC20Metadata(toToken).decimals();\\n\\n        return fromAmount.mulDiv(price * toBase, priceBase * fromBase, rounding);\\n    }\\n```\\n\\nGiven that:\\ntoBase = 10**6 = 1e6 (USDT has 6 decimals)\\nfromBase = 10**18 = 1e18 (USD1 has 18 decimals)\\npriceBase = 1e18\\nprice = 0.99e18 (1 USDT = $0.99)\\nfromAmount = 1e18 (we swap 1 USD1) we get: $1e18 * 0.99e18 * 1e6 / (1e18 * 1e18) = 0.99e6$\\nSo by redeeming 1 USD1 I only get back 0.99 USDT. The other way around, trading USDT for USD1, would get you 1.01 USD1 for 1 USDT: $1e6 * 1e18 * 1e18 / (0.99e18 * 1e6) = 1.01e18$\\nThe contract values USD1 at exactly $1 while USDT's price is variable. But, in reality, USD1 is not pegged to $1. It's pegged to USDT the only underlying asset.\\nThat allows us to do the following:\\nWith USDT back to $1 we get: $1.003009e+23 * 1e18 * 1e6 / (1e18 * 1e18) = 100300.9e6$\\nThat's a profit of 300 USDT. The profit is taken from other users of the protocol who deposited USDT to get access to the other stablecoins.
1 USDT should always be 1 USD1. You treat 1 USD1 as $1 but that's not the case.
An attacker can abuse the price variation of USDT to buy USD1 for cheap.
```\\n        address priceQuoteToken = _getPriceQuoteToken(tokenIn, tokenOut);\\n        price = oracle.getLatestPrice(priceQuoteToken);\\n        _checkPrice(priceQuoteToken, price);\\n\\n        feeNumerator = isBuy ? pair.buyFee : pair.sellFee;\\n        feeToken = IERC20Token(priceQuoteToken == tokenIn ? tokenOut : tokenIn);\\n\\n        SwapRequest memory request;\\n        request.tokenIn = tokenIn;\\n        request.tokenOut = tokenOut;\\n        request.amountType = amountType;\\n        request.amount = amount;\\n        request.feeNumerator = feeNumerator;\\n        request.feeBase = tokenManager.SWAP_FEE_BASE();\\n        request.feeToken = address(feeToken);\\n        request.price = price;\\n        request.priceBase = 10 ** oracle.decimals();\\n        request.quoteToken = priceQuoteToken;\\n\\n        (amountIn, amountOut, fee) = _calculateSwapResult(request);\\n```\\n