From cb56f23f493839421e36927a3bd9c57b9a0c1237 Mon Sep 17 00:00:00 2001
From: bhavik-m <bhavikmehta2001@gmail.com>
Date: Tue, 4 Jan 2022 21:25:53 +0530
Subject: [PATCH 1/8] initial commit

---
 .../arbitrum/connectors/sushiswap/events.sol  |  41 ++++
 .../arbitrum/connectors/sushiswap/helpers.sol | 184 ++++++++++++++++
 .../connectors/sushiswap/interface.sol        |  57 +++++
 .../arbitrum/connectors/sushiswap/main.sol    | 196 ++++++++++++++++++
 .../polygon/connectors/sushiswap/events.sol   |  41 ++++
 .../polygon/connectors/sushiswap/helpers.sol  | 184 ++++++++++++++++
 .../connectors/sushiswap/interface.sol        |  57 +++++
 .../polygon/connectors/sushiswap/main.sol     | 196 ++++++++++++++++++
 8 files changed, 956 insertions(+)
 create mode 100644 contracts/arbitrum/connectors/sushiswap/events.sol
 create mode 100644 contracts/arbitrum/connectors/sushiswap/helpers.sol
 create mode 100644 contracts/arbitrum/connectors/sushiswap/interface.sol
 create mode 100644 contracts/arbitrum/connectors/sushiswap/main.sol
 create mode 100644 contracts/polygon/connectors/sushiswap/events.sol
 create mode 100644 contracts/polygon/connectors/sushiswap/helpers.sol
 create mode 100644 contracts/polygon/connectors/sushiswap/interface.sol
 create mode 100644 contracts/polygon/connectors/sushiswap/main.sol

diff --git a/contracts/arbitrum/connectors/sushiswap/events.sol b/contracts/arbitrum/connectors/sushiswap/events.sol
new file mode 100644
index 00000000..2717b0a3
--- /dev/null
+++ b/contracts/arbitrum/connectors/sushiswap/events.sol
@@ -0,0 +1,41 @@
+pragma solidity ^0.7.0;
+
+contract Events {
+    event LogDepositLiquidity(
+        address indexed tokenA,
+        address indexed tokenB,
+        uint256 amtA,
+        uint256 amtB,
+        uint256 uniAmount,
+        uint256 getId,
+        uint256 setId
+    );
+
+    event LogWithdrawLiquidity(
+        address indexed tokenA,
+        address indexed tokenB,
+        uint256 amountA,
+        uint256 amountB,
+        uint256 uniAmount,
+        uint256 getId,
+        uint256[] setId
+    );
+    
+    event LogBuy(
+        address indexed buyToken,
+        address indexed sellToken,
+        uint256 buyAmt,
+        uint256 sellAmt,
+        uint256 getId,
+        uint256 setId
+    );
+
+    event LogSell(
+        address indexed buyToken,
+        address indexed sellToken,
+        uint256 buyAmt,
+        uint256 sellAmt,
+        uint256 getId,
+        uint256 setId
+    );
+}
\ No newline at end of file
diff --git a/contracts/arbitrum/connectors/sushiswap/helpers.sol b/contracts/arbitrum/connectors/sushiswap/helpers.sol
new file mode 100644
index 00000000..ea29a03f
--- /dev/null
+++ b/contracts/arbitrum/connectors/sushiswap/helpers.sol
@@ -0,0 +1,184 @@
+pragma solidity ^0.7.0;
+
+import {TokenInterface} from "../../common/interfaces.sol";
+import {DSMath} from "../../common/math.sol";
+import {Basic} from "../../common/basic.sol";
+import {ISushiSwapRouter, ISushiSwapFactory} from "./interface.sol";
+
+abstract contract Helpers is DSMath, Basic {
+    /**
+     * @dev ISushiSwapRouter
+     */
+    ISushiSwapRouter internal constant router =
+        ISushiSwapRouter(0xd9e1cE17f2641f24aE83637ab66a2cca9C378B9F);
+
+    function getExpectedBuyAmt(address[] memory paths, uint256 sellAmt)
+        internal
+        view
+        returns (uint256 buyAmt)
+    {
+        uint256[] memory amts = router.getAmountsOut(sellAmt, paths);
+        buyAmt = amts[1];
+    }
+
+    function getExpectedSellAmt(address[] memory paths, uint256 buyAmt)
+        internal
+        view
+        returns (uint256 sellAmt)
+    {
+        uint256[] memory amts = router.getAmountsIn(buyAmt, paths);
+        sellAmt = amts[0];
+    }
+
+    function checkPair(address[] memory paths) internal view {
+        address pair = ISushiSwapFactory(router.factory()).getPair(
+            paths[0],
+            paths[1]
+        );
+        require(pair != address(0), "No-exchange-address");
+    }
+
+    function getPaths(address buyAddr, address sellAddr)
+        internal
+        pure
+        returns (address[] memory paths)
+    {
+        paths = new address[](2);
+        paths[0] = address(sellAddr);
+        paths[1] = address(buyAddr);
+    }
+
+    function getMinAmount(
+        TokenInterface token,
+        uint256 amt,
+        uint256 slippage
+    ) internal view returns (uint256 minAmt) {
+        uint256 _amt18 = convertTo18(token.decimals(), amt);
+        minAmt = wmul(_amt18, sub(WAD, slippage));
+        minAmt = convert18ToDec(token.decimals(), minAmt);
+    }
+
+    function _addLiquidity(
+        address tokenA,
+        address tokenB,
+        uint256 _amt,
+        uint256 unitAmt,
+        uint256 slippage
+    )
+        internal
+        returns (
+            uint256 _amtA,
+            uint256 _amtB,
+            uint256 _liquidity
+        )
+    {
+        (TokenInterface _tokenA, TokenInterface _tokenB) = changeEthAddress(
+            tokenA,
+            tokenB
+        );
+
+        _amtA = _amt == uint256(-1)
+            ? getTokenBal(TokenInterface(tokenA))
+            : _amt;
+        _amtB = convert18ToDec(
+            _tokenB.decimals(),
+            wmul(unitAmt, convertTo18(_tokenA.decimals(), _amtA))
+        );
+
+        bool isEth = address(_tokenA) == wethAddr;
+        convertEthToWeth(isEth, _tokenA, _amtA);
+
+        isEth = address(_tokenB) == wethAddr;
+        convertEthToWeth(isEth, _tokenB, _amtB);
+
+        approve(_tokenA, address(router), _amtA);
+        approve(_tokenB, address(router), _amtB);
+
+        uint256 minAmtA = getMinAmount(_tokenA, _amtA, slippage);
+        uint256 minAmtB = getMinAmount(_tokenB, _amtB, slippage);
+        (_amtA, _amtB, _liquidity) = router.addLiquidity(
+            address(_tokenA),
+            address(_tokenB),
+            _amtA,
+            _amtB,
+            minAmtA,
+            minAmtB,
+            address(this),
+            block.timestamp + 1
+        );
+    }
+
+    function _removeLiquidity(
+        address tokenA,
+        address tokenB,
+        uint256 _amt,
+        uint256 unitAmtA,
+        uint256 unitAmtB
+    )
+        internal
+        returns (
+            uint256 _amtA,
+            uint256 _amtB,
+            uint256 _uniAmt
+        )
+    {
+        TokenInterface _tokenA;
+        TokenInterface _tokenB;
+        (_tokenA, _tokenB, _uniAmt) = _getRemoveLiquidityData(
+            tokenA,
+            tokenB,
+            _amt
+        );
+        {
+            uint256 minAmtA = convert18ToDec(
+                _tokenA.decimals(),
+                wmul(unitAmtA, _uniAmt)
+            );
+            uint256 minAmtB = convert18ToDec(
+                _tokenB.decimals(),
+                wmul(unitAmtB, _uniAmt)
+            );
+            (_amtA, _amtB) = router.removeLiquidity(
+                address(_tokenA),
+                address(_tokenB),
+                _uniAmt,
+                minAmtA,
+                minAmtB,
+                address(this),
+                block.timestamp + 1
+            );
+        }
+
+        bool isEth = address(_tokenA) == wethAddr;
+        convertWethToEth(isEth, _tokenA, _amtA);
+
+        isEth = address(_tokenB) == wethAddr;
+        convertWethToEth(isEth, _tokenB, _amtB);
+    }
+
+    function _getRemoveLiquidityData(
+        address tokenA,
+        address tokenB,
+        uint256 _amt
+    )
+        internal
+        returns (
+            TokenInterface _tokenA,
+            TokenInterface _tokenB,
+            uint256 _uniAmt
+        )
+    {
+        (_tokenA, _tokenB) = changeEthAddress(tokenA, tokenB);
+        address exchangeAddr = ISushiSwapFactory(router.factory()).getPair(
+            address(_tokenA),
+            address(_tokenB)
+        );
+        require(exchangeAddr != address(0), "pair-not-found.");
+
+        TokenInterface uniToken = TokenInterface(exchangeAddr);
+        _uniAmt = _amt == uint256(-1)
+            ? uniToken.balanceOf(address(this))
+            : _amt;
+        approve(uniToken, address(router), _uniAmt);
+    }
+}
diff --git a/contracts/arbitrum/connectors/sushiswap/interface.sol b/contracts/arbitrum/connectors/sushiswap/interface.sol
new file mode 100644
index 00000000..bd3be483
--- /dev/null
+++ b/contracts/arbitrum/connectors/sushiswap/interface.sol
@@ -0,0 +1,57 @@
+pragma solidity ^0.7.0;
+
+interface ISushiSwapRouter {
+    function factory() external pure returns (address);
+    function WETH() external pure returns (address);
+
+    function addLiquidity(
+        address tokenA,
+        address tokenB,
+        uint amountADesired,
+        uint amountBDesired,
+        uint amountAMin,
+        uint amountBMin,
+        address to,
+        uint deadline
+    ) external returns (uint amountA, uint amountB, uint liquidity);
+    function removeLiquidity(
+        address tokenA,
+        address tokenB,
+        uint liquidity,
+        uint amountAMin,
+        uint amountBMin,
+        address to,
+        uint deadline
+    ) external returns (uint amountA, uint amountB);
+    function swapExactTokensForTokens(
+        uint amountIn,
+        uint amountOutMin,
+        address[] calldata path,
+        address to,
+        uint deadline
+    ) external returns (uint[] memory amounts);
+    function swapTokensForExactTokens(
+        uint amountOut,
+        uint amountInMax,
+        address[] calldata path,
+        address to,
+        uint deadline
+    ) external returns (uint[] memory amounts);
+
+    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[] calldata path) external view returns (uint[] memory amounts);
+    function getAmountsIn(uint amountOut, address[] calldata path) external view returns (uint[] memory amounts);
+}
+
+interface ISushiSwapFactory {
+    function getPair(address tokenA, address tokenB) external view returns (address pair);
+    function allPairs(uint) external view returns (address pair);
+    function allPairsLength() external view returns (uint);
+
+    function feeTo() external view returns (address);
+    function feeToSetter() external view returns (address);
+
+    function createPair(address tokenA, address tokenB) external returns (address pair);
+}
diff --git a/contracts/arbitrum/connectors/sushiswap/main.sol b/contracts/arbitrum/connectors/sushiswap/main.sol
new file mode 100644
index 00000000..bd0078bc
--- /dev/null
+++ b/contracts/arbitrum/connectors/sushiswap/main.sol
@@ -0,0 +1,196 @@
+pragma solidity ^0.7.0;
+
+/**
+ * @title SushiSwap.
+ * @dev Decentralized Exchange.
+ */
+
+import { TokenInterface } from "../../common/interfaces.sol";
+import { Helpers } from "./helpers.sol";
+import { Events } from "./events.sol";
+
+abstract contract SushipswapResolver is Helpers, Events {
+    /**
+     * @dev Deposit Liquidity.
+     * @notice Deposit Liquidity to a SushiSwap pool.
+     * @param tokenA The address of token A.(For ETH: 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE)
+     * @param tokenB The address of token B.(For ETH: 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE)
+     * @param amtA The amount of A tokens to deposit.
+     * @param unitAmt The unit amount of of amtB/amtA with slippage.
+     * @param slippage Slippage amount.
+     * @param getId ID to retrieve amtA.
+     * @param setId ID stores the amount of pools tokens received.
+    */
+    function deposit(
+        address tokenA,
+        address tokenB,
+        uint256 amtA,
+        uint256 unitAmt,
+        uint256 slippage,
+        uint256 getId,
+        uint256 setId
+    ) external payable returns (string memory _eventName, bytes memory _eventParam) {
+        uint _amt = getUint(getId, amtA);
+
+        (uint _amtA, uint _amtB, uint _uniAmt) = _addLiquidity(
+                                            tokenA,
+                                            tokenB,
+                                            _amt,
+                                            unitAmt,
+                                            slippage
+                                        );
+        setUint(setId, _uniAmt);
+        
+        _eventName = "LogDepositLiquidity(address,address,uint256,uint256,uint256,uint256,uint256)";
+        _eventParam = abi.encode(tokenA, tokenB, _amtA, _amtB, _uniAmt, getId, setId);
+    }
+
+    /**
+     * @dev Withdraw Liquidity.
+     * @notice Withdraw Liquidity from a SushiSwap pool.
+     * @param tokenA The address of token A.(For ETH: 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE)
+     * @param tokenB The address of token B.(For ETH: 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE)
+     * @param uniAmt The amount of pool tokens to withdraw.
+     * @param unitAmtA The unit amount of amtA/uniAmt with slippage.
+     * @param unitAmtB The unit amount of amtB/uniAmt with slippage.
+     * @param getId ID to retrieve uniAmt.
+     * @param setIds Array of IDs to store the amount tokens received.
+    */
+    function withdraw(
+        address tokenA,
+        address tokenB,
+        uint256 uniAmt,
+        uint256 unitAmtA,
+        uint256 unitAmtB,
+        uint256 getId,
+        uint256[] calldata setIds
+    ) external payable returns (string memory _eventName, bytes memory _eventParam) {
+        uint _amt = getUint(getId, uniAmt);
+
+        (uint _amtA, uint _amtB, uint _uniAmt) = _removeLiquidity(
+            tokenA,
+            tokenB,
+            _amt,
+            unitAmtA,
+            unitAmtB
+        );
+
+        setUint(setIds[0], _amtA);
+        setUint(setIds[1], _amtB);
+        
+        _eventName = "LogWithdrawLiquidity(address,address,uint256,uint256,uint256,uint256,uint256[])";
+        _eventParam = abi.encode(tokenA, tokenB, _amtA, _amtB, _uniAmt, getId, setIds);
+    }
+
+    /**
+     * @dev Buy ETH/ERC20_Token.
+     * @notice Buy a token using a SushiSwap
+     * @param buyAddr The address of the token to buy.(For ETH: 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE)
+     * @param sellAddr The address of the token to sell.(For ETH: 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE)
+     * @param buyAmt The amount of tokens to buy.
+     * @param unitAmt The unit amount of sellAmt/buyAmt with slippage.
+     * @param getId ID to retrieve buyAmt.
+     * @param setId ID to store the amount of tokens sold.
+    */
+    function buy(
+        address buyAddr,
+        address sellAddr,
+        uint256 buyAmt,
+        uint256 unitAmt,
+        uint256 getId,
+        uint256 setId
+    ) external payable returns (string memory _eventName, bytes memory _eventParam) {
+        uint _buyAmt = getUint(getId, buyAmt);
+        (TokenInterface _buyAddr, TokenInterface _sellAddr) = changeEthAddress(buyAddr, sellAddr);
+        address[] memory paths = getPaths(address(_buyAddr), address(_sellAddr));
+
+        uint _slippageAmt = convert18ToDec(_sellAddr.decimals(),
+            wmul(unitAmt, convertTo18(_buyAddr.decimals(), _buyAmt))
+        );
+
+        checkPair(paths);
+        uint _expectedAmt = getExpectedSellAmt(paths, _buyAmt);
+        require(_slippageAmt >= _expectedAmt, "Too much slippage");
+
+        bool isEth = address(_sellAddr) == wethAddr;
+        convertEthToWeth(isEth, _sellAddr, _expectedAmt);
+        approve(_sellAddr, address(router), _expectedAmt);
+
+        uint _sellAmt = router.swapTokensForExactTokens(
+            _buyAmt,
+            _expectedAmt,
+            paths,
+            address(this),
+            block.timestamp + 1
+        )[0];
+
+        isEth = address(_buyAddr) == wethAddr;
+        convertWethToEth(isEth, _buyAddr, _buyAmt);
+
+        setUint(setId, _sellAmt);
+
+        _eventName = "LogBuy(address,address,uint256,uint256,uint256,uint256)";
+        _eventParam = abi.encode(buyAddr, sellAddr, _buyAmt, _sellAmt, getId, setId);
+    }
+
+    /**
+     * @dev Sell ETH/ERC20_Token.
+     * @notice Sell a token using a SushiSwap
+     * @param buyAddr The address of the token to buy.(For ETH: 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE)
+     * @param sellAddr The address of the token to sell.(For ETH: 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE)
+     * @param sellAmt The amount of the token to sell.
+     * @param unitAmt The unit amount of buyAmt/sellAmt with slippage.
+     * @param getId ID to retrieve sellAmt.
+     * @param setId ID stores the amount of token brought.
+    */
+    function sell(
+        address buyAddr,
+        address sellAddr,
+        uint256 sellAmt,
+        uint256 unitAmt,
+        uint256 getId,
+        uint256 setId
+    ) external payable returns (string memory _eventName, bytes memory _eventParam) {
+        uint _sellAmt = getUint(getId, sellAmt);
+        (TokenInterface _buyAddr, TokenInterface _sellAddr) = changeEthAddress(buyAddr, sellAddr);
+        address[] memory paths = getPaths(address(_buyAddr), address(_sellAddr));
+
+        if (_sellAmt == uint(-1)) {
+            _sellAmt = sellAddr == ethAddr ?
+                address(this).balance :
+                _sellAddr.balanceOf(address(this));
+        }
+
+        uint _slippageAmt = convert18ToDec(_buyAddr.decimals(),
+            wmul(unitAmt, convertTo18(_sellAddr.decimals(), _sellAmt))
+        );
+
+        checkPair(paths);
+        uint _expectedAmt = getExpectedBuyAmt(paths, _sellAmt);
+        require(_slippageAmt <= _expectedAmt, "Too much slippage");
+
+        bool isEth = address(_sellAddr) == wethAddr;
+        convertEthToWeth(isEth, _sellAddr, _sellAmt);
+        approve(_sellAddr, address(router), _sellAmt);
+
+        uint _buyAmt = router.swapExactTokensForTokens(
+            _sellAmt,
+            _expectedAmt,
+            paths,
+            address(this),
+            block.timestamp + 1
+        )[1];
+
+        isEth = address(_buyAddr) == wethAddr;
+        convertWethToEth(isEth, _buyAddr, _buyAmt);
+
+        setUint(setId, _buyAmt);
+
+        _eventName = "LogSell(address,address,uint256,uint256,uint256,uint256)";
+        _eventParam = abi.encode(buyAddr, sellAddr, _buyAmt, _sellAmt, getId, setId);
+    }
+}
+
+contract ConnectV2Sushiswap is SushipswapResolver {
+    string public constant name = "Sushipswap-v1.1";
+}
diff --git a/contracts/polygon/connectors/sushiswap/events.sol b/contracts/polygon/connectors/sushiswap/events.sol
new file mode 100644
index 00000000..2717b0a3
--- /dev/null
+++ b/contracts/polygon/connectors/sushiswap/events.sol
@@ -0,0 +1,41 @@
+pragma solidity ^0.7.0;
+
+contract Events {
+    event LogDepositLiquidity(
+        address indexed tokenA,
+        address indexed tokenB,
+        uint256 amtA,
+        uint256 amtB,
+        uint256 uniAmount,
+        uint256 getId,
+        uint256 setId
+    );
+
+    event LogWithdrawLiquidity(
+        address indexed tokenA,
+        address indexed tokenB,
+        uint256 amountA,
+        uint256 amountB,
+        uint256 uniAmount,
+        uint256 getId,
+        uint256[] setId
+    );
+    
+    event LogBuy(
+        address indexed buyToken,
+        address indexed sellToken,
+        uint256 buyAmt,
+        uint256 sellAmt,
+        uint256 getId,
+        uint256 setId
+    );
+
+    event LogSell(
+        address indexed buyToken,
+        address indexed sellToken,
+        uint256 buyAmt,
+        uint256 sellAmt,
+        uint256 getId,
+        uint256 setId
+    );
+}
\ No newline at end of file
diff --git a/contracts/polygon/connectors/sushiswap/helpers.sol b/contracts/polygon/connectors/sushiswap/helpers.sol
new file mode 100644
index 00000000..ea29a03f
--- /dev/null
+++ b/contracts/polygon/connectors/sushiswap/helpers.sol
@@ -0,0 +1,184 @@
+pragma solidity ^0.7.0;
+
+import {TokenInterface} from "../../common/interfaces.sol";
+import {DSMath} from "../../common/math.sol";
+import {Basic} from "../../common/basic.sol";
+import {ISushiSwapRouter, ISushiSwapFactory} from "./interface.sol";
+
+abstract contract Helpers is DSMath, Basic {
+    /**
+     * @dev ISushiSwapRouter
+     */
+    ISushiSwapRouter internal constant router =
+        ISushiSwapRouter(0xd9e1cE17f2641f24aE83637ab66a2cca9C378B9F);
+
+    function getExpectedBuyAmt(address[] memory paths, uint256 sellAmt)
+        internal
+        view
+        returns (uint256 buyAmt)
+    {
+        uint256[] memory amts = router.getAmountsOut(sellAmt, paths);
+        buyAmt = amts[1];
+    }
+
+    function getExpectedSellAmt(address[] memory paths, uint256 buyAmt)
+        internal
+        view
+        returns (uint256 sellAmt)
+    {
+        uint256[] memory amts = router.getAmountsIn(buyAmt, paths);
+        sellAmt = amts[0];
+    }
+
+    function checkPair(address[] memory paths) internal view {
+        address pair = ISushiSwapFactory(router.factory()).getPair(
+            paths[0],
+            paths[1]
+        );
+        require(pair != address(0), "No-exchange-address");
+    }
+
+    function getPaths(address buyAddr, address sellAddr)
+        internal
+        pure
+        returns (address[] memory paths)
+    {
+        paths = new address[](2);
+        paths[0] = address(sellAddr);
+        paths[1] = address(buyAddr);
+    }
+
+    function getMinAmount(
+        TokenInterface token,
+        uint256 amt,
+        uint256 slippage
+    ) internal view returns (uint256 minAmt) {
+        uint256 _amt18 = convertTo18(token.decimals(), amt);
+        minAmt = wmul(_amt18, sub(WAD, slippage));
+        minAmt = convert18ToDec(token.decimals(), minAmt);
+    }
+
+    function _addLiquidity(
+        address tokenA,
+        address tokenB,
+        uint256 _amt,
+        uint256 unitAmt,
+        uint256 slippage
+    )
+        internal
+        returns (
+            uint256 _amtA,
+            uint256 _amtB,
+            uint256 _liquidity
+        )
+    {
+        (TokenInterface _tokenA, TokenInterface _tokenB) = changeEthAddress(
+            tokenA,
+            tokenB
+        );
+
+        _amtA = _amt == uint256(-1)
+            ? getTokenBal(TokenInterface(tokenA))
+            : _amt;
+        _amtB = convert18ToDec(
+            _tokenB.decimals(),
+            wmul(unitAmt, convertTo18(_tokenA.decimals(), _amtA))
+        );
+
+        bool isEth = address(_tokenA) == wethAddr;
+        convertEthToWeth(isEth, _tokenA, _amtA);
+
+        isEth = address(_tokenB) == wethAddr;
+        convertEthToWeth(isEth, _tokenB, _amtB);
+
+        approve(_tokenA, address(router), _amtA);
+        approve(_tokenB, address(router), _amtB);
+
+        uint256 minAmtA = getMinAmount(_tokenA, _amtA, slippage);
+        uint256 minAmtB = getMinAmount(_tokenB, _amtB, slippage);
+        (_amtA, _amtB, _liquidity) = router.addLiquidity(
+            address(_tokenA),
+            address(_tokenB),
+            _amtA,
+            _amtB,
+            minAmtA,
+            minAmtB,
+            address(this),
+            block.timestamp + 1
+        );
+    }
+
+    function _removeLiquidity(
+        address tokenA,
+        address tokenB,
+        uint256 _amt,
+        uint256 unitAmtA,
+        uint256 unitAmtB
+    )
+        internal
+        returns (
+            uint256 _amtA,
+            uint256 _amtB,
+            uint256 _uniAmt
+        )
+    {
+        TokenInterface _tokenA;
+        TokenInterface _tokenB;
+        (_tokenA, _tokenB, _uniAmt) = _getRemoveLiquidityData(
+            tokenA,
+            tokenB,
+            _amt
+        );
+        {
+            uint256 minAmtA = convert18ToDec(
+                _tokenA.decimals(),
+                wmul(unitAmtA, _uniAmt)
+            );
+            uint256 minAmtB = convert18ToDec(
+                _tokenB.decimals(),
+                wmul(unitAmtB, _uniAmt)
+            );
+            (_amtA, _amtB) = router.removeLiquidity(
+                address(_tokenA),
+                address(_tokenB),
+                _uniAmt,
+                minAmtA,
+                minAmtB,
+                address(this),
+                block.timestamp + 1
+            );
+        }
+
+        bool isEth = address(_tokenA) == wethAddr;
+        convertWethToEth(isEth, _tokenA, _amtA);
+
+        isEth = address(_tokenB) == wethAddr;
+        convertWethToEth(isEth, _tokenB, _amtB);
+    }
+
+    function _getRemoveLiquidityData(
+        address tokenA,
+        address tokenB,
+        uint256 _amt
+    )
+        internal
+        returns (
+            TokenInterface _tokenA,
+            TokenInterface _tokenB,
+            uint256 _uniAmt
+        )
+    {
+        (_tokenA, _tokenB) = changeEthAddress(tokenA, tokenB);
+        address exchangeAddr = ISushiSwapFactory(router.factory()).getPair(
+            address(_tokenA),
+            address(_tokenB)
+        );
+        require(exchangeAddr != address(0), "pair-not-found.");
+
+        TokenInterface uniToken = TokenInterface(exchangeAddr);
+        _uniAmt = _amt == uint256(-1)
+            ? uniToken.balanceOf(address(this))
+            : _amt;
+        approve(uniToken, address(router), _uniAmt);
+    }
+}
diff --git a/contracts/polygon/connectors/sushiswap/interface.sol b/contracts/polygon/connectors/sushiswap/interface.sol
new file mode 100644
index 00000000..bd3be483
--- /dev/null
+++ b/contracts/polygon/connectors/sushiswap/interface.sol
@@ -0,0 +1,57 @@
+pragma solidity ^0.7.0;
+
+interface ISushiSwapRouter {
+    function factory() external pure returns (address);
+    function WETH() external pure returns (address);
+
+    function addLiquidity(
+        address tokenA,
+        address tokenB,
+        uint amountADesired,
+        uint amountBDesired,
+        uint amountAMin,
+        uint amountBMin,
+        address to,
+        uint deadline
+    ) external returns (uint amountA, uint amountB, uint liquidity);
+    function removeLiquidity(
+        address tokenA,
+        address tokenB,
+        uint liquidity,
+        uint amountAMin,
+        uint amountBMin,
+        address to,
+        uint deadline
+    ) external returns (uint amountA, uint amountB);
+    function swapExactTokensForTokens(
+        uint amountIn,
+        uint amountOutMin,
+        address[] calldata path,
+        address to,
+        uint deadline
+    ) external returns (uint[] memory amounts);
+    function swapTokensForExactTokens(
+        uint amountOut,
+        uint amountInMax,
+        address[] calldata path,
+        address to,
+        uint deadline
+    ) external returns (uint[] memory amounts);
+
+    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[] calldata path) external view returns (uint[] memory amounts);
+    function getAmountsIn(uint amountOut, address[] calldata path) external view returns (uint[] memory amounts);
+}
+
+interface ISushiSwapFactory {
+    function getPair(address tokenA, address tokenB) external view returns (address pair);
+    function allPairs(uint) external view returns (address pair);
+    function allPairsLength() external view returns (uint);
+
+    function feeTo() external view returns (address);
+    function feeToSetter() external view returns (address);
+
+    function createPair(address tokenA, address tokenB) external returns (address pair);
+}
diff --git a/contracts/polygon/connectors/sushiswap/main.sol b/contracts/polygon/connectors/sushiswap/main.sol
new file mode 100644
index 00000000..bd0078bc
--- /dev/null
+++ b/contracts/polygon/connectors/sushiswap/main.sol
@@ -0,0 +1,196 @@
+pragma solidity ^0.7.0;
+
+/**
+ * @title SushiSwap.
+ * @dev Decentralized Exchange.
+ */
+
+import { TokenInterface } from "../../common/interfaces.sol";
+import { Helpers } from "./helpers.sol";
+import { Events } from "./events.sol";
+
+abstract contract SushipswapResolver is Helpers, Events {
+    /**
+     * @dev Deposit Liquidity.
+     * @notice Deposit Liquidity to a SushiSwap pool.
+     * @param tokenA The address of token A.(For ETH: 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE)
+     * @param tokenB The address of token B.(For ETH: 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE)
+     * @param amtA The amount of A tokens to deposit.
+     * @param unitAmt The unit amount of of amtB/amtA with slippage.
+     * @param slippage Slippage amount.
+     * @param getId ID to retrieve amtA.
+     * @param setId ID stores the amount of pools tokens received.
+    */
+    function deposit(
+        address tokenA,
+        address tokenB,
+        uint256 amtA,
+        uint256 unitAmt,
+        uint256 slippage,
+        uint256 getId,
+        uint256 setId
+    ) external payable returns (string memory _eventName, bytes memory _eventParam) {
+        uint _amt = getUint(getId, amtA);
+
+        (uint _amtA, uint _amtB, uint _uniAmt) = _addLiquidity(
+                                            tokenA,
+                                            tokenB,
+                                            _amt,
+                                            unitAmt,
+                                            slippage
+                                        );
+        setUint(setId, _uniAmt);
+        
+        _eventName = "LogDepositLiquidity(address,address,uint256,uint256,uint256,uint256,uint256)";
+        _eventParam = abi.encode(tokenA, tokenB, _amtA, _amtB, _uniAmt, getId, setId);
+    }
+
+    /**
+     * @dev Withdraw Liquidity.
+     * @notice Withdraw Liquidity from a SushiSwap pool.
+     * @param tokenA The address of token A.(For ETH: 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE)
+     * @param tokenB The address of token B.(For ETH: 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE)
+     * @param uniAmt The amount of pool tokens to withdraw.
+     * @param unitAmtA The unit amount of amtA/uniAmt with slippage.
+     * @param unitAmtB The unit amount of amtB/uniAmt with slippage.
+     * @param getId ID to retrieve uniAmt.
+     * @param setIds Array of IDs to store the amount tokens received.
+    */
+    function withdraw(
+        address tokenA,
+        address tokenB,
+        uint256 uniAmt,
+        uint256 unitAmtA,
+        uint256 unitAmtB,
+        uint256 getId,
+        uint256[] calldata setIds
+    ) external payable returns (string memory _eventName, bytes memory _eventParam) {
+        uint _amt = getUint(getId, uniAmt);
+
+        (uint _amtA, uint _amtB, uint _uniAmt) = _removeLiquidity(
+            tokenA,
+            tokenB,
+            _amt,
+            unitAmtA,
+            unitAmtB
+        );
+
+        setUint(setIds[0], _amtA);
+        setUint(setIds[1], _amtB);
+        
+        _eventName = "LogWithdrawLiquidity(address,address,uint256,uint256,uint256,uint256,uint256[])";
+        _eventParam = abi.encode(tokenA, tokenB, _amtA, _amtB, _uniAmt, getId, setIds);
+    }
+
+    /**
+     * @dev Buy ETH/ERC20_Token.
+     * @notice Buy a token using a SushiSwap
+     * @param buyAddr The address of the token to buy.(For ETH: 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE)
+     * @param sellAddr The address of the token to sell.(For ETH: 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE)
+     * @param buyAmt The amount of tokens to buy.
+     * @param unitAmt The unit amount of sellAmt/buyAmt with slippage.
+     * @param getId ID to retrieve buyAmt.
+     * @param setId ID to store the amount of tokens sold.
+    */
+    function buy(
+        address buyAddr,
+        address sellAddr,
+        uint256 buyAmt,
+        uint256 unitAmt,
+        uint256 getId,
+        uint256 setId
+    ) external payable returns (string memory _eventName, bytes memory _eventParam) {
+        uint _buyAmt = getUint(getId, buyAmt);
+        (TokenInterface _buyAddr, TokenInterface _sellAddr) = changeEthAddress(buyAddr, sellAddr);
+        address[] memory paths = getPaths(address(_buyAddr), address(_sellAddr));
+
+        uint _slippageAmt = convert18ToDec(_sellAddr.decimals(),
+            wmul(unitAmt, convertTo18(_buyAddr.decimals(), _buyAmt))
+        );
+
+        checkPair(paths);
+        uint _expectedAmt = getExpectedSellAmt(paths, _buyAmt);
+        require(_slippageAmt >= _expectedAmt, "Too much slippage");
+
+        bool isEth = address(_sellAddr) == wethAddr;
+        convertEthToWeth(isEth, _sellAddr, _expectedAmt);
+        approve(_sellAddr, address(router), _expectedAmt);
+
+        uint _sellAmt = router.swapTokensForExactTokens(
+            _buyAmt,
+            _expectedAmt,
+            paths,
+            address(this),
+            block.timestamp + 1
+        )[0];
+
+        isEth = address(_buyAddr) == wethAddr;
+        convertWethToEth(isEth, _buyAddr, _buyAmt);
+
+        setUint(setId, _sellAmt);
+
+        _eventName = "LogBuy(address,address,uint256,uint256,uint256,uint256)";
+        _eventParam = abi.encode(buyAddr, sellAddr, _buyAmt, _sellAmt, getId, setId);
+    }
+
+    /**
+     * @dev Sell ETH/ERC20_Token.
+     * @notice Sell a token using a SushiSwap
+     * @param buyAddr The address of the token to buy.(For ETH: 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE)
+     * @param sellAddr The address of the token to sell.(For ETH: 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE)
+     * @param sellAmt The amount of the token to sell.
+     * @param unitAmt The unit amount of buyAmt/sellAmt with slippage.
+     * @param getId ID to retrieve sellAmt.
+     * @param setId ID stores the amount of token brought.
+    */
+    function sell(
+        address buyAddr,
+        address sellAddr,
+        uint256 sellAmt,
+        uint256 unitAmt,
+        uint256 getId,
+        uint256 setId
+    ) external payable returns (string memory _eventName, bytes memory _eventParam) {
+        uint _sellAmt = getUint(getId, sellAmt);
+        (TokenInterface _buyAddr, TokenInterface _sellAddr) = changeEthAddress(buyAddr, sellAddr);
+        address[] memory paths = getPaths(address(_buyAddr), address(_sellAddr));
+
+        if (_sellAmt == uint(-1)) {
+            _sellAmt = sellAddr == ethAddr ?
+                address(this).balance :
+                _sellAddr.balanceOf(address(this));
+        }
+
+        uint _slippageAmt = convert18ToDec(_buyAddr.decimals(),
+            wmul(unitAmt, convertTo18(_sellAddr.decimals(), _sellAmt))
+        );
+
+        checkPair(paths);
+        uint _expectedAmt = getExpectedBuyAmt(paths, _sellAmt);
+        require(_slippageAmt <= _expectedAmt, "Too much slippage");
+
+        bool isEth = address(_sellAddr) == wethAddr;
+        convertEthToWeth(isEth, _sellAddr, _sellAmt);
+        approve(_sellAddr, address(router), _sellAmt);
+
+        uint _buyAmt = router.swapExactTokensForTokens(
+            _sellAmt,
+            _expectedAmt,
+            paths,
+            address(this),
+            block.timestamp + 1
+        )[1];
+
+        isEth = address(_buyAddr) == wethAddr;
+        convertWethToEth(isEth, _buyAddr, _buyAmt);
+
+        setUint(setId, _buyAmt);
+
+        _eventName = "LogSell(address,address,uint256,uint256,uint256,uint256)";
+        _eventParam = abi.encode(buyAddr, sellAddr, _buyAmt, _sellAmt, getId, setId);
+    }
+}
+
+contract ConnectV2Sushiswap is SushipswapResolver {
+    string public constant name = "Sushipswap-v1.1";
+}

From d1e4b028d65bf1c69c1d6904f85427ee001a2beb Mon Sep 17 00:00:00 2001
From: bhavik-m <bhavikmehta2001@gmail.com>
Date: Wed, 5 Jan 2022 13:12:35 +0530
Subject: [PATCH 2/8] added connector on polygon and arbitrum

---
 .../arbitrum/connectors/sushiswap/helpers.sol |  2 +-
 .../arbitrum/connectors/sushiswap/main.sol    |  4 +-
 .../polygon/connectors/sushiswap/helpers.sol  | 22 ++++-----
 .../polygon/connectors/sushiswap/main.sol     | 46 +++++++++----------
 4 files changed, 37 insertions(+), 37 deletions(-)

diff --git a/contracts/arbitrum/connectors/sushiswap/helpers.sol b/contracts/arbitrum/connectors/sushiswap/helpers.sol
index ea29a03f..ae67bdd7 100644
--- a/contracts/arbitrum/connectors/sushiswap/helpers.sol
+++ b/contracts/arbitrum/connectors/sushiswap/helpers.sol
@@ -10,7 +10,7 @@ abstract contract Helpers is DSMath, Basic {
      * @dev ISushiSwapRouter
      */
     ISushiSwapRouter internal constant router =
-        ISushiSwapRouter(0xd9e1cE17f2641f24aE83637ab66a2cca9C378B9F);
+        ISushiSwapRouter(0x1b02dA8Cb0d097eB8D57A175b88c7D8b47997506);
 
     function getExpectedBuyAmt(address[] memory paths, uint256 sellAmt)
         internal
diff --git a/contracts/arbitrum/connectors/sushiswap/main.sol b/contracts/arbitrum/connectors/sushiswap/main.sol
index bd0078bc..b7716406 100644
--- a/contracts/arbitrum/connectors/sushiswap/main.sol
+++ b/contracts/arbitrum/connectors/sushiswap/main.sol
@@ -191,6 +191,6 @@ abstract contract SushipswapResolver is Helpers, Events {
     }
 }
 
-contract ConnectV2Sushiswap is SushipswapResolver {
-    string public constant name = "Sushipswap-v1.1";
+contract ConnectV2SushiswapArbitrum is SushipswapResolver {
+    string public constant name = "Sushiswap-v1.1";
 }
diff --git a/contracts/polygon/connectors/sushiswap/helpers.sol b/contracts/polygon/connectors/sushiswap/helpers.sol
index ea29a03f..9f43f2b6 100644
--- a/contracts/polygon/connectors/sushiswap/helpers.sol
+++ b/contracts/polygon/connectors/sushiswap/helpers.sol
@@ -10,7 +10,7 @@ abstract contract Helpers is DSMath, Basic {
      * @dev ISushiSwapRouter
      */
     ISushiSwapRouter internal constant router =
-        ISushiSwapRouter(0xd9e1cE17f2641f24aE83637ab66a2cca9C378B9F);
+        ISushiSwapRouter(0x1b02dA8Cb0d097eB8D57A175b88c7D8b47997506);
 
     function getExpectedBuyAmt(address[] memory paths, uint256 sellAmt)
         internal
@@ -72,7 +72,7 @@ abstract contract Helpers is DSMath, Basic {
             uint256 _liquidity
         )
     {
-        (TokenInterface _tokenA, TokenInterface _tokenB) = changeEthAddress(
+        (TokenInterface _tokenA, TokenInterface _tokenB) = changeMaticAddress(
             tokenA,
             tokenB
         );
@@ -85,11 +85,11 @@ abstract contract Helpers is DSMath, Basic {
             wmul(unitAmt, convertTo18(_tokenA.decimals(), _amtA))
         );
 
-        bool isEth = address(_tokenA) == wethAddr;
-        convertEthToWeth(isEth, _tokenA, _amtA);
+        bool isMatic = address(_tokenA) == wmaticAddr;
+        convertMaticToWmatic(isMatic, _tokenA, _amtA);
 
-        isEth = address(_tokenB) == wethAddr;
-        convertEthToWeth(isEth, _tokenB, _amtB);
+        isMatic = address(_tokenB) == wmaticAddr;
+        convertMaticToWmatic(isMatic, _tokenB, _amtB);
 
         approve(_tokenA, address(router), _amtA);
         approve(_tokenB, address(router), _amtB);
@@ -149,11 +149,11 @@ abstract contract Helpers is DSMath, Basic {
             );
         }
 
-        bool isEth = address(_tokenA) == wethAddr;
-        convertWethToEth(isEth, _tokenA, _amtA);
+        bool isMatic = address(_tokenA) == wmaticAddr;
+        convertWmaticToMatic(isMatic, _tokenA, _amtA);
 
-        isEth = address(_tokenB) == wethAddr;
-        convertWethToEth(isEth, _tokenB, _amtB);
+        isMatic = address(_tokenB) == wmaticAddr;
+        convertWmaticToMatic(isMatic, _tokenB, _amtB);
     }
 
     function _getRemoveLiquidityData(
@@ -168,7 +168,7 @@ abstract contract Helpers is DSMath, Basic {
             uint256 _uniAmt
         )
     {
-        (_tokenA, _tokenB) = changeEthAddress(tokenA, tokenB);
+        (_tokenA, _tokenB) = changeMaticAddress(tokenA, tokenB);
         address exchangeAddr = ISushiSwapFactory(router.factory()).getPair(
             address(_tokenA),
             address(_tokenB)
diff --git a/contracts/polygon/connectors/sushiswap/main.sol b/contracts/polygon/connectors/sushiswap/main.sol
index bd0078bc..a4647769 100644
--- a/contracts/polygon/connectors/sushiswap/main.sol
+++ b/contracts/polygon/connectors/sushiswap/main.sol
@@ -13,8 +13,8 @@ abstract contract SushipswapResolver is Helpers, Events {
     /**
      * @dev Deposit Liquidity.
      * @notice Deposit Liquidity to a SushiSwap pool.
-     * @param tokenA The address of token A.(For ETH: 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE)
-     * @param tokenB The address of token B.(For ETH: 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE)
+     * @param tokenA The address of token A.(For Matic: 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE)
+     * @param tokenB The address of token B.(For Matic: 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE)
      * @param amtA The amount of A tokens to deposit.
      * @param unitAmt The unit amount of of amtB/amtA with slippage.
      * @param slippage Slippage amount.
@@ -48,8 +48,8 @@ abstract contract SushipswapResolver is Helpers, Events {
     /**
      * @dev Withdraw Liquidity.
      * @notice Withdraw Liquidity from a SushiSwap pool.
-     * @param tokenA The address of token A.(For ETH: 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE)
-     * @param tokenB The address of token B.(For ETH: 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE)
+     * @param tokenA The address of token A.(For Matic: 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE)
+     * @param tokenB The address of token B.(For Matic: 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE)
      * @param uniAmt The amount of pool tokens to withdraw.
      * @param unitAmtA The unit amount of amtA/uniAmt with slippage.
      * @param unitAmtB The unit amount of amtB/uniAmt with slippage.
@@ -83,10 +83,10 @@ abstract contract SushipswapResolver is Helpers, Events {
     }
 
     /**
-     * @dev Buy ETH/ERC20_Token.
+     * @dev Buy Matic/ERC20_Token.
      * @notice Buy a token using a SushiSwap
-     * @param buyAddr The address of the token to buy.(For ETH: 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE)
-     * @param sellAddr The address of the token to sell.(For ETH: 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE)
+     * @param buyAddr The address of the token to buy.(For Matic: 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE)
+     * @param sellAddr The address of the token to sell.(For Matic: 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE)
      * @param buyAmt The amount of tokens to buy.
      * @param unitAmt The unit amount of sellAmt/buyAmt with slippage.
      * @param getId ID to retrieve buyAmt.
@@ -101,7 +101,7 @@ abstract contract SushipswapResolver is Helpers, Events {
         uint256 setId
     ) external payable returns (string memory _eventName, bytes memory _eventParam) {
         uint _buyAmt = getUint(getId, buyAmt);
-        (TokenInterface _buyAddr, TokenInterface _sellAddr) = changeEthAddress(buyAddr, sellAddr);
+        (TokenInterface _buyAddr, TokenInterface _sellAddr) = changeMaticAddress(buyAddr, sellAddr);
         address[] memory paths = getPaths(address(_buyAddr), address(_sellAddr));
 
         uint _slippageAmt = convert18ToDec(_sellAddr.decimals(),
@@ -112,8 +112,8 @@ abstract contract SushipswapResolver is Helpers, Events {
         uint _expectedAmt = getExpectedSellAmt(paths, _buyAmt);
         require(_slippageAmt >= _expectedAmt, "Too much slippage");
 
-        bool isEth = address(_sellAddr) == wethAddr;
-        convertEthToWeth(isEth, _sellAddr, _expectedAmt);
+        bool isMatic = address(_sellAddr) == wmaticAddr;
+        convertMaticToWmatic(isMatic, _sellAddr, _expectedAmt);
         approve(_sellAddr, address(router), _expectedAmt);
 
         uint _sellAmt = router.swapTokensForExactTokens(
@@ -124,8 +124,8 @@ abstract contract SushipswapResolver is Helpers, Events {
             block.timestamp + 1
         )[0];
 
-        isEth = address(_buyAddr) == wethAddr;
-        convertWethToEth(isEth, _buyAddr, _buyAmt);
+        isMatic = address(_buyAddr) == wmaticAddr;
+        convertWmaticToMatic(isMatic, _buyAddr, _buyAmt);
 
         setUint(setId, _sellAmt);
 
@@ -134,10 +134,10 @@ abstract contract SushipswapResolver is Helpers, Events {
     }
 
     /**
-     * @dev Sell ETH/ERC20_Token.
+     * @dev Sell Matic/ERC20_Token.
      * @notice Sell a token using a SushiSwap
-     * @param buyAddr The address of the token to buy.(For ETH: 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE)
-     * @param sellAddr The address of the token to sell.(For ETH: 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE)
+     * @param buyAddr The address of the token to buy.(For Matic: 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE)
+     * @param sellAddr The address of the token to sell.(For Matic: 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE)
      * @param sellAmt The amount of the token to sell.
      * @param unitAmt The unit amount of buyAmt/sellAmt with slippage.
      * @param getId ID to retrieve sellAmt.
@@ -152,11 +152,11 @@ abstract contract SushipswapResolver is Helpers, Events {
         uint256 setId
     ) external payable returns (string memory _eventName, bytes memory _eventParam) {
         uint _sellAmt = getUint(getId, sellAmt);
-        (TokenInterface _buyAddr, TokenInterface _sellAddr) = changeEthAddress(buyAddr, sellAddr);
+        (TokenInterface _buyAddr, TokenInterface _sellAddr) = changeMaticAddress(buyAddr, sellAddr);
         address[] memory paths = getPaths(address(_buyAddr), address(_sellAddr));
 
         if (_sellAmt == uint(-1)) {
-            _sellAmt = sellAddr == ethAddr ?
+            _sellAmt = sellAddr == maticAddr ?
                 address(this).balance :
                 _sellAddr.balanceOf(address(this));
         }
@@ -169,8 +169,8 @@ abstract contract SushipswapResolver is Helpers, Events {
         uint _expectedAmt = getExpectedBuyAmt(paths, _sellAmt);
         require(_slippageAmt <= _expectedAmt, "Too much slippage");
 
-        bool isEth = address(_sellAddr) == wethAddr;
-        convertEthToWeth(isEth, _sellAddr, _sellAmt);
+        bool isMatic = address(_sellAddr) == wmaticAddr;
+        convertMaticToWmatic(isMatic, _sellAddr, _sellAmt);
         approve(_sellAddr, address(router), _sellAmt);
 
         uint _buyAmt = router.swapExactTokensForTokens(
@@ -181,8 +181,8 @@ abstract contract SushipswapResolver is Helpers, Events {
             block.timestamp + 1
         )[1];
 
-        isEth = address(_buyAddr) == wethAddr;
-        convertWethToEth(isEth, _buyAddr, _buyAmt);
+        isMatic = address(_buyAddr) == wmaticAddr;
+        convertWmaticToMatic(isMatic, _buyAddr, _buyAmt);
 
         setUint(setId, _buyAmt);
 
@@ -191,6 +191,6 @@ abstract contract SushipswapResolver is Helpers, Events {
     }
 }
 
-contract ConnectV2Sushiswap is SushipswapResolver {
-    string public constant name = "Sushipswap-v1.1";
+contract ConnectV2SushiswapPolygon is SushipswapResolver {
+    string public constant name = "Sushiswap-v1.1";
 }

From a0a3342c822ee07d0cb850e492ba477e77b3be4e Mon Sep 17 00:00:00 2001
From: pradyuman-verma <pradyumnverma27@gmail.com>
Date: Wed, 5 Jan 2022 23:44:46 +0530
Subject: [PATCH 3/8] sushiswap polygon tests

---
 test/polygon/sushiswap/sushiswap.test.ts | 148 +++++++++++++++++++++++
 1 file changed, 148 insertions(+)
 create mode 100644 test/polygon/sushiswap/sushiswap.test.ts

diff --git a/test/polygon/sushiswap/sushiswap.test.ts b/test/polygon/sushiswap/sushiswap.test.ts
new file mode 100644
index 00000000..4314e1b8
--- /dev/null
+++ b/test/polygon/sushiswap/sushiswap.test.ts
@@ -0,0 +1,148 @@
+import { expect } from "chai";
+import hre from "hardhat";
+const { waffle, ethers } = hre;
+const { provider } = waffle;
+
+import { deployAndEnableConnector } from "../../../scripts/tests/deployAndEnableConnector";
+import { buildDSAv2 } from "../../../scripts/tests/buildDSAv2";
+import { encodeSpells } from "../../../scripts/tests/encodeSpells";
+import { getMasterSigner } from "../../../scripts/tests/getMasterSigner";
+import { addLiquidity } from "../../../scripts/tests/addLiquidity";
+
+import { constants } from "../../../scripts/constant/constant";
+import { addresses } from "../../../scripts/tests/polygon/addresses";
+import { abis } from "../../../scripts/constant/abis";
+import { ConnectV2SushiswapPolygon__factory, ConnectV2SushiswapPolygon } from "../../../typechain";
+import type { Signer, Contract } from "ethers";
+
+const DAI_ADDR = "0x8f3cf7ad23cd3cadbd9735aff958023239c6a063";
+
+describe("Sushiswap", function () {
+  const connectorName = "Sushiswap-v1";
+
+  let dsaWallet0: Contract;
+  let masterSigner: Signer;
+  let instaConnectorsV2: Contract;
+  let connector: Contract;
+
+  const wallets = provider.getWallets();
+  const [wallet0, wallet1, wallet2, wallet3] = wallets;
+  before(async () => {
+    await hre.network.provider.request({
+      method: "hardhat_reset",
+      params: [
+        {
+          forking: {
+            // @ts-ignore
+            jsonRpcUrl: hre.config.networks.hardhat.forking.url,
+            blockNumber: 13005785
+          }
+        }
+      ]
+    });
+
+    masterSigner = await getMasterSigner();
+    instaConnectorsV2 = await ethers.getContractAt(abis.core.connectorsV2, addresses.core.connectorsV2);
+    connector = await deployAndEnableConnector({
+      connectorName,
+      contractArtifact: ConnectV2SushiswapPolygon__factory,
+      signer: masterSigner,
+      connectors: instaConnectorsV2
+    });
+    console.log("Connector address", connector.address);
+  });
+
+  it("Should have contracts deployed.", async function () {
+    expect(!!instaConnectorsV2.address).to.be.true;
+    expect(!!connector.address).to.be.true;
+    expect(!!(await masterSigner.getAddress())).to.be.true;
+  });
+
+  describe("DSA wallet setup", function () {
+    it("Should build DSA v2", async function () {
+      dsaWallet0 = await buildDSAv2(wallet0.address);
+      expect(!!dsaWallet0.address).to.be.true;
+    });
+
+    it("Deposit MATIC & DAI into DSA wallet", async function () {
+      await wallet0.sendTransaction({
+        to: dsaWallet0.address,
+        value: ethers.utils.parseEther("10")
+      });
+      expect(await ethers.provider.getBalance(dsaWallet0.address)).to.be.gte(ethers.utils.parseEther("10"));
+
+      await addLiquidity("dai", dsaWallet0.address, ethers.utils.parseEther("10000"));
+    });
+
+    it("Deposit MATIC & USDT into DSA wallet", async function () {
+      await wallet0.sendTransaction({
+        to: dsaWallet0.address,
+        value: ethers.utils.parseEther("10")
+      });
+      expect(await ethers.provider.getBalance(dsaWallet0.address)).to.be.gte(ethers.utils.parseEther("10"));
+
+      await addLiquidity("usdt", dsaWallet0.address, ethers.utils.parseEther("10000"));
+    });
+  });
+
+  describe("Main", function () {
+    it("Should deposit successfully", async function () {
+      const maticAmount = ethers.utils.parseEther("0.1"); 
+      const daiUnitAmount = ethers.utils.parseEther("4000"); 
+      const maticAddress = constants.native_address;
+
+      const getId = "0";
+      const setId = "0";
+
+      const spells = [
+        {
+          connector: connectorName,
+          method: "deposit",
+          args: [maticAddress, DAI_ADDR, maticAmount, daiUnitAmount, "500000000000000000", getId, setId]
+        }
+      ];
+
+      const tx = await dsaWallet0.connect(wallet0).cast(...encodeSpells(spells), wallet1.address);
+      let receipt = await tx.wait();
+    }).timeout(10000000000);
+
+    it("Should withdraw successfully", async function () {
+      const maticAmount = ethers.utils.parseEther("0.1"); 
+      const maticAddress = constants.native_address;
+
+      const getId = "0";
+      const setIds = ["0", "0"];
+
+      const spells = [
+        {
+          connector: connectorName,
+          method: "withdraw",
+          args: [maticAddress, DAI_ADDR, maticAmount, 0, 0, getId, setIds]
+        }
+      ];
+
+      const tx = await dsaWallet0.connect(wallet0).cast(...encodeSpells(spells), wallet1.address);
+      let receipt = await tx.wait();
+    });
+
+    it("Should buy successfully", async function () {
+      const maticAmount = ethers.utils.parseEther("0.1"); 
+      const daiUnitAmount = ethers.utils.parseEther("4000"); 
+      const maticAddress = constants.native_address;
+
+      const getId = "0";
+      const setId = "0";
+
+      const spells = [
+        {
+          connector: connectorName,
+          method: "buy",
+          args: [maticAddress, DAI_ADDR, maticAmount, daiUnitAmount, getId, setId]
+        }
+      ];
+
+      const tx = await dsaWallet0.connect(wallet0).cast(...encodeSpells(spells), wallet1.address);
+      let receipt = await tx.wait();
+    });
+  });
+});

From aeae64a15fd56b58eae232a037a518acabab1a0e Mon Sep 17 00:00:00 2001
From: pradyuman-verma <pradyumnverma27@gmail.com>
Date: Wed, 5 Jan 2022 23:50:16 +0530
Subject: [PATCH 4/8] sushiswap arbitrum tests

---
 test/arbitrum/sushiswap/sushiswap.test.ts | 148 ++++++++++++++++++++++
 1 file changed, 148 insertions(+)
 create mode 100644 test/arbitrum/sushiswap/sushiswap.test.ts

diff --git a/test/arbitrum/sushiswap/sushiswap.test.ts b/test/arbitrum/sushiswap/sushiswap.test.ts
new file mode 100644
index 00000000..68da8d66
--- /dev/null
+++ b/test/arbitrum/sushiswap/sushiswap.test.ts
@@ -0,0 +1,148 @@
+import { expect } from "chai";
+import hre from "hardhat";
+const { waffle, ethers } = hre;
+const { provider } = waffle;
+
+import { deployAndEnableConnector } from "../../../scripts/tests/deployAndEnableConnector";
+import { buildDSAv2 } from "../../../scripts/tests/buildDSAv2";
+import { encodeSpells } from "../../../scripts/tests/encodeSpells";
+import { getMasterSigner } from "../../../scripts/tests/getMasterSigner";
+import { addLiquidity } from "../../../scripts/tests/addLiquidity";
+
+import { constants } from "../../../scripts/constant/constant";
+import { addresses } from "../../../scripts/tests/arbitrum/addresses";
+import { abis } from "../../../scripts/constant/abis";
+import { ConnectV2SushiswapArbitrum__factory } from "../../../typechain";
+import type { Signer, Contract } from "ethers";
+
+const DAI_ADDR = "0xda10009cbd5d07dd0cecc66161fc93d7c9000da1";
+
+describe("Sushiswap", function () {
+  const connectorName = "Sushiswap-v1";
+
+  let dsaWallet0: Contract;
+  let masterSigner: Signer;
+  let instaConnectorsV2: Contract;
+  let connector: Contract;
+
+  const wallets = provider.getWallets();
+  const [wallet0, wallet1, wallet2, wallet3] = wallets;
+  before(async () => {
+    await hre.network.provider.request({
+      method: "hardhat_reset",
+      params: [
+        {
+          forking: {
+            // @ts-ignore
+            jsonRpcUrl: hre.config.networks.hardhat.forking.url,
+            blockNumber: 13005785
+          }
+        }
+      ]
+    });
+
+    masterSigner = await getMasterSigner();
+    instaConnectorsV2 = await ethers.getContractAt(abis.core.connectorsV2, addresses.core.connectorsV2);
+    connector = await deployAndEnableConnector({
+      connectorName,
+      contractArtifact: ConnectV2SushiswapArbitrum__factory,
+      signer: masterSigner,
+      connectors: instaConnectorsV2
+    });
+    console.log("Connector address", connector.address);
+  });
+
+  it("Should have contracts deployed.", async function () {
+    expect(!!instaConnectorsV2.address).to.be.true;
+    expect(!!connector.address).to.be.true;
+    expect(!!(await masterSigner.getAddress())).to.be.true;
+  });
+
+  describe("DSA wallet setup", function () {
+    it("Should build DSA v2", async function () {
+      dsaWallet0 = await buildDSAv2(wallet0.address);
+      expect(!!dsaWallet0.address).to.be.true;
+    });
+
+    it("Deposit aeth & DAI into DSA wallet", async function () {
+      await wallet0.sendTransaction({
+        to: dsaWallet0.address,
+        value: ethers.utils.parseEther("10")
+      });
+      expect(await ethers.provider.getBalance(dsaWallet0.address)).to.be.gte(ethers.utils.parseEther("10"));
+
+      await addLiquidity("dai", dsaWallet0.address, ethers.utils.parseEther("10000"));
+    });
+
+    it("Deposit aeth & USDT into DSA wallet", async function () {
+      await wallet0.sendTransaction({
+        to: dsaWallet0.address,
+        value: ethers.utils.parseEther("10")
+      });
+      expect(await ethers.provider.getBalance(dsaWallet0.address)).to.be.gte(ethers.utils.parseEther("10"));
+
+      await addLiquidity("usdt", dsaWallet0.address, ethers.utils.parseEther("10000"));
+    });
+  });
+
+  describe("Main", function () {
+    it("Should deposit successfully", async function () {
+      const aethAmount = ethers.utils.parseEther("0.1"); 
+      const daiUnitAmount = ethers.utils.parseEther("4000"); 
+      const aethAddress = constants.native_address;
+
+      const getId = "0";
+      const setId = "0";
+
+      const spells = [
+        {
+          connector: connectorName,
+          method: "deposit",
+          args: [aethAddress, DAI_ADDR, aethAmount, daiUnitAmount, "500000000000000000", getId, setId]
+        }
+      ];
+
+      const tx = await dsaWallet0.connect(wallet0).cast(...encodeSpells(spells), wallet1.address);
+      let receipt = await tx.wait();
+    }).timeout(10000000000);
+
+    it("Should withdraw successfully", async function () {
+      const aethAmount = ethers.utils.parseEther("0.1"); 
+      const aethAddress = constants.native_address;
+
+      const getId = "0";
+      const setIds = ["0", "0"];
+
+      const spells = [
+        {
+          connector: connectorName,
+          method: "withdraw",
+          args: [aethAddress, DAI_ADDR, aethAmount, 0, 0, getId, setIds]
+        }
+      ];
+
+      const tx = await dsaWallet0.connect(wallet0).cast(...encodeSpells(spells), wallet1.address);
+      let receipt = await tx.wait();
+    });
+
+    it("Should buy successfully", async function () {
+      const aethAmount = ethers.utils.parseEther("0.1"); 
+      const daiUnitAmount = ethers.utils.parseEther("4000"); 
+      const aethAddress = constants.native_address;
+
+      const getId = "0";
+      const setId = "0";
+
+      const spells = [
+        {
+          connector: connectorName,
+          method: "buy",
+          args: [aethAddress, DAI_ADDR, aethAmount, daiUnitAmount, getId, setId]
+        }
+      ];
+
+      const tx = await dsaWallet0.connect(wallet0).cast(...encodeSpells(spells), wallet1.address);
+      let receipt = await tx.wait();
+    });
+  });
+});

From 9f73e96f35b2362e40491fda52ffeb8477e09577 Mon Sep 17 00:00:00 2001
From: pradyuman-verma <pradyumnverma27@gmail.com>
Date: Thu, 6 Jan 2022 00:04:33 +0530
Subject: [PATCH 5/8] sushiswap: avalanche

---
 .../avalanche/connectors/sushiswap/events.sol |  42 ++++
 .../connectors/sushiswap/helpers.sol          | 185 ++++++++++++++++
 .../connectors/sushiswap/interface.sol        |  58 ++++++
 .../avalanche/connectors/sushiswap/main.sol   | 197 ++++++++++++++++++
 4 files changed, 482 insertions(+)
 create mode 100644 contracts/avalanche/connectors/sushiswap/events.sol
 create mode 100644 contracts/avalanche/connectors/sushiswap/helpers.sol
 create mode 100644 contracts/avalanche/connectors/sushiswap/interface.sol
 create mode 100644 contracts/avalanche/connectors/sushiswap/main.sol

diff --git a/contracts/avalanche/connectors/sushiswap/events.sol b/contracts/avalanche/connectors/sushiswap/events.sol
new file mode 100644
index 00000000..4697e44c
--- /dev/null
+++ b/contracts/avalanche/connectors/sushiswap/events.sol
@@ -0,0 +1,42 @@
+// SPDX-License-Identifier: MIT
+pragma solidity ^0.7.0;
+
+contract Events {
+    event LogDepositLiquidity(
+        address indexed tokenA,
+        address indexed tokenB,
+        uint256 amtA,
+        uint256 amtB,
+        uint256 uniAmount,
+        uint256 getId,
+        uint256 setId
+    );
+
+    event LogWithdrawLiquidity(
+        address indexed tokenA,
+        address indexed tokenB,
+        uint256 amountA,
+        uint256 amountB,
+        uint256 uniAmount,
+        uint256 getId,
+        uint256[] setId
+    );
+    
+    event LogBuy(
+        address indexed buyToken,
+        address indexed sellToken,
+        uint256 buyAmt,
+        uint256 sellAmt,
+        uint256 getId,
+        uint256 setId
+    );
+
+    event LogSell(
+        address indexed buyToken,
+        address indexed sellToken,
+        uint256 buyAmt,
+        uint256 sellAmt,
+        uint256 getId,
+        uint256 setId
+    );
+}
\ No newline at end of file
diff --git a/contracts/avalanche/connectors/sushiswap/helpers.sol b/contracts/avalanche/connectors/sushiswap/helpers.sol
new file mode 100644
index 00000000..04149201
--- /dev/null
+++ b/contracts/avalanche/connectors/sushiswap/helpers.sol
@@ -0,0 +1,185 @@
+// SPDX-License-Identifier: MIT
+pragma solidity ^0.7.0;
+
+import {TokenInterface} from "../../common/interfaces.sol";
+import {DSMath} from "../../common/math.sol";
+import {Basic} from "../../common/basic.sol";
+import {ISushiSwapRouter, ISushiSwapFactory} from "./interface.sol";
+
+abstract contract Helpers is DSMath, Basic {
+    /**
+     * @dev ISushiSwapRouter
+     */
+    ISushiSwapRouter internal constant router =
+        ISushiSwapRouter(0x1b02dA8Cb0d097eB8D57A175b88c7D8b47997506);
+
+    function getExpectedBuyAmt(address[] memory paths, uint256 sellAmt)
+        internal
+        view
+        returns (uint256 buyAmt)
+    {
+        uint256[] memory amts = router.getAmountsOut(sellAmt, paths);
+        buyAmt = amts[1];
+    }
+
+    function getExpectedSellAmt(address[] memory paths, uint256 buyAmt)
+        internal
+        view
+        returns (uint256 sellAmt)
+    {
+        uint256[] memory amts = router.getAmountsIn(buyAmt, paths);
+        sellAmt = amts[0];
+    }
+
+    function checkPair(address[] memory paths) internal view {
+        address pair = ISushiSwapFactory(router.factory()).getPair(
+            paths[0],
+            paths[1]
+        );
+        require(pair != address(0), "No-exchange-address");
+    }
+
+    function getPaths(address buyAddr, address sellAddr)
+        internal
+        pure
+        returns (address[] memory paths)
+    {
+        paths = new address[](2);
+        paths[0] = address(sellAddr);
+        paths[1] = address(buyAddr);
+    }
+
+    function getMinAmount(
+        TokenInterface token,
+        uint256 amt,
+        uint256 slippage
+    ) internal view returns (uint256 minAmt) {
+        uint256 _amt18 = convertTo18(token.decimals(), amt);
+        minAmt = wmul(_amt18, sub(WAD, slippage));
+        minAmt = convert18ToDec(token.decimals(), minAmt);
+    }
+
+    function _addLiquidity(
+        address tokenA,
+        address tokenB,
+        uint256 _amt,
+        uint256 unitAmt,
+        uint256 slippage
+    )
+        internal
+        returns (
+            uint256 _amtA,
+            uint256 _amtB,
+            uint256 _liquidity
+        )
+    {
+        (TokenInterface _tokenA, TokenInterface _tokenB) = changeAvaxAddress(
+            tokenA,
+            tokenB
+        );
+
+        _amtA = _amt == uint256(-1)
+            ? getTokenBal(TokenInterface(tokenA))
+            : _amt;
+        _amtB = convert18ToDec(
+            _tokenB.decimals(),
+            wmul(unitAmt, convertTo18(_tokenA.decimals(), _amtA))
+        );
+
+        bool isAvax = address(_tokenA) == wavaxAddr;
+        convertAvaxToWavax(isAvax, _tokenA, _amtA);
+
+        isAvax = address(_tokenB) == wavaxAddr;
+        convertAvaxToWavax(isAvax, _tokenB, _amtB);
+
+        approve(_tokenA, address(router), _amtA);
+        approve(_tokenB, address(router), _amtB);
+
+        uint256 minAmtA = getMinAmount(_tokenA, _amtA, slippage);
+        uint256 minAmtB = getMinAmount(_tokenB, _amtB, slippage);
+        (_amtA, _amtB, _liquidity) = router.addLiquidity(
+            address(_tokenA),
+            address(_tokenB),
+            _amtA,
+            _amtB,
+            minAmtA,
+            minAmtB,
+            address(this),
+            block.timestamp + 1
+        );
+    }
+
+    function _removeLiquidity(
+        address tokenA,
+        address tokenB,
+        uint256 _amt,
+        uint256 unitAmtA,
+        uint256 unitAmtB
+    )
+        internal
+        returns (
+            uint256 _amtA,
+            uint256 _amtB,
+            uint256 _uniAmt
+        )
+    {
+        TokenInterface _tokenA;
+        TokenInterface _tokenB;
+        (_tokenA, _tokenB, _uniAmt) = _getRemoveLiquidityData(
+            tokenA,
+            tokenB,
+            _amt
+        );
+        {
+            uint256 minAmtA = convert18ToDec(
+                _tokenA.decimals(),
+                wmul(unitAmtA, _uniAmt)
+            );
+            uint256 minAmtB = convert18ToDec(
+                _tokenB.decimals(),
+                wmul(unitAmtB, _uniAmt)
+            );
+            (_amtA, _amtB) = router.removeLiquidity(
+                address(_tokenA),
+                address(_tokenB),
+                _uniAmt,
+                minAmtA,
+                minAmtB,
+                address(this),
+                block.timestamp + 1
+            );
+        }
+
+        bool isAvax = address(_tokenA) == wavaxAddr;
+        convertWavaxToAvax(isAvax, _tokenA, _amtA);
+
+        isAvax = address(_tokenB) == wavaxAddr;
+        convertWavaxToAvax(isAvax, _tokenB, _amtB);
+    }
+
+    function _getRemoveLiquidityData(
+        address tokenA,
+        address tokenB,
+        uint256 _amt
+    )
+        internal
+        returns (
+            TokenInterface _tokenA,
+            TokenInterface _tokenB,
+            uint256 _uniAmt
+        )
+    {
+        (_tokenA, _tokenB) = changeAvaxAddress(tokenA, tokenB);
+        address exchangeAddr = ISushiSwapFactory(router.factory()).getPair(
+            address(_tokenA),
+            address(_tokenB)
+        );
+        require(exchangeAddr != address(0), "pair-not-found.");
+
+        TokenInterface uniToken = TokenInterface(exchangeAddr);
+        _uniAmt = _amt == uint256(-1)
+            ? uniToken.balanceOf(address(this))
+            : _amt;
+        approve(uniToken, address(router), _uniAmt);
+    }
+}
diff --git a/contracts/avalanche/connectors/sushiswap/interface.sol b/contracts/avalanche/connectors/sushiswap/interface.sol
new file mode 100644
index 00000000..b141c7b5
--- /dev/null
+++ b/contracts/avalanche/connectors/sushiswap/interface.sol
@@ -0,0 +1,58 @@
+// SPDX-License-Identifier: MIT
+pragma solidity ^0.7.0;
+
+interface ISushiSwapRouter {
+    function factory() external pure returns (address);
+    function WETH() external pure returns (address);
+
+    function addLiquidity(
+        address tokenA,
+        address tokenB,
+        uint amountADesired,
+        uint amountBDesired,
+        uint amountAMin,
+        uint amountBMin,
+        address to,
+        uint deadline
+    ) external returns (uint amountA, uint amountB, uint liquidity);
+    function removeLiquidity(
+        address tokenA,
+        address tokenB,
+        uint liquidity,
+        uint amountAMin,
+        uint amountBMin,
+        address to,
+        uint deadline
+    ) external returns (uint amountA, uint amountB);
+    function swapExactTokensForTokens(
+        uint amountIn,
+        uint amountOutMin,
+        address[] calldata path,
+        address to,
+        uint deadline
+    ) external returns (uint[] memory amounts);
+    function swapTokensForExactTokens(
+        uint amountOut,
+        uint amountInMax,
+        address[] calldata path,
+        address to,
+        uint deadline
+    ) external returns (uint[] memory amounts);
+
+    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[] calldata path) external view returns (uint[] memory amounts);
+    function getAmountsIn(uint amountOut, address[] calldata path) external view returns (uint[] memory amounts);
+}
+
+interface ISushiSwapFactory {
+    function getPair(address tokenA, address tokenB) external view returns (address pair);
+    function allPairs(uint) external view returns (address pair);
+    function allPairsLength() external view returns (uint);
+
+    function feeTo() external view returns (address);
+    function feeToSetter() external view returns (address);
+
+    function createPair(address tokenA, address tokenB) external returns (address pair);
+}
diff --git a/contracts/avalanche/connectors/sushiswap/main.sol b/contracts/avalanche/connectors/sushiswap/main.sol
new file mode 100644
index 00000000..8b9ef5e3
--- /dev/null
+++ b/contracts/avalanche/connectors/sushiswap/main.sol
@@ -0,0 +1,197 @@
+// SPDX-License-Identifier: MIT
+pragma solidity ^0.7.0;
+
+/**
+ * @title SushiSwap.
+ * @dev Decentralized Exchange.
+ */
+
+import { TokenInterface } from "../../common/interfaces.sol";
+import { Helpers } from "./helpers.sol";
+import { Events } from "./events.sol";
+
+abstract contract SushipswapResolver is Helpers, Events {
+    /**
+     * @dev Deposit Liquidity.
+     * @notice Deposit Liquidity to a SushiSwap pool.
+     * @param tokenA The address of token A.(For Avax: 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE)
+     * @param tokenB The address of token B.(For Avax: 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE)
+     * @param amtA The amount of A tokens to deposit.
+     * @param unitAmt The unit amount of of amtB/amtA with slippage.
+     * @param slippage Slippage amount.
+     * @param getId ID to retrieve amtA.
+     * @param setId ID stores the amount of pools tokens received.
+    */
+    function deposit(
+        address tokenA,
+        address tokenB,
+        uint256 amtA,
+        uint256 unitAmt,
+        uint256 slippage,
+        uint256 getId,
+        uint256 setId
+    ) external payable returns (string memory _eventName, bytes memory _eventParam) {
+        uint _amt = getUint(getId, amtA);
+
+        (uint _amtA, uint _amtB, uint _uniAmt) = _addLiquidity(
+                                            tokenA,
+                                            tokenB,
+                                            _amt,
+                                            unitAmt,
+                                            slippage
+                                        );
+        setUint(setId, _uniAmt);
+        
+        _eventName = "LogDepositLiquidity(address,address,uint256,uint256,uint256,uint256,uint256)";
+        _eventParam = abi.encode(tokenA, tokenB, _amtA, _amtB, _uniAmt, getId, setId);
+    }
+
+    /**
+     * @dev Withdraw Liquidity.
+     * @notice Withdraw Liquidity from a SushiSwap pool.
+     * @param tokenA The address of token A.(For Avax: 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE)
+     * @param tokenB The address of token B.(For Avax: 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE)
+     * @param uniAmt The amount of pool tokens to withdraw.
+     * @param unitAmtA The unit amount of amtA/uniAmt with slippage.
+     * @param unitAmtB The unit amount of amtB/uniAmt with slippage.
+     * @param getId ID to retrieve uniAmt.
+     * @param setIds Array of IDs to store the amount tokens received.
+    */
+    function withdraw(
+        address tokenA,
+        address tokenB,
+        uint256 uniAmt,
+        uint256 unitAmtA,
+        uint256 unitAmtB,
+        uint256 getId,
+        uint256[] calldata setIds
+    ) external payable returns (string memory _eventName, bytes memory _eventParam) {
+        uint _amt = getUint(getId, uniAmt);
+
+        (uint _amtA, uint _amtB, uint _uniAmt) = _removeLiquidity(
+            tokenA,
+            tokenB,
+            _amt,
+            unitAmtA,
+            unitAmtB
+        );
+
+        setUint(setIds[0], _amtA);
+        setUint(setIds[1], _amtB);
+        
+        _eventName = "LogWithdrawLiquidity(address,address,uint256,uint256,uint256,uint256,uint256[])";
+        _eventParam = abi.encode(tokenA, tokenB, _amtA, _amtB, _uniAmt, getId, setIds);
+    }
+
+    /**
+     * @dev Buy Avax/ERC20_Token.
+     * @notice Buy a token using a SushiSwap
+     * @param buyAddr The address of the token to buy.(For Avax: 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE)
+     * @param sellAddr The address of the token to sell.(For Avax: 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE)
+     * @param buyAmt The amount of tokens to buy.
+     * @param unitAmt The unit amount of sellAmt/buyAmt with slippage.
+     * @param getId ID to retrieve buyAmt.
+     * @param setId ID to store the amount of tokens sold.
+    */
+    function buy(
+        address buyAddr,
+        address sellAddr,
+        uint256 buyAmt,
+        uint256 unitAmt,
+        uint256 getId,
+        uint256 setId
+    ) external payable returns (string memory _eventName, bytes memory _eventParam) {
+        uint _buyAmt = getUint(getId, buyAmt);
+        (TokenInterface _buyAddr, TokenInterface _sellAddr) = changeAvaxAddress(buyAddr, sellAddr);
+        address[] memory paths = getPaths(address(_buyAddr), address(_sellAddr));
+
+        uint _slippageAmt = convert18ToDec(_sellAddr.decimals(),
+            wmul(unitAmt, convertTo18(_buyAddr.decimals(), _buyAmt))
+        );
+
+        checkPair(paths);
+        uint _expectedAmt = getExpectedSellAmt(paths, _buyAmt);
+        require(_slippageAmt >= _expectedAmt, "Too much slippage");
+
+        bool isAvax = address(_sellAddr) == wavaxAddr;
+        convertAvaxToWavax(isAvax, _sellAddr, _expectedAmt);
+        approve(_sellAddr, address(router), _expectedAmt);
+
+        uint _sellAmt = router.swapTokensForExactTokens(
+            _buyAmt,
+            _expectedAmt,
+            paths,
+            address(this),
+            block.timestamp + 1
+        )[0];
+
+        isAvax = address(_buyAddr) == wavaxAddr;
+        convertWavaxToAvax(isAvax, _buyAddr, _buyAmt);
+
+        setUint(setId, _sellAmt);
+
+        _eventName = "LogBuy(address,address,uint256,uint256,uint256,uint256)";
+        _eventParam = abi.encode(buyAddr, sellAddr, _buyAmt, _sellAmt, getId, setId);
+    }
+
+    /**
+     * @dev Sell Avax/ERC20_Token.
+     * @notice Sell a token using a SushiSwap
+     * @param buyAddr The address of the token to buy.(For Avax: 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE)
+     * @param sellAddr The address of the token to sell.(For Avax: 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE)
+     * @param sellAmt The amount of the token to sell.
+     * @param unitAmt The unit amount of buyAmt/sellAmt with slippage.
+     * @param getId ID to retrieve sellAmt.
+     * @param setId ID stores the amount of token brought.
+    */
+    function sell(
+        address buyAddr,
+        address sellAddr,
+        uint256 sellAmt,
+        uint256 unitAmt,
+        uint256 getId,
+        uint256 setId
+    ) external payable returns (string memory _eventName, bytes memory _eventParam) {
+        uint _sellAmt = getUint(getId, sellAmt);
+        (TokenInterface _buyAddr, TokenInterface _sellAddr) = changeAvaxAddress(buyAddr, sellAddr);
+        address[] memory paths = getPaths(address(_buyAddr), address(_sellAddr));
+
+        if (_sellAmt == uint(-1)) {
+            _sellAmt = sellAddr == avaxAddr ?
+                address(this).balance :
+                _sellAddr.balanceOf(address(this));
+        }
+
+        uint _slippageAmt = convert18ToDec(_buyAddr.decimals(),
+            wmul(unitAmt, convertTo18(_sellAddr.decimals(), _sellAmt))
+        );
+
+        checkPair(paths);
+        uint _expectedAmt = getExpectedBuyAmt(paths, _sellAmt);
+        require(_slippageAmt <= _expectedAmt, "Too much slippage");
+
+        bool isAvax = address(_sellAddr) == wavaxAddr;
+        convertAvaxToWavax(isAvax, _sellAddr, _sellAmt);
+        approve(_sellAddr, address(router), _sellAmt);
+
+        uint _buyAmt = router.swapExactTokensForTokens(
+            _sellAmt,
+            _expectedAmt,
+            paths,
+            address(this),
+            block.timestamp + 1
+        )[1];
+
+        isAvax = address(_buyAddr) == wavaxAddr;
+        convertWavaxToAvax(isAvax, _buyAddr, _buyAmt);
+
+        setUint(setId, _buyAmt);
+
+        _eventName = "LogSell(address,address,uint256,uint256,uint256,uint256)";
+        _eventParam = abi.encode(buyAddr, sellAddr, _buyAmt, _sellAmt, getId, setId);
+    }
+}
+
+contract ConnectV2SushiswapAvalanche is SushipswapResolver {
+    string public constant name = "Sushiswap-v1.1";
+}

From e0b165808151b31d4eacbff8c69d666433c22fe4 Mon Sep 17 00:00:00 2001
From: pradyuman-verma <pradyumnverma27@gmail.com>
Date: Thu, 6 Jan 2022 00:05:17 +0530
Subject: [PATCH 6/8] added sushiswap avalanche tests

---
 test/avalanche/sushiswap/sushiswap.test.ts | 148 +++++++++++++++++++++
 1 file changed, 148 insertions(+)
 create mode 100644 test/avalanche/sushiswap/sushiswap.test.ts

diff --git a/test/avalanche/sushiswap/sushiswap.test.ts b/test/avalanche/sushiswap/sushiswap.test.ts
new file mode 100644
index 00000000..c2ef92fe
--- /dev/null
+++ b/test/avalanche/sushiswap/sushiswap.test.ts
@@ -0,0 +1,148 @@
+import { expect } from "chai";
+import hre from "hardhat";
+const { waffle, ethers } = hre;
+const { provider } = waffle;
+
+import { deployAndEnableConnector } from "../../../scripts/tests/deployAndEnableConnector";
+import { buildDSAv2 } from "../../../scripts/tests/buildDSAv2";
+import { encodeSpells } from "../../../scripts/tests/encodeSpells";
+import { getMasterSigner } from "../../../scripts/tests/getMasterSigner";
+import { addLiquidity } from "../../../scripts/tests/addLiquidity";
+
+import { constants } from "../../../scripts/constant/constant";
+import { addresses } from "../../../scripts/tests/avalanche/addresses";
+import { abis } from "../../../scripts/constant/abis";
+import { ConnectV2SushiswapAvalanche__factory, ConnectV2SushiswapAvalanche } from "../../../typechain";
+import type { Signer, Contract } from "ethers";
+
+const DAI_ADDR = "0xd586e7f844cea2f87f50152665bcbc2c279d8d70";
+
+describe("Sushiswap", function () {
+  const connectorName = "Sushiswap-v1";
+
+  let dsaWallet0: Contract;
+  let masterSigner: Signer;
+  let instaConnectorsV2: Contract;
+  let connector: Contract;
+
+  const wallets = provider.getWallets();
+  const [wallet0, wallet1, wallet2, wallet3] = wallets;
+  before(async () => {
+    await hre.network.provider.request({
+      method: "hardhat_reset",
+      params: [
+        {
+          forking: {
+            // @ts-ignore
+            jsonRpcUrl: hre.config.networks.hardhat.forking.url,
+            blockNumber: 13005785
+          }
+        }
+      ]
+    });
+
+    masterSigner = await getMasterSigner();
+    instaConnectorsV2 = await ethers.getContractAt(abis.core.connectorsV2, addresses.core.connectorsV2);
+    connector = await deployAndEnableConnector({
+      connectorName,
+      contractArtifact: ConnectV2SushiswapAvalanche__factory,
+      signer: masterSigner,
+      connectors: instaConnectorsV2
+    });
+    console.log("Connector address", connector.address);
+  });
+
+  it("Should have contracts deployed.", async function () {
+    expect(!!instaConnectorsV2.address).to.be.true;
+    expect(!!connector.address).to.be.true;
+    expect(!!(await masterSigner.getAddress())).to.be.true;
+  });
+
+  describe("DSA wallet setup", function () {
+    it("Should build DSA v2", async function () {
+      dsaWallet0 = await buildDSAv2(wallet0.address);
+      expect(!!dsaWallet0.address).to.be.true;
+    });
+
+    it("Deposit avax & DAI into DSA wallet", async function () {
+      await wallet0.sendTransaction({
+        to: dsaWallet0.address,
+        value: ethers.utils.parseEther("10")
+      });
+      expect(await ethers.provider.getBalance(dsaWallet0.address)).to.be.gte(ethers.utils.parseEther("10"));
+
+      await addLiquidity("dai", dsaWallet0.address, ethers.utils.parseEther("10000"));
+    });
+
+    it("Deposit avax & USDT into DSA wallet", async function () {
+      await wallet0.sendTransaction({
+        to: dsaWallet0.address,
+        value: ethers.utils.parseEther("10")
+      });
+      expect(await ethers.provider.getBalance(dsaWallet0.address)).to.be.gte(ethers.utils.parseEther("10"));
+
+      await addLiquidity("usdt", dsaWallet0.address, ethers.utils.parseEther("10000"));
+    });
+  });
+
+  describe("Main", function () {
+    it("Should deposit successfully", async function () {
+      const avaxAmount = ethers.utils.parseEther("0.1"); 
+      const daiUnitAmount = ethers.utils.parseEther("4000"); 
+      const avaxAddress = constants.native_address;
+
+      const getId = "0";
+      const setId = "0";
+
+      const spells = [
+        {
+          connector: connectorName,
+          method: "deposit",
+          args: [avaxAddress, DAI_ADDR, avaxAmount, daiUnitAmount, "500000000000000000", getId, setId]
+        }
+      ];
+
+      const tx = await dsaWallet0.connect(wallet0).cast(...encodeSpells(spells), wallet1.address);
+      let receipt = await tx.wait();
+    }).timeout(10000000000);
+
+    it("Should withdraw successfully", async function () {
+      const avaxAmount = ethers.utils.parseEther("0.1"); 
+      const avaxAddress = constants.native_address;
+
+      const getId = "0";
+      const setIds = ["0", "0"];
+
+      const spells = [
+        {
+          connector: connectorName,
+          method: "withdraw",
+          args: [avaxAddress, DAI_ADDR, avaxAmount, 0, 0, getId, setIds]
+        }
+      ];
+
+      const tx = await dsaWallet0.connect(wallet0).cast(...encodeSpells(spells), wallet1.address);
+      let receipt = await tx.wait();
+    });
+
+    it("Should buy successfully", async function () {
+      const avaxAmount = ethers.utils.parseEther("0.1"); 
+      const daiUnitAmount = ethers.utils.parseEther("4000"); 
+      const avaxAddress = constants.native_address;
+
+      const getId = "0";
+      const setId = "0";
+
+      const spells = [
+        {
+          connector: connectorName,
+          method: "buy",
+          args: [avaxAddress, DAI_ADDR, avaxAmount, daiUnitAmount, getId, setId]
+        }
+      ];
+
+      const tx = await dsaWallet0.connect(wallet0).cast(...encodeSpells(spells), wallet1.address);
+      let receipt = await tx.wait();
+    });
+  });
+});

From ce83a8bc6e6cc56e0ecd35f0e27b1de19674ef99 Mon Sep 17 00:00:00 2001
From: pradyuman-verma <pradyumnverma27@gmail.com>
Date: Tue, 11 Jan 2022 12:40:22 +0530
Subject: [PATCH 7/8] minor fixes

---
 contracts/arbitrum/connectors/sushiswap/events.sol    | 1 +
 contracts/arbitrum/connectors/sushiswap/helpers.sol   | 1 +
 contracts/arbitrum/connectors/sushiswap/interface.sol | 1 +
 contracts/arbitrum/connectors/sushiswap/main.sol      | 7 ++++---
 contracts/avalanche/connectors/sushiswap/main.sol     | 6 +++---
 contracts/mainnet/connectors/sushiswap/events.sol     | 1 +
 contracts/mainnet/connectors/sushiswap/helpers.sol    | 1 +
 contracts/mainnet/connectors/sushiswap/interface.sol  | 1 +
 contracts/mainnet/connectors/sushiswap/main.sol       | 7 ++++---
 contracts/polygon/connectors/sushiswap/events.sol     | 1 +
 contracts/polygon/connectors/sushiswap/helpers.sol    | 1 +
 contracts/polygon/connectors/sushiswap/interface.sol  | 1 +
 contracts/polygon/connectors/sushiswap/main.sol       | 7 ++++---
 13 files changed, 24 insertions(+), 12 deletions(-)

diff --git a/contracts/arbitrum/connectors/sushiswap/events.sol b/contracts/arbitrum/connectors/sushiswap/events.sol
index 2717b0a3..4697e44c 100644
--- a/contracts/arbitrum/connectors/sushiswap/events.sol
+++ b/contracts/arbitrum/connectors/sushiswap/events.sol
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: MIT
 pragma solidity ^0.7.0;
 
 contract Events {
diff --git a/contracts/arbitrum/connectors/sushiswap/helpers.sol b/contracts/arbitrum/connectors/sushiswap/helpers.sol
index ae67bdd7..91a0ca11 100644
--- a/contracts/arbitrum/connectors/sushiswap/helpers.sol
+++ b/contracts/arbitrum/connectors/sushiswap/helpers.sol
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: MIT
 pragma solidity ^0.7.0;
 
 import {TokenInterface} from "../../common/interfaces.sol";
diff --git a/contracts/arbitrum/connectors/sushiswap/interface.sol b/contracts/arbitrum/connectors/sushiswap/interface.sol
index bd3be483..b141c7b5 100644
--- a/contracts/arbitrum/connectors/sushiswap/interface.sol
+++ b/contracts/arbitrum/connectors/sushiswap/interface.sol
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: MIT
 pragma solidity ^0.7.0;
 
 interface ISushiSwapRouter {
diff --git a/contracts/arbitrum/connectors/sushiswap/main.sol b/contracts/arbitrum/connectors/sushiswap/main.sol
index b7716406..f8b002eb 100644
--- a/contracts/arbitrum/connectors/sushiswap/main.sol
+++ b/contracts/arbitrum/connectors/sushiswap/main.sol
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: MIT
 pragma solidity ^0.7.0;
 
 /**
@@ -9,7 +10,7 @@ import { TokenInterface } from "../../common/interfaces.sol";
 import { Helpers } from "./helpers.sol";
 import { Events } from "./events.sol";
 
-abstract contract SushipswapResolver is Helpers, Events {
+abstract contract SushiswapResolver is Helpers, Events {
     /**
      * @dev Deposit Liquidity.
      * @notice Deposit Liquidity to a SushiSwap pool.
@@ -191,6 +192,6 @@ abstract contract SushipswapResolver is Helpers, Events {
     }
 }
 
-contract ConnectV2SushiswapArbitrum is SushipswapResolver {
-    string public constant name = "Sushiswap-v1.1";
+contract ConnectV2SushiswapArbitrum is SushiswapResolver {
+    string public constant name = "Sushiswap-v1";
 }
diff --git a/contracts/avalanche/connectors/sushiswap/main.sol b/contracts/avalanche/connectors/sushiswap/main.sol
index 8b9ef5e3..f8ed4847 100644
--- a/contracts/avalanche/connectors/sushiswap/main.sol
+++ b/contracts/avalanche/connectors/sushiswap/main.sol
@@ -10,7 +10,7 @@ import { TokenInterface } from "../../common/interfaces.sol";
 import { Helpers } from "./helpers.sol";
 import { Events } from "./events.sol";
 
-abstract contract SushipswapResolver is Helpers, Events {
+abstract contract SushiswapResolver is Helpers, Events {
     /**
      * @dev Deposit Liquidity.
      * @notice Deposit Liquidity to a SushiSwap pool.
@@ -192,6 +192,6 @@ abstract contract SushipswapResolver is Helpers, Events {
     }
 }
 
-contract ConnectV2SushiswapAvalanche is SushipswapResolver {
-    string public constant name = "Sushiswap-v1.1";
+contract ConnectV2SushiswapAvalanche is SushiswapResolver {
+    string public constant name = "Sushiswap-v1";
 }
diff --git a/contracts/mainnet/connectors/sushiswap/events.sol b/contracts/mainnet/connectors/sushiswap/events.sol
index 2717b0a3..4697e44c 100644
--- a/contracts/mainnet/connectors/sushiswap/events.sol
+++ b/contracts/mainnet/connectors/sushiswap/events.sol
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: MIT
 pragma solidity ^0.7.0;
 
 contract Events {
diff --git a/contracts/mainnet/connectors/sushiswap/helpers.sol b/contracts/mainnet/connectors/sushiswap/helpers.sol
index ea29a03f..9260b080 100644
--- a/contracts/mainnet/connectors/sushiswap/helpers.sol
+++ b/contracts/mainnet/connectors/sushiswap/helpers.sol
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: MIT
 pragma solidity ^0.7.0;
 
 import {TokenInterface} from "../../common/interfaces.sol";
diff --git a/contracts/mainnet/connectors/sushiswap/interface.sol b/contracts/mainnet/connectors/sushiswap/interface.sol
index bd3be483..b141c7b5 100644
--- a/contracts/mainnet/connectors/sushiswap/interface.sol
+++ b/contracts/mainnet/connectors/sushiswap/interface.sol
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: MIT
 pragma solidity ^0.7.0;
 
 interface ISushiSwapRouter {
diff --git a/contracts/mainnet/connectors/sushiswap/main.sol b/contracts/mainnet/connectors/sushiswap/main.sol
index bd0078bc..bd559688 100644
--- a/contracts/mainnet/connectors/sushiswap/main.sol
+++ b/contracts/mainnet/connectors/sushiswap/main.sol
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: MIT
 pragma solidity ^0.7.0;
 
 /**
@@ -9,7 +10,7 @@ import { TokenInterface } from "../../common/interfaces.sol";
 import { Helpers } from "./helpers.sol";
 import { Events } from "./events.sol";
 
-abstract contract SushipswapResolver is Helpers, Events {
+abstract contract SushiswapResolver is Helpers, Events {
     /**
      * @dev Deposit Liquidity.
      * @notice Deposit Liquidity to a SushiSwap pool.
@@ -191,6 +192,6 @@ abstract contract SushipswapResolver is Helpers, Events {
     }
 }
 
-contract ConnectV2Sushiswap is SushipswapResolver {
-    string public constant name = "Sushipswap-v1.1";
+contract ConnectV2Sushiswap is SushiswapResolver {
+    string public constant name = "Sushiswap-v1";
 }
diff --git a/contracts/polygon/connectors/sushiswap/events.sol b/contracts/polygon/connectors/sushiswap/events.sol
index 2717b0a3..4697e44c 100644
--- a/contracts/polygon/connectors/sushiswap/events.sol
+++ b/contracts/polygon/connectors/sushiswap/events.sol
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: MIT
 pragma solidity ^0.7.0;
 
 contract Events {
diff --git a/contracts/polygon/connectors/sushiswap/helpers.sol b/contracts/polygon/connectors/sushiswap/helpers.sol
index 9f43f2b6..5a03a061 100644
--- a/contracts/polygon/connectors/sushiswap/helpers.sol
+++ b/contracts/polygon/connectors/sushiswap/helpers.sol
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: MIT
 pragma solidity ^0.7.0;
 
 import {TokenInterface} from "../../common/interfaces.sol";
diff --git a/contracts/polygon/connectors/sushiswap/interface.sol b/contracts/polygon/connectors/sushiswap/interface.sol
index bd3be483..b141c7b5 100644
--- a/contracts/polygon/connectors/sushiswap/interface.sol
+++ b/contracts/polygon/connectors/sushiswap/interface.sol
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: MIT
 pragma solidity ^0.7.0;
 
 interface ISushiSwapRouter {
diff --git a/contracts/polygon/connectors/sushiswap/main.sol b/contracts/polygon/connectors/sushiswap/main.sol
index a4647769..5f80f946 100644
--- a/contracts/polygon/connectors/sushiswap/main.sol
+++ b/contracts/polygon/connectors/sushiswap/main.sol
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: MIT
 pragma solidity ^0.7.0;
 
 /**
@@ -9,7 +10,7 @@ import { TokenInterface } from "../../common/interfaces.sol";
 import { Helpers } from "./helpers.sol";
 import { Events } from "./events.sol";
 
-abstract contract SushipswapResolver is Helpers, Events {
+abstract contract SushiswapResolver is Helpers, Events {
     /**
      * @dev Deposit Liquidity.
      * @notice Deposit Liquidity to a SushiSwap pool.
@@ -191,6 +192,6 @@ abstract contract SushipswapResolver is Helpers, Events {
     }
 }
 
-contract ConnectV2SushiswapPolygon is SushipswapResolver {
-    string public constant name = "Sushiswap-v1.1";
+contract ConnectV2SushiswapPolygon is SushiswapResolver {
+    string public constant name = "Sushiswap-v1";
 }

From 744638ee5d8df7493edf6e5efb98fd7cf2acce72 Mon Sep 17 00:00:00 2001
From: bhavik-m <bhavikmehta2001@gmail.com>
Date: Tue, 11 Jan 2022 17:12:20 +0530
Subject: [PATCH 8/8] fixed getScanApikey func

---
 hardhat.config.ts | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hardhat.config.ts b/hardhat.config.ts
index 8c10d28f..44718268 100644
--- a/hardhat.config.ts
+++ b/hardhat.config.ts
@@ -118,7 +118,7 @@ const config: HardhatUserConfig = {
     tests: "./test",
   },
   etherscan: { 
-     apiKey: getScanApiKey(getNetworkUrl(String(process.env.networkType))),
+     apiKey: getScanApiKey(String(process.env.networkType)),
   },
   typechain: {
     outDir: "typechain",