From 102be3a91c8bc428b58d966ff87e6a004dfb38bb Mon Sep 17 00:00:00 2001 From: cryptoDev222 Date: Fri, 8 Oct 2021 14:21:02 -0500 Subject: [PATCH 01/15] implement sushi connector --- .../mainnet/connectors/sushiswap/events.sol | 41 ++++ .../mainnet/connectors/sushiswap/helpers.sol | 184 +++++++++++++++ .../connectors/sushiswap/interface.sol | 57 +++++ .../mainnet/connectors/sushiswap/main.sol | 196 ++++++++++++++++ test/sushiswap/sushiswap.test.js | 217 ++++++++++++++++++ 5 files changed, 695 insertions(+) create mode 100644 contracts/mainnet/connectors/sushiswap/events.sol create mode 100644 contracts/mainnet/connectors/sushiswap/helpers.sol create mode 100644 contracts/mainnet/connectors/sushiswap/interface.sol create mode 100644 contracts/mainnet/connectors/sushiswap/main.sol create mode 100644 test/sushiswap/sushiswap.test.js diff --git a/contracts/mainnet/connectors/sushiswap/events.sol b/contracts/mainnet/connectors/sushiswap/events.sol new file mode 100644 index 00000000..2717b0a3 --- /dev/null +++ b/contracts/mainnet/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/mainnet/connectors/sushiswap/helpers.sol b/contracts/mainnet/connectors/sushiswap/helpers.sol new file mode 100644 index 00000000..a1baa4c5 --- /dev/null +++ b/contracts/mainnet/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, + minAmtA, + 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/mainnet/connectors/sushiswap/interface.sol b/contracts/mainnet/connectors/sushiswap/interface.sol new file mode 100644 index 00000000..bd3be483 --- /dev/null +++ b/contracts/mainnet/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/mainnet/connectors/sushiswap/main.sol b/contracts/mainnet/connectors/sushiswap/main.sol new file mode 100644 index 00000000..bd0078bc --- /dev/null +++ b/contracts/mainnet/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/test/sushiswap/sushiswap.test.js b/test/sushiswap/sushiswap.test.js new file mode 100644 index 00000000..ead9dfd3 --- /dev/null +++ b/test/sushiswap/sushiswap.test.js @@ -0,0 +1,217 @@ +const { expect } = require("chai"); +const hre = require("hardhat"); +const { web3, deployments, waffle, ethers } = hre; +const { provider, deployContract } = waffle + +const deployAndEnableConnector = require("../../scripts/deployAndEnableConnector.js") +const buildDSAv2 = require("../../scripts/buildDSAv2") +const encodeSpells = require("../../scripts/encodeSpells.js") +const encodeFlashcastData = require("../../scripts/encodeFlashcastData.js") +const getMasterSigner = require("../../scripts/getMasterSigner") +const addLiquidity = require("../../scripts/addLiquidity"); + +const addresses = require("../../scripts/constant/addresses"); +const abis = require("../../scripts/constant/abis"); +const constants = require("../../scripts/constant/constant"); +const tokens = require("../../scripts/constant/tokens"); +const { abi: nftManagerAbi } = require("@uniswap/v3-periphery/artifacts/contracts/NonfungiblePositionManager.sol/NonfungiblePositionManager.json") + +const connectV2SushiswapArtifacts = require("../../artifacts/contracts/mainnet/connectors/sushiswap/main.sol/ConnectV2Sushiswap.json"); +const { eth } = require("../../scripts/constant/tokens"); +const { BigNumber } = require("ethers"); + +const FeeAmount = { + LOW: 500, + MEDIUM: 3000, + HIGH: 10000, +} + +const TICK_SPACINGS = { + 500: 10, + 3000: 60, + 10000: 200 +} + +const USDT_ADDR = "0xdac17f958d2ee523a2206206994597c13d831ec7" +const DAI_ADDR = "0x6b175474e89094c44da98b954eedeac495271d0f" + +let tokenIds = [] +let liquidities = [] +const abiCoder = ethers.utils.defaultAbiCoder + +describe("Sushiswap", function () { + const connectorName = "Sushiswap-v1" + + let dsaWallet0 + let masterSigner; + let instaConnectorsV2; + let connector; + + const wallets = provider.getWallets() + const [wallet0, wallet1, wallet2, wallet3] = wallets + before(async () => { + await hre.network.provider.request({ + method: "hardhat_reset", + params: [ + { + forking: { + jsonRpcUrl: hre.config.networks.hardhat.forking.url, + blockNumber: 13005785, + }, + }, + ], + }); + masterSigner = await getMasterSigner(wallet3) + instaConnectorsV2 = await ethers.getContractAt(abis.core.connectorsV2, addresses.core.connectorsV2); + connector = await deployAndEnableConnector({ + connectorName, + contractArtifact: connectV2SushiswapArtifacts, + 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(!!masterSigner.address).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 ETH & 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("100000")); + }); + + it("Deposit ETH & 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("100000")); + }); + }); + + describe("Main", function () { + + it("Should deposit successfully", async function () { + const ethAmount = ethers.utils.parseEther("0.1") // 1 ETH + const daiUnitAmount = ethers.utils.parseEther("4000") // 1 ETH + const usdtAmount = ethers.utils.parseEther("400") / Math.pow(10, 12) // 1 ETH + const ethAddress = "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee" + + const getId = "0" + const setId = "0" + + const spells = [ + { + connector: connectorName, + method: "deposit", + args: [ + ethAddress, + DAI_ADDR, + ethAmount, + daiUnitAmount, + "500000000000000000", + getId, + setId + ], + } + ] + + const tx = await dsaWallet0.connect(wallet0).cast(...encodeSpells(spells), wallet1.address) + let receipt = await tx.wait() + // let castEvent = new Promise((resolve, reject) => { + // dsaWallet0.on('LogCast', (origin, sender, value, targetNames, targets, eventNames, eventParams, event) => { + // const params = abiCoder.decode(["uint256", "uint256", "uint256", "uint256", "int24", "int24"], eventParams[0]); + // const params1 = abiCoder.decode(["uint256", "uint256", "uint256", "uint256", "int24", "int24"], eventParams[2]); + // tokenIds.push(params[0]); + // tokenIds.push(params1[0]); + // liquidities.push(params[1]); + // event.removeListener(); + + // resolve({ + // eventNames, + // }); + // }); + + // setTimeout(() => { + // reject(new Error('timeout')); + // }, 60000) + // }); + + // let event = await castEvent + + // const data = await nftManager.positions(tokenIds[0]) + + // expect(data.liquidity).to.be.equals(liquidities[0]); + }).timeout(10000000000); + + it("Should withdraw successfully", async function () { + const ethAmount = ethers.utils.parseEther("0.1") // 1 ETH + const ethAddress = "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee" + + const getId = "0" + const setIds = ["0", "0"] + + const spells = [ + { + connector: connectorName, + method: "withdraw", + args: [ + ethAddress, + DAI_ADDR, + ethAmount, + 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 ethAmount = ethers.utils.parseEther("0.1") // 1 ETH + const daiUnitAmount = ethers.utils.parseEther("4000") // 1 ETH + const ethAddress = "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee" + + const getId = "0" + const setId = "0" + + const spells = [ + { + connector: connectorName, + method: "buy", + args: [ + ethAddress, + DAI_ADDR, + ethAmount, + daiUnitAmount, + getId, + setId + ] + } + ] + + const tx = await dsaWallet0.connect(wallet0).cast(...encodeSpells(spells), wallet1.address) + let receipt = await tx.wait() + }); + }); +}) \ No newline at end of file From 650009f45e5882b6eed3d3ef37f9a3f90addb2c8 Mon Sep 17 00:00:00 2001 From: cryptoDev222 Date: Fri, 22 Oct 2021 09:29:32 -0500 Subject: [PATCH 02/15] feat/implement sushiswap double incentive --- contracts/mainnet/common/interfaces.sol | 1 + .../connectors/sushi-incentive/events.sol | 36 +++ .../connectors/sushi-incentive/helpers.sol | 88 +++++++ .../connectors/sushi-incentive/interface.sol | 94 +++++++ .../connectors/sushi-incentive/main.sol | 146 +++++++++++ hardhat.config.js | 90 +++++++ test/sushiswap/sushiswap.test.js | 51 +--- .../sushiswapIncentive/sushiIncentive.test.js | 237 ++++++++++++++++++ 8 files changed, 694 insertions(+), 49 deletions(-) create mode 100644 contracts/mainnet/connectors/sushi-incentive/events.sol create mode 100644 contracts/mainnet/connectors/sushi-incentive/helpers.sol create mode 100644 contracts/mainnet/connectors/sushi-incentive/interface.sol create mode 100644 contracts/mainnet/connectors/sushi-incentive/main.sol create mode 100644 hardhat.config.js create mode 100644 test/sushiswapIncentive/sushiIncentive.test.js diff --git a/contracts/mainnet/common/interfaces.sol b/contracts/mainnet/common/interfaces.sol index 24a4eb47..53e848d3 100644 --- a/contracts/mainnet/common/interfaces.sol +++ b/contracts/mainnet/common/interfaces.sol @@ -8,6 +8,7 @@ interface TokenInterface { function withdraw(uint) external; function balanceOf(address) external view returns (uint); function decimals() external view returns (uint); + function totalSupply() external view returns (uint); } interface MemoryInterface { diff --git a/contracts/mainnet/connectors/sushi-incentive/events.sol b/contracts/mainnet/connectors/sushi-incentive/events.sol new file mode 100644 index 00000000..ebf68ebd --- /dev/null +++ b/contracts/mainnet/connectors/sushi-incentive/events.sol @@ -0,0 +1,36 @@ +pragma solidity ^0.7.0; + +contract Events { + event LogDeposit( + address indexed user, + uint256 indexed pid, + uint256 indexed version, + uint256 amount + ); + event LogWithdraw( + address indexed user, + uint256 indexed pid, + uint256 indexed version, + uint256 amount + ); + event LogEmergencyWithdraw( + address indexed user, + uint256 indexed pid, + uint256 indexed version, + uint256 lpAmount, + uint256 rewardsAmount + ); + event LogHarvest( + address indexed user, + uint256 indexed pid, + uint256 indexed version, + uint256 amount + ); + event LogWithdrawAndHarvest( + address indexed user, + uint256 indexed pid, + uint256 indexed version, + uint256 widrawAmount, + uint256 harvestAmount + ); +} diff --git a/contracts/mainnet/connectors/sushi-incentive/helpers.sol b/contracts/mainnet/connectors/sushi-incentive/helpers.sol new file mode 100644 index 00000000..97522f22 --- /dev/null +++ b/contracts/mainnet/connectors/sushi-incentive/helpers.sol @@ -0,0 +1,88 @@ +// SPDX-License-Identifier: MIT + +pragma solidity ^0.7.0; +pragma experimental ABIEncoderV2; + +import {DSMath} from "../../common/math.sol"; +import {Basic} from "../../common/basic.sol"; +import "./interface.sol"; + +contract Helpers is DSMath, Basic { + IMasterChefV2 immutable masterChefV2 = + IMasterChefV2(0xEF0881eC094552b2e128Cf945EF17a6752B4Ec5d); + IMasterChef immutable masterChef = + IMasterChef(0xc2EdaD668740f1aA35E4D8f227fB8E17dcA888Cd); + ISushiSwapFactory immutable factory = + ISushiSwapFactory(0xC0AEe478e3658e2610c5F7A4A2E1777cE9e4f2Ac); + + function _deposit(uint256 _pid, uint256 _amount, uint256 _version) internal { + if(_version == 2) + masterChefV2.deposit(_pid, _amount, address(this)); + else + masterChef.deposit(_pid, _amount); + } + + function _withdraw(uint256 _pid, uint256 _amount, uint256 _version) internal { + if(_version == 2) + masterChefV2.withdraw(_pid, _amount, address(this)); + else + masterChef.withdraw(_pid, _amount); + } + + function _harvest(uint256 _pid) internal { + masterChefV2.harvest(_pid, address(this)); + } + + function _withdrawAndHarvest(uint256 _pid, uint256 _amount, uint256 _version) internal { + if(_version == 2) + masterChefV2.withdrawAndHarvest(_pid, _amount, address(this)); + else _withdraw(_pid, _amount, _version); + } + + function _emergencyWithdraw(uint256 _pid, uint256 _version) internal { + if(_version == 2) + masterChefV2.emergencyWithdraw(_pid, address(this)); + else + masterChef.emergencyWithdraw(_pid, address(this)); + } + + function _getPoolId(address tokenA, address tokenB) + internal + view + returns (uint256 poolId, uint256 version, address lpToken) + { + address pair = factory.getPair(tokenA, tokenB); + uint256 length = masterChefV2.poolLength(); + version = 2; + poolId = uint256(-1); + + for (uint256 i = 0; i < length; i++) { + lpToken = masterChefV2.lpToken(i); + if (pair == lpToken) { + poolId = i; + break; + } + } + + uint256 lengthV1 = masterChef.poolLength(); + for (uint256 i = 0; i < lengthV1; i++) { + (lpToken, , , ) = masterChef.poolInfo(i); + if (pair == lpToken) { + poolId = i; + version = 1; + break; + } + } + } + + function _getUserInfo(uint256 _pid, uint256 _version) + internal + view + returns (uint256 lpAmount, uint256 rewardsAmount) + { + if(_version == 2) + (lpAmount, rewardsAmount) = masterChefV2.userInfo(_pid, address(this)); + else + (lpAmount, rewardsAmount) = masterChef.userInfo(_pid, address(this)); + } +} diff --git a/contracts/mainnet/connectors/sushi-incentive/interface.sol b/contracts/mainnet/connectors/sushi-incentive/interface.sol new file mode 100644 index 00000000..865ec361 --- /dev/null +++ b/contracts/mainnet/connectors/sushi-incentive/interface.sol @@ -0,0 +1,94 @@ +pragma solidity ^0.7.0; +pragma experimental ABIEncoderV2; +import "./libraries/IERC20.sol"; + +struct UserInfo { + uint256 amount; + uint256 rewardDebt; +} + +struct PoolInfo { + IERC20 lpToken; // Address of LP token contract. + uint256 allocPoint; // How many allocation points assigned to this pool. SUSHIs to distribute per block. + uint256 lastRewardBlock; // Last block number that SUSHIs distribution occurs. + uint256 accSushiPerShare; // Accumulated SUSHIs per share, times 1e12. See below. +} + +interface IMasterChef { + function poolLength() external view returns (uint256); + + function updatePool(uint256 pid) external returns (PoolInfo memory); + + function poolInfo(uint256 pid) external view returns (address, uint256, uint256, uint256); + + function userInfo(uint256 _pid, address _user) + external + view + returns (uint256, uint256); + + function deposit( + uint256 pid, + uint256 amount + ) external; + + function withdraw( + uint256 pid, + uint256 amount + ) external; + + function emergencyWithdraw(uint256 pid, address to) external; +} + +interface IMasterChefV2 { + function poolLength() external view returns (uint256); + + function updatePool(uint256 pid) external returns (PoolInfo memory); + + function lpToken(uint256 pid) external view returns (address); + + function userInfo(uint256 _pid, address _user) + external + view + returns (uint256, uint256); + + function deposit( + uint256 pid, + uint256 amount, + address to + ) external; + + function withdraw( + uint256 pid, + uint256 amount, + address to + ) external; + + function emergencyWithdraw(uint256 pid, address to) external; + + function harvest(uint256 pid, address to) external; + + function withdrawAndHarvest( + uint256 pid, + uint256 amount, + address to + ) external; +} + +interface ISushiSwapFactory { + function getPair(address tokenA, address tokenB) + external + view + returns (address pair); + + function allPairs(uint256) external view returns (address pair); + + function allPairsLength() external view returns (uint256); + + 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/mainnet/connectors/sushi-incentive/main.sol b/contracts/mainnet/connectors/sushi-incentive/main.sol new file mode 100644 index 00000000..a60e6940 --- /dev/null +++ b/contracts/mainnet/connectors/sushi-incentive/main.sol @@ -0,0 +1,146 @@ +pragma solidity ^0.7.0; +pragma experimental ABIEncoderV2; + +/** + * @title SushiSwap Double Incentive. + * @dev Decentralized Exchange. + */ + +import {TokenInterface} from "../../common/interfaces.sol"; +import {Helpers} from "./helpers.sol"; +import {Events} from "./events.sol"; + +abstract contract SushipswapIncentiveResolver is Helpers, Events { + /** + * @dev deposit LP token to masterChef + * @param token1 token1 of LP token + * @param token2 token2 of LP token + * @param amount amount of LP token + * @param getId ID to retrieve amount + * @param setId ID stores Pool ID + */ + function deposit( + address token1, + address token2, + uint256 amount, + uint256 getId, + uint256 setId + ) external { + amount = getUint(getId, amount); + (uint256 _pid, uint256 _version, address lpTokenAddr) = _getPoolId( + token1, + token2 + ); + setUint(setId, _pid); + require(_pid != uint256(-1), "pool-does-not-exist"); + TokenInterface lpToken = TokenInterface(lpTokenAddr); + lpToken.approve(address(masterChef), amount); + _deposit(_pid, amount, _version); + emit LogDeposit(address(this), _pid, _version, amount); + } + + /** + * @dev withdraw LP token from masterChef + * @param token1 token1 of LP token + * @param token2 token2 of LP token + * @param amount amount of LP token + * @param getId ID to retrieve amount + * @param setId ID stores Pool ID + */ + function withdraw( + address token1, + address token2, + uint256 amount, + uint256 getId, + uint256 setId + ) external { + amount = getUint(getId, amount); + (uint256 _pid, uint256 _version, ) = _getPoolId(token1, token2); + setUint(setId, _pid); + require(_pid != uint256(-1), "pool-does-not-exist"); + _withdraw(_pid, amount, _version); + emit LogWithdraw(address(this), _pid, _version, amount); + } + + /** + * @dev harvest from masterChef + * @param token1 token1 deposited of LP token + * @param token2 token2 deposited LP token + * @param setId ID stores Pool ID + */ + function harvest( + address token1, + address token2, + uint256 setId + ) external { + (uint256 _pid, uint256 _version, ) = _getPoolId(token1, token2); + setUint(setId, _pid); + require(_pid != uint256(-1), "pool-does-not-exist"); + (, uint256 rewardsAmount) = _getUserInfo(_pid, _version); + if (_version == 2) _harvest(_pid); + else _withdraw(_pid, 0, _version); + emit LogHarvest(address(this), _pid, _version, rewardsAmount); + } + + /** + * @dev withdraw LP token and harvest from masterChef + * @param token1 token1 of LP token + * @param token2 token2 of LP token + * @param amount amount of LP token + * @param getId ID to retrieve amount + * @param setId ID stores Pool ID + */ + function withdrawAndHarvest( + address token1, + address token2, + uint256 amount, + uint256 getId, + uint256 setId + ) external { + amount = getUint(getId, amount); + (uint256 _pid, uint256 _version, ) = _getPoolId(token1, token2); + setUint(setId, _pid); + require(_pid != uint256(-1), "pool-does-not-exist"); + (, uint256 rewardsAmount) = _getUserInfo(_pid, _version); + _withdrawAndHarvest(_pid, amount, _version); + emit LogWithdrawAndHarvest( + address(this), + _pid, + _version, + amount, + rewardsAmount + ); + } + + /** + * @dev emergency withdraw from masterChef + * @param token1 token1 deposited of LP token + * @param token2 token2 deposited LP token + * @param setId ID stores Pool ID + */ + function emergencyWithdraw( + address token1, + address token2, + uint256 setId + ) external { + (uint256 _pid, uint256 _version, ) = _getPoolId(token1, token2); + setUint(setId, _pid); + require(_pid != uint256(-1), "pool-does-not-exist"); + (uint256 lpAmount, uint256 rewardsAmount) = _getUserInfo( + _pid, + _version + ); + _emergencyWithdraw(_pid, _version); + emit LogEmergencyWithdraw( + address(this), + _pid, + _version, + lpAmount, + rewardsAmount + ); + } +} + +contract ConnectV2SushiswapIncentive is SushipswapIncentiveResolver { + string public constant name = "SushipswapIncentive-v1.1"; +} diff --git a/hardhat.config.js b/hardhat.config.js new file mode 100644 index 00000000..7d88c978 --- /dev/null +++ b/hardhat.config.js @@ -0,0 +1,90 @@ +require("@nomiclabs/hardhat-waffle"); +require("@nomiclabs/hardhat-ethers"); +require("@tenderly/hardhat-tenderly"); +require("@nomiclabs/hardhat-etherscan"); +require("@nomiclabs/hardhat-web3"); +require("hardhat-deploy"); +require("hardhat-deploy-ethers"); +require("dotenv").config(); + +const { utils } = require("ethers"); + +const PRIVATE_KEY = process.env.PRIVATE_KEY; +const ALCHEMY_ID = process.env.ALCHEMY_ID; +const ETHERSCAN_API_KEY = process.env.ETHERSCAN_API_KEY; + +if (!process.env.ALCHEMY_ID) { + throw new Error("ENV Variable ALCHEMY_ID not set!"); +} + +/** + * @type import('hardhat/config').HardhatUserConfig + */ +module.exports = { + solidity: { + compilers: [ + { + version: "0.7.6", + settings: { + optimizer: { + enabled: true, + runs: 200, + }, + }, + }, + { + version: "0.6.0", + }, + { + version: "0.6.2", + }, + { + version: "0.6.12", + }, + { + version: "0.6.5", + }, + ], + }, + networks: { + // defaultNetwork: "hardhat", + kovan: { + url: `https://eth-kovan.alchemyapi.io/v2/${ALCHEMY_ID}`, + accounts: [`0x${PRIVATE_KEY}`], + }, + mainnet: { + url: `https://eth-mainnet.alchemyapi.io/v2/${ALCHEMY_ID}`, + accounts: [`0x${PRIVATE_KEY}`], + timeout: 150000, + gasPrice: parseInt(utils.parseUnits("30", "gwei")), + }, + rinkeby: { + url: `https://eth-rinkeby.alchemyapi.io/v2/${ALCHEMY_ID}`, + accounts: [`0x${PRIVATE_KEY}`], + timeout: 150000, + }, + hardhat: { + forking: { + url: `https://eth-mainnet.alchemyapi.io/v2/${ALCHEMY_ID}`, + blockNumber: 12696000, + }, + blockGasLimit: 12000000, + }, + matic: { + url: "https://rpc-mainnet.maticvigil.com/", + accounts: [`0x${PRIVATE_KEY}`], + timeout: 150000, + gasPrice: parseInt(utils.parseUnits("1", "gwei")), + }, + }, + etherscan: { + apiKey: ETHERSCAN_API_KEY, + }, + tenderly: { + project: process.env.TENDERLY_PROJECT, + username: process.env.TENDERLY_USERNAME, + }, + mocha: { + timeout: 100 * 1000, + }, +}; \ No newline at end of file diff --git a/test/sushiswap/sushiswap.test.js b/test/sushiswap/sushiswap.test.js index ead9dfd3..baaf3876 100644 --- a/test/sushiswap/sushiswap.test.js +++ b/test/sushiswap/sushiswap.test.js @@ -1,44 +1,21 @@ const { expect } = require("chai"); const hre = require("hardhat"); -const { web3, deployments, waffle, ethers } = hre; -const { provider, deployContract } = waffle +const { waffle, ethers } = hre; +const { provider } = waffle const deployAndEnableConnector = require("../../scripts/deployAndEnableConnector.js") const buildDSAv2 = require("../../scripts/buildDSAv2") const encodeSpells = require("../../scripts/encodeSpells.js") -const encodeFlashcastData = require("../../scripts/encodeFlashcastData.js") const getMasterSigner = require("../../scripts/getMasterSigner") const addLiquidity = require("../../scripts/addLiquidity"); const addresses = require("../../scripts/constant/addresses"); const abis = require("../../scripts/constant/abis"); -const constants = require("../../scripts/constant/constant"); -const tokens = require("../../scripts/constant/tokens"); -const { abi: nftManagerAbi } = require("@uniswap/v3-periphery/artifacts/contracts/NonfungiblePositionManager.sol/NonfungiblePositionManager.json") const connectV2SushiswapArtifacts = require("../../artifacts/contracts/mainnet/connectors/sushiswap/main.sol/ConnectV2Sushiswap.json"); -const { eth } = require("../../scripts/constant/tokens"); -const { BigNumber } = require("ethers"); -const FeeAmount = { - LOW: 500, - MEDIUM: 3000, - HIGH: 10000, -} - -const TICK_SPACINGS = { - 500: 10, - 3000: 60, - 10000: 200 -} - -const USDT_ADDR = "0xdac17f958d2ee523a2206206994597c13d831ec7" const DAI_ADDR = "0x6b175474e89094c44da98b954eedeac495271d0f" -let tokenIds = [] -let liquidities = [] -const abiCoder = ethers.utils.defaultAbiCoder - describe("Sushiswap", function () { const connectorName = "Sushiswap-v1" @@ -134,30 +111,6 @@ describe("Sushiswap", function () { const tx = await dsaWallet0.connect(wallet0).cast(...encodeSpells(spells), wallet1.address) let receipt = await tx.wait() - // let castEvent = new Promise((resolve, reject) => { - // dsaWallet0.on('LogCast', (origin, sender, value, targetNames, targets, eventNames, eventParams, event) => { - // const params = abiCoder.decode(["uint256", "uint256", "uint256", "uint256", "int24", "int24"], eventParams[0]); - // const params1 = abiCoder.decode(["uint256", "uint256", "uint256", "uint256", "int24", "int24"], eventParams[2]); - // tokenIds.push(params[0]); - // tokenIds.push(params1[0]); - // liquidities.push(params[1]); - // event.removeListener(); - - // resolve({ - // eventNames, - // }); - // }); - - // setTimeout(() => { - // reject(new Error('timeout')); - // }, 60000) - // }); - - // let event = await castEvent - - // const data = await nftManager.positions(tokenIds[0]) - - // expect(data.liquidity).to.be.equals(liquidities[0]); }).timeout(10000000000); it("Should withdraw successfully", async function () { diff --git a/test/sushiswapIncentive/sushiIncentive.test.js b/test/sushiswapIncentive/sushiIncentive.test.js new file mode 100644 index 00000000..1b2fd01b --- /dev/null +++ b/test/sushiswapIncentive/sushiIncentive.test.js @@ -0,0 +1,237 @@ +const { expect } = require("chai"); +const hre = require("hardhat"); +const { waffle, ethers } = hre; +const { provider } = waffle + +const deployAndEnableConnector = require("../../scripts/deployAndEnableConnector.js") +const buildDSAv2 = require("../../scripts/buildDSAv2") +const encodeSpells = require("../../scripts/encodeSpells.js") +const getMasterSigner = require("../../scripts/getMasterSigner") +const addLiquidity = require("../../scripts/addLiquidity"); + +const addresses = require("../../scripts/constant/addresses"); +const abis = require("../../scripts/constant/abis"); + +const connectV2SushiswapArtifacts = require("../../artifacts/contracts/mainnet/connectors/sushiswap/main.sol/ConnectV2Sushiswap.json"); +const connectV2SushiswapIncentiveArtifacts = require("../../artifacts/contracts/mainnet/connectors/sushi-incentive/main.sol/ConnectV2SushiswapIncentive.json"); + +const DAI_ADDR = "0x6b175474e89094c44da98b954eedeac495271d0f" +const WETH_ADDR = "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2" + +describe("Sushiswap", function () { + const connectorName = "Sushiswap-v1" + const incentiveConnectorName = "Sushiswp-Incentive-v1" + + let dsaWallet0 + let masterSigner; + let instaConnectorsV2; + let connector, connectorIncentive; + + const wallets = provider.getWallets() + const [wallet0, wallet1, wallet2, wallet3] = wallets + before(async () => { + await hre.network.provider.request({ + method: "hardhat_reset", + params: [ + { + forking: { + jsonRpcUrl: hre.config.networks.hardhat.forking.url, + blockNumber: 13005785, + }, + }, + ], + }); + masterSigner = await getMasterSigner(wallet3) + instaConnectorsV2 = await ethers.getContractAt(abis.core.connectorsV2, addresses.core.connectorsV2); + connector = await deployAndEnableConnector({ + connectorName, + contractArtifact: connectV2SushiswapArtifacts, + signer: masterSigner, + connectors: instaConnectorsV2 + }) + console.log("Connector address", connector.address) + + connectorIncentive = await deployAndEnableConnector({ + connectorName: incentiveConnectorName, + contractArtifact: connectV2SushiswapIncentiveArtifacts, + signer: masterSigner, + connectors: instaConnectorsV2 + }) + console.log("Incentive Connector address", connectorIncentive.address) + }) + + it("Should have contracts deployed.", async function () { + expect(!!instaConnectorsV2.address).to.be.true; + expect(!!connector.address).to.be.true; + expect(!!masterSigner.address).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 ETH & 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("100000")); + }); + + it("Deposit ETH & 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("100000")); + }); + }); + + describe("Main", function () { + + it("Should deposit successfully", async function () { + const ethAmount = ethers.utils.parseEther("2") // 1 ETH + const daiUnitAmount = ethers.utils.parseEther("4000") // 1 ETH + const usdtAmount = ethers.utils.parseEther("400") / Math.pow(10, 12) // 1 ETH + const ethAddress = "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee" + + const getId = "0" + const setId = "0" + + const spells = [ + { + connector: connectorName, + method: "deposit", + args: [ + ethAddress, + DAI_ADDR, + ethAmount, + daiUnitAmount, + "500000000000000000", + getId, + setId + ], + } + ] + + const tx = await dsaWallet0.connect(wallet0).cast(...encodeSpells(spells), wallet1.address) + await tx.wait() + + describe("Incentive", () => { + it("Should deposit successfully", async () => { + const getId = 0 + const setId = 0 + const spells = [ + { + connector: incentiveConnectorName, + method: "deposit", + args: [ + WETH_ADDR, + DAI_ADDR, + ethers.utils.parseEther("10"), + getId, + setId + ] + } + ] + + const tx = await dsaWallet0.connect(wallet0).cast(...encodeSpells(spells), wallet0.address) + await tx.wait(); + }) + + it("Should harvest successfully", async () => { + const setId = 0 + const spells = [ + { + connector: incentiveConnectorName, + method: "harvest", + args: [ + WETH_ADDR, + DAI_ADDR, + setId + ] + } + ] + + const tx = await dsaWallet0.connect(wallet0).cast(...encodeSpells(spells), wallet0.address) + await tx.wait(); + }) + + it("Should harvest and withdraw successfully", async () => { + const getId = 0 + const setId = 0 + const spells = [ + { + connector: incentiveConnectorName, + method: "withdrawAndHarvest", + args: [ + WETH_ADDR, + DAI_ADDR, + ethers.utils.parseEther("1"), + getId, + setId + ] + } + ] + + const tx = await dsaWallet0.connect(wallet0).cast(...encodeSpells(spells), wallet0.address) + await tx.wait(); + }) + + it("Should withdraw successfully", async () => { + const getId = 0 + const setId = 0 + const spells = [ + { + connector: incentiveConnectorName, + method: "withdraw", + args: [ + WETH_ADDR, + DAI_ADDR, + ethers.utils.parseEther("1"), + getId, + setId + ] + } + ] + + const tx = await dsaWallet0.connect(wallet0).cast(...encodeSpells(spells), wallet0.address) + await tx.wait(); + }) + }) + }).timeout(10000000000); + + it("Should buy successfully", async function () { + const ethAmount = ethers.utils.parseEther("0.1") // 1 ETH + const daiUnitAmount = ethers.utils.parseEther("4000") // 1 ETH + const ethAddress = "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee" + + const getId = "0" + const setId = "0" + + const spells = [ + { + connector: connectorName, + method: "buy", + args: [ + ethAddress, + DAI_ADDR, + ethAmount, + daiUnitAmount, + getId, + setId + ] + } + ] + + const tx = await dsaWallet0.connect(wallet0).cast(...encodeSpells(spells), wallet1.address) + let receipt = await tx.wait() + }); + }); +}) \ No newline at end of file From 627e839c70a676ff67f31d2a31a9661d59985c69 Mon Sep 17 00:00:00 2001 From: cryptoDev222 Date: Mon, 15 Nov 2021 08:58:14 -0600 Subject: [PATCH 03/15] minor fixes --- contracts/mainnet/common/basic.sol | 4 ++ .../connectors/sushi-incentive/events.sol | 5 -- .../connectors/sushi-incentive/interface.sol | 25 ++++++- .../connectors/sushi-incentive/main.sol | 72 +++++++++++++------ 4 files changed, 78 insertions(+), 28 deletions(-) diff --git a/contracts/mainnet/common/basic.sol b/contracts/mainnet/common/basic.sol index febeb784..c0650dfb 100644 --- a/contracts/mainnet/common/basic.sol +++ b/contracts/mainnet/common/basic.sol @@ -41,6 +41,10 @@ abstract contract Basic is DSMath, Stores { _sell = sell == ethAddr ? TokenInterface(wethAddr) : TokenInterface(sell); } + function changeEthAddrToWethAddr(address token) internal pure returns(address tokenAddr){ + tokenAddr = token == ethAddr ? wethAddr : token; + } + function convertEthToWeth(bool isEth, TokenInterface token, uint amount) internal { if(isEth) token.deposit{value: amount}(); } diff --git a/contracts/mainnet/connectors/sushi-incentive/events.sol b/contracts/mainnet/connectors/sushi-incentive/events.sol index ebf68ebd..aa1c890d 100644 --- a/contracts/mainnet/connectors/sushi-incentive/events.sol +++ b/contracts/mainnet/connectors/sushi-incentive/events.sol @@ -2,32 +2,27 @@ pragma solidity ^0.7.0; contract Events { event LogDeposit( - address indexed user, uint256 indexed pid, uint256 indexed version, uint256 amount ); event LogWithdraw( - address indexed user, uint256 indexed pid, uint256 indexed version, uint256 amount ); event LogEmergencyWithdraw( - address indexed user, uint256 indexed pid, uint256 indexed version, uint256 lpAmount, uint256 rewardsAmount ); event LogHarvest( - address indexed user, uint256 indexed pid, uint256 indexed version, uint256 amount ); event LogWithdrawAndHarvest( - address indexed user, uint256 indexed pid, uint256 indexed version, uint256 widrawAmount, diff --git a/contracts/mainnet/connectors/sushi-incentive/interface.sol b/contracts/mainnet/connectors/sushi-incentive/interface.sol index 865ec361..ba3b1c6c 100644 --- a/contracts/mainnet/connectors/sushi-incentive/interface.sol +++ b/contracts/mainnet/connectors/sushi-incentive/interface.sol @@ -1,6 +1,5 @@ pragma solidity ^0.7.0; pragma experimental ABIEncoderV2; -import "./libraries/IERC20.sol"; struct UserInfo { uint256 amount; @@ -14,6 +13,30 @@ struct PoolInfo { uint256 accSushiPerShare; // Accumulated SUSHIs per share, times 1e12. See below. } +interface IERC20 { + function totalSupply() external view returns (uint256); + + function balanceOf(address account) external view returns (uint256); + + function allowance(address owner, address spender) external view returns (uint256); + + function approve(address spender, uint256 amount) external returns (bool); + + event Transfer(address indexed from, address indexed to, uint256 value); + event Approval(address indexed owner, address indexed spender, uint256 value); + + /// @notice EIP 2612 + function permit( + address owner, + address spender, + uint256 value, + uint256 deadline, + uint8 v, + bytes32 r, + bytes32 s + ) external; +} + interface IMasterChef { function poolLength() external view returns (uint256); diff --git a/contracts/mainnet/connectors/sushi-incentive/main.sol b/contracts/mainnet/connectors/sushi-incentive/main.sol index a60e6940..cc448434 100644 --- a/contracts/mainnet/connectors/sushi-incentive/main.sol +++ b/contracts/mainnet/connectors/sushi-incentive/main.sol @@ -13,6 +13,7 @@ import {Events} from "./events.sol"; abstract contract SushipswapIncentiveResolver is Helpers, Events { /** * @dev deposit LP token to masterChef + * @notice deposit LP token to masterChef * @param token1 token1 of LP token * @param token2 token2 of LP token * @param amount amount of LP token @@ -25,7 +26,13 @@ abstract contract SushipswapIncentiveResolver is Helpers, Events { uint256 amount, uint256 getId, uint256 setId - ) external { + ) + external + payable + returns (string memory _eventName, bytes memory _eventParam) + { + token1 = changeEthAddrToWethAddr(token1); + token2 = changeEthAddrToWethAddr(token2); amount = getUint(getId, amount); (uint256 _pid, uint256 _version, address lpTokenAddr) = _getPoolId( token1, @@ -36,11 +43,13 @@ abstract contract SushipswapIncentiveResolver is Helpers, Events { TokenInterface lpToken = TokenInterface(lpTokenAddr); lpToken.approve(address(masterChef), amount); _deposit(_pid, amount, _version); - emit LogDeposit(address(this), _pid, _version, amount); + _eventName = "LogDeposit(uint256,uint256,uint256)"; + _eventParam = abi.encode(_pid, _version, amount); } /** * @dev withdraw LP token from masterChef + * @notice withdraw LP token from masterChef * @param token1 token1 of LP token * @param token2 token2 of LP token * @param amount amount of LP token @@ -53,17 +62,25 @@ abstract contract SushipswapIncentiveResolver is Helpers, Events { uint256 amount, uint256 getId, uint256 setId - ) external { + ) + external + payable + returns (string memory _eventName, bytes memory _eventParam) + { + token1 = changeEthAddrToWethAddr(token1); + token2 = changeEthAddrToWethAddr(token2); amount = getUint(getId, amount); (uint256 _pid, uint256 _version, ) = _getPoolId(token1, token2); setUint(setId, _pid); require(_pid != uint256(-1), "pool-does-not-exist"); _withdraw(_pid, amount, _version); - emit LogWithdraw(address(this), _pid, _version, amount); + _eventName = "LogWithdraw(uint256,uint256,uint256)"; + _eventParam = abi.encode(_pid, _version, amount); } /** * @dev harvest from masterChef + * @notice harvest from masterChef * @param token1 token1 deposited of LP token * @param token2 token2 deposited LP token * @param setId ID stores Pool ID @@ -72,18 +89,26 @@ abstract contract SushipswapIncentiveResolver is Helpers, Events { address token1, address token2, uint256 setId - ) external { + ) + external + payable + returns (string memory _eventName, bytes memory _eventParam) + { + token1 = changeEthAddrToWethAddr(token1); + token2 = changeEthAddrToWethAddr(token2); (uint256 _pid, uint256 _version, ) = _getPoolId(token1, token2); setUint(setId, _pid); require(_pid != uint256(-1), "pool-does-not-exist"); (, uint256 rewardsAmount) = _getUserInfo(_pid, _version); if (_version == 2) _harvest(_pid); else _withdraw(_pid, 0, _version); - emit LogHarvest(address(this), _pid, _version, rewardsAmount); + _eventName = "LogHarvest(uint256,uint256,uint256)"; + _eventParam = abi.encode(_pid, _version, rewardsAmount); } /** * @dev withdraw LP token and harvest from masterChef + * @notice withdraw LP token and harvest from masterChef * @param token1 token1 of LP token * @param token2 token2 of LP token * @param amount amount of LP token @@ -96,24 +121,26 @@ abstract contract SushipswapIncentiveResolver is Helpers, Events { uint256 amount, uint256 getId, uint256 setId - ) external { + ) + external + payable + returns (string memory _eventName, bytes memory _eventParam) + { + token1 = changeEthAddrToWethAddr(token1); + token2 = changeEthAddrToWethAddr(token2); amount = getUint(getId, amount); (uint256 _pid, uint256 _version, ) = _getPoolId(token1, token2); setUint(setId, _pid); require(_pid != uint256(-1), "pool-does-not-exist"); (, uint256 rewardsAmount) = _getUserInfo(_pid, _version); _withdrawAndHarvest(_pid, amount, _version); - emit LogWithdrawAndHarvest( - address(this), - _pid, - _version, - amount, - rewardsAmount - ); + _eventName = "LogWithdrawAndHarvest(uint256,uint256,uint256,uint256)"; + _eventParam = abi.encode(_pid, _version, amount, rewardsAmount); } /** * @dev emergency withdraw from masterChef + * @notice emergency withdraw from masterChef * @param token1 token1 deposited of LP token * @param token2 token2 deposited LP token * @param setId ID stores Pool ID @@ -122,7 +149,13 @@ abstract contract SushipswapIncentiveResolver is Helpers, Events { address token1, address token2, uint256 setId - ) external { + ) + external + payable + returns (string memory _eventName, bytes memory _eventParam) + { + token1 = changeEthAddrToWethAddr(token1); + token2 = changeEthAddrToWethAddr(token2); (uint256 _pid, uint256 _version, ) = _getPoolId(token1, token2); setUint(setId, _pid); require(_pid != uint256(-1), "pool-does-not-exist"); @@ -131,13 +164,8 @@ abstract contract SushipswapIncentiveResolver is Helpers, Events { _version ); _emergencyWithdraw(_pid, _version); - emit LogEmergencyWithdraw( - address(this), - _pid, - _version, - lpAmount, - rewardsAmount - ); + _eventName = "LogEmergencyWithdraw(uint256,uint256,uint256,uint256)"; + _eventParam = abi.encode(_pid, _version, lpAmount, rewardsAmount); } } From d7b69b4d875d0d7a46e0926c8f6bb9803ad11156 Mon Sep 17 00:00:00 2001 From: cryptoDev222 Date: Mon, 15 Nov 2021 09:00:46 -0600 Subject: [PATCH 04/15] implement quickswap --- .../polygon/connectors/quickswap/events.sol | 41 ++++ .../polygon/connectors/quickswap/helpers.sol | 184 ++++++++++++++++ .../connectors/quickswap/interface.sol | 57 +++++ .../polygon/connectors/quickswap/main.sol | 196 ++++++++++++++++++ 4 files changed, 478 insertions(+) create mode 100644 contracts/polygon/connectors/quickswap/events.sol create mode 100644 contracts/polygon/connectors/quickswap/helpers.sol create mode 100644 contracts/polygon/connectors/quickswap/interface.sol create mode 100644 contracts/polygon/connectors/quickswap/main.sol diff --git a/contracts/polygon/connectors/quickswap/events.sol b/contracts/polygon/connectors/quickswap/events.sol new file mode 100644 index 00000000..2717b0a3 --- /dev/null +++ b/contracts/polygon/connectors/quickswap/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/quickswap/helpers.sol b/contracts/polygon/connectors/quickswap/helpers.sol new file mode 100644 index 00000000..2199cfb6 --- /dev/null +++ b/contracts/polygon/connectors/quickswap/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 {IQuickSwapRouter, IQuickSwapFactory} from "./interface.sol"; + +abstract contract Helpers is DSMath, Basic { + /** + * @dev IQuickSwapRouter + */ + IQuickSwapRouter internal constant router = + IQuickSwapRouter(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 = IQuickSwapFactory(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) = changeMaticAddress( + tokenA, + tokenB + ); + + _amtA = _amt == uint256(-1) + ? getTokenBal(TokenInterface(tokenA)) + : _amt; + _amtB = convert18ToDec( + _tokenB.decimals(), + wmul(unitAmt, convertTo18(_tokenA.decimals(), _amtA)) + ); + + bool isMatic = address(_tokenA) == wmaticAddr; + convertMaticToWmatic(isMatic, _tokenA, _amtA); + + isMatic = address(_tokenB) == wmaticAddr; + convertMaticToWmatic(isMatic, _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, + minAmtA, + 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 isMatic = address(_tokenA) == wmaticAddr; + convertWmaticToMatic(isMatic, _tokenA, _amtA); + + isMatic = address(_tokenB) == wmaticAddr; + convertWmaticToMatic(isMatic, _tokenB, _amtB); + } + + function _getRemoveLiquidityData( + address tokenA, + address tokenB, + uint256 _amt + ) + internal + returns ( + TokenInterface _tokenA, + TokenInterface _tokenB, + uint256 _uniAmt + ) + { + (_tokenA, _tokenB) = changeMaticAddress(tokenA, tokenB); + address exchangeAddr = IQuickSwapFactory(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/quickswap/interface.sol b/contracts/polygon/connectors/quickswap/interface.sol new file mode 100644 index 00000000..4986dca7 --- /dev/null +++ b/contracts/polygon/connectors/quickswap/interface.sol @@ -0,0 +1,57 @@ +pragma solidity ^0.7.0; + +interface IQuickSwapRouter { + 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 IQuickSwapFactory { + 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/quickswap/main.sol b/contracts/polygon/connectors/quickswap/main.sol new file mode 100644 index 00000000..b8c0a79a --- /dev/null +++ b/contracts/polygon/connectors/quickswap/main.sol @@ -0,0 +1,196 @@ +pragma solidity ^0.7.0; + +/** + * @title QuickSwap. + * @dev Decentralized Exchange. + */ + +import { TokenInterface } from "../../common/interfaces.sol"; +import { Helpers } from "./helpers.sol"; +import { Events } from "./events.sol"; + +abstract contract QuickpswapResolver is Helpers, Events { + /** + * @dev Deposit Liquidity. + * @notice Deposit Liquidity to a QuickSwap 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 QuickSwap 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 QuickSwap + * @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) = changeMaticAddress(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) == wmaticAddr; + convertMaticToWmatic(isEth, _sellAddr, _expectedAmt); + approve(_sellAddr, address(router), _expectedAmt); + + uint _sellAmt = router.swapTokensForExactTokens( + _buyAmt, + _expectedAmt, + paths, + address(this), + block.timestamp + 1 + )[0]; + + isEth = address(_buyAddr) == wmaticAddr; + convertWmaticToMatic(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 QuickSwap + * @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) = changeMaticAddress(buyAddr, sellAddr); + address[] memory paths = getPaths(address(_buyAddr), address(_sellAddr)); + + if (_sellAmt == uint(-1)) { + _sellAmt = sellAddr == maticAddr ? + 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) == wmaticAddr; + convertMaticToWmatic(isEth, _sellAddr, _sellAmt); + approve(_sellAddr, address(router), _sellAmt); + + uint _buyAmt = router.swapExactTokensForTokens( + _sellAmt, + _expectedAmt, + paths, + address(this), + block.timestamp + 1 + )[1]; + + isEth = address(_buyAddr) == wmaticAddr; + convertWmaticToMatic(isEth, _buyAddr, _buyAmt); + + setUint(setId, _buyAmt); + + _eventName = "LogSell(address,address,uint256,uint256,uint256,uint256)"; + _eventParam = abi.encode(buyAddr, sellAddr, _buyAmt, _sellAmt, getId, setId); + } +} + +contract ConnectV2Quickswap is QuickpswapResolver { + string public constant name = "Quickpswap-v1.1"; +} From 5d01bc00d27f235620b2cd08bfe1c6d0a1c4aed0 Mon Sep 17 00:00:00 2001 From: pradyuman-verma Date: Tue, 7 Dec 2021 15:11:49 +0530 Subject: [PATCH 05/15] fixed quickswap polygon address --- contracts/polygon/connectors/quickswap/helpers.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contracts/polygon/connectors/quickswap/helpers.sol b/contracts/polygon/connectors/quickswap/helpers.sol index 2199cfb6..07316a2c 100644 --- a/contracts/polygon/connectors/quickswap/helpers.sol +++ b/contracts/polygon/connectors/quickswap/helpers.sol @@ -10,7 +10,7 @@ abstract contract Helpers is DSMath, Basic { * @dev IQuickSwapRouter */ IQuickSwapRouter internal constant router = - IQuickSwapRouter(0xd9e1cE17f2641f24aE83637ab66a2cca9C378B9F); + IQuickSwapRouter(0xa5E0829CaCEd8fFDD4De3c43696c57F7D7A678ff); function getExpectedBuyAmt(address[] memory paths, uint256 sellAmt) internal From baa2200cf2f69b6e0b58a7a10c977e9eabb14170 Mon Sep 17 00:00:00 2001 From: pradyuman-verma Date: Tue, 7 Dec 2021 22:57:37 +0530 Subject: [PATCH 06/15] added quickswap testcases --- test/quickswap-polygon/quickswap.test.js | 169 +++++++++++++++++++++++ 1 file changed, 169 insertions(+) create mode 100644 test/quickswap-polygon/quickswap.test.js diff --git a/test/quickswap-polygon/quickswap.test.js b/test/quickswap-polygon/quickswap.test.js new file mode 100644 index 00000000..e9d2d53b --- /dev/null +++ b/test/quickswap-polygon/quickswap.test.js @@ -0,0 +1,169 @@ +const { expect } = require("chai"); +const hre = require("hardhat"); +const { waffle, ethers } = hre; +const { provider } = waffle + +const deployAndEnableConnector = require("../../scripts/deployAndEnableConnector.js") +const buildDSAv2 = require("../../scripts/buildDSAv2") +const encodeSpells = require("../../scripts/encodeSpells.js") +const getMasterSigner = require("../../scripts/getMasterSigner") +const addLiquidity = require("../../scripts/addLiquidity"); + +const addresses = require("../../scripts/constant/addresses"); +const abis = require("../../scripts/constant/abis"); + +const connectV2QuickswapArtifacts = require("../../artifacts/contracts/polygon/connectors/quickswap/main.sol/ConnectV2Quickswap.json"); + +const DAI_ADDR = "0x8f3cf7ad23cd3cadbd9735aff958023239c6a063" + +describe("Quickswap", function () { + const connectorName = "Quickpswap-v1.1" + + let dsaWallet0 + let masterSigner; + let instaConnectorsV2; + let connector; + + const wallets = provider.getWallets() + const [wallet0, wallet1, wallet2, wallet3] = wallets + before(async () => { + // await hre.network.provider.request({ + // method: "hardhat_reset", + // params: [ + // { + // forking: { + // jsonRpcUrl: hre.config.networks.hardhat.forking.url, + // blockNumber: 13005785, + // }, + // }, + // ], + // }); + masterSigner = await getMasterSigner(wallet3) + instaConnectorsV2 = await ethers.getContractAt(abis.core.connectorsV2, addresses.core.connectorsV2); + connector = await deployAndEnableConnector({ + connectorName, + contractArtifact: connectV2QuickswapArtifacts, + 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(!!masterSigner.address).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 ETH & 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("100000")); + }); + + it("Deposit ETH & 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("100000")); + }); + }); + + describe("Main", function () { + it("Should deposit successfully", async function () { + const ethAmount = ethers.utils.parseEther("100") // 1 ETH + const daiUnitAmount = ethers.utils.parseUnits("4", 6) // 1 ETH + const usdtAmount = ethers.utils.parseEther("400") / Math.pow(10, 12) // 1 ETH + const ethAddress = "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE" + + const getId = "0" + const setId = "0" + + const spells = [ + { + connector: connectorName, + method: "deposit", + args: [ + ethAddress, + DAI_ADDR, + ethAmount, + 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 ethAmount = ethers.utils.parseEther("0.1") // 1 ETH + const ethAddress = "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee" + + const getId = "0" + const setIds = ["0", "0"] + + const spells = [ + { + connector: connectorName, + method: "withdraw", + args: [ + ethAddress, + DAI_ADDR, + ethAmount, + 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 ethAmount = ethers.utils.parseEther("0.1") // 1 ETH + const daiUnitAmount = ethers.utils.parseEther("4000") // 1 ETH + const ethAddress = "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee" + + const getId = "0" + const setId = "0" + + const spells = [ + { + connector: connectorName, + method: "buy", + args: [ + ethAddress, + DAI_ADDR, + ethAmount, + daiUnitAmount, + getId, + setId + ] + } + ] + + const tx = await dsaWallet0.connect(wallet0).cast(...encodeSpells(spells), wallet1.address) + let receipt = await tx.wait() + }); + }); +}) From c7fc18143ca479df82ff75e8873101e88613d813 Mon Sep 17 00:00:00 2001 From: pradyuman-verma Date: Sun, 12 Dec 2021 01:29:54 +0530 Subject: [PATCH 07/15] added typescript support --- .../polygon/connectors/quickswap/events.sol | 4 +- .../connectors/quickswap/interface.sol | 108 +++++--- .../polygon/connectors/quickswap/main.sol | 146 +++++++---- test/polygon/quickswap/quickswap.test.ts | 177 +++++++++++++ test/quickswap-polygon/quickswap.test.js | 169 ------------- test/sushiswap/sushiswap.test.js | 170 ------------- .../sushiswapIncentive/sushiIncentive.test.js | 237 ------------------ 7 files changed, 356 insertions(+), 655 deletions(-) create mode 100644 test/polygon/quickswap/quickswap.test.ts delete mode 100644 test/quickswap-polygon/quickswap.test.js delete mode 100644 test/sushiswap/sushiswap.test.js delete mode 100644 test/sushiswapIncentive/sushiIncentive.test.js diff --git a/contracts/polygon/connectors/quickswap/events.sol b/contracts/polygon/connectors/quickswap/events.sol index 2717b0a3..c8fc41d6 100644 --- a/contracts/polygon/connectors/quickswap/events.sol +++ b/contracts/polygon/connectors/quickswap/events.sol @@ -20,7 +20,7 @@ contract Events { uint256 getId, uint256[] setId ); - + event LogBuy( address indexed buyToken, address indexed sellToken, @@ -38,4 +38,4 @@ contract Events { uint256 getId, uint256 setId ); -} \ No newline at end of file +} diff --git a/contracts/polygon/connectors/quickswap/interface.sol b/contracts/polygon/connectors/quickswap/interface.sol index 4986dca7..438d89c3 100644 --- a/contracts/polygon/connectors/quickswap/interface.sol +++ b/contracts/polygon/connectors/quickswap/interface.sol @@ -2,56 +2,96 @@ pragma solidity ^0.7.0; interface IQuickSwapRouter { 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, + uint256 amountADesired, + uint256 amountBDesired, + uint256 amountAMin, + uint256 amountBMin, address to, - uint deadline - ) external returns (uint amountA, uint amountB, uint liquidity); + uint256 deadline + ) + external + returns ( + uint256 amountA, + uint256 amountB, + uint256 liquidity + ); + function removeLiquidity( address tokenA, address tokenB, - uint liquidity, - uint amountAMin, - uint amountBMin, + uint256 liquidity, + uint256 amountAMin, + uint256 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); + uint256 deadline + ) external returns (uint256 amountA, uint256 amountB); - 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); + function swapExactTokensForTokens( + uint256 amountIn, + uint256 amountOutMin, + address[] calldata path, + address to, + uint256 deadline + ) external returns (uint256[] memory amounts); + + function swapTokensForExactTokens( + uint256 amountOut, + uint256 amountInMax, + address[] calldata path, + address to, + uint256 deadline + ) external returns (uint256[] memory amounts); + + function quote( + uint256 amountA, + uint256 reserveA, + uint256 reserveB + ) external pure returns (uint256 amountB); + + function getAmountOut( + uint256 amountIn, + uint256 reserveIn, + uint256 reserveOut + ) external pure returns (uint256 amountOut); + + function getAmountIn( + uint256 amountOut, + uint256 reserveIn, + uint256 reserveOut + ) external pure returns (uint256 amountIn); + + function getAmountsOut(uint256 amountIn, address[] calldata path) + external + view + returns (uint256[] memory amounts); + + function getAmountsIn(uint256 amountOut, address[] calldata path) + external + view + returns (uint256[] memory amounts); } interface IQuickSwapFactory { - 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 getPair(address tokenA, address tokenB) + external + view + returns (address pair); + + function allPairs(uint256) external view returns (address pair); + + function allPairsLength() external view returns (uint256); function feeTo() external view returns (address); + function feeToSetter() external view returns (address); - function createPair(address tokenA, address tokenB) external returns (address pair); + function createPair(address tokenA, address tokenB) + external + returns (address pair); } diff --git a/contracts/polygon/connectors/quickswap/main.sol b/contracts/polygon/connectors/quickswap/main.sol index b8c0a79a..2cc07049 100644 --- a/contracts/polygon/connectors/quickswap/main.sol +++ b/contracts/polygon/connectors/quickswap/main.sol @@ -5,9 +5,9 @@ pragma solidity ^0.7.0; * @dev Decentralized Exchange. */ -import { TokenInterface } from "../../common/interfaces.sol"; -import { Helpers } from "./helpers.sol"; -import { Events } from "./events.sol"; +import {TokenInterface} from "../../common/interfaces.sol"; +import {Helpers} from "./helpers.sol"; +import {Events} from "./events.sol"; abstract contract QuickpswapResolver is Helpers, Events { /** @@ -20,7 +20,7 @@ abstract contract QuickpswapResolver is Helpers, Events { * @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, @@ -29,20 +29,32 @@ abstract contract QuickpswapResolver is Helpers, Events { uint256 slippage, uint256 getId, uint256 setId - ) external payable returns (string memory _eventName, bytes memory _eventParam) { - uint _amt = getUint(getId, amtA); + ) + external + payable + returns (string memory _eventName, bytes memory _eventParam) + { + uint256 _amt = getUint(getId, amtA); - (uint _amtA, uint _amtB, uint _uniAmt) = _addLiquidity( - tokenA, - tokenB, - _amt, - unitAmt, - slippage - ); + (uint256 _amtA, uint256 _amtB, uint256 _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); + _eventParam = abi.encode( + tokenA, + tokenB, + _amtA, + _amtB, + _uniAmt, + getId, + setId + ); } /** @@ -55,7 +67,7 @@ abstract contract QuickpswapResolver is Helpers, Events { * @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, @@ -64,10 +76,14 @@ abstract contract QuickpswapResolver is Helpers, Events { uint256 unitAmtB, uint256 getId, uint256[] calldata setIds - ) external payable returns (string memory _eventName, bytes memory _eventParam) { - uint _amt = getUint(getId, uniAmt); + ) + external + payable + returns (string memory _eventName, bytes memory _eventParam) + { + uint256 _amt = getUint(getId, uniAmt); - (uint _amtA, uint _amtB, uint _uniAmt) = _removeLiquidity( + (uint256 _amtA, uint256 _amtB, uint256 _uniAmt) = _removeLiquidity( tokenA, tokenB, _amt, @@ -77,9 +93,17 @@ abstract contract QuickpswapResolver is Helpers, Events { 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); + _eventParam = abi.encode( + tokenA, + tokenB, + _amtA, + _amtB, + _uniAmt, + getId, + setIds + ); } /** @@ -91,7 +115,7 @@ abstract contract QuickpswapResolver is Helpers, Events { * @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, @@ -99,24 +123,35 @@ abstract contract QuickpswapResolver is Helpers, Events { uint256 unitAmt, uint256 getId, uint256 setId - ) external payable returns (string memory _eventName, bytes memory _eventParam) { - uint _buyAmt = getUint(getId, buyAmt); - (TokenInterface _buyAddr, TokenInterface _sellAddr) = changeMaticAddress(buyAddr, sellAddr); - address[] memory paths = getPaths(address(_buyAddr), address(_sellAddr)); + ) + external + payable + returns (string memory _eventName, bytes memory _eventParam) + { + uint256 _buyAmt = getUint(getId, buyAmt); + ( + TokenInterface _buyAddr, + TokenInterface _sellAddr + ) = changeMaticAddress(buyAddr, sellAddr); + address[] memory paths = getPaths( + address(_buyAddr), + address(_sellAddr) + ); - uint _slippageAmt = convert18ToDec(_sellAddr.decimals(), + uint256 _slippageAmt = convert18ToDec( + _sellAddr.decimals(), wmul(unitAmt, convertTo18(_buyAddr.decimals(), _buyAmt)) ); checkPair(paths); - uint _expectedAmt = getExpectedSellAmt(paths, _buyAmt); + uint256 _expectedAmt = getExpectedSellAmt(paths, _buyAmt); require(_slippageAmt >= _expectedAmt, "Too much slippage"); bool isEth = address(_sellAddr) == wmaticAddr; convertMaticToWmatic(isEth, _sellAddr, _expectedAmt); approve(_sellAddr, address(router), _expectedAmt); - uint _sellAmt = router.swapTokensForExactTokens( + uint256 _sellAmt = router.swapTokensForExactTokens( _buyAmt, _expectedAmt, paths, @@ -130,7 +165,14 @@ abstract contract QuickpswapResolver is Helpers, Events { setUint(setId, _sellAmt); _eventName = "LogBuy(address,address,uint256,uint256,uint256,uint256)"; - _eventParam = abi.encode(buyAddr, sellAddr, _buyAmt, _sellAmt, getId, setId); + _eventParam = abi.encode( + buyAddr, + sellAddr, + _buyAmt, + _sellAmt, + getId, + setId + ); } /** @@ -142,7 +184,7 @@ abstract contract QuickpswapResolver is Helpers, Events { * @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, @@ -150,30 +192,41 @@ abstract contract QuickpswapResolver is Helpers, Events { uint256 unitAmt, uint256 getId, uint256 setId - ) external payable returns (string memory _eventName, bytes memory _eventParam) { - uint _sellAmt = getUint(getId, sellAmt); - (TokenInterface _buyAddr, TokenInterface _sellAddr) = changeMaticAddress(buyAddr, sellAddr); - address[] memory paths = getPaths(address(_buyAddr), address(_sellAddr)); + ) + external + payable + returns (string memory _eventName, bytes memory _eventParam) + { + uint256 _sellAmt = getUint(getId, sellAmt); + ( + TokenInterface _buyAddr, + TokenInterface _sellAddr + ) = changeMaticAddress(buyAddr, sellAddr); + address[] memory paths = getPaths( + address(_buyAddr), + address(_sellAddr) + ); - if (_sellAmt == uint(-1)) { - _sellAmt = sellAddr == maticAddr ? - address(this).balance : - _sellAddr.balanceOf(address(this)); + if (_sellAmt == uint256(-1)) { + _sellAmt = sellAddr == maticAddr + ? address(this).balance + : _sellAddr.balanceOf(address(this)); } - uint _slippageAmt = convert18ToDec(_buyAddr.decimals(), + uint256 _slippageAmt = convert18ToDec( + _buyAddr.decimals(), wmul(unitAmt, convertTo18(_sellAddr.decimals(), _sellAmt)) ); checkPair(paths); - uint _expectedAmt = getExpectedBuyAmt(paths, _sellAmt); + uint256 _expectedAmt = getExpectedBuyAmt(paths, _sellAmt); require(_slippageAmt <= _expectedAmt, "Too much slippage"); bool isEth = address(_sellAddr) == wmaticAddr; convertMaticToWmatic(isEth, _sellAddr, _sellAmt); approve(_sellAddr, address(router), _sellAmt); - uint _buyAmt = router.swapExactTokensForTokens( + uint256 _buyAmt = router.swapExactTokensForTokens( _sellAmt, _expectedAmt, paths, @@ -187,7 +240,14 @@ abstract contract QuickpswapResolver is Helpers, Events { setUint(setId, _buyAmt); _eventName = "LogSell(address,address,uint256,uint256,uint256,uint256)"; - _eventParam = abi.encode(buyAddr, sellAddr, _buyAmt, _sellAmt, getId, setId); + _eventParam = abi.encode( + buyAddr, + sellAddr, + _buyAmt, + _sellAmt, + getId, + setId + ); } } diff --git a/test/polygon/quickswap/quickswap.test.ts b/test/polygon/quickswap/quickswap.test.ts new file mode 100644 index 00000000..b831dfe5 --- /dev/null +++ b/test/polygon/quickswap/quickswap.test.ts @@ -0,0 +1,177 @@ +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 { addresses } from "../../../scripts/tests/polygon/addresses"; +import { abis } from "../../../scripts/constant/abis"; +import { ConnectV2Quickswap__factory, ConnectV2Quickswap } from "../../../typechain"; +import type { Signer, Contract } from "ethers"; + +const DAI_ADDR = "0x8f3cf7ad23cd3cadbd9735aff958023239c6a063"; + +describe("Quickswap", function() { + const connectorName = "Quickpswap-v1.1"; + + 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: ConnectV2Quickswap__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 ETH & 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("100000") + ); + }); + + it("Deposit ETH & 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("100000") + ); + }); + }); + + describe("Main", function() { + it("Should deposit successfully", async function() { + const ethAmount = ethers.utils.parseEther("100"); // 1 ETH + const daiUnitAmount = ethers.utils.parseUnits("4", 6); // 1 ETH + const usdtAmount = Number(ethers.utils.parseEther("400")) / Math.pow(10, 12); // 1 ETH + const ethAddress = "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE"; + + const getId = "0"; + const setId = "0"; + + const spells = [ + { + connector: connectorName, + method: "deposit", + args: [ + ethAddress, + DAI_ADDR, + ethAmount, + 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 ethAmount = ethers.utils.parseEther("0.1"); // 1 ETH + const ethAddress = "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee"; + + const getId = "0"; + const setIds = ["0", "0"]; + + const spells = [ + { + connector: connectorName, + method: "withdraw", + args: [ethAddress, DAI_ADDR, ethAmount, 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 ethAmount = ethers.utils.parseEther("0.1"); // 1 ETH + const daiUnitAmount = ethers.utils.parseEther("4000"); // 1 ETH + const ethAddress = "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee"; + + const getId = "0"; + const setId = "0"; + + const spells = [ + { + connector: connectorName, + method: "buy", + args: [ethAddress, DAI_ADDR, ethAmount, daiUnitAmount, getId, setId], + }, + ]; + + const tx = await dsaWallet0 + .connect(wallet0) + .cast(...encodeSpells(spells), wallet1.address); + let receipt = await tx.wait(); + }); + }); +}); diff --git a/test/quickswap-polygon/quickswap.test.js b/test/quickswap-polygon/quickswap.test.js deleted file mode 100644 index e9d2d53b..00000000 --- a/test/quickswap-polygon/quickswap.test.js +++ /dev/null @@ -1,169 +0,0 @@ -const { expect } = require("chai"); -const hre = require("hardhat"); -const { waffle, ethers } = hre; -const { provider } = waffle - -const deployAndEnableConnector = require("../../scripts/deployAndEnableConnector.js") -const buildDSAv2 = require("../../scripts/buildDSAv2") -const encodeSpells = require("../../scripts/encodeSpells.js") -const getMasterSigner = require("../../scripts/getMasterSigner") -const addLiquidity = require("../../scripts/addLiquidity"); - -const addresses = require("../../scripts/constant/addresses"); -const abis = require("../../scripts/constant/abis"); - -const connectV2QuickswapArtifacts = require("../../artifacts/contracts/polygon/connectors/quickswap/main.sol/ConnectV2Quickswap.json"); - -const DAI_ADDR = "0x8f3cf7ad23cd3cadbd9735aff958023239c6a063" - -describe("Quickswap", function () { - const connectorName = "Quickpswap-v1.1" - - let dsaWallet0 - let masterSigner; - let instaConnectorsV2; - let connector; - - const wallets = provider.getWallets() - const [wallet0, wallet1, wallet2, wallet3] = wallets - before(async () => { - // await hre.network.provider.request({ - // method: "hardhat_reset", - // params: [ - // { - // forking: { - // jsonRpcUrl: hre.config.networks.hardhat.forking.url, - // blockNumber: 13005785, - // }, - // }, - // ], - // }); - masterSigner = await getMasterSigner(wallet3) - instaConnectorsV2 = await ethers.getContractAt(abis.core.connectorsV2, addresses.core.connectorsV2); - connector = await deployAndEnableConnector({ - connectorName, - contractArtifact: connectV2QuickswapArtifacts, - 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(!!masterSigner.address).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 ETH & 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("100000")); - }); - - it("Deposit ETH & 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("100000")); - }); - }); - - describe("Main", function () { - it("Should deposit successfully", async function () { - const ethAmount = ethers.utils.parseEther("100") // 1 ETH - const daiUnitAmount = ethers.utils.parseUnits("4", 6) // 1 ETH - const usdtAmount = ethers.utils.parseEther("400") / Math.pow(10, 12) // 1 ETH - const ethAddress = "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE" - - const getId = "0" - const setId = "0" - - const spells = [ - { - connector: connectorName, - method: "deposit", - args: [ - ethAddress, - DAI_ADDR, - ethAmount, - 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 ethAmount = ethers.utils.parseEther("0.1") // 1 ETH - const ethAddress = "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee" - - const getId = "0" - const setIds = ["0", "0"] - - const spells = [ - { - connector: connectorName, - method: "withdraw", - args: [ - ethAddress, - DAI_ADDR, - ethAmount, - 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 ethAmount = ethers.utils.parseEther("0.1") // 1 ETH - const daiUnitAmount = ethers.utils.parseEther("4000") // 1 ETH - const ethAddress = "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee" - - const getId = "0" - const setId = "0" - - const spells = [ - { - connector: connectorName, - method: "buy", - args: [ - ethAddress, - DAI_ADDR, - ethAmount, - daiUnitAmount, - getId, - setId - ] - } - ] - - const tx = await dsaWallet0.connect(wallet0).cast(...encodeSpells(spells), wallet1.address) - let receipt = await tx.wait() - }); - }); -}) diff --git a/test/sushiswap/sushiswap.test.js b/test/sushiswap/sushiswap.test.js deleted file mode 100644 index baaf3876..00000000 --- a/test/sushiswap/sushiswap.test.js +++ /dev/null @@ -1,170 +0,0 @@ -const { expect } = require("chai"); -const hre = require("hardhat"); -const { waffle, ethers } = hre; -const { provider } = waffle - -const deployAndEnableConnector = require("../../scripts/deployAndEnableConnector.js") -const buildDSAv2 = require("../../scripts/buildDSAv2") -const encodeSpells = require("../../scripts/encodeSpells.js") -const getMasterSigner = require("../../scripts/getMasterSigner") -const addLiquidity = require("../../scripts/addLiquidity"); - -const addresses = require("../../scripts/constant/addresses"); -const abis = require("../../scripts/constant/abis"); - -const connectV2SushiswapArtifacts = require("../../artifacts/contracts/mainnet/connectors/sushiswap/main.sol/ConnectV2Sushiswap.json"); - -const DAI_ADDR = "0x6b175474e89094c44da98b954eedeac495271d0f" - -describe("Sushiswap", function () { - const connectorName = "Sushiswap-v1" - - let dsaWallet0 - let masterSigner; - let instaConnectorsV2; - let connector; - - const wallets = provider.getWallets() - const [wallet0, wallet1, wallet2, wallet3] = wallets - before(async () => { - await hre.network.provider.request({ - method: "hardhat_reset", - params: [ - { - forking: { - jsonRpcUrl: hre.config.networks.hardhat.forking.url, - blockNumber: 13005785, - }, - }, - ], - }); - masterSigner = await getMasterSigner(wallet3) - instaConnectorsV2 = await ethers.getContractAt(abis.core.connectorsV2, addresses.core.connectorsV2); - connector = await deployAndEnableConnector({ - connectorName, - contractArtifact: connectV2SushiswapArtifacts, - 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(!!masterSigner.address).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 ETH & 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("100000")); - }); - - it("Deposit ETH & 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("100000")); - }); - }); - - describe("Main", function () { - - it("Should deposit successfully", async function () { - const ethAmount = ethers.utils.parseEther("0.1") // 1 ETH - const daiUnitAmount = ethers.utils.parseEther("4000") // 1 ETH - const usdtAmount = ethers.utils.parseEther("400") / Math.pow(10, 12) // 1 ETH - const ethAddress = "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee" - - const getId = "0" - const setId = "0" - - const spells = [ - { - connector: connectorName, - method: "deposit", - args: [ - ethAddress, - DAI_ADDR, - ethAmount, - 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 ethAmount = ethers.utils.parseEther("0.1") // 1 ETH - const ethAddress = "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee" - - const getId = "0" - const setIds = ["0", "0"] - - const spells = [ - { - connector: connectorName, - method: "withdraw", - args: [ - ethAddress, - DAI_ADDR, - ethAmount, - 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 ethAmount = ethers.utils.parseEther("0.1") // 1 ETH - const daiUnitAmount = ethers.utils.parseEther("4000") // 1 ETH - const ethAddress = "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee" - - const getId = "0" - const setId = "0" - - const spells = [ - { - connector: connectorName, - method: "buy", - args: [ - ethAddress, - DAI_ADDR, - ethAmount, - daiUnitAmount, - getId, - setId - ] - } - ] - - const tx = await dsaWallet0.connect(wallet0).cast(...encodeSpells(spells), wallet1.address) - let receipt = await tx.wait() - }); - }); -}) \ No newline at end of file diff --git a/test/sushiswapIncentive/sushiIncentive.test.js b/test/sushiswapIncentive/sushiIncentive.test.js deleted file mode 100644 index 1b2fd01b..00000000 --- a/test/sushiswapIncentive/sushiIncentive.test.js +++ /dev/null @@ -1,237 +0,0 @@ -const { expect } = require("chai"); -const hre = require("hardhat"); -const { waffle, ethers } = hre; -const { provider } = waffle - -const deployAndEnableConnector = require("../../scripts/deployAndEnableConnector.js") -const buildDSAv2 = require("../../scripts/buildDSAv2") -const encodeSpells = require("../../scripts/encodeSpells.js") -const getMasterSigner = require("../../scripts/getMasterSigner") -const addLiquidity = require("../../scripts/addLiquidity"); - -const addresses = require("../../scripts/constant/addresses"); -const abis = require("../../scripts/constant/abis"); - -const connectV2SushiswapArtifacts = require("../../artifacts/contracts/mainnet/connectors/sushiswap/main.sol/ConnectV2Sushiswap.json"); -const connectV2SushiswapIncentiveArtifacts = require("../../artifacts/contracts/mainnet/connectors/sushi-incentive/main.sol/ConnectV2SushiswapIncentive.json"); - -const DAI_ADDR = "0x6b175474e89094c44da98b954eedeac495271d0f" -const WETH_ADDR = "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2" - -describe("Sushiswap", function () { - const connectorName = "Sushiswap-v1" - const incentiveConnectorName = "Sushiswp-Incentive-v1" - - let dsaWallet0 - let masterSigner; - let instaConnectorsV2; - let connector, connectorIncentive; - - const wallets = provider.getWallets() - const [wallet0, wallet1, wallet2, wallet3] = wallets - before(async () => { - await hre.network.provider.request({ - method: "hardhat_reset", - params: [ - { - forking: { - jsonRpcUrl: hre.config.networks.hardhat.forking.url, - blockNumber: 13005785, - }, - }, - ], - }); - masterSigner = await getMasterSigner(wallet3) - instaConnectorsV2 = await ethers.getContractAt(abis.core.connectorsV2, addresses.core.connectorsV2); - connector = await deployAndEnableConnector({ - connectorName, - contractArtifact: connectV2SushiswapArtifacts, - signer: masterSigner, - connectors: instaConnectorsV2 - }) - console.log("Connector address", connector.address) - - connectorIncentive = await deployAndEnableConnector({ - connectorName: incentiveConnectorName, - contractArtifact: connectV2SushiswapIncentiveArtifacts, - signer: masterSigner, - connectors: instaConnectorsV2 - }) - console.log("Incentive Connector address", connectorIncentive.address) - }) - - it("Should have contracts deployed.", async function () { - expect(!!instaConnectorsV2.address).to.be.true; - expect(!!connector.address).to.be.true; - expect(!!masterSigner.address).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 ETH & 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("100000")); - }); - - it("Deposit ETH & 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("100000")); - }); - }); - - describe("Main", function () { - - it("Should deposit successfully", async function () { - const ethAmount = ethers.utils.parseEther("2") // 1 ETH - const daiUnitAmount = ethers.utils.parseEther("4000") // 1 ETH - const usdtAmount = ethers.utils.parseEther("400") / Math.pow(10, 12) // 1 ETH - const ethAddress = "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee" - - const getId = "0" - const setId = "0" - - const spells = [ - { - connector: connectorName, - method: "deposit", - args: [ - ethAddress, - DAI_ADDR, - ethAmount, - daiUnitAmount, - "500000000000000000", - getId, - setId - ], - } - ] - - const tx = await dsaWallet0.connect(wallet0).cast(...encodeSpells(spells), wallet1.address) - await tx.wait() - - describe("Incentive", () => { - it("Should deposit successfully", async () => { - const getId = 0 - const setId = 0 - const spells = [ - { - connector: incentiveConnectorName, - method: "deposit", - args: [ - WETH_ADDR, - DAI_ADDR, - ethers.utils.parseEther("10"), - getId, - setId - ] - } - ] - - const tx = await dsaWallet0.connect(wallet0).cast(...encodeSpells(spells), wallet0.address) - await tx.wait(); - }) - - it("Should harvest successfully", async () => { - const setId = 0 - const spells = [ - { - connector: incentiveConnectorName, - method: "harvest", - args: [ - WETH_ADDR, - DAI_ADDR, - setId - ] - } - ] - - const tx = await dsaWallet0.connect(wallet0).cast(...encodeSpells(spells), wallet0.address) - await tx.wait(); - }) - - it("Should harvest and withdraw successfully", async () => { - const getId = 0 - const setId = 0 - const spells = [ - { - connector: incentiveConnectorName, - method: "withdrawAndHarvest", - args: [ - WETH_ADDR, - DAI_ADDR, - ethers.utils.parseEther("1"), - getId, - setId - ] - } - ] - - const tx = await dsaWallet0.connect(wallet0).cast(...encodeSpells(spells), wallet0.address) - await tx.wait(); - }) - - it("Should withdraw successfully", async () => { - const getId = 0 - const setId = 0 - const spells = [ - { - connector: incentiveConnectorName, - method: "withdraw", - args: [ - WETH_ADDR, - DAI_ADDR, - ethers.utils.parseEther("1"), - getId, - setId - ] - } - ] - - const tx = await dsaWallet0.connect(wallet0).cast(...encodeSpells(spells), wallet0.address) - await tx.wait(); - }) - }) - }).timeout(10000000000); - - it("Should buy successfully", async function () { - const ethAmount = ethers.utils.parseEther("0.1") // 1 ETH - const daiUnitAmount = ethers.utils.parseEther("4000") // 1 ETH - const ethAddress = "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee" - - const getId = "0" - const setId = "0" - - const spells = [ - { - connector: connectorName, - method: "buy", - args: [ - ethAddress, - DAI_ADDR, - ethAmount, - daiUnitAmount, - getId, - setId - ] - } - ] - - const tx = await dsaWallet0.connect(wallet0).cast(...encodeSpells(spells), wallet1.address) - let receipt = await tx.wait() - }); - }); -}) \ No newline at end of file From 4162176d96db103dacbe171688fd1c6552092116 Mon Sep 17 00:00:00 2001 From: pradyuman-verma Date: Sun, 12 Dec 2021 01:31:48 +0530 Subject: [PATCH 08/15] Merge branch 'feat/quickswap' of https://github.com/Instadapp/dsa-connectors into feat/quickswap --- .../polygon/connectors/quickswap/events.sol | 8 + .../connectors/quickswap/interface.sol | 53 ++++ .../polygon/connectors/quickswap/main.sol | 100 ++++++++ test/quickswap-polygon/quickswap.test.js | 169 +++++++++++++ test/sushiswap/sushiswap.test.js | 170 +++++++++++++ .../sushiswapIncentive/sushiIncentive.test.js | 237 ++++++++++++++++++ 6 files changed, 737 insertions(+) create mode 100644 test/quickswap-polygon/quickswap.test.js create mode 100644 test/sushiswap/sushiswap.test.js create mode 100644 test/sushiswapIncentive/sushiIncentive.test.js diff --git a/contracts/polygon/connectors/quickswap/events.sol b/contracts/polygon/connectors/quickswap/events.sol index c8fc41d6..5f8c0f48 100644 --- a/contracts/polygon/connectors/quickswap/events.sol +++ b/contracts/polygon/connectors/quickswap/events.sol @@ -20,7 +20,11 @@ contract Events { uint256 getId, uint256[] setId ); +<<<<<<< HEAD +======= + +>>>>>>> d9a7bfba85acceb302ac1d1dd854e9b380976557 event LogBuy( address indexed buyToken, address indexed sellToken, @@ -38,4 +42,8 @@ contract Events { uint256 getId, uint256 setId ); +<<<<<<< HEAD } +======= +} +>>>>>>> d9a7bfba85acceb302ac1d1dd854e9b380976557 diff --git a/contracts/polygon/connectors/quickswap/interface.sol b/contracts/polygon/connectors/quickswap/interface.sol index 438d89c3..65c0482d 100644 --- a/contracts/polygon/connectors/quickswap/interface.sol +++ b/contracts/polygon/connectors/quickswap/interface.sol @@ -2,12 +2,16 @@ pragma solidity ^0.7.0; interface IQuickSwapRouter { function factory() external pure returns (address); +<<<<<<< HEAD +======= +>>>>>>> d9a7bfba85acceb302ac1d1dd854e9b380976557 function WETH() external pure returns (address); function addLiquidity( address tokenA, address tokenB, +<<<<<<< HEAD uint256 amountADesired, uint256 amountBDesired, uint256 amountAMin, @@ -94,4 +98,53 @@ interface IQuickSwapFactory { function createPair(address tokenA, address tokenB) external returns (address pair); +======= + 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 IQuickSwapFactory { + 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); +>>>>>>> d9a7bfba85acceb302ac1d1dd854e9b380976557 } diff --git a/contracts/polygon/connectors/quickswap/main.sol b/contracts/polygon/connectors/quickswap/main.sol index 2cc07049..de7a1926 100644 --- a/contracts/polygon/connectors/quickswap/main.sol +++ b/contracts/polygon/connectors/quickswap/main.sol @@ -5,9 +5,15 @@ pragma solidity ^0.7.0; * @dev Decentralized Exchange. */ +<<<<<<< HEAD import {TokenInterface} from "../../common/interfaces.sol"; import {Helpers} from "./helpers.sol"; import {Events} from "./events.sol"; +======= +import { TokenInterface } from "../../common/interfaces.sol"; +import { Helpers } from "./helpers.sol"; +import { Events } from "./events.sol"; +>>>>>>> d9a7bfba85acceb302ac1d1dd854e9b380976557 abstract contract QuickpswapResolver is Helpers, Events { /** @@ -20,7 +26,11 @@ abstract contract QuickpswapResolver is Helpers, Events { * @param slippage Slippage amount. * @param getId ID to retrieve amtA. * @param setId ID stores the amount of pools tokens received. +<<<<<<< HEAD */ +======= + */ +>>>>>>> d9a7bfba85acceb302ac1d1dd854e9b380976557 function deposit( address tokenA, address tokenB, @@ -29,6 +39,7 @@ abstract contract QuickpswapResolver is Helpers, Events { uint256 slippage, uint256 getId, uint256 setId +<<<<<<< HEAD ) external payable @@ -55,6 +66,22 @@ abstract contract QuickpswapResolver is Helpers, Events { getId, 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); +>>>>>>> d9a7bfba85acceb302ac1d1dd854e9b380976557 } /** @@ -67,7 +94,11 @@ abstract contract QuickpswapResolver is Helpers, Events { * @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. +<<<<<<< HEAD */ +======= + */ +>>>>>>> d9a7bfba85acceb302ac1d1dd854e9b380976557 function withdraw( address tokenA, address tokenB, @@ -76,6 +107,7 @@ abstract contract QuickpswapResolver is Helpers, Events { uint256 unitAmtB, uint256 getId, uint256[] calldata setIds +<<<<<<< HEAD ) external payable @@ -84,6 +116,12 @@ abstract contract QuickpswapResolver is Helpers, Events { uint256 _amt = getUint(getId, uniAmt); (uint256 _amtA, uint256 _amtB, uint256 _uniAmt) = _removeLiquidity( +======= + ) external payable returns (string memory _eventName, bytes memory _eventParam) { + uint _amt = getUint(getId, uniAmt); + + (uint _amtA, uint _amtB, uint _uniAmt) = _removeLiquidity( +>>>>>>> d9a7bfba85acceb302ac1d1dd854e9b380976557 tokenA, tokenB, _amt, @@ -93,6 +131,7 @@ abstract contract QuickpswapResolver is Helpers, Events { setUint(setIds[0], _amtA); setUint(setIds[1], _amtB); +<<<<<<< HEAD _eventName = "LogWithdrawLiquidity(address,address,uint256,uint256,uint256,uint256,uint256[])"; _eventParam = abi.encode( @@ -104,6 +143,11 @@ abstract contract QuickpswapResolver is Helpers, Events { getId, setIds ); +======= + + _eventName = "LogWithdrawLiquidity(address,address,uint256,uint256,uint256,uint256,uint256[])"; + _eventParam = abi.encode(tokenA, tokenB, _amtA, _amtB, _uniAmt, getId, setIds); +>>>>>>> d9a7bfba85acceb302ac1d1dd854e9b380976557 } /** @@ -115,7 +159,11 @@ abstract contract QuickpswapResolver is Helpers, Events { * @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. +<<<<<<< HEAD */ +======= + */ +>>>>>>> d9a7bfba85acceb302ac1d1dd854e9b380976557 function buy( address buyAddr, address sellAddr, @@ -123,6 +171,7 @@ abstract contract QuickpswapResolver is Helpers, Events { uint256 unitAmt, uint256 getId, uint256 setId +<<<<<<< HEAD ) external payable @@ -140,18 +189,34 @@ abstract contract QuickpswapResolver is Helpers, Events { uint256 _slippageAmt = convert18ToDec( _sellAddr.decimals(), +======= + ) external payable returns (string memory _eventName, bytes memory _eventParam) { + uint _buyAmt = getUint(getId, buyAmt); + (TokenInterface _buyAddr, TokenInterface _sellAddr) = changeMaticAddress(buyAddr, sellAddr); + address[] memory paths = getPaths(address(_buyAddr), address(_sellAddr)); + + uint _slippageAmt = convert18ToDec(_sellAddr.decimals(), +>>>>>>> d9a7bfba85acceb302ac1d1dd854e9b380976557 wmul(unitAmt, convertTo18(_buyAddr.decimals(), _buyAmt)) ); checkPair(paths); +<<<<<<< HEAD uint256 _expectedAmt = getExpectedSellAmt(paths, _buyAmt); +======= + uint _expectedAmt = getExpectedSellAmt(paths, _buyAmt); +>>>>>>> d9a7bfba85acceb302ac1d1dd854e9b380976557 require(_slippageAmt >= _expectedAmt, "Too much slippage"); bool isEth = address(_sellAddr) == wmaticAddr; convertMaticToWmatic(isEth, _sellAddr, _expectedAmt); approve(_sellAddr, address(router), _expectedAmt); +<<<<<<< HEAD uint256 _sellAmt = router.swapTokensForExactTokens( +======= + uint _sellAmt = router.swapTokensForExactTokens( +>>>>>>> d9a7bfba85acceb302ac1d1dd854e9b380976557 _buyAmt, _expectedAmt, paths, @@ -165,6 +230,7 @@ abstract contract QuickpswapResolver is Helpers, Events { setUint(setId, _sellAmt); _eventName = "LogBuy(address,address,uint256,uint256,uint256,uint256)"; +<<<<<<< HEAD _eventParam = abi.encode( buyAddr, sellAddr, @@ -173,6 +239,9 @@ abstract contract QuickpswapResolver is Helpers, Events { getId, setId ); +======= + _eventParam = abi.encode(buyAddr, sellAddr, _buyAmt, _sellAmt, getId, setId); +>>>>>>> d9a7bfba85acceb302ac1d1dd854e9b380976557 } /** @@ -184,7 +253,11 @@ abstract contract QuickpswapResolver is Helpers, Events { * @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. +<<<<<<< HEAD */ +======= + */ +>>>>>>> d9a7bfba85acceb302ac1d1dd854e9b380976557 function sell( address buyAddr, address sellAddr, @@ -192,6 +265,7 @@ abstract contract QuickpswapResolver is Helpers, Events { uint256 unitAmt, uint256 getId, uint256 setId +<<<<<<< HEAD ) external payable @@ -215,18 +289,40 @@ abstract contract QuickpswapResolver is Helpers, Events { uint256 _slippageAmt = convert18ToDec( _buyAddr.decimals(), +======= + ) external payable returns (string memory _eventName, bytes memory _eventParam) { + uint _sellAmt = getUint(getId, sellAmt); + (TokenInterface _buyAddr, TokenInterface _sellAddr) = changeMaticAddress(buyAddr, sellAddr); + address[] memory paths = getPaths(address(_buyAddr), address(_sellAddr)); + + if (_sellAmt == uint(-1)) { + _sellAmt = sellAddr == maticAddr ? + address(this).balance : + _sellAddr.balanceOf(address(this)); + } + + uint _slippageAmt = convert18ToDec(_buyAddr.decimals(), +>>>>>>> d9a7bfba85acceb302ac1d1dd854e9b380976557 wmul(unitAmt, convertTo18(_sellAddr.decimals(), _sellAmt)) ); checkPair(paths); +<<<<<<< HEAD uint256 _expectedAmt = getExpectedBuyAmt(paths, _sellAmt); +======= + uint _expectedAmt = getExpectedBuyAmt(paths, _sellAmt); +>>>>>>> d9a7bfba85acceb302ac1d1dd854e9b380976557 require(_slippageAmt <= _expectedAmt, "Too much slippage"); bool isEth = address(_sellAddr) == wmaticAddr; convertMaticToWmatic(isEth, _sellAddr, _sellAmt); approve(_sellAddr, address(router), _sellAmt); +<<<<<<< HEAD uint256 _buyAmt = router.swapExactTokensForTokens( +======= + uint _buyAmt = router.swapExactTokensForTokens( +>>>>>>> d9a7bfba85acceb302ac1d1dd854e9b380976557 _sellAmt, _expectedAmt, paths, @@ -240,6 +336,7 @@ abstract contract QuickpswapResolver is Helpers, Events { setUint(setId, _buyAmt); _eventName = "LogSell(address,address,uint256,uint256,uint256,uint256)"; +<<<<<<< HEAD _eventParam = abi.encode( buyAddr, sellAddr, @@ -248,6 +345,9 @@ abstract contract QuickpswapResolver is Helpers, Events { getId, setId ); +======= + _eventParam = abi.encode(buyAddr, sellAddr, _buyAmt, _sellAmt, getId, setId); +>>>>>>> d9a7bfba85acceb302ac1d1dd854e9b380976557 } } diff --git a/test/quickswap-polygon/quickswap.test.js b/test/quickswap-polygon/quickswap.test.js new file mode 100644 index 00000000..e9d2d53b --- /dev/null +++ b/test/quickswap-polygon/quickswap.test.js @@ -0,0 +1,169 @@ +const { expect } = require("chai"); +const hre = require("hardhat"); +const { waffle, ethers } = hre; +const { provider } = waffle + +const deployAndEnableConnector = require("../../scripts/deployAndEnableConnector.js") +const buildDSAv2 = require("../../scripts/buildDSAv2") +const encodeSpells = require("../../scripts/encodeSpells.js") +const getMasterSigner = require("../../scripts/getMasterSigner") +const addLiquidity = require("../../scripts/addLiquidity"); + +const addresses = require("../../scripts/constant/addresses"); +const abis = require("../../scripts/constant/abis"); + +const connectV2QuickswapArtifacts = require("../../artifacts/contracts/polygon/connectors/quickswap/main.sol/ConnectV2Quickswap.json"); + +const DAI_ADDR = "0x8f3cf7ad23cd3cadbd9735aff958023239c6a063" + +describe("Quickswap", function () { + const connectorName = "Quickpswap-v1.1" + + let dsaWallet0 + let masterSigner; + let instaConnectorsV2; + let connector; + + const wallets = provider.getWallets() + const [wallet0, wallet1, wallet2, wallet3] = wallets + before(async () => { + // await hre.network.provider.request({ + // method: "hardhat_reset", + // params: [ + // { + // forking: { + // jsonRpcUrl: hre.config.networks.hardhat.forking.url, + // blockNumber: 13005785, + // }, + // }, + // ], + // }); + masterSigner = await getMasterSigner(wallet3) + instaConnectorsV2 = await ethers.getContractAt(abis.core.connectorsV2, addresses.core.connectorsV2); + connector = await deployAndEnableConnector({ + connectorName, + contractArtifact: connectV2QuickswapArtifacts, + 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(!!masterSigner.address).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 ETH & 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("100000")); + }); + + it("Deposit ETH & 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("100000")); + }); + }); + + describe("Main", function () { + it("Should deposit successfully", async function () { + const ethAmount = ethers.utils.parseEther("100") // 1 ETH + const daiUnitAmount = ethers.utils.parseUnits("4", 6) // 1 ETH + const usdtAmount = ethers.utils.parseEther("400") / Math.pow(10, 12) // 1 ETH + const ethAddress = "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE" + + const getId = "0" + const setId = "0" + + const spells = [ + { + connector: connectorName, + method: "deposit", + args: [ + ethAddress, + DAI_ADDR, + ethAmount, + 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 ethAmount = ethers.utils.parseEther("0.1") // 1 ETH + const ethAddress = "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee" + + const getId = "0" + const setIds = ["0", "0"] + + const spells = [ + { + connector: connectorName, + method: "withdraw", + args: [ + ethAddress, + DAI_ADDR, + ethAmount, + 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 ethAmount = ethers.utils.parseEther("0.1") // 1 ETH + const daiUnitAmount = ethers.utils.parseEther("4000") // 1 ETH + const ethAddress = "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee" + + const getId = "0" + const setId = "0" + + const spells = [ + { + connector: connectorName, + method: "buy", + args: [ + ethAddress, + DAI_ADDR, + ethAmount, + daiUnitAmount, + getId, + setId + ] + } + ] + + const tx = await dsaWallet0.connect(wallet0).cast(...encodeSpells(spells), wallet1.address) + let receipt = await tx.wait() + }); + }); +}) diff --git a/test/sushiswap/sushiswap.test.js b/test/sushiswap/sushiswap.test.js new file mode 100644 index 00000000..baaf3876 --- /dev/null +++ b/test/sushiswap/sushiswap.test.js @@ -0,0 +1,170 @@ +const { expect } = require("chai"); +const hre = require("hardhat"); +const { waffle, ethers } = hre; +const { provider } = waffle + +const deployAndEnableConnector = require("../../scripts/deployAndEnableConnector.js") +const buildDSAv2 = require("../../scripts/buildDSAv2") +const encodeSpells = require("../../scripts/encodeSpells.js") +const getMasterSigner = require("../../scripts/getMasterSigner") +const addLiquidity = require("../../scripts/addLiquidity"); + +const addresses = require("../../scripts/constant/addresses"); +const abis = require("../../scripts/constant/abis"); + +const connectV2SushiswapArtifacts = require("../../artifacts/contracts/mainnet/connectors/sushiswap/main.sol/ConnectV2Sushiswap.json"); + +const DAI_ADDR = "0x6b175474e89094c44da98b954eedeac495271d0f" + +describe("Sushiswap", function () { + const connectorName = "Sushiswap-v1" + + let dsaWallet0 + let masterSigner; + let instaConnectorsV2; + let connector; + + const wallets = provider.getWallets() + const [wallet0, wallet1, wallet2, wallet3] = wallets + before(async () => { + await hre.network.provider.request({ + method: "hardhat_reset", + params: [ + { + forking: { + jsonRpcUrl: hre.config.networks.hardhat.forking.url, + blockNumber: 13005785, + }, + }, + ], + }); + masterSigner = await getMasterSigner(wallet3) + instaConnectorsV2 = await ethers.getContractAt(abis.core.connectorsV2, addresses.core.connectorsV2); + connector = await deployAndEnableConnector({ + connectorName, + contractArtifact: connectV2SushiswapArtifacts, + 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(!!masterSigner.address).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 ETH & 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("100000")); + }); + + it("Deposit ETH & 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("100000")); + }); + }); + + describe("Main", function () { + + it("Should deposit successfully", async function () { + const ethAmount = ethers.utils.parseEther("0.1") // 1 ETH + const daiUnitAmount = ethers.utils.parseEther("4000") // 1 ETH + const usdtAmount = ethers.utils.parseEther("400") / Math.pow(10, 12) // 1 ETH + const ethAddress = "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee" + + const getId = "0" + const setId = "0" + + const spells = [ + { + connector: connectorName, + method: "deposit", + args: [ + ethAddress, + DAI_ADDR, + ethAmount, + 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 ethAmount = ethers.utils.parseEther("0.1") // 1 ETH + const ethAddress = "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee" + + const getId = "0" + const setIds = ["0", "0"] + + const spells = [ + { + connector: connectorName, + method: "withdraw", + args: [ + ethAddress, + DAI_ADDR, + ethAmount, + 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 ethAmount = ethers.utils.parseEther("0.1") // 1 ETH + const daiUnitAmount = ethers.utils.parseEther("4000") // 1 ETH + const ethAddress = "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee" + + const getId = "0" + const setId = "0" + + const spells = [ + { + connector: connectorName, + method: "buy", + args: [ + ethAddress, + DAI_ADDR, + ethAmount, + daiUnitAmount, + getId, + setId + ] + } + ] + + const tx = await dsaWallet0.connect(wallet0).cast(...encodeSpells(spells), wallet1.address) + let receipt = await tx.wait() + }); + }); +}) \ No newline at end of file diff --git a/test/sushiswapIncentive/sushiIncentive.test.js b/test/sushiswapIncentive/sushiIncentive.test.js new file mode 100644 index 00000000..1b2fd01b --- /dev/null +++ b/test/sushiswapIncentive/sushiIncentive.test.js @@ -0,0 +1,237 @@ +const { expect } = require("chai"); +const hre = require("hardhat"); +const { waffle, ethers } = hre; +const { provider } = waffle + +const deployAndEnableConnector = require("../../scripts/deployAndEnableConnector.js") +const buildDSAv2 = require("../../scripts/buildDSAv2") +const encodeSpells = require("../../scripts/encodeSpells.js") +const getMasterSigner = require("../../scripts/getMasterSigner") +const addLiquidity = require("../../scripts/addLiquidity"); + +const addresses = require("../../scripts/constant/addresses"); +const abis = require("../../scripts/constant/abis"); + +const connectV2SushiswapArtifacts = require("../../artifacts/contracts/mainnet/connectors/sushiswap/main.sol/ConnectV2Sushiswap.json"); +const connectV2SushiswapIncentiveArtifacts = require("../../artifacts/contracts/mainnet/connectors/sushi-incentive/main.sol/ConnectV2SushiswapIncentive.json"); + +const DAI_ADDR = "0x6b175474e89094c44da98b954eedeac495271d0f" +const WETH_ADDR = "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2" + +describe("Sushiswap", function () { + const connectorName = "Sushiswap-v1" + const incentiveConnectorName = "Sushiswp-Incentive-v1" + + let dsaWallet0 + let masterSigner; + let instaConnectorsV2; + let connector, connectorIncentive; + + const wallets = provider.getWallets() + const [wallet0, wallet1, wallet2, wallet3] = wallets + before(async () => { + await hre.network.provider.request({ + method: "hardhat_reset", + params: [ + { + forking: { + jsonRpcUrl: hre.config.networks.hardhat.forking.url, + blockNumber: 13005785, + }, + }, + ], + }); + masterSigner = await getMasterSigner(wallet3) + instaConnectorsV2 = await ethers.getContractAt(abis.core.connectorsV2, addresses.core.connectorsV2); + connector = await deployAndEnableConnector({ + connectorName, + contractArtifact: connectV2SushiswapArtifacts, + signer: masterSigner, + connectors: instaConnectorsV2 + }) + console.log("Connector address", connector.address) + + connectorIncentive = await deployAndEnableConnector({ + connectorName: incentiveConnectorName, + contractArtifact: connectV2SushiswapIncentiveArtifacts, + signer: masterSigner, + connectors: instaConnectorsV2 + }) + console.log("Incentive Connector address", connectorIncentive.address) + }) + + it("Should have contracts deployed.", async function () { + expect(!!instaConnectorsV2.address).to.be.true; + expect(!!connector.address).to.be.true; + expect(!!masterSigner.address).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 ETH & 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("100000")); + }); + + it("Deposit ETH & 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("100000")); + }); + }); + + describe("Main", function () { + + it("Should deposit successfully", async function () { + const ethAmount = ethers.utils.parseEther("2") // 1 ETH + const daiUnitAmount = ethers.utils.parseEther("4000") // 1 ETH + const usdtAmount = ethers.utils.parseEther("400") / Math.pow(10, 12) // 1 ETH + const ethAddress = "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee" + + const getId = "0" + const setId = "0" + + const spells = [ + { + connector: connectorName, + method: "deposit", + args: [ + ethAddress, + DAI_ADDR, + ethAmount, + daiUnitAmount, + "500000000000000000", + getId, + setId + ], + } + ] + + const tx = await dsaWallet0.connect(wallet0).cast(...encodeSpells(spells), wallet1.address) + await tx.wait() + + describe("Incentive", () => { + it("Should deposit successfully", async () => { + const getId = 0 + const setId = 0 + const spells = [ + { + connector: incentiveConnectorName, + method: "deposit", + args: [ + WETH_ADDR, + DAI_ADDR, + ethers.utils.parseEther("10"), + getId, + setId + ] + } + ] + + const tx = await dsaWallet0.connect(wallet0).cast(...encodeSpells(spells), wallet0.address) + await tx.wait(); + }) + + it("Should harvest successfully", async () => { + const setId = 0 + const spells = [ + { + connector: incentiveConnectorName, + method: "harvest", + args: [ + WETH_ADDR, + DAI_ADDR, + setId + ] + } + ] + + const tx = await dsaWallet0.connect(wallet0).cast(...encodeSpells(spells), wallet0.address) + await tx.wait(); + }) + + it("Should harvest and withdraw successfully", async () => { + const getId = 0 + const setId = 0 + const spells = [ + { + connector: incentiveConnectorName, + method: "withdrawAndHarvest", + args: [ + WETH_ADDR, + DAI_ADDR, + ethers.utils.parseEther("1"), + getId, + setId + ] + } + ] + + const tx = await dsaWallet0.connect(wallet0).cast(...encodeSpells(spells), wallet0.address) + await tx.wait(); + }) + + it("Should withdraw successfully", async () => { + const getId = 0 + const setId = 0 + const spells = [ + { + connector: incentiveConnectorName, + method: "withdraw", + args: [ + WETH_ADDR, + DAI_ADDR, + ethers.utils.parseEther("1"), + getId, + setId + ] + } + ] + + const tx = await dsaWallet0.connect(wallet0).cast(...encodeSpells(spells), wallet0.address) + await tx.wait(); + }) + }) + }).timeout(10000000000); + + it("Should buy successfully", async function () { + const ethAmount = ethers.utils.parseEther("0.1") // 1 ETH + const daiUnitAmount = ethers.utils.parseEther("4000") // 1 ETH + const ethAddress = "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee" + + const getId = "0" + const setId = "0" + + const spells = [ + { + connector: connectorName, + method: "buy", + args: [ + ethAddress, + DAI_ADDR, + ethAmount, + daiUnitAmount, + getId, + setId + ] + } + ] + + const tx = await dsaWallet0.connect(wallet0).cast(...encodeSpells(spells), wallet1.address) + let receipt = await tx.wait() + }); + }); +}) \ No newline at end of file From 7b8659b91cbe08bd148b43a0fe31802448969b75 Mon Sep 17 00:00:00 2001 From: pradyuman-verma Date: Sun, 12 Dec 2021 01:33:32 +0530 Subject: [PATCH 09/15] update --- test/quickswap-polygon/quickswap.test.js | 169 ------------- test/sushiswap/sushiswap.test.js | 170 ------------- .../sushiswapIncentive/sushiIncentive.test.js | 237 ------------------ 3 files changed, 576 deletions(-) delete mode 100644 test/quickswap-polygon/quickswap.test.js delete mode 100644 test/sushiswap/sushiswap.test.js delete mode 100644 test/sushiswapIncentive/sushiIncentive.test.js diff --git a/test/quickswap-polygon/quickswap.test.js b/test/quickswap-polygon/quickswap.test.js deleted file mode 100644 index e9d2d53b..00000000 --- a/test/quickswap-polygon/quickswap.test.js +++ /dev/null @@ -1,169 +0,0 @@ -const { expect } = require("chai"); -const hre = require("hardhat"); -const { waffle, ethers } = hre; -const { provider } = waffle - -const deployAndEnableConnector = require("../../scripts/deployAndEnableConnector.js") -const buildDSAv2 = require("../../scripts/buildDSAv2") -const encodeSpells = require("../../scripts/encodeSpells.js") -const getMasterSigner = require("../../scripts/getMasterSigner") -const addLiquidity = require("../../scripts/addLiquidity"); - -const addresses = require("../../scripts/constant/addresses"); -const abis = require("../../scripts/constant/abis"); - -const connectV2QuickswapArtifacts = require("../../artifacts/contracts/polygon/connectors/quickswap/main.sol/ConnectV2Quickswap.json"); - -const DAI_ADDR = "0x8f3cf7ad23cd3cadbd9735aff958023239c6a063" - -describe("Quickswap", function () { - const connectorName = "Quickpswap-v1.1" - - let dsaWallet0 - let masterSigner; - let instaConnectorsV2; - let connector; - - const wallets = provider.getWallets() - const [wallet0, wallet1, wallet2, wallet3] = wallets - before(async () => { - // await hre.network.provider.request({ - // method: "hardhat_reset", - // params: [ - // { - // forking: { - // jsonRpcUrl: hre.config.networks.hardhat.forking.url, - // blockNumber: 13005785, - // }, - // }, - // ], - // }); - masterSigner = await getMasterSigner(wallet3) - instaConnectorsV2 = await ethers.getContractAt(abis.core.connectorsV2, addresses.core.connectorsV2); - connector = await deployAndEnableConnector({ - connectorName, - contractArtifact: connectV2QuickswapArtifacts, - 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(!!masterSigner.address).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 ETH & 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("100000")); - }); - - it("Deposit ETH & 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("100000")); - }); - }); - - describe("Main", function () { - it("Should deposit successfully", async function () { - const ethAmount = ethers.utils.parseEther("100") // 1 ETH - const daiUnitAmount = ethers.utils.parseUnits("4", 6) // 1 ETH - const usdtAmount = ethers.utils.parseEther("400") / Math.pow(10, 12) // 1 ETH - const ethAddress = "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE" - - const getId = "0" - const setId = "0" - - const spells = [ - { - connector: connectorName, - method: "deposit", - args: [ - ethAddress, - DAI_ADDR, - ethAmount, - 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 ethAmount = ethers.utils.parseEther("0.1") // 1 ETH - const ethAddress = "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee" - - const getId = "0" - const setIds = ["0", "0"] - - const spells = [ - { - connector: connectorName, - method: "withdraw", - args: [ - ethAddress, - DAI_ADDR, - ethAmount, - 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 ethAmount = ethers.utils.parseEther("0.1") // 1 ETH - const daiUnitAmount = ethers.utils.parseEther("4000") // 1 ETH - const ethAddress = "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee" - - const getId = "0" - const setId = "0" - - const spells = [ - { - connector: connectorName, - method: "buy", - args: [ - ethAddress, - DAI_ADDR, - ethAmount, - daiUnitAmount, - getId, - setId - ] - } - ] - - const tx = await dsaWallet0.connect(wallet0).cast(...encodeSpells(spells), wallet1.address) - let receipt = await tx.wait() - }); - }); -}) diff --git a/test/sushiswap/sushiswap.test.js b/test/sushiswap/sushiswap.test.js deleted file mode 100644 index baaf3876..00000000 --- a/test/sushiswap/sushiswap.test.js +++ /dev/null @@ -1,170 +0,0 @@ -const { expect } = require("chai"); -const hre = require("hardhat"); -const { waffle, ethers } = hre; -const { provider } = waffle - -const deployAndEnableConnector = require("../../scripts/deployAndEnableConnector.js") -const buildDSAv2 = require("../../scripts/buildDSAv2") -const encodeSpells = require("../../scripts/encodeSpells.js") -const getMasterSigner = require("../../scripts/getMasterSigner") -const addLiquidity = require("../../scripts/addLiquidity"); - -const addresses = require("../../scripts/constant/addresses"); -const abis = require("../../scripts/constant/abis"); - -const connectV2SushiswapArtifacts = require("../../artifacts/contracts/mainnet/connectors/sushiswap/main.sol/ConnectV2Sushiswap.json"); - -const DAI_ADDR = "0x6b175474e89094c44da98b954eedeac495271d0f" - -describe("Sushiswap", function () { - const connectorName = "Sushiswap-v1" - - let dsaWallet0 - let masterSigner; - let instaConnectorsV2; - let connector; - - const wallets = provider.getWallets() - const [wallet0, wallet1, wallet2, wallet3] = wallets - before(async () => { - await hre.network.provider.request({ - method: "hardhat_reset", - params: [ - { - forking: { - jsonRpcUrl: hre.config.networks.hardhat.forking.url, - blockNumber: 13005785, - }, - }, - ], - }); - masterSigner = await getMasterSigner(wallet3) - instaConnectorsV2 = await ethers.getContractAt(abis.core.connectorsV2, addresses.core.connectorsV2); - connector = await deployAndEnableConnector({ - connectorName, - contractArtifact: connectV2SushiswapArtifacts, - 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(!!masterSigner.address).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 ETH & 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("100000")); - }); - - it("Deposit ETH & 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("100000")); - }); - }); - - describe("Main", function () { - - it("Should deposit successfully", async function () { - const ethAmount = ethers.utils.parseEther("0.1") // 1 ETH - const daiUnitAmount = ethers.utils.parseEther("4000") // 1 ETH - const usdtAmount = ethers.utils.parseEther("400") / Math.pow(10, 12) // 1 ETH - const ethAddress = "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee" - - const getId = "0" - const setId = "0" - - const spells = [ - { - connector: connectorName, - method: "deposit", - args: [ - ethAddress, - DAI_ADDR, - ethAmount, - 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 ethAmount = ethers.utils.parseEther("0.1") // 1 ETH - const ethAddress = "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee" - - const getId = "0" - const setIds = ["0", "0"] - - const spells = [ - { - connector: connectorName, - method: "withdraw", - args: [ - ethAddress, - DAI_ADDR, - ethAmount, - 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 ethAmount = ethers.utils.parseEther("0.1") // 1 ETH - const daiUnitAmount = ethers.utils.parseEther("4000") // 1 ETH - const ethAddress = "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee" - - const getId = "0" - const setId = "0" - - const spells = [ - { - connector: connectorName, - method: "buy", - args: [ - ethAddress, - DAI_ADDR, - ethAmount, - daiUnitAmount, - getId, - setId - ] - } - ] - - const tx = await dsaWallet0.connect(wallet0).cast(...encodeSpells(spells), wallet1.address) - let receipt = await tx.wait() - }); - }); -}) \ No newline at end of file diff --git a/test/sushiswapIncentive/sushiIncentive.test.js b/test/sushiswapIncentive/sushiIncentive.test.js deleted file mode 100644 index 1b2fd01b..00000000 --- a/test/sushiswapIncentive/sushiIncentive.test.js +++ /dev/null @@ -1,237 +0,0 @@ -const { expect } = require("chai"); -const hre = require("hardhat"); -const { waffle, ethers } = hre; -const { provider } = waffle - -const deployAndEnableConnector = require("../../scripts/deployAndEnableConnector.js") -const buildDSAv2 = require("../../scripts/buildDSAv2") -const encodeSpells = require("../../scripts/encodeSpells.js") -const getMasterSigner = require("../../scripts/getMasterSigner") -const addLiquidity = require("../../scripts/addLiquidity"); - -const addresses = require("../../scripts/constant/addresses"); -const abis = require("../../scripts/constant/abis"); - -const connectV2SushiswapArtifacts = require("../../artifacts/contracts/mainnet/connectors/sushiswap/main.sol/ConnectV2Sushiswap.json"); -const connectV2SushiswapIncentiveArtifacts = require("../../artifacts/contracts/mainnet/connectors/sushi-incentive/main.sol/ConnectV2SushiswapIncentive.json"); - -const DAI_ADDR = "0x6b175474e89094c44da98b954eedeac495271d0f" -const WETH_ADDR = "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2" - -describe("Sushiswap", function () { - const connectorName = "Sushiswap-v1" - const incentiveConnectorName = "Sushiswp-Incentive-v1" - - let dsaWallet0 - let masterSigner; - let instaConnectorsV2; - let connector, connectorIncentive; - - const wallets = provider.getWallets() - const [wallet0, wallet1, wallet2, wallet3] = wallets - before(async () => { - await hre.network.provider.request({ - method: "hardhat_reset", - params: [ - { - forking: { - jsonRpcUrl: hre.config.networks.hardhat.forking.url, - blockNumber: 13005785, - }, - }, - ], - }); - masterSigner = await getMasterSigner(wallet3) - instaConnectorsV2 = await ethers.getContractAt(abis.core.connectorsV2, addresses.core.connectorsV2); - connector = await deployAndEnableConnector({ - connectorName, - contractArtifact: connectV2SushiswapArtifacts, - signer: masterSigner, - connectors: instaConnectorsV2 - }) - console.log("Connector address", connector.address) - - connectorIncentive = await deployAndEnableConnector({ - connectorName: incentiveConnectorName, - contractArtifact: connectV2SushiswapIncentiveArtifacts, - signer: masterSigner, - connectors: instaConnectorsV2 - }) - console.log("Incentive Connector address", connectorIncentive.address) - }) - - it("Should have contracts deployed.", async function () { - expect(!!instaConnectorsV2.address).to.be.true; - expect(!!connector.address).to.be.true; - expect(!!masterSigner.address).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 ETH & 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("100000")); - }); - - it("Deposit ETH & 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("100000")); - }); - }); - - describe("Main", function () { - - it("Should deposit successfully", async function () { - const ethAmount = ethers.utils.parseEther("2") // 1 ETH - const daiUnitAmount = ethers.utils.parseEther("4000") // 1 ETH - const usdtAmount = ethers.utils.parseEther("400") / Math.pow(10, 12) // 1 ETH - const ethAddress = "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee" - - const getId = "0" - const setId = "0" - - const spells = [ - { - connector: connectorName, - method: "deposit", - args: [ - ethAddress, - DAI_ADDR, - ethAmount, - daiUnitAmount, - "500000000000000000", - getId, - setId - ], - } - ] - - const tx = await dsaWallet0.connect(wallet0).cast(...encodeSpells(spells), wallet1.address) - await tx.wait() - - describe("Incentive", () => { - it("Should deposit successfully", async () => { - const getId = 0 - const setId = 0 - const spells = [ - { - connector: incentiveConnectorName, - method: "deposit", - args: [ - WETH_ADDR, - DAI_ADDR, - ethers.utils.parseEther("10"), - getId, - setId - ] - } - ] - - const tx = await dsaWallet0.connect(wallet0).cast(...encodeSpells(spells), wallet0.address) - await tx.wait(); - }) - - it("Should harvest successfully", async () => { - const setId = 0 - const spells = [ - { - connector: incentiveConnectorName, - method: "harvest", - args: [ - WETH_ADDR, - DAI_ADDR, - setId - ] - } - ] - - const tx = await dsaWallet0.connect(wallet0).cast(...encodeSpells(spells), wallet0.address) - await tx.wait(); - }) - - it("Should harvest and withdraw successfully", async () => { - const getId = 0 - const setId = 0 - const spells = [ - { - connector: incentiveConnectorName, - method: "withdrawAndHarvest", - args: [ - WETH_ADDR, - DAI_ADDR, - ethers.utils.parseEther("1"), - getId, - setId - ] - } - ] - - const tx = await dsaWallet0.connect(wallet0).cast(...encodeSpells(spells), wallet0.address) - await tx.wait(); - }) - - it("Should withdraw successfully", async () => { - const getId = 0 - const setId = 0 - const spells = [ - { - connector: incentiveConnectorName, - method: "withdraw", - args: [ - WETH_ADDR, - DAI_ADDR, - ethers.utils.parseEther("1"), - getId, - setId - ] - } - ] - - const tx = await dsaWallet0.connect(wallet0).cast(...encodeSpells(spells), wallet0.address) - await tx.wait(); - }) - }) - }).timeout(10000000000); - - it("Should buy successfully", async function () { - const ethAmount = ethers.utils.parseEther("0.1") // 1 ETH - const daiUnitAmount = ethers.utils.parseEther("4000") // 1 ETH - const ethAddress = "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee" - - const getId = "0" - const setId = "0" - - const spells = [ - { - connector: connectorName, - method: "buy", - args: [ - ethAddress, - DAI_ADDR, - ethAmount, - daiUnitAmount, - getId, - setId - ] - } - ] - - const tx = await dsaWallet0.connect(wallet0).cast(...encodeSpells(spells), wallet1.address) - let receipt = await tx.wait() - }); - }); -}) \ No newline at end of file From 494b5fd7c4135e52dc749c27f7af3d2f93c7185b Mon Sep 17 00:00:00 2001 From: pradyuman-verma Date: Sun, 12 Dec 2021 01:58:53 +0530 Subject: [PATCH 10/15] fixed bugs --- .../polygon/connectors/quickswap/events.sol | 8 -- .../connectors/quickswap/interface.sol | 53 ---------- .../polygon/connectors/quickswap/main.sol | 100 ------------------ hardhat.config.js | 90 ---------------- 4 files changed, 251 deletions(-) delete mode 100644 hardhat.config.js diff --git a/contracts/polygon/connectors/quickswap/events.sol b/contracts/polygon/connectors/quickswap/events.sol index 5f8c0f48..c8fc41d6 100644 --- a/contracts/polygon/connectors/quickswap/events.sol +++ b/contracts/polygon/connectors/quickswap/events.sol @@ -20,11 +20,7 @@ contract Events { uint256 getId, uint256[] setId ); -<<<<<<< HEAD -======= - ->>>>>>> d9a7bfba85acceb302ac1d1dd854e9b380976557 event LogBuy( address indexed buyToken, address indexed sellToken, @@ -42,8 +38,4 @@ contract Events { uint256 getId, uint256 setId ); -<<<<<<< HEAD } -======= -} ->>>>>>> d9a7bfba85acceb302ac1d1dd854e9b380976557 diff --git a/contracts/polygon/connectors/quickswap/interface.sol b/contracts/polygon/connectors/quickswap/interface.sol index 65c0482d..438d89c3 100644 --- a/contracts/polygon/connectors/quickswap/interface.sol +++ b/contracts/polygon/connectors/quickswap/interface.sol @@ -2,16 +2,12 @@ pragma solidity ^0.7.0; interface IQuickSwapRouter { function factory() external pure returns (address); -<<<<<<< HEAD -======= ->>>>>>> d9a7bfba85acceb302ac1d1dd854e9b380976557 function WETH() external pure returns (address); function addLiquidity( address tokenA, address tokenB, -<<<<<<< HEAD uint256 amountADesired, uint256 amountBDesired, uint256 amountAMin, @@ -98,53 +94,4 @@ interface IQuickSwapFactory { function createPair(address tokenA, address tokenB) external returns (address pair); -======= - 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 IQuickSwapFactory { - 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); ->>>>>>> d9a7bfba85acceb302ac1d1dd854e9b380976557 } diff --git a/contracts/polygon/connectors/quickswap/main.sol b/contracts/polygon/connectors/quickswap/main.sol index de7a1926..2cc07049 100644 --- a/contracts/polygon/connectors/quickswap/main.sol +++ b/contracts/polygon/connectors/quickswap/main.sol @@ -5,15 +5,9 @@ pragma solidity ^0.7.0; * @dev Decentralized Exchange. */ -<<<<<<< HEAD import {TokenInterface} from "../../common/interfaces.sol"; import {Helpers} from "./helpers.sol"; import {Events} from "./events.sol"; -======= -import { TokenInterface } from "../../common/interfaces.sol"; -import { Helpers } from "./helpers.sol"; -import { Events } from "./events.sol"; ->>>>>>> d9a7bfba85acceb302ac1d1dd854e9b380976557 abstract contract QuickpswapResolver is Helpers, Events { /** @@ -26,11 +20,7 @@ abstract contract QuickpswapResolver is Helpers, Events { * @param slippage Slippage amount. * @param getId ID to retrieve amtA. * @param setId ID stores the amount of pools tokens received. -<<<<<<< HEAD */ -======= - */ ->>>>>>> d9a7bfba85acceb302ac1d1dd854e9b380976557 function deposit( address tokenA, address tokenB, @@ -39,7 +29,6 @@ abstract contract QuickpswapResolver is Helpers, Events { uint256 slippage, uint256 getId, uint256 setId -<<<<<<< HEAD ) external payable @@ -66,22 +55,6 @@ abstract contract QuickpswapResolver is Helpers, Events { getId, 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); ->>>>>>> d9a7bfba85acceb302ac1d1dd854e9b380976557 } /** @@ -94,11 +67,7 @@ abstract contract QuickpswapResolver is Helpers, Events { * @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. -<<<<<<< HEAD */ -======= - */ ->>>>>>> d9a7bfba85acceb302ac1d1dd854e9b380976557 function withdraw( address tokenA, address tokenB, @@ -107,7 +76,6 @@ abstract contract QuickpswapResolver is Helpers, Events { uint256 unitAmtB, uint256 getId, uint256[] calldata setIds -<<<<<<< HEAD ) external payable @@ -116,12 +84,6 @@ abstract contract QuickpswapResolver is Helpers, Events { uint256 _amt = getUint(getId, uniAmt); (uint256 _amtA, uint256 _amtB, uint256 _uniAmt) = _removeLiquidity( -======= - ) external payable returns (string memory _eventName, bytes memory _eventParam) { - uint _amt = getUint(getId, uniAmt); - - (uint _amtA, uint _amtB, uint _uniAmt) = _removeLiquidity( ->>>>>>> d9a7bfba85acceb302ac1d1dd854e9b380976557 tokenA, tokenB, _amt, @@ -131,7 +93,6 @@ abstract contract QuickpswapResolver is Helpers, Events { setUint(setIds[0], _amtA); setUint(setIds[1], _amtB); -<<<<<<< HEAD _eventName = "LogWithdrawLiquidity(address,address,uint256,uint256,uint256,uint256,uint256[])"; _eventParam = abi.encode( @@ -143,11 +104,6 @@ abstract contract QuickpswapResolver is Helpers, Events { getId, setIds ); -======= - - _eventName = "LogWithdrawLiquidity(address,address,uint256,uint256,uint256,uint256,uint256[])"; - _eventParam = abi.encode(tokenA, tokenB, _amtA, _amtB, _uniAmt, getId, setIds); ->>>>>>> d9a7bfba85acceb302ac1d1dd854e9b380976557 } /** @@ -159,11 +115,7 @@ abstract contract QuickpswapResolver is Helpers, Events { * @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. -<<<<<<< HEAD */ -======= - */ ->>>>>>> d9a7bfba85acceb302ac1d1dd854e9b380976557 function buy( address buyAddr, address sellAddr, @@ -171,7 +123,6 @@ abstract contract QuickpswapResolver is Helpers, Events { uint256 unitAmt, uint256 getId, uint256 setId -<<<<<<< HEAD ) external payable @@ -189,34 +140,18 @@ abstract contract QuickpswapResolver is Helpers, Events { uint256 _slippageAmt = convert18ToDec( _sellAddr.decimals(), -======= - ) external payable returns (string memory _eventName, bytes memory _eventParam) { - uint _buyAmt = getUint(getId, buyAmt); - (TokenInterface _buyAddr, TokenInterface _sellAddr) = changeMaticAddress(buyAddr, sellAddr); - address[] memory paths = getPaths(address(_buyAddr), address(_sellAddr)); - - uint _slippageAmt = convert18ToDec(_sellAddr.decimals(), ->>>>>>> d9a7bfba85acceb302ac1d1dd854e9b380976557 wmul(unitAmt, convertTo18(_buyAddr.decimals(), _buyAmt)) ); checkPair(paths); -<<<<<<< HEAD uint256 _expectedAmt = getExpectedSellAmt(paths, _buyAmt); -======= - uint _expectedAmt = getExpectedSellAmt(paths, _buyAmt); ->>>>>>> d9a7bfba85acceb302ac1d1dd854e9b380976557 require(_slippageAmt >= _expectedAmt, "Too much slippage"); bool isEth = address(_sellAddr) == wmaticAddr; convertMaticToWmatic(isEth, _sellAddr, _expectedAmt); approve(_sellAddr, address(router), _expectedAmt); -<<<<<<< HEAD uint256 _sellAmt = router.swapTokensForExactTokens( -======= - uint _sellAmt = router.swapTokensForExactTokens( ->>>>>>> d9a7bfba85acceb302ac1d1dd854e9b380976557 _buyAmt, _expectedAmt, paths, @@ -230,7 +165,6 @@ abstract contract QuickpswapResolver is Helpers, Events { setUint(setId, _sellAmt); _eventName = "LogBuy(address,address,uint256,uint256,uint256,uint256)"; -<<<<<<< HEAD _eventParam = abi.encode( buyAddr, sellAddr, @@ -239,9 +173,6 @@ abstract contract QuickpswapResolver is Helpers, Events { getId, setId ); -======= - _eventParam = abi.encode(buyAddr, sellAddr, _buyAmt, _sellAmt, getId, setId); ->>>>>>> d9a7bfba85acceb302ac1d1dd854e9b380976557 } /** @@ -253,11 +184,7 @@ abstract contract QuickpswapResolver is Helpers, Events { * @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. -<<<<<<< HEAD */ -======= - */ ->>>>>>> d9a7bfba85acceb302ac1d1dd854e9b380976557 function sell( address buyAddr, address sellAddr, @@ -265,7 +192,6 @@ abstract contract QuickpswapResolver is Helpers, Events { uint256 unitAmt, uint256 getId, uint256 setId -<<<<<<< HEAD ) external payable @@ -289,40 +215,18 @@ abstract contract QuickpswapResolver is Helpers, Events { uint256 _slippageAmt = convert18ToDec( _buyAddr.decimals(), -======= - ) external payable returns (string memory _eventName, bytes memory _eventParam) { - uint _sellAmt = getUint(getId, sellAmt); - (TokenInterface _buyAddr, TokenInterface _sellAddr) = changeMaticAddress(buyAddr, sellAddr); - address[] memory paths = getPaths(address(_buyAddr), address(_sellAddr)); - - if (_sellAmt == uint(-1)) { - _sellAmt = sellAddr == maticAddr ? - address(this).balance : - _sellAddr.balanceOf(address(this)); - } - - uint _slippageAmt = convert18ToDec(_buyAddr.decimals(), ->>>>>>> d9a7bfba85acceb302ac1d1dd854e9b380976557 wmul(unitAmt, convertTo18(_sellAddr.decimals(), _sellAmt)) ); checkPair(paths); -<<<<<<< HEAD uint256 _expectedAmt = getExpectedBuyAmt(paths, _sellAmt); -======= - uint _expectedAmt = getExpectedBuyAmt(paths, _sellAmt); ->>>>>>> d9a7bfba85acceb302ac1d1dd854e9b380976557 require(_slippageAmt <= _expectedAmt, "Too much slippage"); bool isEth = address(_sellAddr) == wmaticAddr; convertMaticToWmatic(isEth, _sellAddr, _sellAmt); approve(_sellAddr, address(router), _sellAmt); -<<<<<<< HEAD uint256 _buyAmt = router.swapExactTokensForTokens( -======= - uint _buyAmt = router.swapExactTokensForTokens( ->>>>>>> d9a7bfba85acceb302ac1d1dd854e9b380976557 _sellAmt, _expectedAmt, paths, @@ -336,7 +240,6 @@ abstract contract QuickpswapResolver is Helpers, Events { setUint(setId, _buyAmt); _eventName = "LogSell(address,address,uint256,uint256,uint256,uint256)"; -<<<<<<< HEAD _eventParam = abi.encode( buyAddr, sellAddr, @@ -345,9 +248,6 @@ abstract contract QuickpswapResolver is Helpers, Events { getId, setId ); -======= - _eventParam = abi.encode(buyAddr, sellAddr, _buyAmt, _sellAmt, getId, setId); ->>>>>>> d9a7bfba85acceb302ac1d1dd854e9b380976557 } } diff --git a/hardhat.config.js b/hardhat.config.js deleted file mode 100644 index 7d88c978..00000000 --- a/hardhat.config.js +++ /dev/null @@ -1,90 +0,0 @@ -require("@nomiclabs/hardhat-waffle"); -require("@nomiclabs/hardhat-ethers"); -require("@tenderly/hardhat-tenderly"); -require("@nomiclabs/hardhat-etherscan"); -require("@nomiclabs/hardhat-web3"); -require("hardhat-deploy"); -require("hardhat-deploy-ethers"); -require("dotenv").config(); - -const { utils } = require("ethers"); - -const PRIVATE_KEY = process.env.PRIVATE_KEY; -const ALCHEMY_ID = process.env.ALCHEMY_ID; -const ETHERSCAN_API_KEY = process.env.ETHERSCAN_API_KEY; - -if (!process.env.ALCHEMY_ID) { - throw new Error("ENV Variable ALCHEMY_ID not set!"); -} - -/** - * @type import('hardhat/config').HardhatUserConfig - */ -module.exports = { - solidity: { - compilers: [ - { - version: "0.7.6", - settings: { - optimizer: { - enabled: true, - runs: 200, - }, - }, - }, - { - version: "0.6.0", - }, - { - version: "0.6.2", - }, - { - version: "0.6.12", - }, - { - version: "0.6.5", - }, - ], - }, - networks: { - // defaultNetwork: "hardhat", - kovan: { - url: `https://eth-kovan.alchemyapi.io/v2/${ALCHEMY_ID}`, - accounts: [`0x${PRIVATE_KEY}`], - }, - mainnet: { - url: `https://eth-mainnet.alchemyapi.io/v2/${ALCHEMY_ID}`, - accounts: [`0x${PRIVATE_KEY}`], - timeout: 150000, - gasPrice: parseInt(utils.parseUnits("30", "gwei")), - }, - rinkeby: { - url: `https://eth-rinkeby.alchemyapi.io/v2/${ALCHEMY_ID}`, - accounts: [`0x${PRIVATE_KEY}`], - timeout: 150000, - }, - hardhat: { - forking: { - url: `https://eth-mainnet.alchemyapi.io/v2/${ALCHEMY_ID}`, - blockNumber: 12696000, - }, - blockGasLimit: 12000000, - }, - matic: { - url: "https://rpc-mainnet.maticvigil.com/", - accounts: [`0x${PRIVATE_KEY}`], - timeout: 150000, - gasPrice: parseInt(utils.parseUnits("1", "gwei")), - }, - }, - etherscan: { - apiKey: ETHERSCAN_API_KEY, - }, - tenderly: { - project: process.env.TENDERLY_PROJECT, - username: process.env.TENDERLY_USERNAME, - }, - mocha: { - timeout: 100 * 1000, - }, -}; \ No newline at end of file From 95ed18984f79c0adb70e1649de1a3197e97771b5 Mon Sep 17 00:00:00 2001 From: pradyuman-verma Date: Mon, 13 Dec 2021 21:17:28 +0530 Subject: [PATCH 11/15] added sushiswap tests --- .../mainnet/connectors/sushiswap/helpers.sol | 2 +- test/mainnet/sushiswap/sushiswap.test.ts | 331 ++++++++++++++++++ .../sushiswapIncentive.test.ts | 235 +++++++++++++ 3 files changed, 567 insertions(+), 1 deletion(-) create mode 100644 test/mainnet/sushiswap/sushiswap.test.ts create mode 100644 test/mainnet/sushiswapIncentive/sushiswapIncentive.test.ts diff --git a/contracts/mainnet/connectors/sushiswap/helpers.sol b/contracts/mainnet/connectors/sushiswap/helpers.sol index a1baa4c5..ea29a03f 100644 --- a/contracts/mainnet/connectors/sushiswap/helpers.sol +++ b/contracts/mainnet/connectors/sushiswap/helpers.sol @@ -102,7 +102,7 @@ abstract contract Helpers is DSMath, Basic { _amtA, _amtB, minAmtA, - minAmtA, + minAmtB, address(this), block.timestamp + 1 ); diff --git a/test/mainnet/sushiswap/sushiswap.test.ts b/test/mainnet/sushiswap/sushiswap.test.ts new file mode 100644 index 00000000..8257b47d --- /dev/null +++ b/test/mainnet/sushiswap/sushiswap.test.ts @@ -0,0 +1,331 @@ +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 { addresses } from "../../../scripts/tests/mainnet/addresses"; +import { abis } from "../../../scripts/constant/abis"; +import { ConnectV2Sushiswap__factory, ConnectV2Sushiswap } from "../../../typechain"; +import type { Signer, Contract } from "ethers"; + +const DAI_ADDR = "0x6b175474e89094c44da98b954eedeac495271d0f" + +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: ConnectV2Sushiswap__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 ETH & 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("100000")); + }); + + it("Deposit ETH & 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("100000")); + }); + }); + + describe("Main", function () { + + it("Should deposit successfully", async function () { + const ethAmount = ethers.utils.parseEther("0.1") // 1 ETH + const daiUnitAmount = ethers.utils.parseEther("4000") // 1 ETH + const ethAddress = "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee" + + const getId = "0" + const setId = "0" + + const spells = [ + { + connector: connectorName, + method: "deposit", + args: [ + ethAddress, + DAI_ADDR, + ethAmount, + 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 ethAmount = ethers.utils.parseEther("0.1") // 1 ETH + const ethAddress = "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee" + + const getId = "0" + const setIds = ["0", "0"] + + const spells = [ + { + connector: connectorName, + method: "withdraw", + args: [ + ethAddress, + DAI_ADDR, + ethAmount, + 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 ethAmount = ethers.utils.parseEther("0.1") // 1 ETH + const daiUnitAmount = ethers.utils.parseEther("4000") // 1 ETH + const ethAddress = "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee" + + const getId = "0" + const setId = "0" + + const spells = [ + { + connector: connectorName, + method: "buy", + args: [ + ethAddress, + DAI_ADDR, + ethAmount, + daiUnitAmount, + getId, + setId + ] + } + ] + + const tx = await dsaWallet0.connect(wallet0).cast(...encodeSpells(spells), wallet1.address) + let receipt = await tx.wait() + }); + }); +}) + +// describe("Sushiswap", function() { +// const connectorName = "Sushiswap-v1.1"; + +// 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: ConnectV2Sushiswap__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 ETH & 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("100000") +// ); +// }); + +// it("Deposit ETH & 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("100000") +// ); +// }); +// }); + +// describe("Main", function() { +// it("Should deposit successfully", async function() { +// const ethAmount = ethers.utils.parseEther("1000"); // 1 ETH +// const daiUnitAmount = ethers.utils.parseUnits("4", 18); // 1 ETH +// const usdtAmount = Number(ethers.utils.parseEther("400")) / Math.pow(10, 12); // 1 ETH +// const ethAddress = "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE"; + +// const getId = "0"; +// const setId = "0"; + +// const spells = [ +// { +// connector: connectorName, +// method: "deposit", +// args: [ +// ethAddress, +// DAI_ADDR, +// ethAmount, +// 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 ethAmount = ethers.utils.parseEther("0.1"); // 1 ETH +// const ethAddress = "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee"; + +// const getId = "0"; +// const setIds = ["0", "0"]; + +// const spells = [ +// { +// connector: connectorName, +// method: "withdraw", +// args: [ethAddress, DAI_ADDR, ethAmount, 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 ethAmount = ethers.utils.parseEther("0.1"); // 1 ETH +// const daiUnitAmount = ethers.utils.parseEther("4000"); // 1 ETH +// const ethAddress = "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee"; + +// const getId = "0"; +// const setId = "0"; + +// const spells = [ +// { +// connector: connectorName, +// method: "buy", +// args: [ethAddress, DAI_ADDR, ethAmount, daiUnitAmount, getId, setId], +// }, +// ]; + +// const tx = await dsaWallet0 +// .connect(wallet0) +// .cast(...encodeSpells(spells), wallet1.address); +// let receipt = await tx.wait(); +// }); +// }); +// }); diff --git a/test/mainnet/sushiswapIncentive/sushiswapIncentive.test.ts b/test/mainnet/sushiswapIncentive/sushiswapIncentive.test.ts new file mode 100644 index 00000000..b8a9c32a --- /dev/null +++ b/test/mainnet/sushiswapIncentive/sushiswapIncentive.test.ts @@ -0,0 +1,235 @@ +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 {addresses} from "../../../scripts/tests/mainnet/addresses"; +import {abis} from "../../../scripts/constant/abis"; + +import { ConnectV2Sushiswap__factory, ConnectV2Sushiswap, ConnectV2SushiswapIncentive, ConnectV2SushiswapIncentive__factory } from "../../../typechain"; +import { Contract, Signer } from "ethers"; + +const DAI_ADDR = "0x6b175474e89094c44da98b954eedeac495271d0f" +const WETH_ADDR = "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2" + +describe("Sushiswap", function () { + const connectorName = "Sushiswap-v1" + const incentiveConnectorName = "Sushiswp-Incentive-v1" + + let dsaWallet0: Contract; + let masterSigner: Signer; + let instaConnectorsV2: Contract; + let connector: Contract, connectorIncentive; + + 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: ConnectV2Sushiswap__factory, + signer: masterSigner, + connectors: instaConnectorsV2 + }) + console.log("Connector address", connector.address) + + connectorIncentive = await deployAndEnableConnector({ + connectorName: incentiveConnectorName, + contractArtifact: ConnectV2SushiswapIncentive__factory, + signer: masterSigner, + connectors: instaConnectorsV2 + }) + console.log("Incentive Connector address", connectorIncentive.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 ETH & 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("100000")); + }); + + it("Deposit ETH & 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("100000")); + }); + }); + + describe("Main", function () { + it("Should deposit successfully", async function () { + const ethAmount = ethers.utils.parseEther("2") // 1 ETH + const daiUnitAmount = ethers.utils.parseEther("4000") // 1 ETH + const ethAddress = "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee" + + const getId = "0" + const setId = "0" + + const spells = [ + { + connector: connectorName, + method: "deposit", + args: [ + ethAddress, + DAI_ADDR, + ethAmount, + daiUnitAmount, + "500000000000000000", + getId, + setId + ], + } + ] + + const tx = await dsaWallet0.connect(wallet0).cast(...encodeSpells(spells), wallet1.address) + await tx.wait() + + describe("Incentive", () => { + it("Should deposit successfully", async () => { + const getId = 0 + const setId = 0 + const spells = [ + { + connector: incentiveConnectorName, + method: "deposit", + args: [ + WETH_ADDR, + DAI_ADDR, + ethers.utils.parseEther("10"), + getId, + setId + ] + } + ] + + const tx = await dsaWallet0.connect(wallet0).cast(...encodeSpells(spells), wallet0.address) + await tx.wait(); + }) + + it("Should harvest successfully", async () => { + const setId = 0 + const spells = [ + { + connector: incentiveConnectorName, + method: "harvest", + args: [ + WETH_ADDR, + DAI_ADDR, + setId + ] + } + ] + + const tx = await dsaWallet0.connect(wallet0).cast(...encodeSpells(spells), wallet0.address) + await tx.wait(); + }) + + it("Should harvest and withdraw successfully", async () => { + const getId = 0 + const setId = 0 + const spells = [ + { + connector: incentiveConnectorName, + method: "withdrawAndHarvest", + args: [ + WETH_ADDR, + DAI_ADDR, + ethers.utils.parseEther("1"), + getId, + setId + ] + } + ] + + const tx = await dsaWallet0.connect(wallet0).cast(...encodeSpells(spells), wallet0.address) + await tx.wait(); + }) + + it("Should withdraw successfully", async () => { + const getId = 0 + const setId = 0 + const spells = [ + { + connector: incentiveConnectorName, + method: "withdraw", + args: [ + WETH_ADDR, + DAI_ADDR, + ethers.utils.parseEther("1"), + getId, + setId + ] + } + ] + + const tx = await dsaWallet0.connect(wallet0).cast(...encodeSpells(spells), wallet0.address) + await tx.wait(); + }) + }) + }).timeout(10000000000); + + it("Should buy successfully", async function () { + const ethAmount = ethers.utils.parseEther("0.1") // 1 ETH + const daiUnitAmount = ethers.utils.parseEther("4000") // 1 ETH + const ethAddress = "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee" + + const getId = "0" + const setId = "0" + + const spells = [ + { + connector: connectorName, + method: "buy", + args: [ + ethAddress, + DAI_ADDR, + ethAmount, + daiUnitAmount, + getId, + setId + ] + } + ] + + const tx = await dsaWallet0.connect(wallet0).cast(...encodeSpells(spells), wallet1.address) + let receipt = await tx.wait() + }); + }); +}) From da09b6b1cba620958982df0f6f5a6b6a14ee4f72 Mon Sep 17 00:00:00 2001 From: pradyuman-verma Date: Wed, 15 Dec 2021 16:35:10 +0530 Subject: [PATCH 12/15] updated quickswap --- .../polygon/connectors/quickswap/events.sol | 68 +-- .../polygon/connectors/quickswap/helpers.sol | 326 ++++++------- .../connectors/quickswap/interface.sol | 150 +++--- .../polygon/connectors/quickswap/main.sol | 440 +++++++++--------- 4 files changed, 492 insertions(+), 492 deletions(-) diff --git a/contracts/polygon/connectors/quickswap/events.sol b/contracts/polygon/connectors/quickswap/events.sol index c8fc41d6..9e01ef9d 100644 --- a/contracts/polygon/connectors/quickswap/events.sol +++ b/contracts/polygon/connectors/quickswap/events.sol @@ -1,41 +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 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 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 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 - ); + event LogSell( + address indexed buyToken, + address indexed sellToken, + uint256 buyAmt, + uint256 sellAmt, + uint256 getId, + uint256 setId + ); } diff --git a/contracts/polygon/connectors/quickswap/helpers.sol b/contracts/polygon/connectors/quickswap/helpers.sol index 07316a2c..594b56e1 100644 --- a/contracts/polygon/connectors/quickswap/helpers.sol +++ b/contracts/polygon/connectors/quickswap/helpers.sol @@ -1,184 +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 {IQuickSwapRouter, IQuickSwapFactory} from "./interface.sol"; +import { TokenInterface } from "../../common/interfaces.sol"; +import { DSMath } from "../../common/math.sol"; +import { Basic } from "../../common/basic.sol"; +import { IQuickSwapRouter, IQuickSwapFactory } from "./interface.sol"; abstract contract Helpers is DSMath, Basic { - /** - * @dev IQuickSwapRouter - */ - IQuickSwapRouter internal constant router = - IQuickSwapRouter(0xa5E0829CaCEd8fFDD4De3c43696c57F7D7A678ff); + /** + * @dev IQuickSwapRouter + */ + IQuickSwapRouter internal constant router = + IQuickSwapRouter(0xa5E0829CaCEd8fFDD4De3c43696c57F7D7A678ff); - function getExpectedBuyAmt(address[] memory paths, uint256 sellAmt) - internal - view - returns (uint256 buyAmt) - { - uint256[] memory amts = router.getAmountsOut(sellAmt, paths); - buyAmt = amts[1]; - } + 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 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 = IQuickSwapFactory(router.factory()).getPair( - paths[0], - paths[1] - ); - require(pair != address(0), "No-exchange-address"); - } + function checkPair(address[] memory paths) internal view { + address pair = IQuickSwapFactory(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 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 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) = changeMaticAddress( - tokenA, - tokenB - ); + function _addLiquidity( + address tokenA, + address tokenB, + uint256 _amt, + uint256 unitAmt, + uint256 slippage + ) + internal + returns ( + uint256 _amtA, + uint256 _amtB, + uint256 _liquidity + ) + { + (TokenInterface _tokenA, TokenInterface _tokenB) = changeMaticAddress( + tokenA, + tokenB + ); - _amtA = _amt == uint256(-1) - ? getTokenBal(TokenInterface(tokenA)) - : _amt; - _amtB = convert18ToDec( - _tokenB.decimals(), - wmul(unitAmt, convertTo18(_tokenA.decimals(), _amtA)) - ); + _amtA = _amt == uint256(-1) + ? getTokenBal(TokenInterface(tokenA)) + : _amt; + _amtB = convert18ToDec( + _tokenB.decimals(), + wmul(unitAmt, convertTo18(_tokenA.decimals(), _amtA)) + ); - bool isMatic = address(_tokenA) == wmaticAddr; - convertMaticToWmatic(isMatic, _tokenA, _amtA); + bool isMatic = address(_tokenA) == wmaticAddr; + convertMaticToWmatic(isMatic, _tokenA, _amtA); - isMatic = address(_tokenB) == wmaticAddr; - convertMaticToWmatic(isMatic, _tokenB, _amtB); + isMatic = address(_tokenB) == wmaticAddr; + convertMaticToWmatic(isMatic, _tokenB, _amtB); - approve(_tokenA, address(router), _amtA); - approve(_tokenB, address(router), _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, - minAmtA, - address(this), - block.timestamp + 1 - ); - } + 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 - ); - } + 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 isMatic = address(_tokenA) == wmaticAddr; - convertWmaticToMatic(isMatic, _tokenA, _amtA); + bool isMatic = address(_tokenA) == wmaticAddr; + convertWmaticToMatic(isMatic, _tokenA, _amtA); - isMatic = address(_tokenB) == wmaticAddr; - convertWmaticToMatic(isMatic, _tokenB, _amtB); - } + isMatic = address(_tokenB) == wmaticAddr; + convertWmaticToMatic(isMatic, _tokenB, _amtB); + } - function _getRemoveLiquidityData( - address tokenA, - address tokenB, - uint256 _amt - ) - internal - returns ( - TokenInterface _tokenA, - TokenInterface _tokenB, - uint256 _uniAmt - ) - { - (_tokenA, _tokenB) = changeMaticAddress(tokenA, tokenB); - address exchangeAddr = IQuickSwapFactory(router.factory()).getPair( - address(_tokenA), - address(_tokenB) - ); - require(exchangeAddr != address(0), "pair-not-found."); + function _getRemoveLiquidityData( + address tokenA, + address tokenB, + uint256 _amt + ) + internal + returns ( + TokenInterface _tokenA, + TokenInterface _tokenB, + uint256 _uniAmt + ) + { + (_tokenA, _tokenB) = changeMaticAddress(tokenA, tokenB); + address exchangeAddr = IQuickSwapFactory(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); - } + TokenInterface uniToken = TokenInterface(exchangeAddr); + _uniAmt = _amt == uint256(-1) + ? uniToken.balanceOf(address(this)) + : _amt; + approve(uniToken, address(router), _uniAmt); + } } diff --git a/contracts/polygon/connectors/quickswap/interface.sol b/contracts/polygon/connectors/quickswap/interface.sol index 438d89c3..bd210215 100644 --- a/contracts/polygon/connectors/quickswap/interface.sol +++ b/contracts/polygon/connectors/quickswap/interface.sol @@ -1,97 +1,97 @@ pragma solidity ^0.7.0; interface IQuickSwapRouter { - function factory() external pure returns (address); + function factory() external pure returns (address); - function WETH() external pure returns (address); + function WETH() external pure returns (address); - function addLiquidity( - address tokenA, - address tokenB, - uint256 amountADesired, - uint256 amountBDesired, - uint256 amountAMin, - uint256 amountBMin, - address to, - uint256 deadline - ) - external - returns ( - uint256 amountA, - uint256 amountB, - uint256 liquidity - ); + function addLiquidity( + address tokenA, + address tokenB, + uint256 amountADesired, + uint256 amountBDesired, + uint256 amountAMin, + uint256 amountBMin, + address to, + uint256 deadline + ) + external + returns ( + uint256 amountA, + uint256 amountB, + uint256 liquidity + ); - function removeLiquidity( - address tokenA, - address tokenB, - uint256 liquidity, - uint256 amountAMin, - uint256 amountBMin, - address to, - uint256 deadline - ) external returns (uint256 amountA, uint256 amountB); + function removeLiquidity( + address tokenA, + address tokenB, + uint256 liquidity, + uint256 amountAMin, + uint256 amountBMin, + address to, + uint256 deadline + ) external returns (uint256 amountA, uint256 amountB); - function swapExactTokensForTokens( - uint256 amountIn, - uint256 amountOutMin, - address[] calldata path, - address to, - uint256 deadline - ) external returns (uint256[] memory amounts); + function swapExactTokensForTokens( + uint256 amountIn, + uint256 amountOutMin, + address[] calldata path, + address to, + uint256 deadline + ) external returns (uint256[] memory amounts); - function swapTokensForExactTokens( - uint256 amountOut, - uint256 amountInMax, - address[] calldata path, - address to, - uint256 deadline - ) external returns (uint256[] memory amounts); + function swapTokensForExactTokens( + uint256 amountOut, + uint256 amountInMax, + address[] calldata path, + address to, + uint256 deadline + ) external returns (uint256[] memory amounts); - function quote( - uint256 amountA, - uint256 reserveA, - uint256 reserveB - ) external pure returns (uint256 amountB); + function quote( + uint256 amountA, + uint256 reserveA, + uint256 reserveB + ) external pure returns (uint256 amountB); - function getAmountOut( - uint256 amountIn, - uint256 reserveIn, - uint256 reserveOut - ) external pure returns (uint256 amountOut); + function getAmountOut( + uint256 amountIn, + uint256 reserveIn, + uint256 reserveOut + ) external pure returns (uint256 amountOut); - function getAmountIn( - uint256 amountOut, - uint256 reserveIn, - uint256 reserveOut - ) external pure returns (uint256 amountIn); + function getAmountIn( + uint256 amountOut, + uint256 reserveIn, + uint256 reserveOut + ) external pure returns (uint256 amountIn); - function getAmountsOut(uint256 amountIn, address[] calldata path) - external - view - returns (uint256[] memory amounts); + function getAmountsOut(uint256 amountIn, address[] calldata path) + external + view + returns (uint256[] memory amounts); - function getAmountsIn(uint256 amountOut, address[] calldata path) - external - view - returns (uint256[] memory amounts); + function getAmountsIn(uint256 amountOut, address[] calldata path) + external + view + returns (uint256[] memory amounts); } interface IQuickSwapFactory { - function getPair(address tokenA, address tokenB) - external - view - returns (address pair); + function getPair(address tokenA, address tokenB) + external + view + returns (address pair); - function allPairs(uint256) external view returns (address pair); + function allPairs(uint256) external view returns (address pair); - function allPairsLength() external view returns (uint256); + function allPairsLength() external view returns (uint256); - function feeTo() external view returns (address); + function feeTo() external view returns (address); - function feeToSetter() external view returns (address); + function feeToSetter() external view returns (address); - function createPair(address tokenA, address tokenB) - external - returns (address pair); + function createPair(address tokenA, address tokenB) + external + returns (address pair); } diff --git a/contracts/polygon/connectors/quickswap/main.sol b/contracts/polygon/connectors/quickswap/main.sol index 2cc07049..6973948b 100644 --- a/contracts/polygon/connectors/quickswap/main.sol +++ b/contracts/polygon/connectors/quickswap/main.sol @@ -5,252 +5,252 @@ pragma solidity ^0.7.0; * @dev Decentralized Exchange. */ -import {TokenInterface} from "../../common/interfaces.sol"; -import {Helpers} from "./helpers.sol"; -import {Events} from "./events.sol"; +import { TokenInterface } from "../../common/interfaces.sol"; +import { Helpers } from "./helpers.sol"; +import { Events } from "./events.sol"; abstract contract QuickpswapResolver is Helpers, Events { - /** - * @dev Deposit Liquidity. - * @notice Deposit Liquidity to a QuickSwap 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) - { - uint256 _amt = getUint(getId, amtA); + /** + * @dev Deposit Liquidity. + * @notice Deposit Liquidity to a QuickSwap 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) + { + uint256 _amt = getUint(getId, amtA); - (uint256 _amtA, uint256 _amtB, uint256 _uniAmt) = _addLiquidity( - tokenA, - tokenB, - _amt, - unitAmt, - slippage - ); - setUint(setId, _uniAmt); + (uint256 _amtA, uint256 _amtB, uint256 _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 - ); - } + _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 QuickSwap 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) - { - uint256 _amt = getUint(getId, uniAmt); + /** + * @dev Withdraw Liquidity. + * @notice Withdraw Liquidity from a QuickSwap 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) + { + uint256 _amt = getUint(getId, uniAmt); - (uint256 _amtA, uint256 _amtB, uint256 _uniAmt) = _removeLiquidity( - tokenA, - tokenB, - _amt, - unitAmtA, - unitAmtB - ); + (uint256 _amtA, uint256 _amtB, uint256 _uniAmt) = _removeLiquidity( + tokenA, + tokenB, + _amt, + unitAmtA, + unitAmtB + ); - setUint(setIds[0], _amtA); - setUint(setIds[1], _amtB); + 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 - ); - } + _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 QuickSwap - * @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) - { - uint256 _buyAmt = getUint(getId, buyAmt); - ( - TokenInterface _buyAddr, - TokenInterface _sellAddr - ) = changeMaticAddress(buyAddr, sellAddr); - address[] memory paths = getPaths( - address(_buyAddr), - address(_sellAddr) - ); + /** + * @dev Buy ETH/ERC20_Token. + * @notice Buy a token using a QuickSwap + * @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) + { + uint256 _buyAmt = getUint(getId, buyAmt); + ( + TokenInterface _buyAddr, + TokenInterface _sellAddr + ) = changeMaticAddress(buyAddr, sellAddr); + address[] memory paths = getPaths( + address(_buyAddr), + address(_sellAddr) + ); - uint256 _slippageAmt = convert18ToDec( - _sellAddr.decimals(), - wmul(unitAmt, convertTo18(_buyAddr.decimals(), _buyAmt)) - ); + uint256 _slippageAmt = convert18ToDec( + _sellAddr.decimals(), + wmul(unitAmt, convertTo18(_buyAddr.decimals(), _buyAmt)) + ); - checkPair(paths); - uint256 _expectedAmt = getExpectedSellAmt(paths, _buyAmt); - require(_slippageAmt >= _expectedAmt, "Too much slippage"); + checkPair(paths); + uint256 _expectedAmt = getExpectedSellAmt(paths, _buyAmt); + require(_slippageAmt >= _expectedAmt, "Too much slippage"); - bool isEth = address(_sellAddr) == wmaticAddr; - convertMaticToWmatic(isEth, _sellAddr, _expectedAmt); - approve(_sellAddr, address(router), _expectedAmt); + bool isEth = address(_sellAddr) == wmaticAddr; + convertMaticToWmatic(isEth, _sellAddr, _expectedAmt); + approve(_sellAddr, address(router), _expectedAmt); - uint256 _sellAmt = router.swapTokensForExactTokens( - _buyAmt, - _expectedAmt, - paths, - address(this), - block.timestamp + 1 - )[0]; + uint256 _sellAmt = router.swapTokensForExactTokens( + _buyAmt, + _expectedAmt, + paths, + address(this), + block.timestamp + 1 + )[0]; - isEth = address(_buyAddr) == wmaticAddr; - convertWmaticToMatic(isEth, _buyAddr, _buyAmt); + isEth = address(_buyAddr) == wmaticAddr; + convertWmaticToMatic(isEth, _buyAddr, _buyAmt); - setUint(setId, _sellAmt); + setUint(setId, _sellAmt); - _eventName = "LogBuy(address,address,uint256,uint256,uint256,uint256)"; - _eventParam = abi.encode( - buyAddr, - sellAddr, - _buyAmt, - _sellAmt, - getId, - setId - ); - } + _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 QuickSwap - * @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) - { - uint256 _sellAmt = getUint(getId, sellAmt); - ( - TokenInterface _buyAddr, - TokenInterface _sellAddr - ) = changeMaticAddress(buyAddr, sellAddr); - address[] memory paths = getPaths( - address(_buyAddr), - address(_sellAddr) - ); + /** + * @dev Sell ETH/ERC20_Token. + * @notice Sell a token using a QuickSwap + * @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) + { + uint256 _sellAmt = getUint(getId, sellAmt); + ( + TokenInterface _buyAddr, + TokenInterface _sellAddr + ) = changeMaticAddress(buyAddr, sellAddr); + address[] memory paths = getPaths( + address(_buyAddr), + address(_sellAddr) + ); - if (_sellAmt == uint256(-1)) { - _sellAmt = sellAddr == maticAddr - ? address(this).balance - : _sellAddr.balanceOf(address(this)); - } + if (_sellAmt == uint256(-1)) { + _sellAmt = sellAddr == maticAddr + ? address(this).balance + : _sellAddr.balanceOf(address(this)); + } - uint256 _slippageAmt = convert18ToDec( - _buyAddr.decimals(), - wmul(unitAmt, convertTo18(_sellAddr.decimals(), _sellAmt)) - ); + uint256 _slippageAmt = convert18ToDec( + _buyAddr.decimals(), + wmul(unitAmt, convertTo18(_sellAddr.decimals(), _sellAmt)) + ); - checkPair(paths); - uint256 _expectedAmt = getExpectedBuyAmt(paths, _sellAmt); - require(_slippageAmt <= _expectedAmt, "Too much slippage"); + checkPair(paths); + uint256 _expectedAmt = getExpectedBuyAmt(paths, _sellAmt); + require(_slippageAmt <= _expectedAmt, "Too much slippage"); - bool isEth = address(_sellAddr) == wmaticAddr; - convertMaticToWmatic(isEth, _sellAddr, _sellAmt); - approve(_sellAddr, address(router), _sellAmt); + bool isEth = address(_sellAddr) == wmaticAddr; + convertMaticToWmatic(isEth, _sellAddr, _sellAmt); + approve(_sellAddr, address(router), _sellAmt); - uint256 _buyAmt = router.swapExactTokensForTokens( - _sellAmt, - _expectedAmt, - paths, - address(this), - block.timestamp + 1 - )[1]; + uint256 _buyAmt = router.swapExactTokensForTokens( + _sellAmt, + _expectedAmt, + paths, + address(this), + block.timestamp + 1 + )[1]; - isEth = address(_buyAddr) == wmaticAddr; - convertWmaticToMatic(isEth, _buyAddr, _buyAmt); + isEth = address(_buyAddr) == wmaticAddr; + convertWmaticToMatic(isEth, _buyAddr, _buyAmt); - setUint(setId, _buyAmt); + setUint(setId, _buyAmt); - _eventName = "LogSell(address,address,uint256,uint256,uint256,uint256)"; - _eventParam = abi.encode( - buyAddr, - sellAddr, - _buyAmt, - _sellAmt, - getId, - setId - ); - } + _eventName = "LogSell(address,address,uint256,uint256,uint256,uint256)"; + _eventParam = abi.encode( + buyAddr, + sellAddr, + _buyAmt, + _sellAmt, + getId, + setId + ); + } } contract ConnectV2Quickswap is QuickpswapResolver { - string public constant name = "Quickpswap-v1.1"; + string public constant name = "Quickpswap-v1.1"; } From 99d9d17f23dd2b170bee739277356f9f3cd1c921 Mon Sep 17 00:00:00 2001 From: pradyuman-verma Date: Wed, 15 Dec 2021 16:37:32 +0530 Subject: [PATCH 13/15] updated sushi tests --- test/mainnet/sushiswap/sushiswap.test.ts | 376 ++++++----------------- 1 file changed, 96 insertions(+), 280 deletions(-) diff --git a/test/mainnet/sushiswap/sushiswap.test.ts b/test/mainnet/sushiswap/sushiswap.test.ts index 8257b47d..8c70125b 100644 --- a/test/mainnet/sushiswap/sushiswap.test.ts +++ b/test/mainnet/sushiswap/sushiswap.test.ts @@ -14,318 +14,134 @@ import { abis } from "../../../scripts/constant/abis"; import { ConnectV2Sushiswap__factory, ConnectV2Sushiswap } from "../../../typechain"; import type { Signer, Contract } from "ethers"; -const DAI_ADDR = "0x6b175474e89094c44da98b954eedeac495271d0f" +const DAI_ADDR = "0x6b175474e89094c44da98b954eedeac495271d0f"; describe("Sushiswap", function () { - const connectorName = "Sushiswap-v1" + 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 + 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: ConnectV2Sushiswap__factory, - signer: masterSigner, - connectors: instaConnectorsV2 - }) - console.log("Connector address", connector.address) - }) + 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: ConnectV2Sushiswap__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(!!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("Should build DSA v2", async function () { + dsaWallet0 = await buildDSAv2(wallet0.address); + expect(!!dsaWallet0.address).to.be.true; + }); + + it("Deposit ETH & 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")); - it("Deposit ETH & 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("100000")); + }); - await addLiquidity("dai", dsaWallet0.address, ethers.utils.parseEther("100000")); + it("Deposit ETH & 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")); - it("Deposit ETH & 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("100000")); - }); + await addLiquidity("usdt", dsaWallet0.address, ethers.utils.parseEther("100000")); + }); }); describe("Main", function () { + it("Should deposit successfully", async function () { + const ethAmount = ethers.utils.parseEther("0.1"); // 1 ETH + const daiUnitAmount = ethers.utils.parseEther("4000"); // 1 ETH + const ethAddress = "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee"; - it("Should deposit successfully", async function () { - const ethAmount = ethers.utils.parseEther("0.1") // 1 ETH - const daiUnitAmount = ethers.utils.parseEther("4000") // 1 ETH - const ethAddress = "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee" + const getId = "0"; + const setId = "0"; - const getId = "0" - const setId = "0" + const spells = [ + { + connector: connectorName, + method: "deposit", + args: [ethAddress, DAI_ADDR, ethAmount, daiUnitAmount, "500000000000000000", getId, setId] + } + ]; - const spells = [ - { - connector: connectorName, - method: "deposit", - args: [ - ethAddress, - DAI_ADDR, - ethAmount, - daiUnitAmount, - "500000000000000000", - getId, - setId - ], - } - ] + const tx = await dsaWallet0.connect(wallet0).cast(...encodeSpells(spells), wallet1.address); + let receipt = await tx.wait(); + }).timeout(10000000000); - 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 ethAmount = ethers.utils.parseEther("0.1"); // 1 ETH + const ethAddress = "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee"; - it("Should withdraw successfully", async function () { - const ethAmount = ethers.utils.parseEther("0.1") // 1 ETH - const ethAddress = "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee" + const getId = "0"; + const setIds = ["0", "0"]; - const getId = "0" - const setIds = ["0", "0"] + const spells = [ + { + connector: connectorName, + method: "withdraw", + args: [ethAddress, DAI_ADDR, ethAmount, 0, 0, getId, setIds] + } + ]; - const spells = [ - { - connector: connectorName, - method: "withdraw", - args: [ - ethAddress, - DAI_ADDR, - ethAmount, - 0, - 0, - getId, - setIds - ] - } - ] + const tx = await dsaWallet0.connect(wallet0).cast(...encodeSpells(spells), wallet1.address); + let receipt = await tx.wait(); + }); - const tx = await dsaWallet0.connect(wallet0).cast(...encodeSpells(spells), wallet1.address) - let receipt = await tx.wait() - }); + it("Should buy successfully", async function () { + const ethAmount = ethers.utils.parseEther("0.1"); // 1 ETH + const daiUnitAmount = ethers.utils.parseEther("4000"); // 1 ETH + const ethAddress = "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee"; - it("Should buy successfully", async function () { - const ethAmount = ethers.utils.parseEther("0.1") // 1 ETH - const daiUnitAmount = ethers.utils.parseEther("4000") // 1 ETH - const ethAddress = "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee" + const getId = "0"; + const setId = "0"; - const getId = "0" - const setId = "0" + const spells = [ + { + connector: connectorName, + method: "buy", + args: [ethAddress, DAI_ADDR, ethAmount, daiUnitAmount, getId, setId] + } + ]; - const spells = [ - { - connector: connectorName, - method: "buy", - args: [ - ethAddress, - DAI_ADDR, - ethAmount, - daiUnitAmount, - getId, - setId - ] - } - ] - - const tx = await dsaWallet0.connect(wallet0).cast(...encodeSpells(spells), wallet1.address) - let receipt = await tx.wait() - }); + const tx = await dsaWallet0.connect(wallet0).cast(...encodeSpells(spells), wallet1.address); + let receipt = await tx.wait(); + }); }); -}) - -// describe("Sushiswap", function() { -// const connectorName = "Sushiswap-v1.1"; - -// 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: ConnectV2Sushiswap__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 ETH & 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("100000") -// ); -// }); - -// it("Deposit ETH & 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("100000") -// ); -// }); -// }); - -// describe("Main", function() { -// it("Should deposit successfully", async function() { -// const ethAmount = ethers.utils.parseEther("1000"); // 1 ETH -// const daiUnitAmount = ethers.utils.parseUnits("4", 18); // 1 ETH -// const usdtAmount = Number(ethers.utils.parseEther("400")) / Math.pow(10, 12); // 1 ETH -// const ethAddress = "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE"; - -// const getId = "0"; -// const setId = "0"; - -// const spells = [ -// { -// connector: connectorName, -// method: "deposit", -// args: [ -// ethAddress, -// DAI_ADDR, -// ethAmount, -// 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 ethAmount = ethers.utils.parseEther("0.1"); // 1 ETH -// const ethAddress = "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee"; - -// const getId = "0"; -// const setIds = ["0", "0"]; - -// const spells = [ -// { -// connector: connectorName, -// method: "withdraw", -// args: [ethAddress, DAI_ADDR, ethAmount, 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 ethAmount = ethers.utils.parseEther("0.1"); // 1 ETH -// const daiUnitAmount = ethers.utils.parseEther("4000"); // 1 ETH -// const ethAddress = "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee"; - -// const getId = "0"; -// const setId = "0"; - -// const spells = [ -// { -// connector: connectorName, -// method: "buy", -// args: [ethAddress, DAI_ADDR, ethAmount, daiUnitAmount, getId, setId], -// }, -// ]; - -// const tx = await dsaWallet0 -// .connect(wallet0) -// .cast(...encodeSpells(spells), wallet1.address); -// let receipt = await tx.wait(); -// }); -// }); -// }); +}); From 4f5fb523be86a94b967be30c143af3ec646c1f45 Mon Sep 17 00:00:00 2001 From: pradyuman-verma Date: Wed, 15 Dec 2021 17:52:53 +0530 Subject: [PATCH 14/15] fixed quickswap tests --- test/polygon/quickswap/quickswap.test.ts | 116 ++++++++--------------- 1 file changed, 38 insertions(+), 78 deletions(-) diff --git a/test/polygon/quickswap/quickswap.test.ts b/test/polygon/quickswap/quickswap.test.ts index b831dfe5..5047fd61 100644 --- a/test/polygon/quickswap/quickswap.test.ts +++ b/test/polygon/quickswap/quickswap.test.ts @@ -16,8 +16,8 @@ import type { Signer, Contract } from "ethers"; const DAI_ADDR = "0x8f3cf7ad23cd3cadbd9735aff958023239c6a063"; -describe("Quickswap", function() { - const connectorName = "Quickpswap-v1.1"; +describe("Quickswap", function () { + const connectorName = "Quickswap-v1"; let dsaWallet0: Contract; let masterSigner: Signer; @@ -28,83 +28,57 @@ describe("Quickswap", function() { 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, - }, - }, - ], + 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 - ); + instaConnectorsV2 = await ethers.getContractAt(abis.core.connectorsV2, addresses.core.connectorsV2); connector = await deployAndEnableConnector({ connectorName, contractArtifact: ConnectV2Quickswap__factory, signer: masterSigner, - connectors: instaConnectorsV2, + connectors: instaConnectorsV2 }); console.log("Connector address", connector.address); }); - it("Should have contracts deployed.", async function() { + 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() { + 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 ETH & DAI into DSA wallet", async function() { + it("Deposit ETH & DAI into DSA wallet", async function () { await wallet0.sendTransaction({ to: dsaWallet0.address, - value: ethers.utils.parseEther("10"), + value: ethers.utils.parseEther("10") }); - expect(await ethers.provider.getBalance(dsaWallet0.address)).to.be.gte( - 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("100000") - ); - }); - - it("Deposit ETH & 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("100000") - ); + await addLiquidity("dai", dsaWallet0.address, ethers.utils.parseEther("10000")); }); }); - describe("Main", function() { - it("Should deposit successfully", async function() { - const ethAmount = ethers.utils.parseEther("100"); // 1 ETH - const daiUnitAmount = ethers.utils.parseUnits("4", 6); // 1 ETH - const usdtAmount = Number(ethers.utils.parseEther("400")) / Math.pow(10, 12); // 1 ETH - const ethAddress = "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE"; + describe("Main", function () { + it("Should deposit successfully", async function () { + const ethAmount = ethers.utils.parseEther("0.1"); // 1 ETH + const daiUnitAmount = ethers.utils.parseEther("1"); // 1 ETH + const ethAddress = "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee"; const getId = "0"; const setId = "0"; @@ -113,26 +87,16 @@ describe("Quickswap", function() { { connector: connectorName, method: "deposit", - args: [ - ethAddress, - DAI_ADDR, - ethAmount, - daiUnitAmount, - "500000000000000000", - getId, - setId, - ], - }, + args: [ethAddress, DAI_ADDR, ethAmount, daiUnitAmount, "500000000000000000", getId, setId] + } ]; - const tx = await dsaWallet0 - .connect(wallet0) - .cast(...encodeSpells(spells), wallet1.address); + 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 ethAmount = ethers.utils.parseEther("0.1"); // 1 ETH + it("Should withdraw successfully", async function () { + const ethAmount = ethers.utils.parseEther("0.001"); // 1 ETH const ethAddress = "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee"; const getId = "0"; @@ -142,17 +106,15 @@ describe("Quickswap", function() { { connector: connectorName, method: "withdraw", - args: [ethAddress, DAI_ADDR, ethAmount, 0, 0, getId, setIds], - }, + args: [ethAddress, DAI_ADDR, ethAmount, 0, 0, getId, setIds] + } ]; - const tx = await dsaWallet0 - .connect(wallet0) - .cast(...encodeSpells(spells), wallet1.address); + const tx = await dsaWallet0.connect(wallet0).cast(...encodeSpells(spells), wallet1.address); let receipt = await tx.wait(); }); - it("Should buy successfully", async function() { + it("Should buy successfully", async function () { const ethAmount = ethers.utils.parseEther("0.1"); // 1 ETH const daiUnitAmount = ethers.utils.parseEther("4000"); // 1 ETH const ethAddress = "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee"; @@ -164,13 +126,11 @@ describe("Quickswap", function() { { connector: connectorName, method: "buy", - args: [ethAddress, DAI_ADDR, ethAmount, daiUnitAmount, getId, setId], - }, + args: [ethAddress, DAI_ADDR, ethAmount, daiUnitAmount, getId, setId] + } ]; - const tx = await dsaWallet0 - .connect(wallet0) - .cast(...encodeSpells(spells), wallet1.address); + const tx = await dsaWallet0.connect(wallet0).cast(...encodeSpells(spells), wallet1.address); let receipt = await tx.wait(); }); }); From 37f5fe57485b503d40536f60f4d7f798455f657e Mon Sep 17 00:00:00 2001 From: pradyuman-verma Date: Wed, 15 Dec 2021 18:13:58 +0530 Subject: [PATCH 15/15] quickswap deployed update --- contracts/polygon/connectors/quickswap/main.sol | 2 +- scripts/deployment/deploy.ts | 1 + test/polygon/quickswap/quickswap.test.ts | 4 ++-- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/contracts/polygon/connectors/quickswap/main.sol b/contracts/polygon/connectors/quickswap/main.sol index 6973948b..404b6be0 100644 --- a/contracts/polygon/connectors/quickswap/main.sol +++ b/contracts/polygon/connectors/quickswap/main.sol @@ -251,6 +251,6 @@ abstract contract QuickpswapResolver is Helpers, Events { } } -contract ConnectV2Quickswap is QuickpswapResolver { +contract ConnectV2QuickswapPolygon is QuickpswapResolver { string public constant name = "Quickpswap-v1.1"; } diff --git a/scripts/deployment/deploy.ts b/scripts/deployment/deploy.ts index 381fe091..ac66d9ad 100644 --- a/scripts/deployment/deploy.ts +++ b/scripts/deployment/deploy.ts @@ -18,6 +18,7 @@ async function main() { "GELATO-A": "ConnectV2Gelato", "MAKERDAO-A": "ConnectV2Maker", "UNISWAP-A": "ConnectV2UniswapV2", + "QUICKSWAP-A": "ConnectV2QuickswapPolygon" }; const addressMapping: Record = {}; diff --git a/test/polygon/quickswap/quickswap.test.ts b/test/polygon/quickswap/quickswap.test.ts index 5047fd61..3d3a9346 100644 --- a/test/polygon/quickswap/quickswap.test.ts +++ b/test/polygon/quickswap/quickswap.test.ts @@ -11,7 +11,7 @@ import { addLiquidity } from "../../../scripts/tests/addLiquidity"; import { addresses } from "../../../scripts/tests/polygon/addresses"; import { abis } from "../../../scripts/constant/abis"; -import { ConnectV2Quickswap__factory, ConnectV2Quickswap } from "../../../typechain"; +import { ConnectV2QuickswapPolygon__factory, ConnectV2QuickswapPolygon } from "../../../typechain"; import type { Signer, Contract } from "ethers"; const DAI_ADDR = "0x8f3cf7ad23cd3cadbd9735aff958023239c6a063"; @@ -44,7 +44,7 @@ describe("Quickswap", function () { instaConnectorsV2 = await ethers.getContractAt(abis.core.connectorsV2, addresses.core.connectorsV2); connector = await deployAndEnableConnector({ connectorName, - contractArtifact: ConnectV2Quickswap__factory, + contractArtifact: ConnectV2QuickswapPolygon__factory, signer: masterSigner, connectors: instaConnectorsV2 });