This commit is contained in:
Richa-iitr 2022-09-03 19:25:11 +05:30
parent ebd2ed88f0
commit 54ac2ff70f

View File

@ -1,35 +1,36 @@
import { expect, should } from "chai"; import { expect, should } from "chai";
import hre, { ethers, waffle } from "hardhat"; import hre, { ethers, waffle } from "hardhat";
import type { Signer, Contract } from "ethers"; import type { Signer, Contract } from "ethers";
import { ecsign, ecrecover, pubToAddress } from "ethereumjs-util";
import { keccak256 } from "@ethersproject/keccak256";
import { defaultAbiCoder } from "@ethersproject/abi";
import { BigNumber } from "bignumber.js"; import { BigNumber } from "bignumber.js";
import { buildDSAv2 } from "../../../scripts/tests/buildDSAv2"; import { buildDSAv2 } from "../../../scripts/tests/buildDSAv2";
import { addresses } from "../../../scripts/tests/mainnet/addresses"; import { addresses } from "../../../scripts/tests/mainnet/addresses";
import { deployAndEnableConnector } from "../../../scripts/tests/deployAndEnableConnector"; import { deployAndEnableConnector } from "../../../scripts/tests/deployAndEnableConnector";
import { abis } from "../../../scripts/constant/abis"; import { abis } from "../../../scripts/constant/abis";
import { getMasterSigner } from "../../../scripts/tests/getMasterSigner"; import { getMasterSigner } from "../../../scripts/tests/getMasterSigner";
import { defaultAbiCoder, keccak256, parseEther, parseUnits } from "ethers/lib/utils"; import { parseEther, parseUnits } from "ethers/lib/utils";
import { ecsign, ecrecover, pubToAddress } from "ethereumjs-util";
import { encodeSpells } from "../../../scripts/tests/encodeSpells"; import { encodeSpells } from "../../../scripts/tests/encodeSpells";
import encodeFlashcastData from "../../../scripts/tests/encodeFlashcastData"; import encodeFlashcastData from "../../../scripts/tests/encodeFlashcastData";
import { ConnectV2CompoundV3__factory } from "../../../typechain"; import { ConnectV2CompoundV3__factory, IERC20__factory } from "../../../typechain";
import { tokens } from "../../../scripts/tests/mainnet/tokens"; import { tokens } from "../../../scripts/tests/mainnet/tokens";
const { provider } = waffle; const { provider } = waffle;
const comet = "0xc3d688B66703497DAA19211EEdff47f25384cdc3";
const user = "0x0a904e5e342d853952ad8159502dc1a29f9b084e";
const wethWhale = "0xf04a5cc80b1e94c69b48f5ee68a08cd2f09a7c3e";
const mnemonic = "test test test test test test test test test test test junk";
const ABI = [ const ABI = [
"function balanceOf(address account) public view returns (uint256)", "function balanceOf(address account) public view returns (uint256)",
"function approve(address spender, uint256 amount) external returns(bool)", "function approve(address spender, uint256 amount) external returns(bool)",
"function transfer(address recipient, uint256 amount) external returns (bool)" "function transfer(address recipient, uint256 amount) external returns (bool)"
]; ];
const wethContract = new ethers.Contract(tokens.weth.address, ABI);
let wethSigner: any;
let walletSigner: any;
let cometABI = [ const market = "0xc3d688B66703497DAA19211EEdff47f25384cdc3";
const user = "0x0a904e5e342d853952ad8159502dc1a29f9b084e";
const wethWhale = "0xf04a5cc80b1e94c69b48f5ee68a08cd2f09a7c3e";
const account = "0x72a53cdbbcc1b9efa39c834a540550e23463aacb";
const mnemonic = "test test test test test test test test test test test junk";
const connectorName = "COMPOUND-V3-X";
const cometABI = [
{ {
inputs: [{ internalType: "address", name: "account", type: "address" }], inputs: [{ internalType: "address", name: "account", type: "address" }],
name: "balanceOf", name: "balanceOf",
@ -44,32 +45,6 @@ let cometABI = [
stateMutability: "view", stateMutability: "view",
type: "function" type: "function"
}, },
{
inputs: [
{ internalType: "address", name: "asset", type: "address" },
{ internalType: "uint256", name: "minAmount", type: "uint256" },
{ internalType: "uint256", name: "baseAmount", type: "uint256" },
{ internalType: "address", name: "recipient", type: "address" }
],
name: "buyCollateral",
outputs: [],
stateMutability: "nonpayable",
type: "function"
},
{
inputs: [],
name: "decimals",
outputs: [{ internalType: "uint8", name: "", type: "uint8" }],
stateMutability: "view",
type: "function"
},
{
inputs: [{ internalType: "address", name: "priceFeed", type: "address" }],
name: "getPrice",
outputs: [{ internalType: "uint256", name: "", type: "uint256" }],
stateMutability: "view",
type: "function"
},
{ {
inputs: [ inputs: [
{ internalType: "address", name: "asset", type: "address" }, { internalType: "address", name: "asset", type: "address" },
@ -80,18 +55,6 @@ let cometABI = [
stateMutability: "nonpayable", stateMutability: "nonpayable",
type: "function" type: "function"
}, },
{
inputs: [
{ internalType: "address", name: "from", type: "address" },
{ internalType: "address", name: "dst", type: "address" },
{ internalType: "address", name: "asset", type: "address" },
{ internalType: "uint256", name: "amount", type: "uint256" }
],
name: "supplyFrom",
outputs: [],
stateMutability: "nonpayable",
type: "function"
},
{ {
inputs: [ inputs: [
{ internalType: "address", name: "dst", type: "address" }, { internalType: "address", name: "dst", type: "address" },
@ -136,30 +99,6 @@ let cometABI = [
stateMutability: "nonpayable", stateMutability: "nonpayable",
type: "function" type: "function"
}, },
{
inputs: [
{ internalType: "address", name: "src", type: "address" },
{ internalType: "address", name: "dst", type: "address" },
{ internalType: "uint256", name: "amount", type: "uint256" }
],
name: "transferFrom",
outputs: [{ internalType: "bool", name: "", type: "bool" }],
stateMutability: "nonpayable",
type: "function"
},
{
inputs: [{ internalType: "address", name: "", type: "address" }],
name: "userBasic",
outputs: [
{ internalType: "int104", name: "principal", type: "int104" },
{ internalType: "uint64", name: "baseTrackingIndex", type: "uint64" },
{ internalType: "uint64", name: "baseTrackingAccrued", type: "uint64" },
{ internalType: "uint16", name: "assetsIn", type: "uint16" },
{ internalType: "uint8", name: "_reserved", type: "uint8" }
],
stateMutability: "view",
type: "function"
},
{ {
inputs: [ inputs: [
{ internalType: "address", name: "", type: "address" }, { internalType: "address", name: "", type: "address" },
@ -189,42 +128,24 @@ let cometABI = [
outputs: [], outputs: [],
stateMutability: "nonpayable", stateMutability: "nonpayable",
type: "function" type: "function"
},
{
inputs: [
{ internalType: "address", name: "src", type: "address" },
{ internalType: "address", name: "to", type: "address" },
{ internalType: "address", name: "asset", type: "address" },
{ internalType: "uint256", name: "amount", type: "uint256" }
],
name: "withdrawFrom",
outputs: [],
stateMutability: "nonpayable",
type: "function"
},
{
inputs: [
{ internalType: "address", name: "to", type: "address" },
{ internalType: "address", name: "asset", type: "address" },
{ internalType: "uint256", name: "amount", type: "uint256" }
],
name: "withdrawTo",
outputs: [],
stateMutability: "nonpayable",
type: "function"
} }
]; ];
describe("Import Compound V3", function () {
const connectorName = "COMPOUND-V3-X"; const comet = new ethers.Contract(market, cometABI);
const wethContract = new ethers.Contract(tokens.weth.address, ABI);
describe("Import Compound v3 Position", function () {
let dsaWallet0: any; let dsaWallet0: any;
let masterSigner: Signer; let masterSigner: Signer;
let signer: any;
let wallet0: any;
let walletSigner: any;
let instaConnectorsV2: Contract; let instaConnectorsV2: Contract;
let connector: any; let connector: any;
const cometInstance = new ethers.Contract(comet, cometABI);
const wallets = provider.getWallets(); const wallets = provider.getWallets();
const [wallet0, wallet1, wallet2, wallet3] = wallets; const [wallet1, wallet2, wallet3] = wallets;
const wallet = ethers.Wallet.fromMnemonic(mnemonic); const wallet = ethers.Wallet.fromMnemonic(mnemonic);
before(async () => { before(async () => {
@ -233,67 +154,75 @@ describe("Import Compound V3", function () {
params: [ params: [
{ {
forking: { forking: {
// @ts-ignore //@ts-ignore
jsonRpcUrl: hre.config.networks.hardhat.forking.url, jsonRpcUrl: hre.config.networks.hardhat.forking.url,
blockNumber: 14441991 blockNumber: 15444500
} }
} }
] ]
}); });
masterSigner = await getMasterSigner(); masterSigner = await getMasterSigner();
instaConnectorsV2 = await ethers.getContractAt(abis.core.connectorsV2, addresses.core.connectorsV2);
await hre.network.provider.send("hardhat_setBalance", [account, ethers.utils.parseEther("10").toHexString()]);
await hre.network.provider.send("hardhat_setBalance", [wethWhale, ethers.utils.parseEther("10").toHexString()]);
await hre.network.provider.request({
method: "hardhat_impersonateAccount",
params: [wethWhale]
});
signer = await ethers.getSigner(wethWhale);
[wallet0] = await ethers.getSigners();
await hre.network.provider.request({
method: "hardhat_impersonateAccount",
params: [wallet.address]
});
walletSigner = await ethers.getSigner(wallet.address);
instaConnectorsV2 = await ethers.getContractAt(abis.core.connectorsV2, addresses.core.connectorsV2);
connector = await deployAndEnableConnector({ connector = await deployAndEnableConnector({
connectorName, connectorName,
contractArtifact: ConnectV2CompoundV3__factory, contractArtifact: ConnectV2CompoundV3__factory,
signer: masterSigner, signer: masterSigner,
connectors: instaConnectorsV2 connectors: instaConnectorsV2
}); });
console.log("Connector address", connector.address); });
await hre.network.provider.request({ describe("check user Compound position", async () => {
method: "hardhat_impersonateAccount", it("Should create Compound v3 position of DAI(collateral) and ETH(debt)", async () => {
params: [wethWhale] await wethContract.connect(signer).transfer(wallet.address, parseEther("100"));
// approve WETH to market
await wethContract.connect(walletSigner).approve(market, parseEther("100"));
//deposit WETH in Compound
await comet.connect(walletSigner).supply(tokens.weth.address, parseEther("100"));
console.log("Supplied WETH on compound");
//borrow Base from compound
await comet.connect(walletSigner).withdraw(tokens.usdc.address, parseUnits("100", 6));
console.log("Borrowed USDC from compound");
}); });
wethSigner = await ethers.getSigner(wethWhale); it("Should check position of user", async () => {
expect((await comet.connect(signer).userCollateral(wallet.address, tokens.weth.address)).balance).to.be.gte(
new BigNumber(100).multipliedBy(1e18).toString()
);
await hre.network.provider.request({ expect(await comet.connect(signer).borrowBalanceOf(wallet.address)).to.be.gte(
method: "hardhat_impersonateAccount", new BigNumber(100).multipliedBy(1e6).toString()
params: [wallet.address] );
}); });
walletSigner = await ethers.getSigner(wallet.address);
console.log(new BigNumber(await wethContract.connect(wethSigner).balanceOf(wethSigner.address)).toFixed());
await wethContract.connect(wethSigner).transfer(wallet0.address, ethers.utils.parseEther("50"));
console.log("weth transferred");
await cometInstance.connect(wallet0).supplyTo(wallet.address, tokens.weth.address, ethers.utils.parseEther("50"));
console.log("weth supplied");
await cometInstance.connect(walletSigner).withdraw(tokens.usdc.address, ethers.utils.parseUnits("100", 6));
}); });
describe("Deployment", async () => { describe("Deployment", async () => {
it("Should set correct name", async () => { it("Should set correct name", async () => {
expect(await connector.name()).to.eq("Compound-Import-v2"); expect(await connector.name()).to.eq("CompoundV3-v1.0");
});
});
describe("checks", async () => {
it("Should check user COMPOUND V3 position", async () => {
expect(
await cometInstance.connect(wallet0).userCollateral(wallet.address, tokens.weth.address).balance
).to.be.gte(ethers.utils.parseEther("100"));
expect(await cometInstance.connect(wallet0).borrowBalanceOf(wallet.address)).to.be.gte(
ethers.utils.parseUnits("100", 6)
);
}); });
}); });
describe("DSA wallet setup", async () => { describe("DSA wallet setup", async () => {
it("Should build DSA v2", async () => { it("Should build DSA v2", async () => {
dsaWallet0 = await buildDSAv2(wallet0.address); dsaWallet0 = await buildDSAv2(wallet.address);
expect(!!dsaWallet0.address).to.be.true; expect(!!dsaWallet0.address).to.be.true;
}); });
@ -302,29 +231,32 @@ describe("Import Compound V3", function () {
to: dsaWallet0.address, 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"));
}); });
}); });
describe("Compound v3 position migration", async () => { describe("Compound position migration", async () => {
it("Should migrate Compound position", async () => { it("Should migrate Compound position", async () => {
const DOMAIN_TYPEHASH = keccak256( const DOMAIN_TYPEHASH = keccak256(
"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)" ethers.utils.toUtf8Bytes("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)")
); );
const PERMIT_TYPEHASH = keccak256( const PERMIT_TYPEHASH = keccak256(
"Authorization(address owner,address manager,bool isAllowed,uint256 nonce,uint256 expiry)" ethers.utils.toUtf8Bytes(
"Authorization(address owner,address manager,bool isAllowed,uint256 nonce,uint256 expiry)"
)
); );
const name = keccak256(ethers.utils.toUtf8Bytes(await cometInstance.connect(wallet0).name())); const name = keccak256(ethers.utils.toUtf8Bytes("Compound USDC"));
const version = keccak256(ethers.utils.toUtf8Bytes(await cometInstance.connect(wallet0).version())); const version = keccak256(ethers.utils.toUtf8Bytes("0"));
const chainId = 1; const chainId = 1;
const DOMAIN_SEPARATOR = keccak256( const DOMAIN_SEPARATOR = keccak256(
defaultAbiCoder.encode( defaultAbiCoder.encode(
["bytes32", "bytes32", "bytes32", "uint256", "address"], ["bytes32", "bytes32", "bytes32", "uint256", "address"],
[DOMAIN_TYPEHASH, name, version, chainId, comet] [DOMAIN_TYPEHASH, name, version, chainId, market]
) )
); );
let nonce = (await cometInstance.connect(wallet).userNonce(wallet.address)).toNumber(); let nonce = (await comet.connect(walletSigner).userNonce(wallet.address)).toNumber();
//Approving max amount //Approving max amount
const amount = ethers.constants.MaxUint256; const amount = ethers.constants.MaxUint256;
const expiry = Date.now() + 20 * 60; const expiry = Date.now() + 20 * 60;
@ -348,7 +280,7 @@ describe("Import Compound V3", function () {
const { v, r, s } = ecsign(Buffer.from(digest.slice(2), "hex"), Buffer.from(wallet.privateKey.slice(2), "hex")); const { v, r, s } = ecsign(Buffer.from(digest.slice(2), "hex"), Buffer.from(wallet.privateKey.slice(2), "hex"));
let buffer = ethers.utils.parseUnits("100", 6).toNumber(); let buffer = ethers.utils.parseUnits("100", 6).toNumber();
let amount0 = new BigNumber(await cometInstance.connect(wallet0).borrowBalanceOf(wallet.address)).plus(buffer); let amount0 = new BigNumber(await comet.connect(wallet0).borrowBalanceOf(wallet.address)).plus(buffer);
let amountB = new BigNumber(amount0.toString()).multipliedBy(5).dividedBy(1e4); let amountB = new BigNumber(amount0.toString()).multipliedBy(5).dividedBy(1e4);
let amountWithFee = amount0.plus(amountB); let amountWithFee = amount0.plus(amountB);
const spells1 = [ const spells1 = [
@ -367,17 +299,17 @@ describe("Import Compound V3", function () {
{ {
connector: "COMPOUND-V3-X", connector: "COMPOUND-V3-X",
method: "paybackOnBehalf", method: "paybackOnBehalf",
args: [comet, tokens.usdc.address, wallet.address, ethers.constants.MaxUint256, 0, 0] args: [market, tokens.usdc.address, wallet.address, ethers.constants.MaxUint256, 0, 0]
}, },
{ {
connector: "COMPOUND-V3-X", connector: "COMPOUND-V3-X",
method: "transferAssetFromUsingManager", method: "transferAssetFromUsingManager",
args: [comet, tokens.eth.address, wallet.address, dsaWallet0.address, ethers.constants.MaxUint256, 0, 0] args: [market, tokens.eth.address, wallet.address, dsaWallet0.address, ethers.constants.MaxUint256, 0, 0]
}, },
{ {
connector: "COMPOUND-V3-X", connector: "COMPOUND-V3-X",
method: "borrow", method: "borrow",
args: [comet, tokens.usdc.address, amountWithFee.toFixed(0), 0, 0] args: [market, tokens.usdc.address, amountWithFee.toFixed(0), 0, 0]
}, },
{ {
connector: "INSTAPOOL-C", connector: "INSTAPOOL-C",
@ -398,10 +330,10 @@ describe("Import Compound V3", function () {
}); });
it("Should check DSA COMPOUND position", async () => { it("Should check DSA COMPOUND position", async () => {
expect( expect((await comet.connect(wallet0).userCollateral(dsaWallet0.address, tokens.weth.address)).balance).to.be.gte(
await cometInstance.connect(wallet0).userCollateral(dsaWallet0.address, tokens.weth.address).balance ethers.utils.parseEther("100")
).to.be.gte(ethers.utils.parseEther("100")); );
expect(await cometInstance.connect(wallet0).borrowBalanceOf(dsaWallet0.address)).to.be.gte( expect(await comet.connect(wallet0).borrowBalanceOf(dsaWallet0.address)).to.be.gte(
ethers.utils.parseUnits("100", 6) ethers.utils.parseUnits("100", 6)
); );
}); });