Omniscia Tangible Audit
Exchange Manual Review Findings
Exchange Manual Review Findings
EEG-01M: Incorrect Output Amount Measurement
| Type | Severity | Location |
|---|---|---|
| Logical Fault | ![]() | Exchange.sol:L156 |
Description:
The Exchange::quoteOut function will incorrectly assess the output amount of a swap via the IRouter::getAmountOut as the function's stable boolean result is not mandated to match the stable configuration of the tokenized trade path.
Impact:
The output amount yielded by Exchange::quoteOut may be higher than the actual output of a trade via the stable configuration, causing reliance on the function's outputs for setting minimum outputs to be incorrect.
Example:
144function quoteOut(145 address tokenIn,146 address tokenOut,147 uint256 amountIn148) external view returns (uint256) {149 uint256[] memory amounts = new uint256[](2);150
151 bytes memory tokenized = abi.encodePacked(tokenIn, tokenOut);152 address _router = routers[tokenized];153 require(address(0) != _router, "router 0 qo");154
155 if (simpleSwap[tokenized]) {156 (amounts[1], ) = IRouter(_router).getAmountOut(amountIn, tokenIn, tokenOut);157 } else {158 amounts = new uint256[](routePaths[tokenized].length);159 amounts = IRouter(_router).getAmountsOut(amountIn, routePaths[tokenized]);160 }161
162 return amounts[amounts.length - 1];163}Recommendation:
We advise the code to ensure that the stable boolean result of the IRouter::getAmountOut function call matches the stable configuration of the trade path and to handle the failure case accordingly.
Alleviation (2ad448279d9e8e4b6edd94bcd2eb22129b6f7357):
The Exchange::quoteOut function was revised to integrate with Uniswap V3 like pools, thereby no longer being susceptible to the same vulnerability.
As such, we consider this exhibit to be no longer applicable.
EEG-02M: Inexistent Sanitization of Trade Routes
| Type | Severity | Location |
|---|---|---|
| Logical Fault | ![]() | Exchange.sol:L74-L75 |
Description:
The Exchange::addRouterForTokens function permits explicit trade routes to be added for a particular token pair, however, these trade routes are not validated in their outputs.
Impact:
A misconfigured trade route may lead to the minimum output values passed into Exchange::exchange to be incorrectly consumed and may cause smart-contract integrators of the Exchange::exchange function to lose funds.
Example:
56function addRouterForTokens(57 address tokenInAddress,58 address tokenOutAddress,59 address _router,60 IRouter.Route[] calldata _routes,61 IRouter.Route[] calldata _routesReversed,62 bool _simpleSwap,63 bool _stable64) external onlyFactoryOwner {65 require(_routes.length == _routesReversed.length, "mismatch");66 bytes memory tokenized = abi.encodePacked(tokenInAddress, tokenOutAddress);67 bytes memory tokenizedReverse = abi.encodePacked(tokenOutAddress, tokenInAddress);68 // set routes69 routers[tokenized] = _router;70 routers[tokenizedReverse] = _router;71 // set paths if any72 uint256 length = _routes.length;73 for (uint256 i; i < length; ) {74 routePaths[tokenized].push(_routes[i]);75 routePaths[tokenizedReverse].push(_routesReversed[i]);76 unchecked {77 ++i;78 }79 }80 // set if simple swap or with hops81 simpleSwap[tokenized] = _simpleSwap;82 simpleSwap[tokenizedReverse] = _simpleSwap;83 //set if pool is stable or not84 stable[tokenized] = _stable;85 stable[tokenizedReverse] = _stable;86}Recommendation:
As they are passed in as-is in the Exchange::exchange function, we advise the code to ensure that the input and, more importantly, the output tokens of the trade route match the desired outcome.
Alleviation (2ad448279d9e8e4b6edd94bcd2eb22129b6f7357):
The Exchange contract was revised to integrate with Uniswap V3 like pools, thereby no longer requiring interim path definitions and only the input and output tokens from which the tokenized and tokenizedReverse variables are calculated from.
As such, we consider this exhibit no longer applicable.
