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.