Omniscia Teahouse Finance Audit

UniswapV3PathRecommender Manual Review Findings

UniswapV3PathRecommender Manual Review Findings

UVP-01M: Inexistent Sorting of Tokens

Description:

The swapPath mapping may end up with an inefficient data structure as it does not sort the srcToken and dstToken values prior to writing to them.

Impact:

This change is classified under manual review findings given that it pertains to a design adjustment that we deem important for the long-term viability of the project.

Example:

contracts/UniswapV3PathRecommender.sol
17function setRecommendedPath(
18 address[] calldata _tokens,
19 uint24[] calldata _fees
20) external onlyOwner returns (
21 bytes memory pathExactInput,
22 bytes memory pathExactOutput
23) {
24 uint256 feesLength = _fees.length;
25 uint256 tokensLength = _tokens.length;
26 if (tokensLength != feesLength + 1) revert TokensFeesLengthMismatch();
27
28 address srcToken = _tokens[0];
29 address dstToken = _tokens[tokensLength - 1];
30 // swap router path:
31 // exact input: abi.encodePacked(srcToken, fee, intermediaryToken, ..., fee, dstToken)
32 // exact output: abi.encodePacked(dstToken, fee, intermediaryToken, ..., fee, srcToken)
33 // sample of DAI => WETH9: DAI to USDC and then USDC to WETH9
34 // exact input: the path encoding is (DAI, 0.3%, USDC, 0.3%, WETH9)
35 // exact output: the path encoding is (WETH9, 0.3%, USDC, 0.3%, DAI)
36 pathExactInput = abi.encodePacked(srcToken);
37 pathExactOutput = abi.encodePacked(dstToken);
38 for (uint256 i; i < feesLength; i = i + 1) {
39 pathExactInput = bytes.concat(pathExactInput, abi.encodePacked(_fees[i], _tokens[i + 1]));
40 pathExactOutput = bytes.concat(pathExactOutput, abi.encodePacked(_fees[feesLength - i - 1], _tokens[feesLength - i - 1]));
41 }
42
43 swapPath[srcToken][dstToken] = [pathExactInput, pathExactOutput];
44 emit SwapPathSet(block.timestamp, srcToken, dstToken, pathExactInput, pathExactOutput);
45}
46
47function getRecommendedPath(bool _isExactInput, address _srcToken, address _dstToken) external view returns (bytes memory path) {
48 return _isExactInput ? swapPath[_srcToken][_dstToken][0] : swapPath[_srcToken][_dstToken][1];
49}

Recommendation:

We advise the swapPath to contain the sorted tokens as keys to it, permitting callers to acquire the swapPath of any token combination via a single entry given that the swapPath array contains both input and output paths.

Alleviation (302b96f324a88038a0872015466cd43783c14543):

The Teahouse Finance team stated that a token path between two tokens is not necessarily interchangeable.

As such, we consider the exhibit nullified given that its recommendation is inapplicable based on the business requirements of the UniswapV3PathRecommender.