// SPDX-License-Identifier: Apache-2.0 pragma solidity ^0.8.0; import {ICurveRouter} from "./dependencies/ICurveRouter.sol"; import {BytesLib} from "solidity-bytes-utils/contracts/BytesLib.sol"; /** * @title Library to access a set of curve routes stored as tightly packed bytes * * @dev The format is a concatenation of bytes, packed (ethers.solidityPack in js) with the following fields * * Fields: * * * -- for each route -- * *
*
MAX_SWAPS) revert TooManySwaps(nSwaps); for (uint256 i; i < _routeLen(nSwaps); i++) { route.route[i] = curveRoutes.toAddress(offset + UINT8_SIZE + i * ADDRESS_SIZE); } offset += UINT8_SIZE + _routeLen(nSwaps) * ADDRESS_SIZE; for (uint256 i; i < nSwaps; i++) { route.swapParams[i][0] = curveRoutes.toUint8(offset + i * UINT8_SIZE * 5); route.swapParams[i][1] = curveRoutes.toUint8(offset + i * UINT8_SIZE * 5 + 1); route.swapParams[i][2] = curveRoutes.toUint8(offset + i * UINT8_SIZE * 5 + 2); route.swapParams[i][3] = curveRoutes.toUint8(offset + i * UINT8_SIZE * 5 + 3); route.swapParams[i][4] = curveRoutes.toUint8(offset + i * UINT8_SIZE * 5 + 4); } offset += nSwaps * UINT8_SIZE * 5; for (uint256 i; i < nSwaps; i++) { route.pools[i] = curveRoutes.toAddress(offset + i * ADDRESS_SIZE); } } function routeSize(uint8 nSwaps) internal pure returns (uint256) { return UINT8_SIZE + // nSwaps _routeLen(nSwaps) * ADDRESS_SIZE + // route (nSwaps * 5 * UINT8_SIZE) + // swapParams (nSwaps * ADDRESS_SIZE); // pools } function _routeLen(uint8 nSwaps) private pure returns (uint256) { return (nSwaps * 2 + 1); } function findRoute( bytes memory curveRoutes, address tokenIn, address tokenOut ) internal pure returns (ICurveRouter router, CurveRoute memory route) { router = ICurveRouter(curveRoutes.toAddress(ROUTER_OFFSET)); uint8 nRoutes = curveRoutes.toUint8(N_ROUTES_OFFSET); uint256 offset = ROUTES_BASE_OFFSET; for (uint256 i; i < nRoutes; i++) { uint8 nSwaps = curveRoutes.toUint8(offset); if ( curveRoutes.toAddress(offset + UINT8_SIZE) == tokenIn && curveRoutes.toAddress(offset + UINT8_SIZE + ADDRESS_SIZE * nSwaps * 2) == tokenOut ) { (, route) = readRoute(curveRoutes, offset); return (router, route); } offset += routeSize(nSwaps); } revert RouteNotFound(tokenIn, tokenOut); } }