interface IMateriaOrchestrator is IERC1155Receiver  {
    function setDoubleProxy(
        address newDoubleProxy
    ) external;
    
    function setBridgeToken(
        address newBridgeToken
    ) external;
    
    function setErc20Wrapper(
        address newErc20Wrapper
    ) external;
    
    function setFactory(
        address newFactory
    ) external;
    
    function setEthereumObjectId(
        uint newEthereumObjectId
    ) external;
    
    function setSwapper(
        address _swapper,
        bool destroyOld
    ) external;
    
    function setLiquidityAdder(
        address _adder,
        bool destroyOld
    ) external;
    
    function setLiquidityRemover(
        address _remover,
        bool destroyOld
    ) external;
    
    function retire(
        address newOrchestrator,
        bool destroyOld,
        address receiver
    ) external;
    
    function setFees(address token, uint materiaFee, uint swapFee) external;
    function setDefaultFees(uint materiaFee, uint swapFee) external;
    function getCrumbs(
        address token,
        uint amount,
        address receiver
    ) external;

    function factory() external view returns(IMateriaFactory);
    function bridgeToken() external view returns(IERC20);
    function erc20Wrapper() external view returns(IERC20WrapperV1);
    function ETHEREUM_OBJECT_ID() external view returns(uint);
    function swapper() external view returns(IMateriaOperator);
    function liquidityAdder() external view returns(IMateriaOperator);
    function liquidityRemover() external view returns(IMateriaOperator);
    function doubleProxy() external view returns(IDoubleProxy);


    
    
    
    
    //Liquidity adding
    
    function addLiquidity(
        address token,
        uint tokenAmountDesired,
        uint bridgeAmountDesired,
        uint tokenAmountMin,
        uint bridgeAmountMin,
        address to,
        uint deadline
    ) external returns (uint amountA, uint amountB, uint liquidity);
    
    function addLiquidityETH(
        uint bridgeAmountDesired,
        uint EthAmountMin,
        uint bridgeAmountMin,
        address to,
        uint deadline
    ) external payable returns (uint amountToken, uint amountETH, uint liquidity);
    
    //Liquidity removing
    
     function removeLiquidity(
        address token,
        uint liquidity,
        uint tokenAmountMin,
        uint bridgeAmountMin,
        address to,
        uint deadline
    ) external;
    
    function removeLiquidityETH(
        uint liquidity,
        uint bridgeAmountMin,
        uint EthAmountMin,
        address to,
        uint deadline
    ) external;
    
    function removeLiquidityWithPermit(
        address token,
        uint liquidity,
        uint tokenAmountMin,
        uint bridgeAmountMin,
        address to,
        uint deadline,
        bool approveMax, uint8 v, bytes32 r, bytes32 s
    ) external;
    
    function removeLiquidityETHWithPermit(
        uint liquidity,
        uint ethAmountMin,
        uint bridgeAmountMin,
        address to,
        uint deadline,
        bool approveMax, uint8 v, bytes32 r, bytes32 s
    ) external;
    
    //Swapping
    
    function swapExactTokensForTokens(
        uint amountIn,
        uint amountOutMin,
        address[] memory path,
        address to,
        uint deadline
    ) external returns (uint[] memory amounts);
    
    function swapTokensForExactTokens(
        uint amountOut,
        uint amountInMax,
        address[] memory path,
        address to,
        uint deadline
    ) external returns (uint[] memory amounts);
    
    function swapExactETHForTokens(
        uint amountOutMin,
        address[] memory path,
        address to,
        uint deadline
    ) external payable;
   
    function swapTokensForExactETH(
        uint amountOut,
        uint amountInMax,
        address[] memory path,
        address to,
        uint deadline
    ) external;
    
    function swapExactTokensForETH(
        uint amountIn,
        uint amountOutMin,
        address[] memory path,
        address to,
        uint deadline
    ) external;
    
    function swapETHForExactTokens(
        uint amountOut,
        address[] memory path,
        address to,
        uint deadline
    ) external payable;
    
    //Materia utilities
    
    function isEthItem(
        address token
    ) external view returns(address collection, bool ethItem, uint256 itemId);
    
    function quote(
        uint amountA,
        uint reserveA,
        uint reserveB
    ) external pure returns (uint amountB);

    function getAmountOut(
        uint amountIn,
        uint reserveIn,
        uint reserveOut
    ) external pure returns (uint amountOut);

    function getAmountIn(
        uint amountOut, 
        uint reserveIn, 
        uint reserveOut
    ) external pure returns (uint amountIn);

    function getAmountsOut(
        uint amountIn,
        address[] memory path
    ) external view returns (uint[] memory amounts);

    function getAmountsIn(
        uint amountOut,
        address[] memory path
    ) external view returns (uint[] memory amounts);
}
// Dependency file: contracts/interfaces/IMateriaOrchestrator.sol
// pragma solidity 0.8.0;
// import 'contracts/interfaces/IERC1155Receiver.sol';
// import 'contracts/interfaces/IMateriaFactory.sol';
// import 'contracts/interfaces/IERC20.sol';
// import 'contracts/interfaces/IERC20WrapperV1.sol';
// import 'contracts/interfaces/IMateriaOperator.sol';
// import 'contracts/interfaces/IDoubleProxy.sol';
function swapExactTokensForTokens(
    uint amountIn,
    uint amountOutMin,
    address[] memory path,
    address to,
    uint deadline
) external returns (uint[] memory amounts);

//Swapping