{
    "Function": "slitherConstructorConstantVariables",
    "File": "contracts/routers/StrategyRouter.sol",
    "Parent Contracts": [
        "contracts/helpers/StrategyTypes.sol",
        "contracts/interfaces/IStrategyRouter.sol"
    ],
    "High-Level Calls": [],
    "Internal Calls": [],
    "Library Calls": [],
    "Low-Level Calls": [],
    "Code": "abstract contract StrategyRouter is IStrategyRouter, StrategyTypes {\n    using SafeMath for uint256;\n    using SignedSafeMath for int256;\n    using SafeERC20 for IERC20;\n\n    uint256 internal constant DIVISOR = 1000;\n\n    RouterCategory public override immutable category;\n    IStrategyController public override immutable controller;\n    address public immutable weth;\n\n    constructor(RouterCategory category_, address controller_) public {\n        category = category_;\n        controller = IStrategyController(controller_);\n        weth = IStrategyController(controller_).oracle().weth();\n    }\n\n    /**\n     * @dev Throws if called by any account other than the controller.\n     */\n    modifier onlyController() {\n        require(address(controller) == msg.sender, \"Only controller\");\n        _;\n    }\n\n    // Abstract external functions to be defined by inheritor\n    function deposit(address strategy, bytes calldata data) external virtual override;\n\n    function withdraw(address strategy, bytes calldata data) external virtual override;\n\n    function rebalance(address strategy, bytes calldata data) external virtual override;\n\n    function restructure(address strategy, bytes calldata data) external virtual override;\n\n    function _delegateSwap(\n        address adapter,\n        uint256 amount,\n        uint256 expected,\n        address tokenIn,\n        address tokenOut,\n        address from,\n        address to\n    ) internal {\n        require(controller.whitelist().approved(adapter), \"Not approved\");\n        bytes memory swapData =\n            abi.encodeWithSelector(\n                bytes4(\n                    keccak256(\"swap(uint256,uint256,address,address,address,address)\")\n                ),\n                amount,\n                expected,\n                tokenIn,\n                tokenOut,\n                from,\n                to\n            );\n        uint256 txGas = gasleft();\n        bool success;\n        assembly {\n            success := delegatecall(txGas, adapter, add(swapData, 0x20), mload(swapData), 0, 0)\n        }\n        if (!success) {\n            assembly {\n                let ptr := mload(0x40)\n                let size := returndatasize()\n                returndatacopy(ptr, 0, size)\n                revert(ptr, size)\n            }\n        }\n    }\n\n    function _sellPath(\n        TradeData memory data,\n        uint256 amount,\n        address token,\n        address strategy\n    ) internal {\n        if (amount > 0) {\n            for (int256 i = int256(data.adapters.length-1); i >= 0; i--) { //this doesn't work with uint256?? wtf solidity\n                uint256 _amount;\n                address _tokenIn;\n                address _tokenOut;\n                address _from;\n                address _to;\n                if (uint256(i) == data.adapters.length-1) {\n                    _tokenIn = token;\n                    _amount = amount;\n                    _from = strategy;\n                } else {\n                    _tokenIn = data.path[uint256(i)];\n                    _from = address(this);\n                    _amount = IERC20(_tokenIn).balanceOf(_from);\n                }\n                if (uint256(i) == 0) {\n                    _tokenOut = weth;\n                    _to = strategy;\n                } else {\n                    _tokenOut = data.path[uint256(i-1)];\n                    _to = address(this);\n                }\n                _delegateSwap(\n                    data.adapters[uint256(i)],\n                    _amount,\n                    1,\n                    _tokenIn,\n                    _tokenOut,\n                    _from,\n                    _to\n                );\n            }\n        }\n    }\n\n    function _buyPath(\n        TradeData memory data,\n        uint256 amount,\n        address token,\n        address strategy,\n        address from\n    ) internal {\n        if (amount > 0) {\n            for (uint256 i = 0; i < data.adapters.length; i++) {\n                uint256 _amount;\n                address _tokenIn;\n                address _tokenOut;\n                address _from;\n                address _to;\n                if (i == 0) {\n                    _tokenIn = weth;\n                    _amount = amount;\n                    _from = from;\n                } else {\n                    _tokenIn = data.path[i-1];\n                    _from = address(this);\n                    _amount = IERC20(_tokenIn).balanceOf(_from);\n                }\n                if (i == data.adapters.length-1) {\n                    _tokenOut = token;\n                    _to = strategy;\n                } else {\n                    _tokenOut = data.path[i];\n                    _to = address(this);\n                }\n                _delegateSwap(\n                    data.adapters[i],\n                    _amount,\n                    1,\n                    _tokenIn,\n                    _tokenOut,\n                    _from,\n                    _to\n                );\n            }\n        }\n    }\n\n    function _estimateSellAmount(\n        address strategy,\n        address token,\n        uint256 amount,\n        uint256 estimatedValue\n    ) internal view returns (uint256) {\n        uint256 balance = IERC20(token).balanceOf(strategy);\n        if (estimatedValue > amount) {\n          return balance.mul(amount).div(estimatedValue);\n        } else {\n          return balance;\n        }\n    }\n}"
}