feat: initial setup

This commit is contained in:
Shriya Tyagi 2023-12-16 04:20:02 +05:30
parent b99aa8cd4b
commit 3a9dcabc54
159 changed files with 43241 additions and 0 deletions

11
.env.example Normal file
View File

@ -0,0 +1,11 @@
ETHERSCAN_API_KEY=""
PRIVATE_KEY=""
TENDERLY_PROJECT=""
TENDERLY_USERNAME=""
ALCHEMY_ID=""
MAIN_ETHSCAN_KEY=
OPT_ETHSCAN_KEY=
POLY_ETHSCAN_KEY=
ARB_ETHSCAN_KEY=
AVAX_ETHSCAN_KEY=
FTM_ETHSCAN_KEY=

67
.gitignore vendored Normal file
View File

@ -0,0 +1,67 @@
lib-cov
*.seed
*.log
*.csv
*.dat
*.out
*.pid
*.gz
*.swp
pids
logs
results
tmp
# Optional npm cache directory
.npm
#Build
coverage
public/css/main.css
.nyc_output/*
#Libraries from npm packages
public/js/lib/bootstrap.min*
public/js/lib/jquery.min*
public/js/lib/popper.min*
# API keys and secrets
.env
# Dependency directory
node_modules
bower_components
# Editors
.idea
.vscode
*.iml
modules.xml
*.ipr
# Folder config file
Desktop.ini
# Recycle Bin used on file shares
$RECYCLE.BIN/
# OS metadata
.DS_Store
Thumbs.db
.DocumentRevisions-V100
.fseventsd
.Spotlight-V100
.TemporaryItems
.Trashes
.VolumeIcon.icns
.com.apple.timemachine.donotpresent
# truffle
build/contracts
# buidler
artifacts
cache
typechain

154
hardhat.config.ts Normal file
View File

@ -0,0 +1,154 @@
import "@typechain/hardhat";
import { resolve } from "path";
import { config as dotenvConfig } from "dotenv";
import { HardhatUserConfig } from "hardhat/config";
import { NetworkUserConfig } from "hardhat/types";
import Web3 from "web3";
import { network } from "hardhat";
import bigNumber from "bignumber.js";
import "./scripts/tests/run_test_through_cmd";
dotenvConfig({ path: resolve(__dirname, "./.env") });
const chainIds = {
ganache: 1337,
hardhat: 31337,
mainnet: 1,
avalanche: 43114,
polygon: 137,
arbitrum: 42161,
optimism: 10,
fantom: 250,
base: 8453,
};
const alchemyApiKey = process.env.ALCHEMY_API_KEY;
if (!alchemyApiKey) {
throw new Error("Please set your ALCHEMY_API_KEY in a .env file");
}
const PRIVATE_KEY = process.env.PRIVATE_KEY;
const mnemonic = process.env.MNEMONIC ?? "test test test test test test test test test test test junk";
const networkGasPriceConfig: Record<string, number> = {
mainnet: 41,
polygon: 50,
avalanche: 40,
arbitrum: 1,
optimism: 0.001,
fantom: 210,
base: 0.0005
};
function createConfig(network: string) {
return {
url: getNetworkUrl(network),
accounts: !!PRIVATE_KEY ? [`0x${PRIVATE_KEY}`] : { mnemonic },
gasPrice: new bigNumber(networkGasPriceConfig[network]).times(1e9).toNumber() // Update the mapping above
};
}
function getNetworkUrl(networkType: string) {
if (networkType === "avalanche") return "https://api.avax.network/ext/bc/C/rpc";
else if (networkType === "polygon") return `https://polygon-mainnet.g.alchemy.com/v2/${alchemyApiKey}`;
else if (networkType === "arbitrum") return `https://arb-mainnet.g.alchemy.com/v2/${alchemyApiKey}`;
else if (networkType === "optimism") return `https://opt-mainnet.g.alchemy.com/v2/${alchemyApiKey}`;
else if (networkType === "fantom") return `https://rpc.ftm.tools/`;
else if (networkType === "base") return `https://1rpc.io/base`;
else return `https://eth-mainnet.alchemyapi.io/v2/${alchemyApiKey}`;
}
/**
* @type import('hardhat/config').HardhatUserConfig
*/
const config: any = {
solidity: {
compilers: [
{
version: "0.8.22",
settings: {
optimizer: {
enabled: true,
runs: 200
}
}
},
{
version: "0.7.6",
settings: {
optimizer: {
enabled: true,
runs: 200
}
}
},
{
version: "0.6.0"
},
{
version: "0.6.2"
},
{
version: "0.6.5"
}
]
},
networks: {
hardhat: {
accounts: {
mnemonic
},
chainId: chainIds.hardhat,
forking: {
url: String(getNetworkUrl(String(process.env.networkType)))
}
},
mainnet: createConfig("mainnet"),
polygon: createConfig("polygon"),
avalanche: createConfig("avalanche"),
arbitrum: createConfig("arbitrum"),
optimism: createConfig("optimism"),
fantom: createConfig("fantom"),
base: createConfig("base")
},
paths: {
artifacts: "./artifacts",
cache: "./cache",
sources: "./contracts",
tests: "./test"
},
etherscan: {
apiKey: {
mainnet: String(process.env.MAIN_ETHSCAN_KEY),
optimisticEthereum: String(process.env.OPT_ETHSCAN_KEY),
polygon: String(process.env.POLY_ETHSCAN_KEY),
arbitrumOne: String(process.env.ARB_ETHSCAN_KEY),
avalanche: String(process.env.AVAX_ETHSCAN_KEY),
opera: String(process.env.FTM_ETHSCAN_KEY),
base: String(process.env.BASE_ETHSCAN_KEY),
},
customChains: [
{
network: "base",
chainId: 8453,
urls: {
apiURL: "https://api.basescan.org/api",
browserURL: "https://basescan.org"
}
}
]
},
typechain: {
outDir: "typechain",
target: "ethers-v5"
},
mocha: {
timeout: 10000 * 1000 // 10,000 seconds
}
// tenderly: {
// project: process.env.TENDERLY_PROJECT,
// username: process.env.TENDERLY_USERNAME,
// },
};
export default config;

9078
package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

19
package.json Normal file
View File

@ -0,0 +1,19 @@
{
"name": "dsa-connectors-2.0",
"version": "1.0.0",
"description": "DSA Connectors 2.0",
"directories": {},
"devDependencies": {
"hardhat": "^2.19.2",
"typechain": "^8.3.2"
},
"dependencies": {
"@openzeppelin/contracts": "^4.9.5",
"@typechain/ethers-v5": "^10.2.1",
"@typechain/hardhat": "^6.1.6",
"bignumber.js": "^4.0.4",
"dotenv": "^16.3.1",
"ts-node": "^10.9.2",
"web3": "^4.3.0"
}
}

View File

@ -0,0 +1,222 @@
[
{
"constant": true,
"inputs": [],
"name": "name",
"outputs": [
{
"name": "",
"type": "string"
}
],
"payable": false,
"stateMutability": "view",
"type": "function"
},
{
"constant": false,
"inputs": [
{
"name": "_spender",
"type": "address"
},
{
"name": "_value",
"type": "uint256"
}
],
"name": "approve",
"outputs": [
{
"name": "",
"type": "bool"
}
],
"payable": false,
"stateMutability": "nonpayable",
"type": "function"
},
{
"constant": true,
"inputs": [],
"name": "totalSupply",
"outputs": [
{
"name": "",
"type": "uint256"
}
],
"payable": false,
"stateMutability": "view",
"type": "function"
},
{
"constant": false,
"inputs": [
{
"name": "_from",
"type": "address"
},
{
"name": "_to",
"type": "address"
},
{
"name": "_value",
"type": "uint256"
}
],
"name": "transferFrom",
"outputs": [
{
"name": "",
"type": "bool"
}
],
"payable": false,
"stateMutability": "nonpayable",
"type": "function"
},
{
"constant": true,
"inputs": [],
"name": "decimals",
"outputs": [
{
"name": "",
"type": "uint8"
}
],
"payable": false,
"stateMutability": "view",
"type": "function"
},
{
"constant": true,
"inputs": [
{
"name": "_owner",
"type": "address"
}
],
"name": "balanceOf",
"outputs": [
{
"name": "balance",
"type": "uint256"
}
],
"payable": false,
"stateMutability": "view",
"type": "function"
},
{
"constant": true,
"inputs": [],
"name": "symbol",
"outputs": [
{
"name": "",
"type": "string"
}
],
"payable": false,
"stateMutability": "view",
"type": "function"
},
{
"constant": false,
"inputs": [
{
"name": "_to",
"type": "address"
},
{
"name": "_value",
"type": "uint256"
}
],
"name": "transfer",
"outputs": [
{
"name": "",
"type": "bool"
}
],
"payable": false,
"stateMutability": "nonpayable",
"type": "function"
},
{
"constant": true,
"inputs": [
{
"name": "_owner",
"type": "address"
},
{
"name": "_spender",
"type": "address"
}
],
"name": "allowance",
"outputs": [
{
"name": "",
"type": "uint256"
}
],
"payable": false,
"stateMutability": "view",
"type": "function"
},
{
"payable": true,
"stateMutability": "payable",
"type": "fallback"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"name": "owner",
"type": "address"
},
{
"indexed": true,
"name": "spender",
"type": "address"
},
{
"indexed": false,
"name": "value",
"type": "uint256"
}
],
"name": "Approval",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"name": "from",
"type": "address"
},
{
"indexed": true,
"name": "to",
"type": "address"
},
{
"indexed": false,
"name": "value",
"type": "uint256"
}
],
"name": "Transfer",
"type": "event"
}
]

View File

@ -0,0 +1,97 @@
[
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "_msgSender",
"type": "address"
},
{
"indexed": true,
"internalType": "address",
"name": "_authority",
"type": "address"
}
],
"name": "LogAddAuth",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "_msgSender",
"type": "address"
},
{
"indexed": true,
"internalType": "address",
"name": "_authority",
"type": "address"
}
],
"name": "LogRemoveAuth",
"type": "event"
},
{
"inputs": [
{
"internalType": "address",
"name": "authority",
"type": "address"
}
],
"name": "add",
"outputs": [],
"stateMutability": "payable",
"type": "function"
},
{
"inputs": [],
"name": "connectorID",
"outputs": [
{
"internalType": "uint256",
"name": "_type",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "_id",
"type": "uint256"
}
],
"stateMutability": "pure",
"type": "function"
},
{
"inputs": [],
"name": "name",
"outputs": [
{
"internalType": "string",
"name": "",
"type": "string"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "authority",
"type": "address"
}
],
"name": "remove",
"outputs": [],
"stateMutability": "payable",
"type": "function"
}
]

View File

@ -0,0 +1,133 @@
[
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "erc20",
"type": "address"
},
{
"indexed": false,
"internalType": "uint256",
"name": "tokenAmt",
"type": "uint256"
},
{
"indexed": false,
"internalType": "uint256",
"name": "getId",
"type": "uint256"
},
{
"indexed": false,
"internalType": "uint256",
"name": "setId",
"type": "uint256"
}
],
"name": "LogDeposit",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "erc20",
"type": "address"
},
{
"indexed": false,
"internalType": "uint256",
"name": "tokenAmt",
"type": "uint256"
},
{
"indexed": true,
"internalType": "address",
"name": "to",
"type": "address"
},
{
"indexed": false,
"internalType": "uint256",
"name": "getId",
"type": "uint256"
},
{
"indexed": false,
"internalType": "uint256",
"name": "setId",
"type": "uint256"
}
],
"name": "LogWithdraw",
"type": "event"
},
{
"inputs": [],
"name": "connectorID",
"outputs": [
{ "internalType": "uint256", "name": "_type", "type": "uint256" },
{ "internalType": "uint256", "name": "_id", "type": "uint256" }
],
"stateMutability": "pure",
"type": "function"
},
{
"inputs": [
{ "internalType": "address", "name": "erc20", "type": "address" },
{ "internalType": "uint256", "name": "tokenAmt", "type": "uint256" },
{ "internalType": "uint256", "name": "getId", "type": "uint256" },
{ "internalType": "uint256", "name": "setId", "type": "uint256" }
],
"name": "deposit",
"outputs": [],
"stateMutability": "payable",
"type": "function"
},
{
"inputs": [],
"name": "getEthAddr",
"outputs": [{ "internalType": "address", "name": "", "type": "address" }],
"stateMutability": "pure",
"type": "function"
},
{
"inputs": [],
"name": "getEventAddr",
"outputs": [{ "internalType": "address", "name": "", "type": "address" }],
"stateMutability": "pure",
"type": "function"
},
{
"inputs": [],
"name": "getMemoryAddr",
"outputs": [{ "internalType": "address", "name": "", "type": "address" }],
"stateMutability": "pure",
"type": "function"
},
{
"inputs": [],
"name": "name",
"outputs": [{ "internalType": "string", "name": "", "type": "string" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{ "internalType": "address", "name": "erc20", "type": "address" },
{ "internalType": "uint256", "name": "tokenAmt", "type": "uint256" },
{ "internalType": "address payable", "name": "to", "type": "address" },
{ "internalType": "uint256", "name": "getId", "type": "uint256" },
{ "internalType": "uint256", "name": "setId", "type": "uint256" }
],
"name": "withdraw",
"outputs": [],
"stateMutability": "payable",
"type": "function"
}
]

View File

@ -0,0 +1,445 @@
[
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "token",
"type": "address"
},
{
"indexed": false,
"internalType": "address",
"name": "cToken",
"type": "address"
},
{
"indexed": false,
"internalType": "uint256",
"name": "tokenAmt",
"type": "uint256"
},
{
"indexed": false,
"internalType": "uint256",
"name": "getId",
"type": "uint256"
},
{
"indexed": false,
"internalType": "uint256",
"name": "setId",
"type": "uint256"
}
],
"name": "LogBorrow",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "token",
"type": "address"
},
{
"indexed": false,
"internalType": "address",
"name": "cToken",
"type": "address"
},
{
"indexed": false,
"internalType": "uint256",
"name": "tokenAmt",
"type": "uint256"
},
{
"indexed": false,
"internalType": "uint256",
"name": "getId",
"type": "uint256"
},
{
"indexed": false,
"internalType": "uint256",
"name": "setId",
"type": "uint256"
}
],
"name": "LogDeposit",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "token",
"type": "address"
},
{
"indexed": false,
"internalType": "address",
"name": "cToken",
"type": "address"
},
{
"indexed": false,
"internalType": "uint256",
"name": "tokenAmt",
"type": "uint256"
},
{
"indexed": false,
"internalType": "uint256",
"name": "cTokenAmt",
"type": "uint256"
},
{
"indexed": false,
"internalType": "uint256",
"name": "getId",
"type": "uint256"
},
{
"indexed": false,
"internalType": "uint256",
"name": "setId",
"type": "uint256"
}
],
"name": "LogDepositCToken",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "borrower",
"type": "address"
},
{
"indexed": true,
"internalType": "address",
"name": "tokenToPay",
"type": "address"
},
{
"indexed": true,
"internalType": "address",
"name": "tokenInReturn",
"type": "address"
},
{
"indexed": false,
"internalType": "uint256",
"name": "tokenAmt",
"type": "uint256"
},
{
"indexed": false,
"internalType": "uint256",
"name": "getId",
"type": "uint256"
},
{
"indexed": false,
"internalType": "uint256",
"name": "setId",
"type": "uint256"
}
],
"name": "LogLiquidate",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "token",
"type": "address"
},
{
"indexed": false,
"internalType": "address",
"name": "cToken",
"type": "address"
},
{
"indexed": false,
"internalType": "uint256",
"name": "tokenAmt",
"type": "uint256"
},
{
"indexed": false,
"internalType": "uint256",
"name": "getId",
"type": "uint256"
},
{
"indexed": false,
"internalType": "uint256",
"name": "setId",
"type": "uint256"
}
],
"name": "LogPayback",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "borrower",
"type": "address"
},
{
"indexed": true,
"internalType": "address",
"name": "token",
"type": "address"
},
{
"indexed": false,
"internalType": "address",
"name": "cToken",
"type": "address"
},
{
"indexed": false,
"internalType": "uint256",
"name": "tokenAmt",
"type": "uint256"
},
{
"indexed": false,
"internalType": "uint256",
"name": "getId",
"type": "uint256"
},
{
"indexed": false,
"internalType": "uint256",
"name": "setId",
"type": "uint256"
}
],
"name": "LogPaybackBehalf",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "token",
"type": "address"
},
{
"indexed": false,
"internalType": "address",
"name": "cToken",
"type": "address"
},
{
"indexed": false,
"internalType": "uint256",
"name": "tokenAmt",
"type": "uint256"
},
{
"indexed": false,
"internalType": "uint256",
"name": "getId",
"type": "uint256"
},
{
"indexed": false,
"internalType": "uint256",
"name": "setId",
"type": "uint256"
}
],
"name": "LogWithdraw",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "token",
"type": "address"
},
{
"indexed": false,
"internalType": "address",
"name": "cToken",
"type": "address"
},
{
"indexed": false,
"internalType": "uint256",
"name": "cTokenAmt",
"type": "uint256"
},
{
"indexed": false,
"internalType": "uint256",
"name": "getId",
"type": "uint256"
},
{
"indexed": false,
"internalType": "uint256",
"name": "setId",
"type": "uint256"
}
],
"name": "LogWithdrawCToken",
"type": "event"
},
{
"inputs": [
{ "internalType": "address", "name": "token", "type": "address" },
{ "internalType": "uint256", "name": "amt", "type": "uint256" },
{ "internalType": "uint256", "name": "getId", "type": "uint256" },
{ "internalType": "uint256", "name": "setId", "type": "uint256" }
],
"name": "borrow",
"outputs": [],
"stateMutability": "payable",
"type": "function"
},
{
"inputs": [],
"name": "connectorID",
"outputs": [
{ "internalType": "uint256", "name": "_type", "type": "uint256" },
{ "internalType": "uint256", "name": "_id", "type": "uint256" }
],
"stateMutability": "pure",
"type": "function"
},
{
"inputs": [
{ "internalType": "address", "name": "token", "type": "address" },
{ "internalType": "uint256", "name": "amt", "type": "uint256" },
{ "internalType": "uint256", "name": "getId", "type": "uint256" },
{ "internalType": "uint256", "name": "setId", "type": "uint256" }
],
"name": "deposit",
"outputs": [],
"stateMutability": "payable",
"type": "function"
},
{
"inputs": [
{ "internalType": "address", "name": "token", "type": "address" },
{ "internalType": "uint256", "name": "amt", "type": "uint256" },
{ "internalType": "uint256", "name": "getId", "type": "uint256" },
{ "internalType": "uint256", "name": "setId", "type": "uint256" }
],
"name": "depositCToken",
"outputs": [],
"stateMutability": "payable",
"type": "function"
},
{
"inputs": [
{ "internalType": "address", "name": "borrower", "type": "address" },
{ "internalType": "address", "name": "tokenToPay", "type": "address" },
{ "internalType": "address", "name": "tokenInReturn", "type": "address" },
{ "internalType": "uint256", "name": "amt", "type": "uint256" },
{ "internalType": "uint256", "name": "getId", "type": "uint256" },
{ "internalType": "uint256", "name": "setId", "type": "uint256" }
],
"name": "liquidate",
"outputs": [],
"stateMutability": "payable",
"type": "function"
},
{
"inputs": [],
"name": "name",
"outputs": [{ "internalType": "string", "name": "", "type": "string" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{ "internalType": "address", "name": "token", "type": "address" },
{ "internalType": "uint256", "name": "amt", "type": "uint256" },
{ "internalType": "uint256", "name": "getId", "type": "uint256" },
{ "internalType": "uint256", "name": "setId", "type": "uint256" }
],
"name": "payback",
"outputs": [],
"stateMutability": "payable",
"type": "function"
},
{
"inputs": [
{ "internalType": "address", "name": "borrower", "type": "address" },
{ "internalType": "address", "name": "token", "type": "address" },
{ "internalType": "uint256", "name": "amt", "type": "uint256" },
{ "internalType": "uint256", "name": "getId", "type": "uint256" },
{ "internalType": "uint256", "name": "setId", "type": "uint256" }
],
"name": "paybackBehalf",
"outputs": [],
"stateMutability": "payable",
"type": "function"
},
{
"inputs": [
{ "internalType": "address", "name": "token", "type": "address" },
{ "internalType": "uint256", "name": "amt", "type": "uint256" },
{ "internalType": "uint256", "name": "getId", "type": "uint256" },
{ "internalType": "uint256", "name": "setId", "type": "uint256" }
],
"name": "withdraw",
"outputs": [],
"stateMutability": "payable",
"type": "function"
},
{
"inputs": [
{ "internalType": "address", "name": "token", "type": "address" },
{ "internalType": "uint256", "name": "cTokenAmt", "type": "uint256" },
{ "internalType": "uint256", "name": "getId", "type": "uint256" },
{ "internalType": "uint256", "name": "setId", "type": "uint256" }
],
"name": "withdrawCToken",
"outputs": [],
"stateMutability": "payable",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "setId",
"type": "uint256"
}
],
"name": "ClaimComp",
"outputs": [],
"stateMutability": "payable",
"type": "function"
}
]

View File

@ -0,0 +1,114 @@
[
{
"anonymous": false,
"inputs": [
{ "indexed": false, "internalType": "address", "name": "token", "type": "address" },
{ "indexed": false, "internalType": "uint256", "name": "tokenAmt", "type": "uint256" }
],
"name": "LogFlashBorrow",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{ "indexed": false, "internalType": "address[]", "name": "token", "type": "address[]" },
{ "indexed": false, "internalType": "uint256[]", "name": "tokenAmts", "type": "uint256[]" }
],
"name": "LogFlashMultiBorrow",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{ "indexed": false, "internalType": "address[]", "name": "token", "type": "address[]" },
{ "indexed": false, "internalType": "uint256[]", "name": "tokenAmts", "type": "uint256[]" }
],
"name": "LogFlashMultiPayback",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{ "indexed": false, "internalType": "address", "name": "token", "type": "address" },
{ "indexed": false, "internalType": "uint256", "name": "tokenAmt", "type": "uint256" }
],
"name": "LogFlashPayback",
"type": "event"
},
{
"inputs": [
{ "internalType": "address", "name": "token", "type": "address" },
{ "internalType": "uint256", "name": "amt", "type": "uint256" },
{ "internalType": "uint256", "name": "route", "type": "uint256" },
{ "internalType": "bytes", "name": "data", "type": "bytes" },
{ "internalType": "bytes", "name": "extraData", "type": "bytes" }
],
"name": "flashBorrowAndCast",
"outputs": [
{ "internalType": "string", "name": "_eventName", "type": "string" },
{ "internalType": "bytes", "name": "_eventParam", "type": "bytes" }
],
"stateMutability": "payable",
"type": "function"
},
{
"inputs": [
{ "internalType": "address[]", "name": "tokens_", "type": "address[]" },
{ "internalType": "uint256[]", "name": "amts_", "type": "uint256[]" },
{ "internalType": "uint256", "name": "route", "type": "uint256" },
{ "internalType": "bytes", "name": "data", "type": "bytes" },
{ "internalType": "bytes", "name": "extraData", "type": "bytes" }
],
"name": "flashMultiBorrowAndCast",
"outputs": [
{ "internalType": "string", "name": "_eventName", "type": "string" },
{ "internalType": "bytes", "name": "_eventParam", "type": "bytes" }
],
"stateMutability": "payable",
"type": "function"
},
{
"inputs": [
{ "internalType": "address[]", "name": "tokens_", "type": "address[]" },
{ "internalType": "uint256[]", "name": "amts_", "type": "uint256[]" },
{ "internalType": "uint256[]", "name": "getIds", "type": "uint256[]" },
{ "internalType": "uint256[]", "name": "setIds", "type": "uint256[]" }
],
"name": "flashMultiPayback",
"outputs": [
{ "internalType": "string", "name": "_eventName", "type": "string" },
{ "internalType": "bytes", "name": "_eventParam", "type": "bytes" }
],
"stateMutability": "payable",
"type": "function"
},
{
"inputs": [
{ "internalType": "address", "name": "token", "type": "address" },
{ "internalType": "uint256", "name": "amt", "type": "uint256" },
{ "internalType": "uint256", "name": "getId", "type": "uint256" },
{ "internalType": "uint256", "name": "setId", "type": "uint256" }
],
"name": "flashPayback",
"outputs": [
{ "internalType": "string", "name": "_eventName", "type": "string" },
{ "internalType": "bytes", "name": "_eventParam", "type": "bytes" }
],
"stateMutability": "payable",
"type": "function"
},
{
"inputs": [],
"name": "instaPool",
"outputs": [{ "internalType": "contract InstaFlashV4Interface", "name": "", "type": "address" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "name",
"outputs": [{ "internalType": "string", "name": "", "type": "string" }],
"stateMutability": "view",
"type": "function"
}
]

View File

@ -0,0 +1 @@
[{"type":"event","name":"LogFlashBorrow","inputs":[{"type":"address","name":"token","internalType":"address","indexed":false},{"type":"uint256","name":"tokenAmt","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"LogFlashMultiBorrow","inputs":[{"type":"address[]","name":"token","internalType":"address[]","indexed":false},{"type":"uint256[]","name":"tokenAmts","internalType":"uint256[]","indexed":false}],"anonymous":false},{"type":"event","name":"LogFlashMultiPayback","inputs":[{"type":"address[]","name":"token","internalType":"address[]","indexed":false},{"type":"uint256[]","name":"tokenAmts","internalType":"uint256[]","indexed":false}],"anonymous":false},{"type":"event","name":"LogFlashPayback","inputs":[{"type":"address","name":"token","internalType":"address","indexed":false},{"type":"uint256","name":"tokenAmt","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"function","stateMutability":"payable","outputs":[{"type":"string","name":"_eventName","internalType":"string"},{"type":"bytes","name":"_eventParam","internalType":"bytes"}],"name":"flashBorrowAndCast","inputs":[{"type":"address","name":"token","internalType":"address"},{"type":"uint256","name":"amt","internalType":"uint256"},{"type":"uint256","name":"route","internalType":"uint256"},{"type":"bytes","name":"data","internalType":"bytes"}]},{"type":"function","stateMutability":"payable","outputs":[{"type":"string","name":"_eventName","internalType":"string"},{"type":"bytes","name":"_eventParam","internalType":"bytes"}],"name":"flashMultiBorrowAndCast","inputs":[{"type":"address[]","name":"tokens","internalType":"address[]"},{"type":"uint256[]","name":"amts","internalType":"uint256[]"},{"type":"uint256","name":"route","internalType":"uint256"},{"type":"bytes","name":"data","internalType":"bytes"}]},{"type":"function","stateMutability":"payable","outputs":[{"type":"string","name":"_eventName","internalType":"string"},{"type":"bytes","name":"_eventParam","internalType":"bytes"}],"name":"flashMultiPayback","inputs":[{"type":"address[]","name":"tokens","internalType":"address[]"},{"type":"uint256[]","name":"amts","internalType":"uint256[]"},{"type":"uint256[]","name":"getId","internalType":"uint256[]"},{"type":"uint256[]","name":"setId","internalType":"uint256[]"}]},{"type":"function","stateMutability":"payable","outputs":[{"type":"string","name":"_eventName","internalType":"string"},{"type":"bytes","name":"_eventParam","internalType":"bytes"}],"name":"flashPayback","inputs":[{"type":"address","name":"token","internalType":"address"},{"type":"uint256","name":"amt","internalType":"uint256"},{"type":"uint256","name":"getId","internalType":"uint256"},{"type":"uint256","name":"setId","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"contract InstaFlashV2Interface"}],"name":"instaPool","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"string","name":"","internalType":"string"}],"name":"name","inputs":[]}]

View File

@ -0,0 +1,483 @@
[
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "uint256",
"name": "vault",
"type": "uint256"
},
{
"indexed": true,
"internalType": "bytes32",
"name": "ilk",
"type": "bytes32"
},
{
"indexed": false,
"internalType": "uint256",
"name": "tokenAmt",
"type": "uint256"
},
{
"indexed": false,
"internalType": "uint256",
"name": "getId",
"type": "uint256"
},
{
"indexed": false,
"internalType": "uint256",
"name": "setId",
"type": "uint256"
}
],
"name": "LogBorrow",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "uint256",
"name": "vault",
"type": "uint256"
},
{
"indexed": true,
"internalType": "bytes32",
"name": "ilk",
"type": "bytes32"
}
],
"name": "LogClose",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "uint256",
"name": "vault",
"type": "uint256"
},
{
"indexed": true,
"internalType": "bytes32",
"name": "ilk",
"type": "bytes32"
},
{
"indexed": false,
"internalType": "uint256",
"name": "tokenAmt",
"type": "uint256"
},
{
"indexed": false,
"internalType": "uint256",
"name": "getId",
"type": "uint256"
},
{
"indexed": false,
"internalType": "uint256",
"name": "setId",
"type": "uint256"
}
],
"name": "LogDeposit",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": false,
"internalType": "uint256",
"name": "tokenAmt",
"type": "uint256"
},
{
"indexed": false,
"internalType": "uint256",
"name": "getId",
"type": "uint256"
},
{
"indexed": false,
"internalType": "uint256",
"name": "setId",
"type": "uint256"
}
],
"name": "LogDepositDai",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "uint256",
"name": "vault",
"type": "uint256"
},
{
"indexed": true,
"internalType": "bytes32",
"name": "ilk",
"type": "bytes32"
},
{
"indexed": false,
"internalType": "uint256",
"name": "tokenAmt",
"type": "uint256"
},
{
"indexed": false,
"internalType": "uint256",
"name": "getId",
"type": "uint256"
},
{
"indexed": false,
"internalType": "uint256",
"name": "setId",
"type": "uint256"
}
],
"name": "LogExitDai",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "uint256",
"name": "vault",
"type": "uint256"
},
{
"indexed": true,
"internalType": "bytes32",
"name": "ilk",
"type": "bytes32"
}
],
"name": "LogOpen",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "uint256",
"name": "vault",
"type": "uint256"
},
{
"indexed": true,
"internalType": "bytes32",
"name": "ilk",
"type": "bytes32"
},
{
"indexed": false,
"internalType": "uint256",
"name": "tokenAmt",
"type": "uint256"
},
{
"indexed": false,
"internalType": "uint256",
"name": "getId",
"type": "uint256"
},
{
"indexed": false,
"internalType": "uint256",
"name": "setId",
"type": "uint256"
}
],
"name": "LogPayback",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "uint256",
"name": "vault",
"type": "uint256"
},
{
"indexed": true,
"internalType": "bytes32",
"name": "ilk",
"type": "bytes32"
},
{
"indexed": false,
"internalType": "address",
"name": "newOwner",
"type": "address"
}
],
"name": "LogTransfer",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "uint256",
"name": "vault",
"type": "uint256"
},
{
"indexed": true,
"internalType": "bytes32",
"name": "ilk",
"type": "bytes32"
},
{
"indexed": false,
"internalType": "uint256",
"name": "tokenAmt",
"type": "uint256"
},
{
"indexed": false,
"internalType": "uint256",
"name": "getId",
"type": "uint256"
},
{
"indexed": false,
"internalType": "uint256",
"name": "setId",
"type": "uint256"
}
],
"name": "LogWithdraw",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": false,
"internalType": "uint256",
"name": "tokenAmt",
"type": "uint256"
},
{
"indexed": false,
"internalType": "uint256",
"name": "getId",
"type": "uint256"
},
{
"indexed": false,
"internalType": "uint256",
"name": "setId",
"type": "uint256"
}
],
"name": "LogWithdrawDai",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "uint256",
"name": "vault",
"type": "uint256"
},
{
"indexed": true,
"internalType": "bytes32",
"name": "ilk",
"type": "bytes32"
},
{
"indexed": false,
"internalType": "uint256",
"name": "tokenAmt",
"type": "uint256"
},
{
"indexed": false,
"internalType": "uint256",
"name": "getId",
"type": "uint256"
},
{
"indexed": false,
"internalType": "uint256",
"name": "setId",
"type": "uint256"
}
],
"name": "LogWithdrawLiquidated",
"type": "event"
},
{
"inputs": [
{ "internalType": "uint256", "name": "vault", "type": "uint256" },
{ "internalType": "uint256", "name": "amt", "type": "uint256" },
{ "internalType": "uint256", "name": "getId", "type": "uint256" },
{ "internalType": "uint256", "name": "setId", "type": "uint256" }
],
"name": "borrow",
"outputs": [],
"stateMutability": "payable",
"type": "function"
},
{
"inputs": [
{ "internalType": "uint256", "name": "vault", "type": "uint256" }
],
"name": "close",
"outputs": [],
"stateMutability": "payable",
"type": "function"
},
{
"inputs": [],
"name": "connectorID",
"outputs": [
{ "internalType": "uint256", "name": "_type", "type": "uint256" },
{ "internalType": "uint256", "name": "_id", "type": "uint256" }
],
"stateMutability": "pure",
"type": "function"
},
{
"inputs": [
{ "internalType": "uint256", "name": "vault", "type": "uint256" },
{ "internalType": "uint256", "name": "amt", "type": "uint256" },
{ "internalType": "uint256", "name": "getId", "type": "uint256" },
{ "internalType": "uint256", "name": "setId", "type": "uint256" }
],
"name": "deposit",
"outputs": [],
"stateMutability": "payable",
"type": "function"
},
{
"inputs": [
{ "internalType": "uint256", "name": "vault", "type": "uint256" },
{ "internalType": "uint256", "name": "depositAmt", "type": "uint256" },
{ "internalType": "uint256", "name": "borrowAmt", "type": "uint256" },
{ "internalType": "uint256", "name": "getIdDeposit", "type": "uint256" },
{ "internalType": "uint256", "name": "getIdBorrow", "type": "uint256" },
{ "internalType": "uint256", "name": "setIdDeposit", "type": "uint256" },
{ "internalType": "uint256", "name": "setIdBorrow", "type": "uint256" }
],
"name": "depositAndBorrow",
"outputs": [],
"stateMutability": "payable",
"type": "function"
},
{
"inputs": [
{ "internalType": "uint256", "name": "amt", "type": "uint256" },
{ "internalType": "uint256", "name": "getId", "type": "uint256" },
{ "internalType": "uint256", "name": "setId", "type": "uint256" }
],
"name": "depositDai",
"outputs": [],
"stateMutability": "payable",
"type": "function"
},
{
"inputs": [
{ "internalType": "uint256", "name": "vault", "type": "uint256" },
{ "internalType": "uint256", "name": "amt", "type": "uint256" },
{ "internalType": "uint256", "name": "getId", "type": "uint256" },
{ "internalType": "uint256", "name": "setId", "type": "uint256" }
],
"name": "exitDai",
"outputs": [],
"stateMutability": "payable",
"type": "function"
},
{
"inputs": [],
"name": "name",
"outputs": [{ "internalType": "string", "name": "", "type": "string" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{ "internalType": "string", "name": "colType", "type": "string" }
],
"name": "open",
"outputs": [
{ "internalType": "uint256", "name": "vault", "type": "uint256" }
],
"stateMutability": "payable",
"type": "function"
},
{
"inputs": [
{ "internalType": "uint256", "name": "vault", "type": "uint256" },
{ "internalType": "uint256", "name": "amt", "type": "uint256" },
{ "internalType": "uint256", "name": "getId", "type": "uint256" },
{ "internalType": "uint256", "name": "setId", "type": "uint256" }
],
"name": "payback",
"outputs": [],
"stateMutability": "payable",
"type": "function"
},
{
"inputs": [
{ "internalType": "uint256", "name": "vault", "type": "uint256" },
{ "internalType": "uint256", "name": "amt", "type": "uint256" },
{ "internalType": "uint256", "name": "getId", "type": "uint256" },
{ "internalType": "uint256", "name": "setId", "type": "uint256" }
],
"name": "withdraw",
"outputs": [],
"stateMutability": "payable",
"type": "function"
},
{
"inputs": [
{ "internalType": "uint256", "name": "amt", "type": "uint256" },
{ "internalType": "uint256", "name": "getId", "type": "uint256" },
{ "internalType": "uint256", "name": "setId", "type": "uint256" }
],
"name": "withdrawDai",
"outputs": [],
"stateMutability": "payable",
"type": "function"
},
{
"inputs": [
{ "internalType": "uint256", "name": "vault", "type": "uint256" },
{ "internalType": "uint256", "name": "amt", "type": "uint256" },
{ "internalType": "uint256", "name": "getId", "type": "uint256" },
{ "internalType": "uint256", "name": "setId", "type": "uint256" }
],
"name": "withdrawLiquidated",
"outputs": [],
"stateMutability": "payable",
"type": "function"
}
]

View File

@ -0,0 +1,177 @@
[
{
"inputs": [
{
"internalType": "address",
"name": "buyAddr",
"type": "address"
},
{
"internalType": "address",
"name": "sellAddr",
"type": "address"
},
{
"internalType": "uint256",
"name": "buyAmt",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "unitAmt",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "getId",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "setId",
"type": "uint256"
}
],
"name": "buy",
"outputs": [],
"stateMutability": "payable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "tokenA",
"type": "address"
},
{
"internalType": "address",
"name": "tokenB",
"type": "address"
},
{
"internalType": "uint256",
"name": "amtA",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "unitAmt",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "slippage",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "getId",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "setId",
"type": "uint256"
}
],
"name": "deposit",
"outputs": [],
"stateMutability": "payable",
"type": "function"
},
{
"inputs": [],
"name": "name",
"outputs": [
{
"internalType": "string",
"name": "",
"type": "string"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "buyAddr",
"type": "address"
},
{
"internalType": "address",
"name": "sellAddr",
"type": "address"
},
{
"internalType": "uint256",
"name": "sellAmt",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "unitAmt",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "getId",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "setId",
"type": "uint256"
}
],
"name": "sell",
"outputs": [],
"stateMutability": "payable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "tokenA",
"type": "address"
},
{
"internalType": "address",
"name": "tokenB",
"type": "address"
},
{
"internalType": "uint256",
"name": "uniAmt",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "unitAmtA",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "unitAmtB",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "getId",
"type": "uint256"
},
{
"internalType": "uint256[]",
"name": "setIds",
"type": "uint256[]"
}
],
"name": "withdraw",
"outputs": [],
"stateMutability": "payable",
"type": "function"
}
]

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,250 @@
[
{
"inputs": [
{
"internalType": "address",
"name": "_instaIndex",
"type": "address"
}
],
"stateMutability": "nonpayable",
"type": "constructor"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "bytes32",
"name": "connectorNameHash",
"type": "bytes32"
},
{
"indexed": false,
"internalType": "string",
"name": "connectorName",
"type": "string"
},
{
"indexed": true,
"internalType": "address",
"name": "connector",
"type": "address"
}
],
"name": "LogConnectorAdded",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "bytes32",
"name": "connectorNameHash",
"type": "bytes32"
},
{
"indexed": false,
"internalType": "string",
"name": "connectorName",
"type": "string"
},
{
"indexed": true,
"internalType": "address",
"name": "connector",
"type": "address"
}
],
"name": "LogConnectorRemoved",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "bytes32",
"name": "connectorNameHash",
"type": "bytes32"
},
{
"indexed": false,
"internalType": "string",
"name": "connectorName",
"type": "string"
},
{
"indexed": true,
"internalType": "address",
"name": "oldConnector",
"type": "address"
},
{
"indexed": true,
"internalType": "address",
"name": "newConnector",
"type": "address"
}
],
"name": "LogConnectorUpdated",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "addr",
"type": "address"
},
{
"indexed": true,
"internalType": "bool",
"name": "isChief",
"type": "bool"
}
],
"name": "LogController",
"type": "event"
},
{
"inputs": [
{
"internalType": "string[]",
"name": "_connectorNames",
"type": "string[]"
},
{
"internalType": "address[]",
"name": "_connectors",
"type": "address[]"
}
],
"name": "addConnectors",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"name": "chief",
"outputs": [
{
"internalType": "bool",
"name": "",
"type": "bool"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "string",
"name": "",
"type": "string"
}
],
"name": "connectors",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "instaIndex",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "string[]",
"name": "_connectorNames",
"type": "string[]"
}
],
"name": "isConnectors",
"outputs": [
{
"internalType": "bool",
"name": "isOk",
"type": "bool"
},
{
"internalType": "address[]",
"name": "_connectors",
"type": "address[]"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "string[]",
"name": "_connectorNames",
"type": "string[]"
}
],
"name": "removeConnectors",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "_chiefAddress",
"type": "address"
}
],
"name": "toggleChief",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "string[]",
"name": "_connectorNames",
"type": "string[]"
},
{
"internalType": "address[]",
"name": "_connectors",
"type": "address[]"
}
],
"name": "updateConnectors",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
}
]

View File

@ -0,0 +1,380 @@
[
{
"anonymous": false,
"inputs": [
{
"indexed": false,
"internalType": "address",
"name": "sender",
"type": "address"
},
{
"indexed": true,
"internalType": "address",
"name": "owner",
"type": "address"
},
{
"indexed": true,
"internalType": "address",
"name": "account",
"type": "address"
},
{
"indexed": true,
"internalType": "address",
"name": "origin",
"type": "address"
}
],
"name": "LogAccountCreated",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "_newAccount",
"type": "address"
},
{
"indexed": true,
"internalType": "address",
"name": "_connectors",
"type": "address"
},
{
"indexed": true,
"internalType": "address",
"name": "_check",
"type": "address"
}
],
"name": "LogNewAccount",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "uint256",
"name": "accountVersion",
"type": "uint256"
},
{
"indexed": true,
"internalType": "address",
"name": "check",
"type": "address"
}
],
"name": "LogNewCheck",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "master",
"type": "address"
}
],
"name": "LogNewMaster",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "master",
"type": "address"
}
],
"name": "LogUpdateMaster",
"type": "event"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"name": "account",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "_newAccount",
"type": "address"
},
{
"internalType": "address",
"name": "_connectors",
"type": "address"
},
{
"internalType": "address",
"name": "_check",
"type": "address"
}
],
"name": "addNewAccount",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "_owner",
"type": "address"
},
{
"internalType": "uint256",
"name": "accountVersion",
"type": "uint256"
},
{
"internalType": "address",
"name": "_origin",
"type": "address"
}
],
"name": "build",
"outputs": [
{
"internalType": "address",
"name": "_account",
"type": "address"
}
],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "_owner",
"type": "address"
},
{
"internalType": "uint256",
"name": "accountVersion",
"type": "uint256"
},
{
"internalType": "address[]",
"name": "_targets",
"type": "address[]"
},
{
"internalType": "bytes[]",
"name": "_datas",
"type": "bytes[]"
},
{
"internalType": "address",
"name": "_origin",
"type": "address"
}
],
"name": "buildWithCast",
"outputs": [
{
"internalType": "address",
"name": "_account",
"type": "address"
}
],
"stateMutability": "payable",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "accountVersion",
"type": "uint256"
},
{
"internalType": "address",
"name": "_newCheck",
"type": "address"
}
],
"name": "changeCheck",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "_newMaster",
"type": "address"
}
],
"name": "changeMaster",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"name": "check",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"name": "connectors",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "version",
"type": "uint256"
},
{
"internalType": "address",
"name": "query",
"type": "address"
}
],
"name": "isClone",
"outputs": [
{
"internalType": "bool",
"name": "result",
"type": "bool"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "list",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "master",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "_master",
"type": "address"
},
{
"internalType": "address",
"name": "_list",
"type": "address"
},
{
"internalType": "address",
"name": "_account",
"type": "address"
},
{
"internalType": "address",
"name": "_connectors",
"type": "address"
}
],
"name": "setBasics",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [],
"name": "updateMaster",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [],
"name": "versionCount",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
}
]

View File

@ -0,0 +1,186 @@
[
{
"inputs": [],
"name": "getCETHAddress",
"outputs": [{ "internalType": "address", "name": "", "type": "address" }],
"stateMutability": "pure",
"type": "function"
},
{
"inputs": [],
"name": "getCompReadAddress",
"outputs": [{ "internalType": "address", "name": "", "type": "address" }],
"stateMutability": "pure",
"type": "function"
},
{
"inputs": [],
"name": "getCompToken",
"outputs": [
{
"internalType": "contract TokenInterface",
"name": "",
"type": "address"
}
],
"stateMutability": "pure",
"type": "function"
},
{
"inputs": [
{ "internalType": "address", "name": "owner", "type": "address" },
{ "internalType": "address[]", "name": "cAddress", "type": "address[]" }
],
"name": "getCompoundData",
"outputs": [
{
"components": [
{
"internalType": "uint256",
"name": "tokenPriceInEth",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "tokenPriceInUsd",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "exchangeRateStored",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "balanceOfUser",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "borrowBalanceStoredUser",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "supplyRatePerBlock",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "borrowRatePerBlock",
"type": "uint256"
}
],
"internalType": "struct Helpers.CompData[]",
"name": "",
"type": "tuple[]"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "getComptroller",
"outputs": [
{
"internalType": "contract ComptrollerLensInterface",
"name": "",
"type": "address"
}
],
"stateMutability": "pure",
"type": "function"
},
{
"inputs": [],
"name": "getOracleAddress",
"outputs": [{ "internalType": "address", "name": "", "type": "address" }],
"stateMutability": "pure",
"type": "function"
},
{
"inputs": [
{ "internalType": "address", "name": "owner", "type": "address" },
{ "internalType": "address[]", "name": "cAddress", "type": "address[]" }
],
"name": "getPosition",
"outputs": [
{
"components": [
{
"internalType": "uint256",
"name": "tokenPriceInEth",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "tokenPriceInUsd",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "exchangeRateStored",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "balanceOfUser",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "borrowBalanceStoredUser",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "supplyRatePerBlock",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "borrowRatePerBlock",
"type": "uint256"
}
],
"internalType": "struct Helpers.CompData[]",
"name": "",
"type": "tuple[]"
},
{
"components": [
{ "internalType": "uint256", "name": "balance", "type": "uint256" },
{ "internalType": "uint256", "name": "votes", "type": "uint256" },
{ "internalType": "address", "name": "delegate", "type": "address" },
{ "internalType": "uint256", "name": "allocated", "type": "uint256" }
],
"internalType": "struct CompReadInterface.CompBalanceMetadataExt",
"name": "",
"type": "tuple"
}
],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{ "internalType": "address", "name": "cToken", "type": "address" },
{ "internalType": "address", "name": "token", "type": "address" }
],
"name": "getPriceInEth",
"outputs": [
{ "internalType": "uint256", "name": "priceInETH", "type": "uint256" },
{ "internalType": "uint256", "name": "priceInUSD", "type": "uint256" }
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "name",
"outputs": [{ "internalType": "string", "name": "", "type": "string" }],
"stateMutability": "view",
"type": "function"
}
]

View File

@ -0,0 +1,312 @@
[
{
"inputs": [
{ "internalType": "address", "name": "_index", "type": "address" },
{ "internalType": "address", "name": "gnosisFactory", "type": "address" }
],
"stateMutability": "nonpayable",
"type": "constructor"
},
{
"inputs": [],
"name": "connectors",
"outputs": [{ "internalType": "address", "name": "", "type": "address" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [{ "internalType": "uint64", "name": "id", "type": "uint64" }],
"name": "getAccount",
"outputs": [
{ "internalType": "address", "name": "account", "type": "address" }
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{ "internalType": "address", "name": "account", "type": "address" }
],
"name": "getAccountAuthorities",
"outputs": [
{ "internalType": "address[]", "name": "", "type": "address[]" }
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{ "internalType": "address", "name": "account", "type": "address" }
],
"name": "getAccountAuthoritiesTypes",
"outputs": [
{
"components": [
{ "internalType": "address", "name": "owner", "type": "address" },
{ "internalType": "uint256", "name": "authType", "type": "uint256" }
],
"internalType": "struct AccountResolver.AuthType[]",
"name": "",
"type": "tuple[]"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{ "internalType": "address", "name": "account", "type": "address" }
],
"name": "getAccountDetails",
"outputs": [
{
"components": [
{ "internalType": "uint256", "name": "ID", "type": "uint256" },
{ "internalType": "address", "name": "account", "type": "address" },
{ "internalType": "uint256", "name": "version", "type": "uint256" },
{
"internalType": "address[]",
"name": "authorities",
"type": "address[]"
}
],
"internalType": "struct AccountResolver.AccountData",
"name": "",
"type": "tuple"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [{ "internalType": "uint256", "name": "id", "type": "uint256" }],
"name": "getAccountIdDetails",
"outputs": [
{
"components": [
{ "internalType": "uint256", "name": "ID", "type": "uint256" },
{ "internalType": "address", "name": "account", "type": "address" },
{ "internalType": "uint256", "name": "version", "type": "uint256" },
{
"internalType": "address[]",
"name": "authorities",
"type": "address[]"
}
],
"internalType": "struct AccountResolver.AccountData",
"name": "",
"type": "tuple"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{ "internalType": "address[]", "name": "accounts", "type": "address[]" }
],
"name": "getAccountVersions",
"outputs": [
{ "internalType": "uint256[]", "name": "", "type": "uint256[]" }
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{ "internalType": "address", "name": "authority", "type": "address" }
],
"name": "getAuthorityAccounts",
"outputs": [
{ "internalType": "address[]", "name": "", "type": "address[]" }
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{ "internalType": "address", "name": "authority", "type": "address" }
],
"name": "getAuthorityDetails",
"outputs": [
{
"components": [
{ "internalType": "uint64[]", "name": "IDs", "type": "uint64[]" },
{
"internalType": "address[]",
"name": "accounts",
"type": "address[]"
},
{
"internalType": "uint256[]",
"name": "versions",
"type": "uint256[]"
}
],
"internalType": "struct AccountResolver.AuthorityData",
"name": "",
"type": "tuple"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{ "internalType": "address", "name": "authority", "type": "address" }
],
"name": "getAuthorityIDs",
"outputs": [{ "internalType": "uint64[]", "name": "", "type": "uint64[]" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "address[]",
"name": "authorities",
"type": "address[]"
}
],
"name": "getAuthorityTypes",
"outputs": [
{
"components": [
{ "internalType": "address", "name": "owner", "type": "address" },
{ "internalType": "uint256", "name": "authType", "type": "uint256" }
],
"internalType": "struct AccountResolver.AuthType[]",
"name": "",
"type": "tuple[]"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{ "internalType": "address", "name": "_addr", "type": "address" }
],
"name": "getContractCode",
"outputs": [{ "internalType": "bytes", "name": "o_code", "type": "bytes" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "getEnabledConnectors",
"outputs": [
{ "internalType": "address[]", "name": "", "type": "address[]" }
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "getEnabledConnectorsData",
"outputs": [
{
"components": [
{ "internalType": "address", "name": "connector", "type": "address" },
{
"internalType": "uint256",
"name": "connectorID",
"type": "uint256"
},
{ "internalType": "string", "name": "name", "type": "string" }
],
"internalType": "struct ConnectorsResolver.ConnectorsData[]",
"name": "",
"type": "tuple[]"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{ "internalType": "address", "name": "account", "type": "address" }
],
"name": "getID",
"outputs": [{ "internalType": "uint256", "name": "id", "type": "uint256" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [{ "internalType": "uint256", "name": "id", "type": "uint256" }],
"name": "getIDAuthorities",
"outputs": [
{ "internalType": "address[]", "name": "", "type": "address[]" }
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "getStaticConnectors",
"outputs": [
{ "internalType": "address[]", "name": "", "type": "address[]" }
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "getStaticConnectorsData",
"outputs": [
{
"components": [
{ "internalType": "address", "name": "connector", "type": "address" },
{
"internalType": "uint256",
"name": "connectorID",
"type": "uint256"
},
{ "internalType": "string", "name": "name", "type": "string" }
],
"internalType": "struct ConnectorsResolver.ConnectorsData[]",
"name": "",
"type": "tuple[]"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "index",
"outputs": [{ "internalType": "address", "name": "", "type": "address" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{ "internalType": "address", "name": "account", "type": "address" }
],
"name": "isShield",
"outputs": [{ "internalType": "bool", "name": "shield", "type": "bool" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "list",
"outputs": [{ "internalType": "address", "name": "", "type": "address" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "name",
"outputs": [{ "internalType": "string", "name": "", "type": "string" }],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "version",
"outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }],
"stateMutability": "view",
"type": "function"
}
]

View File

@ -0,0 +1,68 @@
[
{
"inputs": [
{
"internalType": "address",
"name": "owner",
"type": "address"
},
{
"internalType": "address",
"name": "spender",
"type": "address"
},
{
"internalType": "address[]",
"name": "tknAddress",
"type": "address[]"
}
],
"name": "getAllowances",
"outputs": [
{
"internalType": "uint256[]",
"name": "",
"type": "uint256[]"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "owner",
"type": "address"
},
{
"internalType": "address[]",
"name": "tknAddress",
"type": "address[]"
}
],
"name": "getBalances",
"outputs": [
{
"internalType": "uint256[]",
"name": "",
"type": "uint256[]"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "name",
"outputs": [
{
"internalType": "string",
"name": "",
"type": "string"
}
],
"stateMutability": "view",
"type": "function"
}
]

View File

@ -0,0 +1,263 @@
[
{
"inputs": [
{
"internalType": "string[]",
"name": "name",
"type": "string[]"
}
],
"name": "getColInfo",
"outputs": [
{
"components": [
{
"internalType": "uint256",
"name": "borrowRate",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "price",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "liquidationRatio",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "debtCeiling",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "totalDebt",
"type": "uint256"
}
],
"internalType": "struct Helpers.ColInfo[]",
"name": "",
"type": "tuple[]"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "owner",
"type": "address"
}
],
"name": "getDaiPosition",
"outputs": [
{
"internalType": "uint256",
"name": "amt",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "dsr",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "getDsrRate",
"outputs": [
{
"internalType": "uint256",
"name": "dsr",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "getMcdAddresses",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "pure",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "id",
"type": "uint256"
}
],
"name": "getVaultById",
"outputs": [
{
"components": [
{
"internalType": "uint256",
"name": "id",
"type": "uint256"
},
{
"internalType": "address",
"name": "owner",
"type": "address"
},
{
"internalType": "string",
"name": "colType",
"type": "string"
},
{
"internalType": "uint256",
"name": "collateral",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "art",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "debt",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "liquidatedCol",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "borrowRate",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "colPrice",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "liquidationRatio",
"type": "uint256"
},
{
"internalType": "address",
"name": "vaultAddress",
"type": "address"
}
],
"internalType": "struct Helpers.VaultData",
"name": "",
"type": "tuple"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "owner",
"type": "address"
}
],
"name": "getVaults",
"outputs": [
{
"components": [
{
"internalType": "uint256",
"name": "id",
"type": "uint256"
},
{
"internalType": "address",
"name": "owner",
"type": "address"
},
{
"internalType": "string",
"name": "colType",
"type": "string"
},
{
"internalType": "uint256",
"name": "collateral",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "art",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "debt",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "liquidatedCol",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "borrowRate",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "colPrice",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "liquidationRatio",
"type": "uint256"
},
{
"internalType": "address",
"name": "vaultAddress",
"type": "address"
}
],
"internalType": "struct Helpers.VaultData[]",
"name": "",
"type": "tuple[]"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "name",
"outputs": [
{
"internalType": "string",
"name": "",
"type": "string"
}
],
"stateMutability": "view",
"type": "function"
}
]

View File

@ -0,0 +1,281 @@
[
{
"inputs": [
{
"internalType": "address",
"name": "buyAddr",
"type": "address"
},
{
"internalType": "address",
"name": "sellAddr",
"type": "address"
},
{
"internalType": "uint256",
"name": "sellAmt",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "slippage",
"type": "uint256"
}
],
"name": "getBuyAmount",
"outputs": [
{
"internalType": "uint256",
"name": "buyAmt",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "unitAmt",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "tokenA",
"type": "address"
},
{
"internalType": "address",
"name": "tokenB",
"type": "address"
},
{
"internalType": "uint256",
"name": "amtA",
"type": "uint256"
}
],
"name": "getDepositAmount",
"outputs": [
{
"internalType": "uint256",
"name": "amtB",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "unitAmt",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "tokenA",
"type": "address"
},
{
"internalType": "address",
"name": "tokenB",
"type": "address"
},
{
"internalType": "uint256",
"name": "amtA",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "amtB",
"type": "uint256"
}
],
"name": "getDepositAmountNewPool",
"outputs": [
{
"internalType": "uint256",
"name": "unitAmt",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "getEthAddr",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "pure",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "owner",
"type": "address"
},
{
"components": [
{
"internalType": "address",
"name": "tokenA",
"type": "address"
},
{
"internalType": "address",
"name": "tokenB",
"type": "address"
}
],
"internalType": "struct Resolver.TokenPair[]",
"name": "tokenPairs",
"type": "tuple[]"
}
],
"name": "getPosition",
"outputs": [
{
"components": [
{
"internalType": "uint256",
"name": "tokenAShareAmt",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "tokenBShareAmt",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "uniAmt",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "totalSupply",
"type": "uint256"
}
],
"internalType": "struct Resolver.PoolData[]",
"name": "",
"type": "tuple[]"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "buyAddr",
"type": "address"
},
{
"internalType": "address",
"name": "sellAddr",
"type": "address"
},
{
"internalType": "uint256",
"name": "buyAmt",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "slippage",
"type": "uint256"
}
],
"name": "getSellAmount",
"outputs": [
{
"internalType": "uint256",
"name": "sellAmt",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "unitAmt",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "tokenA",
"type": "address"
},
{
"internalType": "address",
"name": "tokenB",
"type": "address"
},
{
"internalType": "uint256",
"name": "uniAmt",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "slippage",
"type": "uint256"
}
],
"name": "getWithdrawAmounts",
"outputs": [
{
"internalType": "uint256",
"name": "amtA",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "amtB",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "unitAmtA",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "unitAmtB",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "name",
"outputs": [
{
"internalType": "string",
"name": "",
"type": "string"
}
],
"stateMutability": "view",
"type": "function"
}
]

16
scripts/constant/abis.ts Normal file
View File

@ -0,0 +1,16 @@
export const abis: Record<string, any> = {
core: {
connectorsV2: require("./abi/core/connectorsV2.json"),
instaIndex: require("./abi/core/instaIndex.json")
},
connectors: {
"Basic-v1": require("./abi/connectors/basic.json"),
basic: require("./abi/connectors/basic.json"),
auth: require("./abi/connectors/auth.json"),
"INSTAPOOL-A": require("./abi/connectors/instapool.json"),
"INSTAPOOL-C": require("./abi/connectors/instapool-c.json")
},
basic: {
erc20: require("./abi/basics/erc20.json")
}
};

View File

@ -0,0 +1,6 @@
export const constants = {
address_zero: "0x0000000000000000000000000000000000000000",
native_address: "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE",
max_value:
"115792089237316195423570985008687907853269984665640564039457584007913129639935",
};

View File

View File

@ -0,0 +1,71 @@
export const connectMapping: Record<string, any> = {
mainnet: {
"1INCH-A": "ConnectV2OneInch",
"1INCH-B": "ConnectV2OneProto",
"AAVE-V1-A": "ConnectV2AaveV1",
"AAVE-V2-A": "ConnectV2AaveV2",
"AUTHORITY-A": "ConnectV2Auth",
"BASIC-A": "ConnectV2Basic",
"BASIC-D": "ConnectV2BasicERC4626",
"COMP-A": "ConnectV2COMP",
"COMPOUND-A": "ConnectV2Compound",
"DYDX-A": "ConnectV2Dydx",
"FEE-A": "ConnectV2Fee",
"GELATO-A": "ConnectV2Gelato",
"MAKERDAO-A": "ConnectV2Maker",
"UNISWAP-A": "ConnectV2UniswapV2",
},
polygon: {
"QUICKSWAP-A": "ConnectV2Paraswap",
"UniswapV3-v1": "ConnectV2UniswapV3Polygon",
"Uniswap-V3-Staker-v1.1": "ConnectV2UniswapV3StakerPolygon",
"Paraswap-v5": "ConnectV2ParaswapV5Polygon",
"1INCH-V4": "ConnectV2OneInchV4Polygon",
},
avalanche: {
"ZEROEX-A": "ConnectV2ZeroExAvalanche",
},
};
export const connectors: Record<string, Array<string>> = {
mainnet: [
'ConnectV2ZeroEx',
'ConnectV2ApproveTokens',
'ConnectV2Auth',
'ConnectV2Basic',
'ConnectV2BasicERC721',
'ConnectV2BasicERC1155',
'ConnectV2CompoundV3',
'ConnectV2CompoundV3Rewards',
'ConnectV2InstaDexSimulation',
'ConnectV2DSASpell',
'ConnectV2SwapAggregator',
'ConnectV2UniswapV3',
'ConnectV2UniswapV3AutoRouter',
'ConnectV2UniswapV3Swap',
],
polygon: [
"QUICKSWAP-A",
"UniswapV3-v1",
"Uniswap-V3-Staker-v1.1",
"Paraswap-v5",
"1INCH-V4",
],
avalanche: ["ZEROEX-A"],
base: [
'ConnectV2ZeroExBase',
'ConnectV2ApproveTokensBase',
'ConnectV2AuthBase',
'ConnectV2BasicBase',
'ConnectV2BasicERC721Base',
'ConnectV2BasicERC1155Base',
'ConnectV2CompoundV3Base',
'ConnectV2CompoundV3RewardsBase',
'ConnectV2InstaDexSimulationBase',
'ConnectV2DSASpellBase',
'ConnectV2SwapAggregatorBase',
'ConnectV2UniswapV3Base',
'ConnectV2UniswapV3AutoRouterBase',
'ConnectV2UniswapV3SwapBase',
],
};

View File

@ -0,0 +1,23 @@
import { ethers } from "hardhat";
import { deployConnector } from "./deployConnector";
import { connectMapping } from "./connectors";
async function main() {
if (process.env.connectorName) {
await deployConnector();
} else {
const addressMapping: Record<string, string> = {};
for (const key in connectMapping) {
addressMapping[key] = await deployConnector(connectMapping[key]);
}
console.log(addressMapping);
}
}
main()
.then(() => process.exit(0))
.catch((error) => {
console.error(error);
process.exit(1);
});

View File

@ -0,0 +1,24 @@
import hre from "hardhat";
const { ethers, deployments, getUnnamedAccounts } = hre;
const { deploy } = deployments;
async function main() {
const deployer = (await getUnnamedAccounts())[0];
const connector = "// Add connector name over here Eg: ConnectV2InstaPoolV3Avalanche"
const connectorInstance = await deploy(connector, {
from: deployer,
});
console.log(`${connector} deployed: `, connectorInstance.address);
await hre.run("sourcify", {
address: connectorInstance.address,
});
}
main()
.then(() => process.exit(0))
.catch((error) => {
console.error(error);
process.exit(1);
});

View File

@ -0,0 +1,79 @@
import hre from "hardhat";
const { ethers } = hre;
async function main() {
const CONNECTORS_V2 = "0x97b0B3A8bDeFE8cB9563a3c610019Ad10DB8aD11";
const ctokenMapping = {
"ETH-A": "0x4ddc2d193948926d02f9b1fe9e1daa0718270ed5",
"BAT-A": "0x6c8c6b02e7b2be14d4fa6022dfd6d75921d90e4e",
"COMP-A": "0x70e36f6bf80a52b3b46b3af8e106cc0ed743e8e4",
"DAI-A": "0x5d3a536e4d6dbd6114cc1ead35777bab948e3643",
"REP-A": "0x158079ee67fce2f58472a96584a73c7ab9ac95c1",
"UNI-A": "0x35a18000230da775cac24873d00ff85bccded550",
"USDC-A": "0x39aa39c021dfbae8fac545936693ac917d5e7563",
"USDT-A": "0xf650c3d88d12db855b8bf7d11be6c55a4e07dcc9",
"WBTC-A": "0xc11b1268c1a384e55c48c2391d8d480264a3a7f4",
"WBTC-B": "0xccF4429DB6322D5C611ee964527D42E5d685DD6a",
"ZRX-A": "0xb3319f5d18bc0d84dd1b4825dcde5d5f7266d407",
"YFI-A": "0x80a2ae356fc9ef4305676f7a3e2ed04e12c33946",
"SUSHI-A": "0x4b0181102a0112a2ef11abee5563bb4a3176c9d7",
"MKR-A": "0x95b4ef2869ebd94beb4eee400a99824bf5dc325b",
"AAVE-A": "0xe65cdb6479bac1e22340e4e755fae7e509ecd06c",
"TUSD-A": "0x12392f67bdf24fae0af363c24ac620a2f67dad86",
"LINK-A": "0xface851a4921ce59e912d19329929ce6da6eb0c7",
};
const tokenMapping = {
"ETH-A": "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE",
"BAT-A": "0x0D8775F648430679A709E98d2b0Cb6250d2887EF",
"COMP-A": "0xc00e94cb662c3520282e6f5717214004a7f26888",
"DAI-A": "0x6b175474e89094c44da98b954eedeac495271d0f",
"REP-A": "0x1985365e9f78359a9B6AD760e32412f4a445E862",
"UNI-A": "0x1f9840a85d5af5bf1d1762f925bdaddc4201f984",
"USDC-A": "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48",
"USDT-A": "0xdac17f958d2ee523a2206206994597c13d831ec7",
"WBTC-A": "0x2260fac5e5542a773aa44fbcfedf7c193bc2c599",
"WBTC-B": "0x2260fac5e5542a773aa44fbcfedf7c193bc2c599",
"ZRX-A": "0xe41d2489571d322189246dafa5ebde1f4699f498",
"YFI-A": "0x0bc529c00C6401aEF6D220BE8C6Ea1667F6Ad93e",
"SUSHI-A": "0x6B3595068778DD592e39A122f4f5a5cF09C90fE2",
"MKR-A": "0x9f8F72aA9304c8B593d555F12eF6589cC3A579A2",
"AAVE-A": "0x7Fc66500c84A76Ad7e9c93437bFc5Ac33E2DDaE9",
"TUSD-A": "0x0000000000085d4780B73119b644AE5ecd22b376",
"LINK-A": "0x514910771af9ca656af840dff83e8264ecf986ca",
};
const Mapping = await ethers.getContractFactory("InstaCompoundMapping");
const mapping = await Mapping.deploy(
CONNECTORS_V2,
Object.keys(ctokenMapping),
Object.values(tokenMapping),
Object.values(ctokenMapping)
);
await mapping.deployed();
console.log(`InstaCompoundMapping Deployed: ${mapping.address}`);
try {
await hre.run("verify:verify", {
address: mapping.address,
constructorArguments: [
CONNECTORS_V2,
Object.keys(ctokenMapping),
Object.values(tokenMapping),
Object.values(ctokenMapping),
],
});
} catch (error) {
console.log(`Failed to verify: InstaCompoundMapping@${mapping.address}`);
console.log(error);
console.log();
}
}
main()
.then(() => process.exit(0))
.catch((error) => {
console.error(error);
process.exit(1);
});

View File

@ -0,0 +1,37 @@
import hre, { ethers } from "hardhat";
import { execScript } from "../tests/command";
export const deployConnector = async (connectorName?: string) => {
connectorName = String(process.env.connectorName) ?? connectorName;
const Connector = await ethers.getContractFactory(connectorName);
const connector = await Connector.deploy();
await connector.deployed();
console.log(`${connectorName} Deployed: ${connector.address}`);
const chain = String(hre.network.name);
if (chain !== "hardhat") {
const allPaths = await hre.artifacts.getArtifactPaths();
let connectorPath;
for (const path of allPaths)
if (path.split("/").includes(connectorName + ".json"))
connectorPath = path.slice(path.indexOf("contracts"), path.indexOf(connectorName) - 1) + `:${connectorName}`;
try {
await execScript({
cmd: "npx",
args: ["hardhat", "verify", "--network", `${chain}`, `${connector.address}`, "--contract", `${connectorPath}`],
env: {
networkType: chain
}
});
} catch (error) {
console.log(`Failed to verify: ${connectorName}@${connector.address}`);
console.log(error);
console.log();
}
}
return connector.address;
};

View File

@ -0,0 +1,88 @@
import { execScript } from "../tests/command";
import inquirer from "inquirer";
import { connectors, connectMapping } from "./connectors";
import { join } from "path";
let start: number, end: number, runchain: string;
// async function connectorSelect(chain: string) {
// let { connector } = await inquirer.prompt([
// {
// name: "connector",
// message: "Which connector do you want to deploy?",
// type: "list",
// choices: connectors[chain],
// },
// ]);
// return connector;
// }
async function deployRunner() {
let { chain } = await inquirer.prompt([
{
name: "chain",
message: "What chain do you want to deploy on?",
type: "list",
choices: ["mainnet", "polygon", "avalanche", "arbitrum", "optimism", "fantom", "base"]
}
]);
// let connector = await connectorSelect(chain);
// let { choice } = await inquirer.prompt([
// {
// name: "choice",
// message: "Do you wanna select again?",
// type: "list",
// choices: ["yes", "no"],
// },
// ]);
// if (choice === "yes") {
// connector = await connectorSelect(chain);
// }
// connector = connectMapping[chain][connector];
let { connector } = await inquirer.prompt([
{
name: "connector",
message: "Enter the connector contract name? (ex: ConnectV2Paraswap)",
type: "input"
}
]);
let { choice } = await inquirer.prompt([
{
name: "choice",
message: "Do you wanna try deploy on hardhat first?",
type: "list",
choices: ["yes", "no"]
}
]);
runchain = choice === "yes" ? "hardhat" : chain;
console.log(`Deploying ${connector} on ${runchain}, press (ctrl + c) to stop`);
start = Date.now();
await execScript({
cmd: "npx",
args: ["hardhat", "run", "scripts/deployment/deploy.ts", "--network", `${runchain}`],
env: {
connectorName: connector,
networkType: chain
}
});
end = Date.now();
}
deployRunner()
.then(() => {
console.log(`Done successfully, total time taken: ${(end - start) / 1000} sec`);
process.exit(0);
})
.catch((err) => {
console.log("error:", err);
process.exit(1);
});

View File

@ -0,0 +1,86 @@
import { execScript } from "../tests/command";
import inquirer from "inquirer";
import { connectors, connectMapping } from "./connectors";
import { join } from "path";
let start: number, end: number, runchain: string;
// async function connectorSelect(chain: string) {
// let { connector } = await inquirer.prompt([
// {
// name: "connector",
// message: "Which connector do you want to deploy?",
// type: "list",
// choices: connectors[chain],
// },
// ]);
// return connector;
// }
async function deployRunner() {
let { chain } = await inquirer.prompt([
{
name: "chain",
message: "What chain do you want to deploy on?",
type: "list",
choices: ["mainnet", "polygon", "avalanche", "arbitrum", "optimism", "fantom", "base"]
}
]);
// let connector = await connectorSelect(chain);
// let { choice } = await inquirer.prompt([
// {
// name: "choice",
// message: "Do you wanna select again?",
// type: "list",
// choices: ["yes", "no"],
// },
// ]);
// if (choice === "yes") {
// connector = await connectorSelect(chain);
// }
// connector = connectMapping[chain][connector];
let { choice } = await inquirer.prompt([
{
name: "choice",
message: "Do you wanna try deploy on hardhat first?",
type: "list",
choices: ["yes", "no"]
}
]);
runchain = choice === "yes" ? "hardhat" : chain;
console.log(`Deploying on ${runchain}, press (ctrl + c) to stop`);
start = Date.now();
for (let i = 0; i < connectors[chain].length; i++) {
try {
await execScript({
cmd: "npx",
args: ["hardhat", "run", "scripts/deployment/deploy.ts", "--network", `${runchain}`],
env: {
connectorName: connectors[chain][i],
networkType: chain
}
});
} catch(e) {
console.error(`Failed of ${connectors[chain][i]} connector`)
}
}
end = Date.now();
}
deployRunner()
.then(() => {
console.log(`Done successfully, total time taken: ${(end - start) / 1000} sec`);
process.exit(0);
})
.catch((err) => {
console.log("error:", err);
process.exit(1);
});

View File

@ -0,0 +1,37 @@
import hre from "hardhat";
const { ethers } = hre;
async function main() {
if (hre.network.name === "mainnet") {
console.log("\n\n Deploying Contracts to mainnet. Hit ctrl + c to abort");
} else if (hre.network.name === "hardhat") {
console.log("\n\n Deploying Contracts to hardhat.");
}
const InstaMappingController = await ethers.getContractFactory(
"InstaMappingController"
);
const instaMappingController = await InstaMappingController.deploy();
await instaMappingController.deployed();
console.log(
"InstaMappingController deployed: ",
instaMappingController.address
);
if (hre.network.name === "mainnet") {
await hre.run("verify:verify", {
address: instaMappingController.address,
constructorArguments: [],
});
} else if (hre.network.name === "hardhat") {
console.log("Contracts deployed.");
}
}
main()
.then(() => process.exit(0))
.catch((error) => {
console.error(error);
process.exit(1);
});

View File

@ -0,0 +1,23 @@
import { Contract } from "@ethersproject/contracts";
import hre, { ethers } from "hardhat";
import { Greeter__factory } from "../../typechain";
async function main(): Promise<void> {
const Greeter: Greeter__factory = await ethers.getContractFactory("Greeter");
const greeter: Contract = await Greeter.deploy("Hello, Buidler!");
await greeter.deployed();
console.log("Greeter deployed to: ", greeter.address);
await hre.run("verify:verify", {
address: greeter.address
});
}
main()
.then(() => process.exit(0))
.catch((error: Error) => {
console.error(error);
process.exit(1);
});

View File

@ -0,0 +1,34 @@
import hre from "hardhat";
const { ethers } = hre;
async function main() {
if (hre.network.name === "mainnet") {
console.log("\n\n Deploying Contracts to mainnet. Hit ctrl + c to abort");
} else if (hre.network.name === "hardhat") {
console.log("\n\n Deploying Contracts to hardhat.");
}
const mappingContract = "CONTRACT_NAME";
const InstaProtocolMapping = await ethers.getContractFactory(mappingContract);
const instaProtocolMapping = await InstaProtocolMapping.deploy();
await instaProtocolMapping.deployed();
console.log(`${mappingContract} deployed: `, instaProtocolMapping.address);
if (hre.network.name === "mainnet") {
await hre.run("verify:verify", {
address: instaProtocolMapping.address,
constructorArguments: [],
});
} else if (hre.network.name === "hardhat") {
console.log("Contracts deployed.");
}
}
main()
.then(() => process.exit(0))
.catch((error) => {
console.error(error);
process.exit(1);
});

View File

@ -0,0 +1,42 @@
import { ethers, network } from "hardhat";
import { impersonateAccounts } from "./impersonate";
import { tokenMapping as mainnetMapping } from "./mainnet/tokens";
import { tokenMapping as polygonMapping } from "./polygon/tokens";
import { tokenMapping as avalancheMapping } from "./avalanche/tokens";
import { tokenMapping as optimismMapping } from "./optimism/tokens";
import { tokenMapping as arbitrumMapping } from "./arbitrum/tokens";
import { tokenMapping as fantomMapping } from "./fantom/tokens";
const mineTx = async (tx: any) => {
await (await tx).wait();
};
const tokenMapping: Record<string, Record<string, any>> = {
mainnet: mainnetMapping,
polygon: polygonMapping,
avalanche: avalancheMapping,
optimism: optimismMapping,
arbitrum: arbitrumMapping,
fantom: fantomMapping
};
export async function addLiquidity(tokenName: string, address: any, amt: any) {
const [signer] = await ethers.getSigners();
tokenName = tokenName.toLowerCase();
const chain = String(process.env.networkType);
if (!tokenMapping[chain][tokenName]) {
throw new Error(`Add liquidity doesn't support the following token: ${tokenName}`);
}
const token = tokenMapping[chain][tokenName];
const [impersonatedSigner] = await impersonateAccounts([token.impersonateSigner]);
// send 2 eth to cover any tx costs.
await network.provider.send("hardhat_setBalance", [
impersonatedSigner.address,
ethers.utils.parseEther("2").toHexString()
]);
await token.process(impersonatedSigner, address, amt);
}

View File

@ -0,0 +1,11 @@
export const addresses: Record<string, any> = {
connectors: {
// basic: "0x6214f9c4F9700fc7a50B5f9aEEB819d647406Ac7",
// auth: "0xD6daA927ad756a4022858dddcc4E26137b30DB4D",
// "INSTAPOOL-A": "0x8f1e38c53af7bD2b2bE01b9580911b7Cca504F1b",
},
core: {
connectorsV2: "0x67fCE99Dd6d8d659eea2a1ac1b8881c57eb6592B",
instaIndex: "0x1eE00C305C51Ff3bE60162456A9B533C07cD9288",
},
};

View File

@ -0,0 +1,60 @@
import { Provider } from "@ethersproject/abstract-provider";
import { Signer } from "@ethersproject/abstract-signer";
import { ethers } from "hardhat";
const mineTx = async (tx: any) => {
await (await tx).wait();
};
export const tokens = {
eth: {
type: "token",
symbol: "ETH",
name: "Ethereum",
address: "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee",
decimals: 18
},
dai: {
type: "token",
symbol: "DAI",
name: "DAI Stable",
address: "0xd586e7f844cea2f87f50152665bcbc2c279d8d70",
decimals: 18
},
usdc: {
type: "token",
symbol: "USDC",
name: "USD Coin",
address: "0xa7d7079b0fead91f3e65f86e8915cb59c1a4c664",
decimals: 6
},
weth: {
type: "token",
symbol: "WETH",
name: "Wrapped ETH",
address: "0x82aF49447D8a07e3bd95BD0d56f35241523fBab1",
decimals: 6
}
};
export const tokenMapping: Record<string, any> = {
usdc: {
impersonateSigner: "0xce2cc46682e9c6d5f174af598fb4931a9c0be68e",
address: "0xa7d7079b0fead91f3e65f86e8915cb59c1a4c664",
abi: ["function mint(address _to, uint256 _amount) external returns (bool);"],
process: async function (owner: Signer | Provider, to: any, amt: any) {
const contract = new ethers.Contract(this.address, this.abi, owner);
await mineTx(contract.mint(to, amt));
}
},
dai: {
impersonateSigner: "0xc5ed2333f8a2c351fca35e5ebadb2a82f5d254c3",
abi: ["function transfer(address to, uint value)"],
address: "0xd586e7f844cea2f87f50152665bcbc2c279d8d70",
process: async function (owner: Signer | Provider, to: any, amt: any) {
const contract = new ethers.Contract(this.address, this.abi, owner);
await mineTx(contract.transfer(to, amt));
}
}
};

View File

@ -0,0 +1,11 @@
export const addresses: Record<string, any> = {
connectors: {
// basic: "0x6214f9c4F9700fc7a50B5f9aEEB819d647406Ac7",
// auth: "0xD6daA927ad756a4022858dddcc4E26137b30DB4D",
// "INSTAPOOL-A": "0x8f1e38c53af7bD2b2bE01b9580911b7Cca504F1b",
},
core: {
connectorsV2: "0x127d8cD0E2b2E0366D522DeA53A787bfE9002C14",
instaIndex: "0x6CE3e607C808b4f4C26B7F6aDAeB619e49CAbb25",
},
};

View File

@ -0,0 +1,87 @@
import { Provider } from "@ethersproject/abstract-provider";
import { Signer } from "@ethersproject/abstract-signer";
import { ethers } from "hardhat";
const mineTx = async (tx: any) => {
await (await tx).wait();
};
export const tokens = {
eth: {
type: "token",
symbol: "ETH",
name: "Ethereum",
address: "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee",
decimals: 18,
},
dai: {
type: "token",
symbol: "DAI",
name: "DAI Stable",
address: "0xd586e7f844cea2f87f50152665bcbc2c279d8d70",
decimals: 18,
},
usdc: {
type: "token",
symbol: "USDC",
name: "USD Coin",
address: "0xa7d7079b0fead91f3e65f86e8915cb59c1a4c664",
decimals: 6,
},
};
export const tokenMapping: Record<string, any> = {
usdc: {
impersonateSigner: "0xc5ed2333f8a2c351fca35e5ebadb2a82f5d254c3",
address: "0xa7d7079b0fead91f3e65f86e8915cb59c1a4c664",
abi: [
"function mint(address _to, uint256 _amount) external returns (bool);",
],
process: async function (owner: Signer | Provider, to: any, amt: any) {
const contract = new ethers.Contract(this.address, this.abi, owner);
await mineTx(contract.mint(to, amt));
},
},
dai: {
impersonateSigner: "0xed2a7edd7413021d440b09d654f3b87712abab66",
address: "0xd586e7f844cea2f87f50152665bcbc2c279d8d70",
abi: ["function transfer(address to, uint value)"],
process: async function (owner: Signer | Provider, to: any, amt: any) {
const contract = new ethers.Contract(this.address, this.abi, owner);
await mineTx(contract.transfer(to, amt));
},
},
usdt: {
impersonateSigner: "0xc5ed2333f8a2c351fca35e5ebadb2a82f5d254c3",
address: "0xc7198437980c041c805a1edcba50c1ce5db95118",
abi: [
"function issue(uint amount)",
"function transfer(address to, uint value)",
],
process: async function (owner: Signer | Provider, address: any, amt: any) {
const contract = new ethers.Contract(this.address, this.abi, owner);
await mineTx(contract.issue(amt));
await mineTx(contract.transfer(address, amt));
},
},
wbtc: {
impersonateSigner: "0x63cdb19c13497383726ad6bbf7c6b6cf725a3164",
address: "0x50b7545627a5162f82a992c33b87adc75187b218",
abi: ["function mint(address _to, uint256 _amount) public returns (bool)"],
process: async function (owner: Signer | Provider, address: any, amt: any) {
const contract = new ethers.Contract(this.address, this.abi, owner);
await mineTx(contract.mint(address, amt));
},
},
// inst: {
// impersonateSigner: "0x75e89d5979E4f6Fba9F97c104c2F0AFB3F1dcB88",
// address: "0x6f40d4a6237c257fff2db00fa0510deeecd303eb",
// abi: ["function transfer(address to, uint value)"],
// process: async function (owner: Signer | Provider, address: any, amt: any) {
// const contract = new ethers.Contract(this.address, this.abi, owner);
// await mineTx(contract.transfer(address, amt));
// },
// },
};

View File

@ -0,0 +1,33 @@
import { ethers } from "hardhat";
import { addresses as addressesPolygon } from "./polygon/addresses";
import { addresses as addressesArbitrum } from "./arbitrum/addresses";
import { addresses as addressesAvalanche } from "./avalanche/addresses";
import { addresses as addressesOptimism } from "./optimism/addresses";
import { addresses as addressesFantom } from "./fantom/addresses";
import { addresses } from "./mainnet/addresses";
import { abis } from "../constant/abis";
import { abi } from "../../deployements/mainnet/Implementation_m1.sol/InstaImplementationM1.json";
function getAddress(network: string | undefined) {
if (network === "polygon") return addressesPolygon.core.instaIndex;
else if (network === "arbitrum") return addressesArbitrum.core.instaIndex;
else if (network === "avalanche") return addressesAvalanche.core.instaIndex;
else if (network === "optimism") return addressesOptimism.core.instaIndex;
else if (network === "fantom") return addressesFantom.core.instaIndex;
else return addresses.core.instaIndex;
}
export async function buildDSAv2(owner: any) {
const instaIndex = await ethers.getContractAt(
abis.core.instaIndex,
getAddress(String(process.env.networkType))
);
const tx = await instaIndex.build(owner, 2, owner);
const receipt = await tx.wait();
const event = receipt.events.find(
(a: { event: string }) => a.event === "LogAccountCreated"
);
return await ethers.getContractAt(abi, event.args.account);
}

33
scripts/tests/command.ts Normal file
View File

@ -0,0 +1,33 @@
import { execFile, spawn } from "child_process";
interface ICommand {
readonly cmd: string;
readonly args: string[];
readonly env: {
[param: string]: string;
};
}
export async function execScript(input: ICommand): Promise<number> {
return new Promise((resolve, reject) => {
let cmdEnv = Object.create(process.env);
for (let param in input.env) {
cmdEnv[param] = input.env[param];
}
const proc = spawn(input.cmd, [...input.args], {
env: cmdEnv,
shell: true,
stdio: "inherit",
});
proc.on("exit", (code) => {
if (code !== 0) {
reject(code);
return;
}
resolve(code);
});
});
}

View File

@ -0,0 +1,51 @@
import { addresses as addressesPolygon } from "./polygon/addresses";
import { addresses } from "./mainnet/addresses";
import { abis } from "../constant/abis";
import { addresses as addressesArbitrum } from "./arbitrum/addresses";
import { addresses as addressesAvalanche } from "./avalanche/addresses";
import { addresses as addressesOptimism } from "./optimism/addresses";
import { addresses as addressesFantom } from "./fantom/addresses";
import hre from "hardhat";
import type { Signer, Contract } from "ethers";
import type { ContractJSON } from "ethereum-waffle/dist/esm/ContractJSON";
const { ethers, waffle } = hre;
const { deployContract } = waffle;
interface DeployInterface {
connectorName: string;
contractArtifact: ContractJSON;
signer: Signer;
connectors: Contract;
}
function getAddress(network: string | undefined) {
if (network === "polygon") return addressesPolygon;
else if (network === "arbitrum") return addressesArbitrum;
else if (network === "avalanche") return addressesAvalanche;
else if (network === "optimism") return addressesOptimism;
else if (network === "fantom") return addressesFantom;
else return addresses;
}
export async function deployAndEnableConnector(
{
connectorName,
contractArtifact,
signer,
connectors
} : DeployInterface
) {
const connectorInstanace: Contract = await deployContract(signer, contractArtifact);
await connectors
.connect(signer)
.addConnectors([connectorName], [connectorInstanace.address]);
getAddress(String(process.env.networkType)).connectors[connectorName] =
connectorInstanace.address;
abis.connectors[connectorName] = contractArtifact.abi;
return connectorInstanace;
}

View File

@ -0,0 +1,13 @@
import hre from "hardhat";
const { web3 } = hre;
import { encodeSpells } from "./encodeSpells";
export default function encodeFlashcastData(spells: any) {
const encodeSpellsData = encodeSpells(spells);
let argTypes = ["string[]", "bytes[]"];
return web3.eth.abi.encodeParameters(argTypes, [
encodeSpellsData[0],
encodeSpellsData[1],
]);
};

View File

@ -0,0 +1,17 @@
import { web3 } from "hardhat";
import { abis } from "../constant/abis";
export function encodeSpells(spells: any[]) {
const targets = spells.map((a) => a.connector);
const calldatas = spells.map((a) => {
const functionName = a.method;
// console.log(functionName)
const abi = abis.connectors[a.connector].find((b: { name: any }) => {
return b.name === functionName;
});
// console.log(functionName)
if (!abi) throw new Error("Couldn't find function");
return web3.eth.abi.encodeFunctionCall(abi, a.args);
});
return [targets, calldatas];
}

View File

@ -0,0 +1,11 @@
export const addresses: Record<string, any> = {
connectors: {
// basic: "0x6214f9c4F9700fc7a50B5f9aEEB819d647406Ac7",
// auth: "0xD6daA927ad756a4022858dddcc4E26137b30DB4D",
// "INSTAPOOL-A": "0x8f1e38c53af7bD2b2bE01b9580911b7Cca504F1b",
},
core: {
connectorsV2: "0x819910794a030403F69247E1e5C0bBfF1593B968",
instaIndex: "0x2fa042BEEB7A40A7078EaA5aC755e3842248292b",
},
};

View File

@ -0,0 +1,64 @@
import { Provider } from "@ethersproject/abstract-provider";
import { Signer } from "@ethersproject/abstract-signer";
import { ethers } from "hardhat";
const mineTx = async (tx: any) => {
await (await tx).wait();
};
export const tokens = {
ftm: {
type: "token",
symbol: "FTM",
name: "Fantom",
address: "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee",
decimals: 18,
},
dai: {
type: "token",
symbol: "DAI",
name: "DAI Stable",
address: "0x8D11eC38a3EB5E956B052f67Da8Bdc9bef8Abf3E",
decimals: 18,
},
usdc: {
type: "token",
symbol: "USDC",
name: "USD Coin",
address: "0x04068DA6C83AFCFA0e13ba15A6696662335D5B75",
decimals: 6,
},
};
export const tokenMapping: Record<string, any> = {
usdc: {
impersonateSigner: "0x4188663a85C92EEa35b5AD3AA5cA7CeB237C6fe9",
address: "0x04068DA6C83AFCFA0e13ba15A6696662335D5B75",
abi: [
"function mint(address _to, uint256 _amount) external returns (bool);",
],
process: async function (owner: Signer | Provider, to: any, amt: any) {
const contract = new ethers.Contract(this.address, this.abi, owner);
await mineTx(contract.mint(to, amt));
},
},
dai: {
impersonateSigner: "0x9bdB521a97E95177BF252C253E256A60C3e14447",
address: "0x8D11eC38a3EB5E956B052f67Da8Bdc9bef8Abf3E",
abi: ["function transfer(address to, uint value)"],
process: async function (owner: Signer | Provider, to: any, amt: any) {
const contract = new ethers.Contract(this.address, this.abi, owner);
await mineTx(contract.transfer(to, amt));
},
},
// inst: {
// impersonateSigner: "0x75e89d5979E4f6Fba9F97c104c2F0AFB3F1dcB88",
// address: "0x6f40d4a6237c257fff2db00fa0510deeecd303eb",
// abi: ["function transfer(address to, uint value)"],
// process: async function (owner: Signer | Provider, address: any, amt: any) {
// const contract = new ethers.Contract(this.address, this.abi, owner);
// await mineTx(contract.transfer(address, amt));
// },
// },
};

View File

@ -0,0 +1,39 @@
import { ethers, network } from "hardhat";
import { addresses } from "./mainnet/addresses";
import { addresses as addressesPolygon } from "./polygon/addresses";
import { addresses as addressesArbitrum } from "./arbitrum/addresses";
import { addresses as addressesAvalanche } from "./avalanche/addresses";
import { addresses as addressesOptimism } from "./optimism/addresses";
import { addresses as addressesFantom } from "./fantom/addresses";
import { abis } from "../constant/abis";
function getAddress(network: string | undefined) {
if (network === "polygon") return addressesPolygon.core.instaIndex;
else if (network === "arbitrum") return addressesArbitrum.core.instaIndex;
else if (network === "avalanche") return addressesAvalanche.core.instaIndex;
else if (network === "optimism") return addressesOptimism.core.instaIndex;
else if (network === "fantom") return addressesFantom.core.instaIndex;
else return addresses.core.instaIndex;
}
export async function getMasterSigner() {
const [_, __, ___, wallet3] = await ethers.getSigners();
const instaIndex = new ethers.Contract(
getAddress(String(process.env.networkType)),
abis.core.instaIndex,
wallet3
);
const masterAddress = await instaIndex.master();
await network.provider.request({
method: "hardhat_impersonateAccount",
params: [masterAddress],
});
await network.provider.send("hardhat_setBalance", [
masterAddress,
"0x8ac7230489e80000", // 1e19 wei
]);
return await ethers.getSigner(masterAddress);
}

View File

@ -0,0 +1,44 @@
import { promises as fs } from "fs";
import { join } from "path";
import { execScript } from "./command";
let start: number, end: number;
async function testRunner() {
const chain = ["avalanche", "mainnet", "polygon", "arbitrum", "optimism"];
start = Date.now();
for (let ch of chain) {
console.log(`📗Running test for %c${ch}: `, "blue");
let path: string;
const testsPath = join(__dirname, "../../test", ch);
await fs.access(testsPath);
const availableTests = await fs.readdir(testsPath);
if (availableTests.length !== 0) {
for (let test of availableTests) {
path = join(testsPath, test);
path += "/*";
await execScript({
cmd: "npx",
args: ["hardhat", "test", path],
env: {
networkType: ch,
},
});
}
}
}
end = Date.now();
}
testRunner()
.then(() =>
console.log(
`🙌 finished running the test, total time taken ${(end - start) /
1000} sec`
)
)
.catch((err) => console.error("❌ failed due to error: ", err));

View File

@ -0,0 +1,14 @@
import { ethers, network } from "hardhat";
export const impersonateAccounts = async (accounts: any) => {
const signers = [];
for (const account of accounts) {
await network.provider.request({
method: "hardhat_impersonateAccount",
params: [account],
});
signers.push(await ethers.getSigner(account));
}
return signers;
};

View File

@ -0,0 +1,11 @@
export const addresses: Record<string, any> = {
connectors: {
"basic": "0xe5398f279175962E56fE4c5E0b62dc7208EF36c6",
"auth": "0xd1aff9f2acf800c876c409100d6f39aea93fc3d9",
"INSTAPOOL-A": "0x5806af7ab22e2916fa582ff05731bf7c682387b2",
},
core: {
"connectorsV2": "0x97b0B3A8bDeFE8cB9563a3c610019Ad10DB8aD11",
"instaIndex": "0x2971AdFa57b20E5a416aE5a708A8655A9c74f723",
},
};

View File

@ -0,0 +1,164 @@
import { Provider } from "@ethersproject/abstract-provider";
import { Signer } from "@ethersproject/abstract-signer";
import { ethers } from "hardhat";
const mineTx = async (tx: any) => {
await (await tx).wait();
};
export const tokens = {
eth: {
type: "token",
symbol: "ETH",
name: "Ethereum",
address: "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee",
aTokenAddress: "0x030bA81f1c18d280636F32af80b9AAd02Cf0854e",
cTokenAddress: "0x4Ddc2D193948926D02f9B1fE9e1daa0718270ED5",
decimals: 18
},
dai: {
type: "token",
symbol: "DAI",
name: "DAI Stable",
address: "0x6B175474E89094C44Da98b954EedeAC495271d0F",
aTokenAddress: "0x028171bCA77440897B824Ca71D1c56caC55b68A3",
cTokenAddress: "0x5d3a536E4D6DbD6114cc1Ead35777bAB948E3643",
decimals: 18
},
usdc: {
type: "token",
symbol: "USDC",
name: "USD Coin",
address: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
aTokenAddress: "0xBcca60bB61934080951369a648Fb03DF4F96263C",
cTokenAddress: "0x39AA39c021dfbaE8faC545936693aC917d5E7563",
decimals: 6
},
weth: {
type: "token",
symbol: "WETH",
name: "Wrapped Ether",
address: "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2",
aTokenAddress: "0x030bA81f1c18d280636F32af80b9AAd02Cf0854e",
cTokenAddress: "0x4Ddc2D193948926D02f9B1fE9e1daa0718270ED5",
decimals: 18
},
ens: {
type: "token",
symbol: "ENS",
name: "Etherem Name Services",
address: "0xC18360217D8F7Ab5e7c516566761Ea12Ce7F9D72",
aTokenAddress: "0x9a14e23A58edf4EFDcB360f68cd1b95ce2081a2F",
decimals: 18
},
comp: {
type: "token",
symbol: "COMP",
name: "Compound",
address: "0xc00e94Cb662C3520282E6f5717214004A7f26888",
cTokenAddress: "0x70e36f6BF80a52b3B46b3aF8e106CC0ed743E8e4",
decimals: 18
},
link: {
type: "token",
symbol: "LINK",
name: "ChainLink Token",
address: "0x514910771AF9Ca656af840dff83E8264EcF986CA",
aTokenAddress: "0xa06bC25B5805d5F8d82847D191Cb4Af5A3e873E0",
cTokenAddress: "0xFAce851a4921ce59e912d19329929CE6da6EB0c7",
decimals: 18
},
uni: {
type: "token",
symbol: "UNI",
name: "Uniswap",
address: "0x1f9840a85d5aF5bf1D1762F925BDADdC4201F984",
aTokenAddress: "0xB9D7CB55f463405CDfBe4E90a6D2Df01C2B92BF1",
cTokenAddress: "0x35A18000230DA775CAc24873d00Ff85BccdeD550",
decimals: 18
},
crvusd: {
type: "token",
symbol: "crvUSD",
name: "Curve.Fi USD Stablecoin",
address: "0xf939E0A03FB07F59A73314E73794Be0E57ac1b4E",
decimals: 18
},
sfrxeth: {
type: "token",
symbol: "sfrxETH",
name: "Staked Frax Ether",
address: "0xac3E018457B222d93114458476f3E3416Abbe38F",
decimals: 18
},
wsteth: {
type: "token",
symbol: "wstETH",
name: "Wrapped liquid staked Ether 2.0",
address: "0x7f39C581F595B53c5cb19bD0b3f8dA6c935E2Ca0",
decimals: 18
},
wbtc: {
type: "token",
symbol: "WBTC",
name: "Wrapped BTC",
address: "0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599",
decimals: 8
},
};
export const dsaMaxValue = "115792089237316195423570985008687907853269984665640564039457584007913129639935";
export const tokenMapping: Record<string, any> = {
usdc: {
impersonateSigner: "0xfcb19e6a322b27c06842a71e8c725399f049ae3a",
address: "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48",
abi: [
"function mint(address _to, uint256 _amount) external returns (bool)",
"function balanceOf(address user) external returns (uint256)"
],
process: async function (owner: Signer | Provider, to: any, amt: any) {
const contract = new ethers.Contract(this.address, this.abi, owner);
await mineTx(contract.mint(to, amt));
}
},
dai: {
impersonateSigner: "0x47ac0fb4f2d84898e4d9e7b4dab3c24507a6d503",
abi: ["function transfer(address to, uint value)"],
address: "0x6b175474e89094c44da98b954eedeac495271d0f",
process: async function (owner: Signer | Provider, to: any, amt: any) {
const contract = new ethers.Contract(this.address, this.abi, owner);
await mineTx(contract.transfer(to, amt));
}
},
usdt: {
impersonateSigner: "0xc6cde7c39eb2f0f0095f41570af89efc2c1ea828",
address: "0xdac17f958d2ee523a2206206994597c13d831ec7",
abi: ["function issue(uint amount)", "function transfer(address to, uint value)"],
process: async function (owner: Signer | Provider, address: any, amt: any) {
const contract = new ethers.Contract(this.address, this.abi, owner);
await mineTx(contract.issue(amt));
await mineTx(contract.transfer(address, amt));
}
},
wbtc: {
impersonateSigner: "0xCA06411bd7a7296d7dbdd0050DFc846E95fEBEB7",
address: "0x2260fac5e5542a773aa44fbcfedf7c193bc2c599",
abi: ["function mint(address _to, uint256 _amount) public returns (bool)"],
process: async function (owner: Signer | Provider, address: any, amt: any) {
const contract = new ethers.Contract(this.address, this.abi, owner);
await mineTx(contract.mint(address, amt));
}
},
inst: {
impersonateSigner: "0x75e89d5979E4f6Fba9F97c104c2F0AFB3F1dcB88",
address: "0x6f40d4a6237c257fff2db00fa0510deeecd303eb",
abi: ["function transfer(address to, uint value)"],
process: async function (owner: Signer | Provider, address: any, amt: any) {
const contract = new ethers.Contract(this.address, this.abi, owner);
await mineTx(contract.transfer(address, amt));
}
}
};

View File

@ -0,0 +1,10 @@
export const addresses: Record<string, any> = {
connectors: {
basic: "0xe5398f279175962E56fE4c5E0b62dc7208EF36c6",
auth: "0xd1aff9f2acf800c876c409100d6f39aea93fc3d9",
},
core: {
connectorsV2: "0x127d8cD0E2b2E0366D522DeA53A787bfE9002C14",
instaIndex: "0x6CE3e607C808b4f4C26B7F6aDAeB619e49CAbb25",
},
};

View File

@ -0,0 +1,88 @@
import { Provider } from "@ethersproject/abstract-provider";
import { Signer } from "@ethersproject/abstract-signer";
import { ethers } from "hardhat";
const mineTx = async (tx: any) => {
await (await tx).wait();
};
export const tokens = {
eth: {
type: "token",
symbol: "ETH",
name: "Eth",
address: "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee",
decimals: 18
},
dai: {
type: "token",
symbol: "DAI",
name: "DAI Stable",
address: "0x8f3Cf7ad23Cd3CaDbD9735AFf958023239c6A063",
decimals: 18
},
usdc: {
type: "token",
symbol: "USDC",
name: "USD Coin",
address: "0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174",
decimals: 6
},
usdt: {
type: "token",
symbol: "USDT",
name: "Tether USD Coin",
address: "0x94b008aA00579c1307B0EF2c499aD98a8ce58e58",
decimals: 6
}
};
export const tokenMapping: Record<string, any> = {
usdc: {
impersonateSigner: "0x31efc4aeaa7c39e54a33fdc3c46ee2bd70ae0a09",
address: "0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174",
abi: ["function mint(address _to, uint256 _amount) external returns (bool);"],
process: async function (owner: Signer | Provider, to: any, amt: any) {
const contract = new ethers.Contract(this.address, this.abi, owner);
await mineTx(contract.mint(to, amt));
}
},
dai: {
impersonateSigner: "0x360537542135943E8Fc1562199AEA6d0017F104B",
address: "0xDA10009cBd5D07dd0CeCc66161FC93D7c9000da1",
abi: ["function transfer(address to, uint value)"],
process: async function (owner: Signer | Provider, to: any, amt: any) {
const contract = new ethers.Contract(this.address, this.abi, owner);
await mineTx(contract.transfer(to, amt));
}
},
usdt: {
impersonateSigner: "0xc858a329bf053be78d6239c4a4343b8fbd21472b",
address: "0x94b008aA00579c1307B0EF2c499aD98a8ce58e58",
abi: ["function issue(uint amount)", "function transfer(address to, uint value)"],
process: async function (owner: Signer | Provider, address: any, amt: any) {
const contract = new ethers.Contract(this.address, this.abi, owner);
await mineTx(contract.issue(amt));
await mineTx(contract.transfer(address, amt));
}
},
wbtc: {
impersonateSigner: "0x3aa76aa74bdfa09d68d9ebeb462c5f40d727283f",
address: "0x68f180fcCe6836688e9084f035309E29Bf0A2095",
abi: ["function mint(address _to, uint256 _amount) public returns (bool)"],
process: async function (owner: Signer | Provider, address: any, amt: any) {
const contract = new ethers.Contract(this.address, this.abi, owner);
await mineTx(contract.mint(address, amt));
}
}
// inst: {
// impersonateSigner: "0xf1f22f25f748f79263d44735198e023b72806ab1",
// address: "0x6f40d4A6237C257fff2dB00FA0510DeEECd303eb",
// abi: ["function transfer(address to, uint value)"],
// process: async function (owner: Signer | Provider, address: any, amt: any) {
// const contract = new ethers.Contract(this.address, this.abi, owner);
// await mineTx(contract.transfer(address, amt));
// },
// },
};

View File

@ -0,0 +1,10 @@
export const addresses: Record<string, any> = {
connectors: {
basic: "0x1cAF5EC802ca602E98139AD96A8f2B7BC524264E",
auth: "0xf6474aD0dA75A0dE15D2c915e601D9f754B9e6fe",
},
core: {
connectorsV2: "0x2A00684bFAb9717C21271E0751BCcb7d2D763c88",
instaIndex: "0xA9B99766E6C676Cf1975c0D3166F96C0848fF5ad",
},
};

View File

@ -0,0 +1,101 @@
import { Provider } from "@ethersproject/abstract-provider";
import { Signer } from "@ethersproject/abstract-signer";
import { ethers } from "hardhat";
const mineTx = async (tx: any) => {
await (await tx).wait();
};
export const tokens = {
matic: {
type: "token",
symbol: "MATIC",
name: "Matic",
address: "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee",
decimals: 18,
},
wmatic: {
type: "token",
symbol: "WMATIC",
name: "Wrapped Matic",
address: "0x0d500B1d8E8eF31E21C99d1Db9A6444d3ADf1270",
decimals: 18,
},
eth: {
type: "token",
symbol: "ETH",
name: "Ethereum",
address: "0x7ceb23fd6bc0add59e62ac25578270cff1b9f619",
decimals: 18,
},
dai: {
type: "token",
symbol: "DAI",
name: "DAI Stable",
address: "0x8f3Cf7ad23Cd3CaDbD9735AFf958023239c6A063",
decimals: 18,
},
usdc: {
type: "token",
symbol: "USDC",
name: "USD Coin",
address: "0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174",
decimals: 6,
},
};
export const tokenMapping: Record<string, any> = {
usdc: {
impersonateSigner: "0x6e7a5fafcec6bb1e78bae2a1f0b612012bf14827",
address: "0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174",
abi: [
"function mint(address _to, uint256 _amount) external returns (bool);",
],
process: async function (owner: Signer | Provider, to: any, amt: any) {
const contract = new ethers.Contract(this.address, this.abi, owner);
await mineTx(contract.mint(to, amt));
},
},
dai: {
impersonateSigner: "0x4a35582a710e1f4b2030a3f826da20bfb6703c09",
address: "0x8f3Cf7ad23Cd3CaDbD9735AFf958023239c6A063",
abi: ["function transfer(address to, uint value)"],
process: async function (owner: Signer | Provider, to: any, amt: any) {
const contract = new ethers.Contract(this.address, this.abi, owner);
await mineTx(contract.transfer(to, amt));
},
},
usdt: {
impersonateSigner: "0x0d0707963952f2fba59dd06f2b425ace40b492fe",
address: "0xc2132d05d31c914a87c6611c10748aeb04b58e8f",
abi: [
"function issue(uint amount)",
"function transfer(address to, uint value)",
],
process: async function (owner: Signer | Provider, address: any, amt: any) {
const contract = new ethers.Contract(this.address, this.abi, owner);
await mineTx(contract.issue(amt));
await mineTx(contract.transfer(address, amt));
},
},
wbtc: {
impersonateSigner: "0xdc9232e2df177d7a12fdff6ecbab114e2231198d",
address: "0x1bfd67037b42cf73acf2047067bd4f2c47d9bfd6",
abi: ["function mint(address _to, uint256 _amount) public returns (bool)"],
process: async function (owner: Signer | Provider, address: any, amt: any) {
const contract = new ethers.Contract(this.address, this.abi, owner);
await mineTx(contract.mint(address, amt));
},
},
inst: {
impersonateSigner: "0xf1f22f25f748f79263d44735198e023b72806ab1",
address: "0xf50d05a1402d0adafa880d36050736f9f6ee7dee",
abi: ["function transfer(address to, uint value)"],
process: async function (owner: Signer | Provider, address: any, amt: any) {
const contract = new ethers.Contract(this.address, this.abi, owner);
await mineTx(contract.transfer(address, amt));
},
},
};

View File

@ -0,0 +1,68 @@
import inquirer from "inquirer";
import { promises as fs } from "fs";
import { join } from "path";
import { execScript } from "./command";
let start: number, end: number;
async function testRunner() {
const { chain } = await inquirer.prompt([
{
name: "chain",
message: "What chain do you want to run tests on?",
type: "list",
choices: ["mainnet", "polygon", "avalanche", "arbitrum", "optimism", "fantom"],
},
]);
const testsPath = join(__dirname, "../../test", chain);
await fs.access(testsPath);
const availableTests = await fs.readdir(testsPath);
if (availableTests.length === 0) {
throw new Error(`No tests available for ${chain}`);
}
const { testName } = await inquirer.prompt([
{
name: "testName",
message: "For which connector you want to run the tests?",
type: "list",
choices: ["all", ...availableTests],
},
]);
start = Date.now();
let path: string;
if (testName === "all") {
for (let test of availableTests) {
path = join(testsPath, test);
path += "/*";
await execScript({
cmd: "npx",
args: ["hardhat", "test", path],
env: {
networkType: chain,
},
});
}
} else {
path = join(testsPath, testName);
path += "/*";
await execScript({
cmd: "npx",
args: ["hardhat", "test", path],
env: {
networkType: chain,
},
});
}
end = Date.now();
}
testRunner()
.then(() =>
console.log(
`🙌 finished the test runner, time taken ${(end - start) / 1000} sec`
)
)
.catch((err) => console.error("❌ failed due to error: ", err));

View File

@ -0,0 +1,63 @@
import { promises as fs } from "fs";
import { join } from "path";
import { execScript } from "./command";
import { task } from "hardhat/config";
let start: number, end: number;
task("run_tests", "runs specified test on a specified chain")
.addPositionalParam("chain")
.addPositionalParam("test")
.setAction(async (taskArgs) => {
const chain = taskArgs.chain;
const test = taskArgs.test;
await testRunner(chain,test)
.then(() =>
console.log(
`🙌 finished the test runner, time taken ${(end - start) / 1000} sec`
)
)
.catch((err) => console.error("❌ failed due to error: ", err));
});
async function testRunner(chain: string, testName: string) {
const testsPath = join(__dirname, "../../test", chain);
await fs.access(testsPath);
const availableTests = await fs.readdir(testsPath);
if (availableTests.length === 0) {
throw new Error(`No tests available for ${chain}`);
}
start = Date.now();
let path: string;
if (testName === "all") {
for (let test of availableTests) {
path = join(testsPath, test);
path += "/*";
await execScript({
cmd: "npx",
args: ["hardhat", "test", path],
env: {
networkType: chain,
},
}).catch((err)=>console.log(`failed ${test}`))
}
} else {
path = join(testsPath, testName);
path += "/*";
await execScript({
cmd: "npx",
args: ["hardhat", "test", path],
env: {
networkType: chain,
},
});
}
end = Date.now();
}

0
test/.gitkeep Normal file
View File

View File

@ -0,0 +1,303 @@
import { expect, should } from "chai";
import hre, { ethers, waffle } from "hardhat";
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 { buildDSAv2 } from "../../../scripts/tests/buildDSAv2";
import { addresses } from "../../../scripts/tests/arbitrum/addresses";
import { deployAndEnableConnector } from "../../../scripts/tests/deployAndEnableConnector";
import { abis } from "../../../scripts/constant/abis";
import { getMasterSigner } from "../../../scripts/tests/getMasterSigner";
import { parseEther, parseUnits } from "ethers/lib/utils";
import { encodeSpells } from "../../../scripts/tests/encodeSpells";
import encodeFlashcastData from "../../../scripts/tests/encodeFlashcastData";
import { ConnectV2AaveV3ImportPermitArbitrum__factory, IERC20__factory } from "../../../typechain";
const ABI = [
"function DOMAIN_SEPARATOR() public view returns (bytes32)",
"function balanceOf(address account) public view returns (uint256)",
"function nonces(address owner) public view returns (uint256)"
];
const aDaiAddress = "0x82E64f49Ed5EC1bC6e43DAD4FC8Af9bb3A2312EE";
const aaveAddress = "0x794a61358D6845594F94dc1DB02A252b5b4814aD";
let account = "0xc5ed2333f8a2c351fca35e5ebadb2a82f5d254c3";
const DAI = "0xDA10009cBd5D07dd0CeCc66161FC93D7c9000da1";
const USDC = "0xFF970A61A04b1cA14834A43f5dE4533eBDDB5CC8";
const mnemonic = "test test test test test test test test test test test junk";
const connectorName = "AAVE-V3-IMPORT-PERMIT-X";
let signer: any, wallet0: any;
const aaveAbi = [
{
inputs: [
{ internalType: "address", name: "asset", type: "address" },
{ internalType: "uint256", name: "amount", type: "uint256" },
{ internalType: "uint256", name: "interestRateMode", type: "uint256" },
{ internalType: "uint16", name: "referralCode", type: "uint16" },
{ internalType: "address", name: "onBehalfOf", type: "address" }
],
name: "borrow",
outputs: [],
stateMutability: "nonpayable",
type: "function"
},
{
inputs: [
{ internalType: "address", name: "asset", type: "address" },
{ internalType: "uint256", name: "amount", type: "uint256" },
{ internalType: "address", name: "onBehalfOf", type: "address" },
{ internalType: "uint16", name: "referralCode", type: "uint16" }
],
name: "supply",
outputs: [],
stateMutability: "nonpayable",
type: "function"
}
];
const erc20Abi = [
{
constant: false,
inputs: [
{
name: "_spender",
type: "address"
},
{
name: "_value",
type: "uint256"
}
],
name: "approve",
outputs: [
{
name: "",
type: "bool"
}
],
payable: false,
stateMutability: "nonpayable",
type: "function"
},
{
constant: true,
inputs: [],
name: "totalSupply",
outputs: [
{
name: "",
type: "uint256"
}
],
payable: false,
stateMutability: "view",
type: "function"
},
{
constant: true,
inputs: [
{
name: "_owner",
type: "address"
}
],
name: "balanceOf",
outputs: [
{
name: "balance",
type: "uint256"
}
],
payable: false,
stateMutability: "view",
type: "function"
},
{
constant: false,
inputs: [
{
name: "_to",
type: "address"
},
{
name: "_value",
type: "uint256"
}
],
name: "transfer",
outputs: [
{
name: "",
type: "bool"
}
],
payable: false,
stateMutability: "nonpayable",
type: "function"
}
];
const token = new ethers.Contract(DAI, erc20Abi);
const aDai = new ethers.Contract(aDaiAddress, ABI);
const usdcToken = new ethers.Contract(USDC, erc20Abi);
const aave = new ethers.Contract(aaveAddress, aaveAbi);
describe("Import Aave v3 Position for Arbitrum", function () {
let dsaWallet0: any;
let masterSigner: Signer;
let instaConnectorsV2: Contract;
let connector: any;
const wallet = ethers.Wallet.fromMnemonic(mnemonic);
before(async () => {
await hre.network.provider.request({
method: "hardhat_reset",
params: [
{
forking: {
//@ts-ignore
jsonRpcUrl: hre.config.networks.hardhat.forking.url,
blockNumber: 9333600
}
}
]
});
masterSigner = await getMasterSigner();
[wallet0] = await ethers.getSigners();
await hre.network.provider.send("hardhat_setBalance", [account, ethers.utils.parseEther("10").toHexString()]);
await hre.network.provider.request({
method: "hardhat_impersonateAccount",
params: [account]
});
signer = await ethers.getSigner(account);
await token.connect(signer).transfer(wallet0.address, ethers.utils.parseEther("10"));
instaConnectorsV2 = await ethers.getContractAt(abis.core.connectorsV2, addresses.core.connectorsV2);
connector = await deployAndEnableConnector({
connectorName,
contractArtifact: ConnectV2AaveV3ImportPermitArbitrum__factory,
signer: masterSigner,
connectors: instaConnectorsV2
});
});
describe("check user AAVE position", async () => {
it("Should create Aave v3 position of DAI(collateral) and USDC(debt)", async () => {
// approve DAI to aavePool
await token.connect(wallet0).approve(aaveAddress, parseEther("10"));
//deposit DAI in aave
await aave.connect(wallet0).supply(DAI, parseEther("10"), wallet.address, 3228);
console.log("Supplied DAI on aave");
//borrow USDC from aave
await aave.connect(wallet0).borrow(USDC, parseUnits("3", 6), 2, 3228, wallet.address);
console.log("Borrowed USDC from aave");
});
it("Should check position of user", async () => {
expect(await aDai.connect(wallet0).balanceOf(wallet.address)).to.be.gte(
new BigNumber(10).multipliedBy(1e18).toString()
);
expect(await usdcToken.connect(wallet0).balanceOf(wallet.address)).to.be.gte(
new BigNumber(3).multipliedBy(1e6).toString()
);
});
});
describe("Deployment", async () => {
it("Should set correct name", async () => {
expect(await connector.name()).to.eq("Aave-v3-import-permit-v1");
});
});
describe("DSA wallet setup", async () => {
it("Should build DSA v2", async () => {
dsaWallet0 = await buildDSAv2(wallet.address);
expect(!!dsaWallet0.address).to.be.true;
});
it("Deposit ETH into DSA wallet", async function () {
await wallet0.sendTransaction({
to: dsaWallet0.address,
value: ethers.utils.parseEther("5")
});
expect(await ethers.provider.getBalance(dsaWallet0.address)).to.be.gte(ethers.utils.parseEther("5"));
});
});
describe("Aave position migration", async () => {
it("Should migrate Aave position", async () => {
const DOMAIN_SEPARATOR = await aDai.connect(wallet0).DOMAIN_SEPARATOR();
const PERMIT_TYPEHASH = "0x6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9";
let nonce = (await aDai.connect(wallet0).nonces(wallet.address)).toNumber();
//Approving max amount
const amount = ethers.constants.MaxUint256;
const expiry = Date.now() + 20 * 60;
const digest = keccak256(
ethers.utils.solidityPack(
["bytes1", "bytes1", "bytes32", "bytes32"],
[
"0x19",
"0x01",
DOMAIN_SEPARATOR,
keccak256(
defaultAbiCoder.encode(
["bytes32", "address", "address", "uint256", "uint256", "uint256"],
[PERMIT_TYPEHASH, wallet.address, dsaWallet0.address, amount, nonce, expiry]
)
)
]
)
);
const { v, r, s } = ecsign(Buffer.from(digest.slice(2), "hex"), Buffer.from(wallet.privateKey.slice(2), "hex"));
const amount0 = new BigNumber(await usdcToken.connect(wallet0).balanceOf(wallet.address));
const amountB = new BigNumber(amount0.toString()).multipliedBy(5).dividedBy(1e4);
const amountWithFee = amount0.plus(amountB);
const flashSpells = [
{
connector: "AAVE-V3-IMPORT-PERMIT-X",
method: "importAave",
args: [
wallet.address,
[[DAI], [USDC], false, [amountB.toFixed(0)]],
[[v], [ethers.utils.hexlify(r)], [ethers.utils.hexlify(s)], [expiry]]
]
},
{
connector: "INSTAPOOL-C",
method: "flashPayback",
args: [USDC, amountWithFee.toFixed(0), 0, 0]
}
];
const spells = [
{
connector: "INSTAPOOL-C",
method: "flashBorrowAndCast",
args: [USDC, amount0.toString(), 5, encodeFlashcastData(flashSpells), "0x"]
}
];
const tx = await dsaWallet0.connect(wallet0).cast(...encodeSpells(spells), wallet.address);
const receipt = await tx.wait();
});
it("Should check DSA AAVE position", async () => {
expect(await aDai.connect(wallet0).balanceOf(dsaWallet0.address)).to.be.gte(
new BigNumber(10).multipliedBy(1e18).toString()
);
});
});
});

View File

@ -0,0 +1,292 @@
import { expect, should } from "chai";
import hre, { ethers, waffle } from "hardhat";
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 { buildDSAv2 } from "../../../scripts/tests/buildDSAv2";
import { addresses } from "../../../scripts/tests/arbitrum/addresses";
import { deployAndEnableConnector } from "../../../scripts/tests/deployAndEnableConnector";
import { abis } from "../../../scripts/constant/abis";
import { getMasterSigner } from "../../../scripts/tests/getMasterSigner";
import { parseEther, parseUnits } from "ethers/lib/utils";
import { encodeSpells } from "../../../scripts/tests/encodeSpells";
import encodeFlashcastData from "../../../scripts/tests/encodeFlashcastData";
import { ConnectV2AaveV3Arbitrum__factory, IERC20__factory } from "../../../typechain";
const ABI = ["function balanceOf(address account) public view returns (uint256)"];
const aDaiAddress = "0x82E64f49Ed5EC1bC6e43DAD4FC8Af9bb3A2312EE";
const aaveAddress = "0x69FA688f1Dc47d4B5d8029D5a35FB7a548310654";
let account = "0xc5ed2333f8a2c351fca35e5ebadb2a82f5d254c3";
const DAI = "0xDA10009cBd5D07dd0CeCc66161FC93D7c9000da1";
const USDC = "0xFF970A61A04b1cA14834A43f5dE4533eBDDB5CC8";
const mnemonic = "test test test test test test test test test test test junk";
const connectorName = "AAVE-V3-X";
let signer: any, wallet0: any;
const aaveAbi = [
{
inputs: [
{ internalType: "address", name: "asset", type: "address" },
{ internalType: "address", name: "user", type: "address" }
],
name: "getUserReserveData",
outputs: [
{ internalType: "uint256", name: "currentATokenBalance", type: "uint256" },
{ internalType: "uint256", name: "currentStableDebt", type: "uint256" },
{ internalType: "uint256", name: "currentVariableDebt", type: "uint256" },
{ internalType: "uint256", name: "principalStableDebt", type: "uint256" },
{ internalType: "uint256", name: "scaledVariableDebt", type: "uint256" },
{ internalType: "uint256", name: "stableBorrowRate", type: "uint256" },
{ internalType: "uint256", name: "liquidityRate", type: "uint256" },
{ internalType: "uint40", name: "stableRateLastUpdated", type: "uint40" },
{ internalType: "bool", name: "usageAsCollateralEnabled", type: "bool" }
],
stateMutability: "view",
type: "function"
}
];
const erc20Abi = [
{
constant: false,
inputs: [
{
name: "_spender",
type: "address"
},
{
name: "_value",
type: "uint256"
}
],
name: "approve",
outputs: [
{
name: "",
type: "bool"
}
],
payable: false,
stateMutability: "nonpayable",
type: "function"
},
{
constant: true,
inputs: [],
name: "totalSupply",
outputs: [
{
name: "",
type: "uint256"
}
],
payable: false,
stateMutability: "view",
type: "function"
},
{
constant: true,
inputs: [
{
name: "_owner",
type: "address"
}
],
name: "balanceOf",
outputs: [
{
name: "balance",
type: "uint256"
}
],
payable: false,
stateMutability: "view",
type: "function"
},
{
constant: false,
inputs: [
{
name: "_to",
type: "address"
},
{
name: "_value",
type: "uint256"
}
],
name: "transfer",
outputs: [
{
name: "",
type: "bool"
}
],
payable: false,
stateMutability: "nonpayable",
type: "function"
}
];
const token = new ethers.Contract(DAI, erc20Abi);
const aDai = new ethers.Contract(aDaiAddress, ABI);
const usdcToken = new ethers.Contract(USDC, erc20Abi);
const aave = new ethers.Contract(aaveAddress, aaveAbi);
describe("Aave v3 Position for Arbitrum", function () {
let dsaWallet0: any;
let masterSigner: Signer;
let instaConnectorsV2: Contract;
let connector: any;
const wallet = ethers.Wallet.fromMnemonic(mnemonic);
before(async () => {
await hre.network.provider.request({
method: "hardhat_reset",
params: [
{
forking: {
//@ts-ignore
jsonRpcUrl: hre.config.networks.hardhat.forking.url,
blockNumber: 9333600
}
}
]
});
masterSigner = await getMasterSigner();
[wallet0] = await ethers.getSigners();
await hre.network.provider.send("hardhat_setBalance", [account, ethers.utils.parseEther("10").toHexString()]);
await hre.network.provider.request({
method: "hardhat_impersonateAccount",
params: [account]
});
signer = await ethers.getSigner(account);
await token.connect(signer).transfer(wallet0.address, ethers.utils.parseEther("10"));
instaConnectorsV2 = await ethers.getContractAt(abis.core.connectorsV2, addresses.core.connectorsV2);
connector = await deployAndEnableConnector({
connectorName,
contractArtifact: ConnectV2AaveV3Arbitrum__factory,
signer: masterSigner,
connectors: instaConnectorsV2
});
});
describe("Deployment", async () => {
it("Should set correct name", async () => {
expect(await connector.name()).to.eq("AaveV3-v1.2");
});
});
describe("DSA wallet setup", async () => {
it("Should build DSA v2", async () => {
dsaWallet0 = await buildDSAv2(wallet0.address);
expect(!!dsaWallet0.address).to.be.true;
});
it("Deposit ETH into DSA wallet", async function () {
await wallet0.sendTransaction({
to: dsaWallet0.address,
value: ethers.utils.parseEther("5")
});
expect(await ethers.provider.getBalance(dsaWallet0.address)).to.be.gte(ethers.utils.parseEther("5"));
});
});
describe("check user AAVE position", async () => {
it("Should create DSA Aave v3 position of DAI(collateral) and USDC(debt)", async () => {
await token.connect(signer).transfer(dsaWallet0.address, ethers.utils.parseEther("10"));
const spells = [
//deposit DAI in aave
{
connector: connectorName,
method: "deposit",
args: [DAI, parseEther("10"), 0, 0]
},
//borrow USDC from aave
{
connector: connectorName,
method: "borrow",
args: [USDC, parseUnits("3", 6), 2, 0, 0]
}
];
const tx = await dsaWallet0.connect(wallet0).cast(...encodeSpells(spells), wallet0.address);
const receipt = await tx.wait();
});
it("Should check position of dsa", async () => {
expect(await aDai.connect(wallet0).balanceOf(dsaWallet0.address)).to.be.gte(
new BigNumber(10).multipliedBy(1e18).toString()
);
expect(await usdcToken.connect(wallet0).balanceOf(dsaWallet0.address)).to.be.gte(
new BigNumber(3).multipliedBy(1e6).toString()
);
expect((await aave.connect(wallet0).getUserReserveData(USDC, dsaWallet0.address)).currentStableDebt).to.be.equal(
0
);
expect((await aave.connect(wallet0).getUserReserveData(USDC, dsaWallet0.address)).currentVariableDebt).to.be.gte(
new BigNumber(3).multipliedBy(1e6).toString()
);
console.log(
`\tstable borrow before: ${
(await aave.connect(wallet0).getUserReserveData(USDC, dsaWallet0.address)).currentStableDebt
}`
);
console.log(
`\tvariable borrow before: ${
(await aave.connect(wallet0).getUserReserveData(USDC, dsaWallet0.address)).currentVariableDebt
}`
);
});
it("Should swap borrowRateMode", async () => {
const spells = [
//deposit DAI in aave
{
connector: connectorName,
method: "swapBorrowRateMode",
args: [USDC, 2]
}
];
const tx = await dsaWallet0.connect(wallet0).cast(...encodeSpells(spells), wallet0.address);
const receipt = await tx.wait();
});
it("Should check position of dsa", async () => {
expect(await aDai.connect(wallet0).balanceOf(dsaWallet0.address)).to.be.gte(
new BigNumber(10).multipliedBy(1e18).toString()
);
expect(await usdcToken.connect(wallet0).balanceOf(dsaWallet0.address)).to.be.gte(
new BigNumber(3).multipliedBy(1e6).toString()
);
expect(
(await aave.connect(wallet0).getUserReserveData(USDC, dsaWallet0.address)).currentVariableDebt
).to.be.equal(0);
expect((await aave.connect(wallet0).getUserReserveData(USDC, dsaWallet0.address)).currentStableDebt).to.be.gte(
new BigNumber(3).multipliedBy(1e6).toString()
);
console.log(
`\tstable borrow after: ${
(await aave.connect(wallet0).getUserReserveData(USDC, dsaWallet0.address)).currentStableDebt
}`
);
console.log(
`\tvariable borrow after: ${
(await aave.connect(wallet0).getUserReserveData(USDC, dsaWallet0.address)).currentVariableDebt
}`
);
});
});
});

View File

@ -0,0 +1,80 @@
import { SignerWithAddress } from "@nomiclabs/hardhat-ethers/signers";
import { ethers } from "hardhat";
import { ConnectV2ArbitrumAirdrop, ConnectV2ArbitrumAirdrop__factory } from "../../../typechain";
import hre from "hardhat";
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 { addresses } from "../../../scripts/tests/arbitrum/addresses";
import { abis } from "../../../scripts/constant/abis";
describe("Arbitrum Airdrop Claim Test", () => {
let signer: SignerWithAddress;
let signer_user: any;
const user = "0x30c3D961a21c2352A6FfAfFd4e8cB8730Bf82757";
const connectorName = "arbitrum-airdrop";
let dsaWallet0: any;
before(async () => {
[signer] = await ethers.getSigners();
});
describe("Arbitrum Airdrop Functions", () => {
let contract: ConnectV2ArbitrumAirdrop;
before(async () => {
await hre.network.provider.request({
method: "hardhat_reset",
params: [
{
forking: {
//@ts-ignore
jsonRpcUrl: hre.config.networks.hardhat.forking.url,
blockNumber: 70606643,
},
},
],
});
const deployer = new ConnectV2ArbitrumAirdrop__factory(signer);
contract = await deployer.deploy();
await contract.deployed();
console.log("Contract deployed at: ", contract.address);
await deployAndEnableConnector({
connectorName,
contractArtifact: ConnectV2ArbitrumAirdrop__factory,
signer: signer,
connectors: await ethers.getContractAt(abis.core.connectorsV2, addresses.core.connectorsV2),
});
await hre.network.provider.request({
method: 'hardhat_impersonateAccount',
params: [user],
});
signer_user = await ethers.getSigner(user);
dsaWallet0 = await buildDSAv2(user);
});
it("Claims Arbitrum Airdrop and checks claimable tokens", async () => {
const claimableBefore = await contract.claimableArbTokens(user);
console.log("Claimable tokens before: ", claimableBefore.toString());
const spells = [
{
connector: connectorName,
method: "claimAirdrop",
args: ["0"],
},
];
const tx = await dsaWallet0.connect(signer_user).cast(...encodeSpells(spells), user);
await tx.wait();
const claimableAfter = await contract.claimableArbTokens(user);
console.log("Claimable tokens after: ", claimableAfter.toString());
});
});
});

View File

@ -0,0 +1,444 @@
import { expect } from "chai";
import hre from "hardhat";
const { waffle, ethers } = hre;
const { provider, deployContract } = waffle;
import { Signer, Contract } from "ethers";
import { BigNumber } from "bignumber.js";
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 { addresses } from "../../../scripts/tests/arbitrum/addresses";
import { tokens, tokenMapping } from "../../../scripts/tests/arbitrum/tokens";
import { abis } from "../../../scripts/constant/abis";
import { ConnectV2CompoundV3ArbitrumRewards__factory, ConnectV2CompoundV3Arbitrum__factory } from "../../../typechain";
describe("Compound III Arbitrum Rewards", function () {
let connectorName = "COMPOUND-V3-REWARDS-TEST-A";
const market = "0xA5EDBDD9646f8dFF606d7448e414884C7d905dCA";
const rewards = "0x88730d254A2f7e6AC8388c3198aFd694bA9f7fae";
const base = "0xFF970A61A04b1cA14834A43f5dE4533eBDDB5CC8";
const account = "0x62383739d68dd0f844103db8dfb05a7eded5bbe6";
const wethWhale = "0xe50fA9b3c56FfB159cB0FCA61F5c9D750e8128c8";
const baseWhale = "0x62383739d68dd0f844103db8dfb05a7eded5bbe6";
const ABI = [
"function balanceOf(address account) public view returns (uint256)",
"function approve(address spender, uint256 amount) external returns(bool)",
"function transfer(address recipient, uint256 amount) external returns (bool)"
];
const wethContract = new ethers.Contract(tokens.weth.address, ABI);
const baseContract = new ethers.Contract(base, ABI);
const cometABI = [
{
inputs: [
{ internalType: "address", name: "comet", type: "address" },
{ internalType: "address", name: "src", type: "address" },
{ internalType: "bool", name: "shouldAccrue", type: "bool" }
],
name: "claim",
outputs: [],
stateMutability: "nonpayable",
type: "function"
},
{
inputs: [
{ internalType: "address", name: "comet", type: "address" },
{ internalType: "address", name: "src", type: "address" },
{ internalType: "address", name: "to", type: "address" },
{ internalType: "bool", name: "shouldAccrue", type: "bool" }
],
name: "claimTo",
outputs: [],
stateMutability: "nonpayable",
type: "function"
},
{
inputs: [
{ internalType: "address", name: "comet", type: "address" },
{ internalType: "address", name: "account", type: "address" }
],
name: "getRewardOwed",
outputs: [
{
components: [
{ internalType: "address", name: "token", type: "address" },
{ internalType: "uint256", name: "owed", type: "uint256" }
],
internalType: "struct CometRewards.RewardOwed",
name: "",
type: "tuple"
}
],
stateMutability: "nonpayable",
type: "function"
},
{
inputs: [{ internalType: "address", name: "", type: "address" }],
name: "rewardConfig",
outputs: [
{ internalType: "address", name: "token", type: "address" },
{ internalType: "uint64", name: "rescaleFactor", type: "uint64" },
{ internalType: "bool", name: "shouldUpscale", type: "bool" }
],
stateMutability: "view",
type: "function"
},
{
inputs: [
{ internalType: "address", name: "", type: "address" },
{ internalType: "address", name: "", type: "address" }
],
name: "rewardsClaimed",
outputs: [{ internalType: "uint256", name: "", type: "uint256" }],
stateMutability: "view",
type: "function"
}
];
const marketABI = [
{
inputs: [{ internalType: "address", name: "account", type: "address" }],
name: "balanceOf",
outputs: [{ internalType: "uint256", name: "", type: "uint256" }],
stateMutability: "view",
type: "function"
},
{
inputs: [{ internalType: "address", name: "account", type: "address" }],
name: "borrowBalanceOf",
outputs: [{ internalType: "uint256", name: "", type: "uint256" }],
stateMutability: "view",
type: "function"
},
{
inputs: [],
name: "baseBorrowMin",
outputs: [{ internalType: "uint256", name: "", type: "uint256" }],
stateMutability: "view",
type: "function"
},
{
inputs: [],
name: "baseMinForRewards",
outputs: [{ internalType: "uint256", name: "", type: "uint256" }],
stateMutability: "view",
type: "function"
},
{
inputs: [],
name: "baseToken",
outputs: [{ internalType: "address", name: "", type: "address" }],
stateMutability: "view",
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: [
{ internalType: "address", name: "owner", type: "address" },
{ internalType: "address", name: "manager", type: "address" }
],
name: "hasPermission",
outputs: [{ internalType: "bool", name: "", type: "bool" }],
stateMutability: "view",
type: "function"
},
{
inputs: [],
name: "numAssets",
outputs: [{ internalType: "uint8", name: "", type: "uint8" }],
stateMutability: "view",
type: "function"
},
{
inputs: [
{ internalType: "address", name: "asset", type: "address" },
{ internalType: "uint256", name: "baseAmount", type: "uint256" }
],
name: "quoteCollateral",
outputs: [{ internalType: "uint256", name: "", type: "uint256" }],
stateMutability: "view",
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: [
{ internalType: "address", name: "", type: "address" },
{ internalType: "address", name: "", type: "address" }
],
name: "userCollateral",
outputs: [
{ internalType: "uint128", name: "balance", type: "uint128" },
{ internalType: "uint128", name: "_reserved", type: "uint128" }
],
stateMutability: "view",
type: "function"
}
];
let dsaWallet0: any;
let dsaWallet1: any;
let wallet: any;
let dsa0Signer: any;
let masterSigner: Signer;
let instaConnectorsV2: Contract;
let connector: any;
let connectorMain: any;
let signer: any;
let wethSigner: any;
let usdcSigner: any;
const cometReward = new ethers.Contract(rewards, cometABI);
const comet = new ethers.Contract(market, marketABI);
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: 15444500
}
}
]
});
masterSigner = await getMasterSigner();
instaConnectorsV2 = await ethers.getContractAt(abis.core.connectorsV2, addresses.core.connectorsV2);
connector = await deployAndEnableConnector({
connectorName,
contractArtifact: ConnectV2CompoundV3ArbitrumRewards__factory,
signer: masterSigner,
connectors: instaConnectorsV2
});
console.log("Connector address", connector.address);
await hre.network.provider.send("hardhat_setBalance", [account, ethers.utils.parseEther("10").toHexString()]);
await hre.network.provider.request({
method: "hardhat_impersonateAccount",
params: [account]
});
signer = await ethers.getSigner(account);
await hre.network.provider.request({
method: "hardhat_impersonateAccount",
params: [wethWhale]
});
wethSigner = await ethers.getSigner(wethWhale);
await hre.network.provider.request({
method: "hardhat_impersonateAccount",
params: [baseWhale]
});
usdcSigner = await ethers.getSigner(baseWhale);
await hre.network.provider.send("hardhat_setBalance", [
usdcSigner.address,
ethers.utils.parseEther("10").toHexString()
]);
});
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;
dsaWallet1 = await buildDSAv2(wallet0.address);
expect(!!dsaWallet1.address).to.be.true;
wallet = await ethers.getSigner(dsaWallet0.address);
expect(!!dsaWallet1.address).to.be.true;
});
it("Deposit ETH into DSA wallet", async function () {
await hre.network.provider.request({
method: "hardhat_impersonateAccount",
params: [wallet.address]
});
dsa0Signer = await ethers.getSigner(wallet.address);
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 wallet0.sendTransaction({
to: dsaWallet1.address,
value: ethers.utils.parseEther("10")
});
expect(await ethers.provider.getBalance(dsaWallet1.address)).to.be.gte(ethers.utils.parseEther("10"));
});
it("should deposit USDC in dsa wallet", async function () {
await baseContract.connect(usdcSigner).transfer(dsaWallet0.address, ethers.utils.parseUnits("500", 6));
expect(await baseContract.connect(usdcSigner).balanceOf(dsaWallet0.address)).to.be.gte(
ethers.utils.parseUnits("500", 6)
);
});
});
describe("Main", function () {
//deposit asset
it("Should supply USDC in Compound V3", async function () {
connectorName = "COMPOUND-V3-TEST-A";
connectorMain = await deployAndEnableConnector({
connectorName,
contractArtifact: ConnectV2CompoundV3Arbitrum__factory,
signer: masterSigner,
connectors: instaConnectorsV2
});
const amount = ethers.utils.parseUnits("400", 6);
const spells = [
{
connector: "COMPOUND-V3-TEST-A",
method: "deposit",
args: [market, base, amount, 0, 0]
}
];
const tx = await dsaWallet0.connect(wallet0).cast(...encodeSpells(spells), wallet1.address);
const receipt = await tx.wait();
expect(new BigNumber(await baseContract.connect(signer).balanceOf(dsaWallet0.address)).toFixed(0)).to.be.lte(
ethers.utils.parseUnits("100", 6)
);
expect(new BigNumber(await comet.connect(signer).balanceOf(dsaWallet0.address)).toFixed(0)).to.be.gte(
ethers.utils.parseUnits("399", 6)
);
});
let connector_ = "COMPOUND-V3-REWARDS-TEST-A";
it("Should claim rewards", async function () {
let reward = (await cometReward.connect(signer).rewardConfig(market)).token;
let rewardInterface = new ethers.Contract(reward, ABI);
let owed_ = await cometReward.connect(signer).callStatic.getRewardOwed(market, dsaWallet0.address);
let amt: number = owed_.owed;
console.log(new BigNumber(amt).toFixed(0));
const spells = [
{
connector: connector_,
method: "claimRewards",
args: [market, 0]
}
];
const tx = await dsaWallet0.connect(wallet0).cast(...encodeSpells(spells), wallet1.address);
const receipt = await tx.wait();
expect(new BigNumber(await rewardInterface.connect(signer).balanceOf(dsaWallet0.address)).toFixed(0)).to.be.gte(
amt
);
});
it("Should supply USDC in Compound V3 through dsaWallet0", async function () {
const amount = ethers.utils.parseUnits("100", 6); // 1 ETH
const spells = [
{
connector: "COMPOUND-V3-TEST-A",
method: "deposit",
args: [market, base, amount, 0, 0]
}
];
const tx = await dsaWallet0.connect(wallet0).cast(...encodeSpells(spells), wallet1.address);
const receipt = await tx.wait();
expect(new BigNumber(await baseContract.connect(signer).balanceOf(dsaWallet0.address)).toFixed(0)).to.be.lte(
ethers.utils.parseUnits("0", 6)
);
expect(new BigNumber(await comet.connect(signer).balanceOf(dsaWallet0.address)).toFixed(0)).to.be.gte(
ethers.utils.parseUnits("499", 6)
);
});
it("Should claim rewards to dsa1", async function () {
let reward = (await cometReward.connect(signer).rewardConfig(market)).token;
let rewardInterface = new ethers.Contract(reward, ABI);
let owed_ = await cometReward.connect(signer).callStatic.getRewardOwed(market, dsaWallet0.address);
let amt: number = owed_.owed;
const spells = [
{
connector: connector_,
method: "claimRewardsOnBehalfOf",
args: [market, dsaWallet0.address, dsaWallet1.address, 0]
}
];
const tx = await dsaWallet0.connect(wallet0).cast(...encodeSpells(spells), wallet1.address);
const receipt = await tx.wait();
expect(new BigNumber(await rewardInterface.connect(signer).balanceOf(dsaWallet1.address)).toFixed(0)).to.be.gte(
amt
);
});
it("should allow manager for dsaWallet0's collateral and base", async function () {
const spells = [
{
connector: connectorName,
method: "toggleAccountManager",
args: [market, dsaWallet1.address, true]
}
];
const tx = await dsaWallet0.connect(wallet0).cast(...encodeSpells(spells), wallet1.address);
const receipt = await tx.wait();
});
it("Should claim rewards to dsa1 using manager", async function () {
let reward = (await cometReward.connect(signer).rewardConfig(market)).token;
let rewardInterface = new ethers.Contract(reward, ABI);
let owed_ = await cometReward.connect(signer).callStatic.getRewardOwed(market, dsaWallet0.address);
let amt: number = owed_.owed;
const spells = [
{
connector: connector_,
method: "claimRewardsOnBehalfOf",
args: [market, dsaWallet0.address, dsaWallet1.address, 0]
}
];
const tx = await dsaWallet1.connect(wallet0).cast(...encodeSpells(spells), wallet1.address);
const receipt = await tx.wait();
expect(new BigNumber(await rewardInterface.connect(signer).balanceOf(dsaWallet1.address)).toFixed(0)).to.be.gte(
amt
);
});
});
});

View File

@ -0,0 +1,651 @@
import { expect } from "chai";
import hre from "hardhat";
const { waffle, ethers } = hre;
const { provider, deployContract } = waffle;
import { Signer, Contract } from "ethers";
import { BigNumber } from "bignumber.js";
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 { addresses } from "../../../scripts/tests/arbitrum/addresses";
import { tokens, tokenMapping } from "../../../scripts/tests/arbitrum/tokens";
import { abis } from "../../../scripts/constant/abis";
import { ConnectV2CompoundV3Arbitrum__factory } from "../../../typechain";
describe("Compound III Arbitrum", function () {
const connectorName = "COMPOUND-V3-TEST-A";
const market = "0xA5EDBDD9646f8dFF606d7448e414884C7d905dCA";
const base = "0xFF970A61A04b1cA14834A43f5dE4533eBDDB5CC8";
const account = "0x62383739d68dd0f844103db8dfb05a7eded5bbe6";
const wethWhale = "0xe50fA9b3c56FfB159cB0FCA61F5c9D750e8128c8";
const ABI = [
"function balanceOf(address account) public view returns (uint256)",
"function approve(address spender, uint256 amount) external returns(bool)",
"function transfer(address recipient, uint256 amount) external returns (bool)"
];
const wethContract = new ethers.Contract(tokens.weth.address, ABI);
const baseContract = new ethers.Contract(base, ABI);
const cometABI = [
{
inputs: [{ internalType: "address", name: "account", type: "address" }],
name: "balanceOf",
outputs: [{ internalType: "uint256", name: "", type: "uint256" }],
stateMutability: "view",
type: "function"
},
{
inputs: [{ internalType: "address", name: "account", type: "address" }],
name: "borrowBalanceOf",
outputs: [{ internalType: "uint256", name: "", type: "uint256" }],
stateMutability: "view",
type: "function"
},
{
inputs: [],
name: "baseBorrowMin",
outputs: [{ internalType: "uint256", name: "", type: "uint256" }],
stateMutability: "view",
type: "function"
},
{
inputs: [],
name: "baseMinForRewards",
outputs: [{ internalType: "uint256", name: "", type: "uint256" }],
stateMutability: "view",
type: "function"
},
{
inputs: [],
name: "baseToken",
outputs: [{ internalType: "address", name: "", type: "address" }],
stateMutability: "view",
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: [
{ internalType: "address", name: "owner", type: "address" },
{ internalType: "address", name: "manager", type: "address" }
],
name: "hasPermission",
outputs: [{ internalType: "bool", name: "", type: "bool" }],
stateMutability: "view",
type: "function"
},
{
inputs: [],
name: "numAssets",
outputs: [{ internalType: "uint8", name: "", type: "uint8" }],
stateMutability: "view",
type: "function"
},
{
inputs: [
{ internalType: "address", name: "asset", type: "address" },
{ internalType: "uint256", name: "baseAmount", type: "uint256" }
],
name: "quoteCollateral",
outputs: [{ internalType: "uint256", name: "", type: "uint256" }],
stateMutability: "view",
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: [
{ internalType: "address", name: "", type: "address" },
{ internalType: "address", name: "", type: "address" }
],
name: "userCollateral",
outputs: [
{ internalType: "uint128", name: "balance", type: "uint128" },
{ internalType: "uint128", name: "_reserved", type: "uint128" }
],
stateMutability: "view",
type: "function"
}
];
let dsaWallet0: any;
let dsaWallet1: any;
let dsaWallet2: any;
let dsaWallet3: any;
let wallet: any;
let dsa0Signer: any;
let masterSigner: Signer;
let instaConnectorsV2: Contract;
let connector: any;
let signer: any;
let wethSigner: any;
const comet = new ethers.Contract(market, cometABI);
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,
ignoreUnknownTxType: true,
// blockNumber: 15444500
}
}
]
});
masterSigner = await getMasterSigner();
instaConnectorsV2 = await ethers.getContractAt(abis.core.connectorsV2, addresses.core.connectorsV2);
connector = await deployAndEnableConnector({
connectorName,
contractArtifact: ConnectV2CompoundV3Arbitrum__factory,
signer: masterSigner,
connectors: instaConnectorsV2
});
console.log("Connector address", connector.address);
await hre.network.provider.send("hardhat_setBalance", [account, '0x56bc75e2d63100000']); // set balance as 100 eth
await hre.network.provider.request({
method: "hardhat_impersonateAccount",
params: [account]
});
signer = await ethers.getSigner(account);
await hre.network.provider.send("hardhat_setBalance", [wethWhale, '0x56bc75e2d63100000']); // set balance as 100 eth
await hre.network.provider.request({
method: "hardhat_impersonateAccount",
params: [wethWhale]
});
wethSigner = await ethers.getSigner(wethWhale);
});
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;
dsaWallet1 = await buildDSAv2(wallet0.address);
expect(!!dsaWallet1.address).to.be.true;
dsaWallet2 = await buildDSAv2(wallet0.address);
expect(!!dsaWallet2.address).to.be.true;
dsaWallet3 = await buildDSAv2(wallet0.address);
expect(!!dsaWallet3.address).to.be.true;
wallet = await ethers.getSigner(dsaWallet0.address);
expect(!!dsaWallet1.address).to.be.true;
});
it("Deposit ETH into DSA wallet", async function () {
await hre.network.provider.request({
method: "hardhat_impersonateAccount",
params: [wallet.address]
});
dsa0Signer = await ethers.getSigner(wallet.address);
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 wallet0.sendTransaction({
to: dsaWallet1.address,
value: ethers.utils.parseEther("10")
});
expect(await ethers.provider.getBalance(dsaWallet0.address)).to.be.gte(ethers.utils.parseEther("10"));
await wallet0.sendTransaction({
to: dsaWallet3.address,
value: ethers.utils.parseEther("10")
});
expect(await ethers.provider.getBalance(dsaWallet0.address)).to.be.gte(ethers.utils.parseEther("10"));
});
});
describe("Main", function () {
//deposit asset
it("Should supply ETH collateral in Compound V3", async function () {
const amount = ethers.utils.parseEther("5"); // 1 ETH
const spells = [
{
connector: connectorName,
method: "deposit",
args: [market, tokens.eth.address, amount, 0, 0]
}
];
const tx = await dsaWallet0.connect(wallet0).cast(...encodeSpells(spells), wallet1.address);
const receipt = await tx.wait();
expect(await ethers.provider.getBalance(dsaWallet0.address)).to.be.lte(ethers.utils.parseEther("5"));
expect((await comet.connect(signer).userCollateral(dsaWallet0.address, tokens.weth.address)).balance).to.be.gte(
ethers.utils.parseEther("5")
);
});
//deposit asset on behalf of
it("Should supply ETH collateral on behalf of dsaWallet0 in Compound V3", async function () {
const amount = ethers.utils.parseEther("1"); // 1 ETH
const spells = [
{
connector: connectorName,
method: "depositOnBehalf",
args: [market, tokens.eth.address, dsaWallet0.address, amount, 0, 0]
}
];
const tx = await dsaWallet1.connect(wallet0).cast(...encodeSpells(spells), wallet1.address);
const receipt = await tx.wait();
expect(await ethers.provider.getBalance(dsaWallet1.address)).to.be.lte(ethers.utils.parseEther("9"));
expect((await comet.connect(wallet0).userCollateral(dsaWallet0.address, tokens.weth.address)).balance).to.be.gte(
ethers.utils.parseEther("6")
);
});
it("Should borrow and payback base token from Compound", async function () {
const amount = ethers.utils.parseUnits("150", 6);
const spells = [
{
connector: connectorName,
method: "borrow",
args: [market, base, amount, 0, 0]
},
{
connector: connectorName,
method: "payback",
args: [market, base, ethers.utils.parseUnits("50", 6), 0, 0]
}
];
const tx = await dsaWallet0.connect(wallet0).cast(...encodeSpells(spells), wallet1.address);
const receipt = await tx.wait();
expect(await comet.connect(wallet0).borrowBalanceOf(dsaWallet0.address)).to.be.equal(
ethers.utils.parseUnits("100", 6)
);
expect(await baseContract.connect(wallet0).balanceOf(dsaWallet0.address)).to.be.equal(
ethers.utils.parseUnits("100", 6)
);
});
it("should allow manager for dsaWallet0's collateral and base", async function () {
const spells = [
{
connector: connectorName,
method: "toggleAccountManager",
args: [market, dsaWallet2.address, true]
}
];
const tx = await dsaWallet0.connect(wallet0).cast(...encodeSpells(spells), wallet1.address);
const receipt = await tx.wait();
});
it("should payback base token on Compound using manager", async function () {
await baseContract.connect(signer).transfer(dsaWallet0.address, ethers.utils.parseUnits("5", 6));
const amount = ethers.utils.parseUnits("102", 6);
await baseContract.connect(dsa0Signer).approve(market, amount);
const spells = [
{
connector: connectorName,
method: "paybackFromUsingManager",
args: [market, base, dsaWallet0.address, dsaWallet0.address, ethers.constants.MaxUint256, 0, 0]
}
];
const tx = await dsaWallet2.connect(wallet0).cast(...encodeSpells(spells), wallet1.address);
const receipt = await tx.wait();
expect(await comet.connect(signer).borrowBalanceOf(dsaWallet0.address)).to.be.equal(
ethers.utils.parseUnits("0", 6)
);
});
it("Should borrow to another dsa from Compound", async function () {
const amount = ethers.utils.parseUnits("100", 6);
const spells = [
{
connector: connectorName,
method: "borrowTo",
args: [market, base, dsaWallet1.address, amount, 0, 0]
}
];
const tx = await dsaWallet0.connect(wallet0).cast(...encodeSpells(spells), wallet1.address);
const receipt = await tx.wait();
expect(new BigNumber(await comet.connect(signer).borrowBalanceOf(dsaWallet0.address)).toFixed()).to.be.equal(
ethers.utils.parseUnits("100", 6)
);
});
it("Should payback on behalf of from Compound", async function () {
const spells = [
{
connector: connectorName,
method: "paybackOnBehalf",
args: [market, base, dsaWallet0.address, ethers.constants.MaxUint256, 0, 0]
}
];
const tx = await dsaWallet1.connect(wallet0).cast(...encodeSpells(spells), wallet1.address);
const receipt = await tx.wait();
expect(await comet.connect(signer).borrowBalanceOf(dsaWallet0.address)).to.be.equal(
ethers.utils.parseUnits("0", 6)
);
});
it("should withdraw some ETH collateral", async function () {
let initialBal = await ethers.provider.getBalance(dsaWallet0.address);
const amount_ = ethers.utils.parseEther("2");
const spells = [
{
connector: connectorName,
method: "withdraw",
args: [market, tokens.eth.address, amount_, 0, 0]
}
];
const tx = await dsaWallet0.connect(wallet0).cast(...encodeSpells(spells), wallet1.address);
const receipt = await tx.wait();
expect((await comet.connect(signer).userCollateral(dsaWallet0.address, tokens.weth.address)).balance).to.be.gte(
ethers.utils.parseEther("4")
);
expect(await ethers.provider.getBalance(dsaWallet0.address)).to.be.gte(initialBal.add(amount_).toString());
});
it("manager should be able to withdraw collateral from the position and transfer", async function () {
await wallet1.sendTransaction({
to: tokens.weth.address,
value: ethers.utils.parseEther("10")
});
const amount = ethers.constants.MaxUint256;
const spells = [
{
connector: connectorName,
method: "withdrawOnBehalfAndTransfer",
args: [market, tokens.eth.address, dsaWallet0.address, dsaWallet1.address, amount, 0, 0]
}
];
const tx = await dsaWallet2.connect(wallet0).cast(...encodeSpells(spells), wallet1.address);
const receipt = await tx.wait();
expect((await comet.connect(signer).userCollateral(dsaWallet0.address, tokens.weth.address)).balance).to.be.gte(
ethers.utils.parseEther("0")
);
expect(await wethContract.connect(wallet0).balanceOf(dsaWallet1.address)).to.be.gte(ethers.utils.parseEther("4"));
});
it("Should withdraw collateral to another DSA", async function () {
const spells1 = [
{
connector: connectorName,
method: "deposit",
args: [market, tokens.eth.address, ethers.utils.parseEther("5"), 0, 0]
}
];
const tx1 = await dsaWallet1.connect(wallet0).cast(...encodeSpells(spells1), wallet1.address);
let initialBal = await ethers.provider.getBalance(dsaWallet0.address);
const amount = ethers.utils.parseEther("2");
const spells = [
{
connector: connectorName,
method: "withdrawTo",
args: [market, tokens.eth.address, dsaWallet0.address, amount, 0, 0]
}
];
const tx = await dsaWallet1.connect(wallet0).cast(...encodeSpells(spells), wallet1.address);
const receipt = await tx.wait();
expect(await wethContract.connect(wallet0).balanceOf(dsaWallet0.address)).to.be.gte(amount);
expect((await comet.connect(signer).userCollateral(dsaWallet1.address, tokens.weth.address)).balance).to.be.gte(
ethers.utils.parseEther("3")
);
});
it("Should withdraw collateral to another DSA", async function () {
const spells1 = [
{
connector: connectorName,
method: "deposit",
args: [market, tokens.eth.address, ethers.utils.parseEther("3"), 0, 0]
}
];
const tx1 = await dsaWallet0.connect(wallet0).cast(...encodeSpells(spells1), wallet1.address);
let initialBal = await ethers.provider.getBalance(dsaWallet0.address);
const amount = ethers.utils.parseEther("2");
const spells = [
{
connector: connectorName,
method: "withdrawTo",
args: [market, tokens.eth.address, dsaWallet0.address, amount, 0, 0]
}
];
const tx = await dsaWallet0.connect(wallet0).cast(...encodeSpells(spells), wallet1.address);
const receipt = await tx.wait();
expect(await ethers.provider.getBalance(dsaWallet0.address)).to.be.gte(initialBal.add(amount));
expect((await comet.connect(signer).userCollateral(dsaWallet1.address, tokens.weth.address)).balance).to.be.gte(
ethers.utils.parseEther("1")
);
});
it("should transfer eth from dsaWallet1 to dsaWallet0 position", async function () {
const spells = [
{
connector: connectorName,
method: "transferAsset",
args: [market, tokens.eth.address, dsaWallet0.address, ethers.utils.parseEther("3"), 0, 0]
}
];
const tx = await dsaWallet1.connect(wallet0).cast(...encodeSpells(spells), wallet1.address);
const receipt = await tx.wait();
expect((await comet.connect(signer).userCollateral(dsaWallet1.address, tokens.weth.address)).balance).to.be.gte(
ethers.utils.parseEther("0")
);
expect((await comet.connect(signer).userCollateral(dsaWallet0.address, tokens.weth.address)).balance).to.be.gte(
ethers.utils.parseEther("3")
);
});
it("should transfer base token from dsaWallet1 to dsaWallet0 position", async function () {
await baseContract.connect(signer).transfer(dsaWallet1.address, ethers.utils.parseUnits("10", 6));
const spells = [
{
connector: connectorName,
method: "deposit",
args: [market, base, ethers.constants.MaxUint256, 0, 0]
}
];
const tx = await dsaWallet1.connect(wallet0).cast(...encodeSpells(spells), wallet1.address);
const receipt = await tx.wait();
let initialBal = await baseContract.connect(signer).balanceOf(dsaWallet1.address);
let spells1 = [
{
connector: connectorName,
method: "transferAsset",
args: [market, base, dsaWallet0.address, ethers.constants.MaxUint256, 0, 0]
}
];
const tx1 = await dsaWallet1.connect(wallet0).cast(...encodeSpells(spells1), wallet1.address);
const receipt1 = await tx.wait();
expect(await comet.connect(signer).balanceOf(dsaWallet1.address)).to.be.lte(ethers.utils.parseUnits("0", 6));
expect(await comet.connect(signer).balanceOf(dsaWallet0.address)).to.be.gte(initialBal);
});
it("should transfer base token using manager from dsaWallet0 to dsaWallet1 position", async function () {
const spells = [
{
connector: connectorName,
method: "transferAssetOnBehalf",
args: [market, base, dsaWallet0.address, dsaWallet1.address, ethers.constants.MaxUint256, 0, 0]
}
];
let initialBal = await baseContract.connect(signer).balanceOf(dsaWallet0.address);
const tx = await dsaWallet2.connect(wallet0).cast(...encodeSpells(spells), wallet1.address);
const receipt = await tx.wait();
expect(await comet.connect(signer).balanceOf(dsaWallet0.address)).to.be.lte(ethers.utils.parseUnits("0", 6));
expect(await comet.connect(signer).balanceOf(dsaWallet1.address)).to.be.gte(initialBal);
});
it("should deposit weth using manager", async function () {
await wethContract.connect(wethSigner).transfer(dsaWallet0.address, ethers.utils.parseEther("10"));
let initialBal = await wethContract.connect(wallet0).balanceOf(dsaWallet0.address);
const amount = ethers.utils.parseEther("1");
await wethContract.connect(dsa0Signer).approve(market, amount);
const spells = [
{
connector: connectorName,
method: "depositFromUsingManager",
args: [market, tokens.eth.address, dsaWallet0.address, dsaWallet1.address, amount, 0, 0]
}
];
const tx = await dsaWallet2.connect(wallet0).cast(...encodeSpells(spells), wallet1.address);
const receipt = await tx.wait();
expect((await comet.connect(signer).userCollateral(dsaWallet1.address, tokens.weth.address)).balance).to.be.gte(
ethers.utils.parseEther("1")
);
expect(await wethContract.connect(wallet0).balanceOf(dsaWallet0.address)).to.be.lte(initialBal.sub(amount));
});
it("should allow manager for dsaWallet0's collateral", async function () {
const spells = [
{
connector: connectorName,
method: "toggleAccountManager",
args: [market, dsaWallet2.address, true]
}
];
const tx = await dsaWallet3.connect(wallet0).cast(...encodeSpells(spells), wallet1.address);
const receipt = await tx.wait();
});
it("should borrow on behalf using manager", async function () {
let initialBal = await baseContract.connect(wallet0).balanceOf(dsaWallet0.address);
await wallet0.sendTransaction({
to: dsaWallet3.address,
value: ethers.utils.parseEther("15")
});
const spells1 = [
{
connector: connectorName,
method: "deposit",
args: [market, tokens.eth.address, ethers.utils.parseEther("15"), 0, 0]
}
];
const tx1 = await dsaWallet3.connect(wallet0).cast(...encodeSpells(spells1), wallet1.address);
const amount = ethers.utils.parseUnits("500", 6);
const spells = [
{
connector: connectorName,
method: "borrowOnBehalfAndTransfer",
args: [market, base, dsaWallet3.address, dsaWallet0.address, amount, 0, 0]
}
];
const tx = await dsaWallet2.connect(wallet0).cast(...encodeSpells(spells), wallet1.address);
const receipt = await tx.wait();
expect(new BigNumber(await comet.connect(signer).borrowBalanceOf(dsaWallet3.address)).toFixed()).to.be.equal(
ethers.utils.parseUnits("500", 6)
);
expect(await baseContract.connect(wallet0).balanceOf(dsaWallet0.address)).to.be.equal(initialBal.add(amount));
});
it("should transferAsset collateral using manager", async function () {
let bal1 = (await comet.connect(signer).userCollateral(dsaWallet1.address, tokens.weth.address)).balance;
let bal0 = (await comet.connect(signer).userCollateral(dsaWallet0.address, tokens.weth.address)).balance;
const spells = [
{
connector: connectorName,
method: "transferAssetOnBehalf",
args: [market, tokens.eth.address, dsaWallet0.address, dsaWallet1.address, ethers.utils.parseEther("1"), 0, 0]
}
];
const tx = await dsaWallet2.connect(wallet0).cast(...encodeSpells(spells), wallet1.address);
const receipt = await tx.wait();
expect((await comet.connect(signer).userCollateral(dsaWallet1.address, tokens.weth.address)).balance).to.be.gte(
bal1.add(ethers.utils.parseEther("1")).toString()
);
expect((await comet.connect(signer).userCollateral(dsaWallet0.address, tokens.weth.address)).balance).to.be.gte(
bal0.sub(ethers.utils.parseEther("1")).toString()
);
});
//can buy only when target reserves not reached.
// it("should buy collateral", async function () {
// //deposit 10 usdc(base token) to dsa
// await baseContract.connect(signer).transfer(dsaWallet0.address, ethers.utils.parseUnits("10", 6));
// console.log(await baseContract.connect(signer).balanceOf(dsaWallet0.address));
// //dsawallet0 --> collateral 0eth, balance 9eth 10usdc
// //dsaWallet1 --> balance 2eth coll: 3eth
// const amount = ethers.utils.parseUnits("1",6);
// const bal = await baseContract.connect(signer).balanceOf(dsaWallet0.address);
// const spells = [
// {
// connector: connectorName,
// method: "buyCollateral",
// args: [market, tokens.link.address, dsaWallet0.address, amount, bal, 0, 0]
// }
// ];
// const tx = await dsaWallet0.connect(wallet0).cast(...encodeSpells(spells), wallet1.address);
// const receipt = await tx.wait();
// expect(new BigNumber(await linkContract.connect(signer).balanceOf(dsaWallet0.address)).toFixed()).to.be.gte(
// ethers.utils.parseEther("1")
// );
// //dsawallet0 --> collateral 0eth, balance 9eth >1link
// //dsaWallet1 --> balance 2eth coll: 3eth
// });
});
});

View File

@ -0,0 +1,154 @@
import { expect } from "chai";
import hre from "hardhat";
const { ethers, waffle } = 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 { addresses } from "../../../scripts/tests/arbitrum/addresses";
import { abis } from "../../../scripts/constant/abis";
import { ConnectV2ConnextArbitrum__factory } from "../../../typechain";
import { Signer, Contract } from "ethers";
describe("Connext Connector [Arbitrum]", () => {
const connectorName = "CONNEXT-TEST-A";
let dsaWallet0: Contract;
let masterSigner: Signer;
let instaConnectorsV2: Contract;
let connector: Contract;
let usdcContract: Contract;
let signer: any;
const usdcAddr = "0xFF970A61A04b1cA14834A43f5dE4533eBDDB5CC8";
const ethAddr = "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE";
const account = "0x62383739d68dd0f844103db8dfb05a7eded5bbe6";
const wallets = provider.getWallets();
const [wallet0, wallet1] = wallets;
before(async () => {
await hre.network.provider.request({
method: "hardhat_reset",
params: [
{
forking: {
// @ts-ignore
jsonRpcUrl: hre.config.networks.hardhat.forking.url,
blockNumber: 82686991
}
}
]
});
masterSigner = await getMasterSigner();
instaConnectorsV2 = await ethers.getContractAt(abis.core.connectorsV2, addresses.core.connectorsV2);
connector = await deployAndEnableConnector({
connectorName,
contractArtifact: ConnectV2ConnextArbitrum__factory,
signer: masterSigner,
connectors: instaConnectorsV2
});
usdcContract = await ethers.getContractAt(abis.basic.erc20, usdcAddr);
signer = await ethers.getSigner(account);
await hre.network.provider.send("hardhat_setBalance", [account, ethers.utils.parseEther("10").toHexString()]);
await hre.network.provider.request({
method: "hardhat_impersonateAccount",
params: [account]
});
await usdcContract.connect(signer).transfer(wallet0.address, ethers.utils.parseUnits("10000", 6));
console.log("deployed connector: ", connector.address);
});
it("Should have contracts deployed.", async () => {
expect(!!instaConnectorsV2.address).to.be.true;
expect(!!connector.address).to.be.true;
expect(!!(await masterSigner.getAddress())).to.be.true;
});
describe("DSA wallet setup", () => {
it("Should build DSA v2", async () => {
dsaWallet0 = await buildDSAv2(wallet0.getAddress());
expect(!!dsaWallet0.address).to.be.true;
});
it("Deposit ETH & USDC into DSA wallet", async () => {
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 usdcContract.connect(wallet0).transfer(dsaWallet0.address, ethers.utils.parseUnits("10", 6));
expect(await usdcContract.balanceOf(dsaWallet0.address)).to.be.gte(ethers.utils.parseUnits("10", 6));
});
});
describe("Main", () => {
it("should xcall with eth", async () => {
const amount = ethers.utils.parseEther("5");
const domainId = 6648936;
const slippage = 10000;
const relayerFee = ethers.utils.parseEther("1");
const callData = "0x";
const xcallParams: any = [
domainId,
wallet1.address,
ethAddr,
wallet1.address,
amount,
slippage,
relayerFee,
callData
];
const spells = [
{
connector: connectorName,
method: "xcall",
args: [xcallParams, 0, 0]
}
];
const tx = await dsaWallet0.connect(wallet0).cast(...encodeSpells(spells), wallet1.address);
const receipt = await tx.wait();
});
it("should xcall with usdc", async () => {
const amount = ethers.utils.parseUnits("5", 6);
const domainId = 6648936;
const slippage = 10000;
const relayerFee = ethers.utils.parseEther("1");
const callData = "0x";
const xcallParams: any = [
domainId,
wallet1.address,
usdcAddr,
wallet1.address,
amount,
slippage,
relayerFee,
callData
];
const spells = [
{
connector: connectorName,
method: "xcall",
args: [xcallParams, 0, 0]
}
];
const tx = await dsaWallet0.connect(wallet0).cast(...encodeSpells(spells), wallet1.address);
const receipt = await tx.wait();
});
});
});

View File

@ -0,0 +1,180 @@
import hre from "hardhat";
import axios from "axios";
import { expect } from "chai";
const { ethers } = hre; //check
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 { addresses } from "../../../scripts/tests/arbitrum/addresses";
import { abis } from "../../../scripts/constant/abis";
import { ConnectV2DSASpellArbitrum__factory } from "../../../typechain";
import { Signer, Contract } from "ethers";
import { BigNumber } from "bignumber.js";
describe("DSA Spell", function () {
const connectorName = "dsa-spell-test";
let dsaWallet0: any;
let dsaWallet1: any;
let dsaWallet2: any;
let walletB: any;
let wallet0: any;
let masterSigner: Signer;
let instaConnectorsV2: Contract;
let connector: any;
before(async () => {
await hre.network.provider.request({
method: "hardhat_reset",
params: [
{
forking: {
// @ts-ignore
jsonRpcUrl: hre.config.networks.hardhat.forking.url
}
}
]
});
[wallet0] = await ethers.getSigners();
masterSigner = await getMasterSigner();
instaConnectorsV2 = await ethers.getContractAt(abis.core.connectorsV2, addresses.core.connectorsV2);
connector = await deployAndEnableConnector({
connectorName,
contractArtifact: ConnectV2DSASpellArbitrum__factory,
signer: masterSigner,
connectors: instaConnectorsV2
});
console.log("\tConnector 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;
walletB = await ethers.getSigner(dsaWallet0.address);
dsaWallet1 = await buildDSAv2(dsaWallet0.address);
expect(!!dsaWallet1.address).to.be.true;
console.log(`\t${dsaWallet1.address}`);
});
it("Deposit eth into DSA wallet 0", 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 into DSA wallet 1", async function () {
await wallet0.sendTransaction({
to: dsaWallet1.address,
value: ethers.utils.parseEther("10")
});
expect(await ethers.provider.getBalance(dsaWallet1.address)).to.be.gte(ethers.utils.parseEther("10"));
});
});
describe("Main", function () {
let ETH = "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE";
let USDC = "0xFF970A61A04b1cA14834A43f5dE4533eBDDB5CC8";
let usdc = new ethers.Contract(USDC, abis.basic.erc20);
let aETH = "0xe50fA9b3c56FfB159cB0FCA61F5c9D750e8128c8";
let aEth = new ethers.Contract(aETH, abis.basic.aToken);
var abi = [
"function withdraw(address,uint256,address,uint256,uint256)",
"function deposit(address,uint256,uint256,uint256)",
"function borrow(address,uint256,uint256,uint256,uint256)"
];
function getCallData(spell: string, params: any) {
var iface = new ethers.utils.Interface(abi);
let data = iface.encodeFunctionData(spell, params);
return ethers.utils.hexlify(data);
}
it("should cast spells", async function () {
async function getArg(connectors: any, spells: any, params: any) {
let datas = [];
for (let i = 0; i < connectors.length; i++) {
datas.push(getCallData(spells[i], params[i]));
}
return [dsaWallet1.address, connectors, datas];
}
let connectors = ["BASIC-A", "AAVE-V3-A", "AAVE-V3-A"];
let methods = ["withdraw", "deposit", "borrow"];
let params = [
[ETH, ethers.utils.parseEther("2"), dsaWallet0.address, 0, 0],
[ETH, ethers.constants.MaxUint256, 0, 0],
[USDC, ethers.utils.parseUnits("1", 6), 2, 0, 0]
];
let arg = await getArg(connectors, methods, params);
const spells = [
{
connector: connectorName,
method: "castOnDSA",
args: arg
}
];
const tx = await dsaWallet0.connect(wallet0).cast(...encodeSpells(spells), await wallet0.getAddress());
const receipt = await tx.wait();
});
it("should check balances after cast on DSA", async function () {
expect(await ethers.provider.getBalance(dsaWallet1.address)).to.be.lte(0);
expect(await usdc.connect(wallet0).balanceOf(dsaWallet1.address)).to.be.gte(
new BigNumber(1).multipliedBy(1e6).toString()
);
expect(await ethers.provider.getBalance(dsaWallet0.address)).to.be.gte(
new BigNumber(12).multipliedBy(1e18).toString()
);
});
it("should cast spell on the first successful", async function () {
async function getArg(connectors: any, spells: any, params: any) {
let datas = [];
for (let i = 0; i < connectors.length; i++) {
datas.push(getCallData(spells[i], params[i]));
}
return [connectors, datas];
}
let connectors = ["AAVE-V3-A"];
let methods = ["deposit"];
let params = [
[ETH, ethers.utils.parseEther("10"), 0, 0]
];
let arg = await getArg(connectors, methods, params);
const spells = [
{
connector: connectorName,
method: "castAny",
args: arg
}
];
const tx = await dsaWallet0
.connect(wallet0)
.cast(...encodeSpells(spells), await wallet0.getAddress());
const receipt = await tx.wait();
});
it("should check balances after spells on DSA", async function () {
expect(await ethers.provider.getBalance(dsaWallet0.address)).to.be.lte(
new BigNumber(2).multipliedBy(1e18).toString()
);
expect(await aEth.connect(wallet0).balanceOf(dsaWallet0.address)).to.be.gte(
new BigNumber(10).multipliedBy(1e18).toString()
);
});
});
});

View File

@ -0,0 +1,142 @@
import { expect } from "chai";
import hre, { ethers } from "hardhat";
import type { Signer, Contract } from "ethers";
import { BigNumber } from "bignumber.js";
import { buildDSAv2 } from "../../../scripts/tests/buildDSAv2";
import { addresses } from "../../../scripts/tests/arbitrum/addresses";
import { deployAndEnableConnector } from "../../../scripts/tests/deployAndEnableConnector";
import { abis } from "../../../scripts/constant/abis";
import { getMasterSigner } from "../../../scripts/tests/getMasterSigner";
import { parseEther } from "ethers/lib/utils";
import { encodeSpells } from "../../../scripts/tests/encodeSpells";
import { ConnectV2HopArbitrum__factory, IERC20__factory } from "../../../typechain";
let account = "0xa067668661c84476afcdc6fa5d758c4c01c34352";
const mnemonic = "test test test test test test test test test test test junk";
const WETH = "0x82aF49447D8a07e3bd95BD0d56f35241523fBab1";
const connectorName = "HOP-X";
let signer: any, wallet0: any;
describe("Hop connector", function () {
let dsaWallet0: any;
let masterSigner: Signer;
let instaConnectorsV2: Contract;
let connector: any;
const wallet = ethers.Wallet.fromMnemonic(mnemonic);
const token = new ethers.Contract(WETH, IERC20__factory.abi);
before(async () => {
await hre.network.provider.request({
method: "hardhat_reset",
params: [
{
forking: {
//@ts-ignore
jsonRpcUrl: hre.config.networks.hardhat.forking.url
// blockNumber: 9333600
}
}
]
});
masterSigner = await getMasterSigner();
[wallet0] = await ethers.getSigners();
await hre.network.provider.send("hardhat_setBalance", [account, ethers.utils.parseEther("10").toHexString()]);
await hre.network.provider.request({
method: "hardhat_impersonateAccount",
params: [account]
});
signer = await ethers.getSigner(account);
instaConnectorsV2 = await ethers.getContractAt(abis.core.connectorsV2, addresses.core.connectorsV2);
connector = await deployAndEnableConnector({
connectorName,
contractArtifact: ConnectV2HopArbitrum__factory,
signer: masterSigner,
connectors: instaConnectorsV2
});
});
describe("Deployment", async () => {
it("Should set correct name", async () => {
expect(await connector.name()).to.eq("Hop-v1.0");
});
});
describe("DSA wallet setup", async () => {
it("Should build DSA v2", async () => {
dsaWallet0 = await buildDSAv2(wallet.address);
expect(!!dsaWallet0.address).to.be.true;
});
it("Deposit ETH into DSA wallet", async function () {
await wallet0.sendTransaction({
to: dsaWallet0.address,
value: ethers.utils.parseEther("5")
});
expect(await ethers.provider.getBalance(dsaWallet0.address)).to.be.gte(ethers.utils.parseEther("5"));
});
});
describe("Main", async () => {
it("should send ETH successfully", async () => {
const deadline = new BigNumber(Date.now()).dividedBy(1000).plus(604800).toFixed(0);
const bridgeParams = [
"0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE",
"0x33ceb27b39d2Bb7D2e61F7564d3Df29344020417",
dsaWallet0.address,
"137",
parseEther("1"),
parseEther("0.01"),
parseEther("0.8"),
deadline,
parseEther("0.8"),
deadline
];
const spells = [
{
connector: connectorName,
method: "bridge",
args: [bridgeParams, "0"]
}
];
const tx = await dsaWallet0.connect(wallet0).cast(...encodeSpells(spells), wallet.getAddress());
await tx.wait();
});
it("should send WETH successfully", async () => {
const deadline = new BigNumber(Date.now()).dividedBy(1000).plus(604800).toFixed(0);
await token.connect(signer).transfer(dsaWallet0.address, ethers.utils.parseEther("10"));
const bridgeParams = [
"0x82aF49447D8a07e3bd95BD0d56f35241523fBab1",
"0x33ceb27b39d2Bb7D2e61F7564d3Df29344020417",
dsaWallet0.address,
"137",
parseEther("1"),
parseEther("0.01"),
parseEther("0.8"),
deadline,
parseEther("0.8"),
deadline
];
const spells = [
{
connector: connectorName,
method: "bridge",
args: [bridgeParams, "0"]
}
];
const tx = await dsaWallet0.connect(wallet0).cast(...encodeSpells(spells), wallet.getAddress());
await tx.wait();
});
});
});

View File

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

View File

@ -0,0 +1,151 @@
import hre from "hardhat";
import axios from "axios";
import { expect } from "chai";
const { ethers } = hre; //check
import { BigNumber } from "bignumber.js";
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 { addresses } from "../../../scripts/tests/arbitrum/addresses";
import { abis } from "../../../scripts/constant/abis";
import { ConnectV2SwapAggregatorArbitrum__factory } from "../../../typechain";
import er20abi from "../../../scripts/constant/abi/basics/erc20.json";
import type { Signer, Contract } from "ethers";
describe("Swap | Arbitrum", function () {
const connectorName = "swap-test";
let dsaWallet0: Contract;
let wallet0: Signer, wallet1: Signer;
let masterSigner: Signer;
let instaConnectorsV2: Contract;
let connector: Contract;
before(async () => {
await hre.network.provider.request({
method: "hardhat_reset",
params: [
{
forking: {
// @ts-ignore
jsonRpcUrl: hre.config.networks.hardhat.forking.url
}
}
]
});
[wallet0, wallet1] = await ethers.getSigners();
masterSigner = await getMasterSigner();
instaConnectorsV2 = await ethers.getContractAt(abis.core.connectorsV2, addresses.core.connectorsV2);
connector = await deployAndEnableConnector({
connectorName,
contractArtifact: ConnectV2SwapAggregatorArbitrum__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(await wallet0.getAddress());
console.log(dsaWallet0.address);
expect(!!dsaWallet0.address).to.be.true;
});
it("Deposit matic 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"));
});
});
describe("Main", function () {
it("should swap the tokens", async function () {
let buyTokenAmount1Inch: any;
let buyTokenAmountParaswap: any;
async function getArg() {
const slippage = 0.5;
/* eth -> dai */
const sellTokenAddress = "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE"; // eth, decimals 18
const sellTokenDecimals = 18;
const buyTokenAddress = "0xDA10009cBd5D07dd0CeCc66161FC93D7c9000da1"; // DAI, decimals 18
const buyTokenDecimals = 18;
const amount = 1;
const srcAmount = new BigNumber(amount).times(new BigNumber(10).pow(sellTokenDecimals)).toFixed(0);
//1inch
const paramDaiUsdc = {
buyToken: buyTokenAddress,
sellToken: sellTokenAddress,
sellAmount: "1000000000000000000",
dsaAddress: dsaWallet0.address
};
const response1 = await axios.get("https://api.instadapp.io/defi/arbitrum/1inch/swap", {
params: paramDaiUsdc
});
const data1 = response1.data;
// console.log(data1);
let unitAmt1Inch = data1.unitAmt;
const calldata1Inch = data1.calldata;
buyTokenAmount1Inch = data1.buyTokenAmount;
console.log(buyTokenAmount1Inch);
function getCallData(connector: string, unitAmt: any, callData: any) {
var abi = [
"function swap(address,address,uint256,uint256,bytes,uint256)",
"function sell(address,address,uint256,uint256,bytes,uint256)"
];
var iface = new ethers.utils.Interface(abi);
const spell = connector === "1INCH-A" ? "sell" : "swap";
let data = iface.encodeFunctionData(spell, [
buyTokenAddress,
sellTokenAddress,
srcAmount,
unitAmt,
callData,
0
]);
return data;
}
let data1Inch = ethers.utils.hexlify(await getCallData("1INCH-A", unitAmt1Inch, calldata1Inch));
let datas = [data1Inch];
let connectors = ["1INCH-A"];
return [connectors, datas];
}
let arg = await getArg();
const spells = [
{
connector: connectorName,
method: "swap",
args: arg
}
];
const tx = await dsaWallet0.connect(wallet0).cast(...encodeSpells(spells), await wallet1.getAddress());
const receipt = await tx.wait();
const daiToken = await ethers.getContractAt(
er20abi,
"0xDA10009cBd5D07dd0CeCc66161FC93D7c9000da1" // dai address
);
expect(await daiToken.balanceOf(dsaWallet0.address)).to.be.gte(buyTokenAmount1Inch);
expect(await ethers.provider.getBalance(dsaWallet0.address)).to.be.lte(ethers.utils.parseEther("9"));
});
});
});

View File

@ -0,0 +1,129 @@
import { BigNumberish } from "@ethersproject/bignumber";
import { Contract } from "@ethersproject/contracts";
import { expect } from "chai";
import hre, { artifacts } from "hardhat";
const { ethers } = hre;
const USDC_ADDR = "0xff970a61a04b1ca14834a43f5de4533ebddb5cc8";
const WETH_ADDR = "0x82af49447d8a07e3bd95bd0d56f35241523fbab1";
describe("Uniswap-sell-beta", function () {
let UniswapSellBeta, uniswapSellBeta: Contract;
async function setBalance(address: string) {
await hre.network.provider.send("hardhat_setBalance", [
address,
ethers.utils.parseEther("10.0").toHexString(),
]);
}
async function impersonate(owner: string, account: any, token0: string, decimals: BigNumberish | undefined) {
const tokenArtifact = await artifacts.readArtifact(
"@openzeppelin/contracts/token/ERC20/IERC20.sol:IERC20"
);
setBalance(owner);
setBalance(account);
await hre.network.provider.request({
method: "hardhat_impersonateAccount",
params: [account],
});
const signer = await ethers.getSigner(account);
const token = new ethers.Contract(
token0,
tokenArtifact.abi,
ethers.provider
);
// console.log((await token.balanceOf(account)).toString());
await token
.connect(signer)
.transfer(owner, ethers.utils.parseUnits("10", decimals));
await hre.network.provider.request({
method: "hardhat_stopImpersonatingAccount",
params: [account],
});
}
beforeEach(async () => {
const account0 = "0xa067668661c84476afcdc6fa5d758c4c01c34352";
const account1 = "0x0db3fe3b770c95a0b99d1ed6f2627933466c0dd8";
const [owner, add1, add2] = await ethers.getSigners();
await impersonate(owner.address, account1, USDC_ADDR, 6);
await impersonate(owner.address, account0, WETH_ADDR, 18);
UniswapSellBeta = await ethers.getContractFactory(
"ConnectV2UniswapSellBeta"
);
uniswapSellBeta = await UniswapSellBeta.deploy();
await uniswapSellBeta.deployed();
});
it("Should have contracts deployed.", async function () {
expect(uniswapSellBeta.address).to.exist;
});
it("Should swap WETH with USDC", async () => {
const [owner, add1, add2] = await ethers.getSigners();
const tokenArtifact = await artifacts.readArtifact(
"@openzeppelin/contracts/token/ERC20/IERC20.sol:IERC20"
);
const token = new ethers.Contract(
WETH_ADDR,
tokenArtifact.abi,
ethers.provider
);
const signer = await ethers.getSigner(owner.address);
await token
.connect(signer)
.transfer(uniswapSellBeta.address, ethers.utils.parseUnits("10.0", 18));
const tx = await uniswapSellBeta.sell(
WETH_ADDR,
USDC_ADDR,
3000,
ethers.utils.parseUnits("10.0", 18),
0
);
// console.log(tx);
});
it("Should swap USDC with WETH", async () => {
const [owner, add1, add2] = await ethers.getSigners();
const tokenArtifact = await artifacts.readArtifact(
"@openzeppelin/contracts/token/ERC20/IERC20.sol:IERC20"
);
const token = new ethers.Contract(
USDC_ADDR,
tokenArtifact.abi,
ethers.provider
);
const signer = await ethers.getSigner(owner.address);
await token
.connect(signer)
.transfer(uniswapSellBeta.address, ethers.utils.parseUnits("10.0", 6));
const tx = await uniswapSellBeta.sell(
USDC_ADDR,
WETH_ADDR,
3000,
ethers.utils.parseUnits("10.0", 6),
0
);
// console.log(tx);
});
});

View File

@ -0,0 +1,138 @@
import { expect } from "chai";
import hre from "hardhat";
const { web3, deployments, waffle, ethers } = hre;
const { provider, deployContract } = 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/arbitrum/addresses";
import { abis } from "../../../scripts/constant/abis";
import type { Signer, Contract } from "ethers";
import { abi } from "@uniswap/v3-periphery/artifacts/contracts/NonfungiblePositionManager.sol/NonfungiblePositionManager.json";
import { ConnectV2UniswapV3SwapArbitrum__factory } from "../../../typechain";
const FeeAmount = {
LOW: 500,
MEDIUM: 3000,
HIGH: 10000
};
const TICK_SPACINGS: Record<number, number> = {
500: 10,
3000: 60,
10000: 200
};
const DAI_ADDR = "0xDA10009cBd5D07dd0CeCc66161FC93D7c9000da1";
let tokenIds: any[] = [];
let liquidities: any[] = [];
const abiCoder = ethers.utils.defaultAbiCoder;
describe("UniswapV3 [Arbitrum]", function () {
const connectorName = "UniswapV3-Swap-v1";
let dsaWallet0: any;
let masterSigner: Signer;
let instaConnectorsV2: Contract;
let connector: Contract;
let nftManager: 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: 11201500
}
}
]
});
masterSigner = await getMasterSigner();
instaConnectorsV2 = await ethers.getContractAt(abis.core.connectorsV2, addresses.core.connectorsV2);
connector = await deployAndEnableConnector({
connectorName,
contractArtifact: ConnectV2UniswapV3SwapArbitrum__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"));
});
});
describe("Main", function () {
it("Should buy successfully", async function () {
const ethAmount = ethers.utils.parseEther("0.1");
const unitAmt = ethers.utils.parseEther("0.000359232717483266");
const ethAddress = "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee";
const getId = "0";
const setId = "0";
const spells = [
{
connector: connectorName,
method: "buy",
args: [DAI_ADDR, ethAddress, FeeAmount.MEDIUM, unitAmt, ethAmount, getId, setId]
}
];
const tx = await dsaWallet0.connect(wallet0).cast(...encodeSpells(spells), wallet1.address);
const receipt = await tx.wait();
// console.log(receipt);
});
it("Should sell successfully", async function () {
const ethAmount = ethers.utils.parseEther("0.1");
const unitAmt = ethers.utils.parseEther("2770.23");
const ethAddress = "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee";
const getId = "0";
const setId = "0";
const spells = [
{
connector: connectorName,
method: "sell",
args: [DAI_ADDR, ethAddress, FeeAmount.MEDIUM, unitAmt, ethAmount, getId, setId]
}
];
const tx = await dsaWallet0.connect(wallet0).cast(...encodeSpells(spells), wallet1.address);
const receipt = await tx.wait();
// console.log(receipt);
});
});
});
const getMinTick = (tickSpacing: number) => Math.ceil(-887272 / tickSpacing) * tickSpacing;
const getMaxTick = (tickSpacing: number) => Math.floor(887272 / tickSpacing) * tickSpacing;

View File

@ -0,0 +1,159 @@
import hre from "hardhat";
import axios from "axios";
import { expect } from "chai";
const { ethers } = hre; //check
import { BigNumber } from "bignumber.js";
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 { addresses } from "../../../scripts/tests/avalanche/addresses";
import { abis } from "../../../scripts/constant/abis";
import {ConnectV2ZeroExAvalanche__factory } from "../../../typechain";
import er20abi from "../../../scripts/constant/abi/basics/erc20.json";
import type { Signer, Contract } from "ethers";
describe("ZeroEx", function() {
const connectorName = "zeroEx-test";
let dsaWallet0: Contract;
let wallet0: Signer, wallet1: Signer;
let masterSigner: Signer;
let instaConnectorsV2: Contract;
let connector: Contract;
before(async () => {
await hre.network.provider.request({
method: "hardhat_reset",
params: [
{
forking: {
// @ts-ignore
jsonRpcUrl: hre.config.networks.hardhat.forking.url,
},
},
],
});
[wallet0, wallet1] = await ethers.getSigners();
masterSigner = await getMasterSigner();
instaConnectorsV2 = await ethers.getContractAt(
abis.core.connectorsV2,
addresses.core.connectorsV2
);
connector = await deployAndEnableConnector({
connectorName,
contractArtifact: ConnectV2ZeroExAvalanche__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(await wallet0.getAddress());
expect(!!dsaWallet0.address).to.be.true;
});
it("Deposit matic 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")
);
});
});
describe("Main", function() {
it("should swap the tokens", async function() {
let buyTokenAmount: any;
async function getArg() {
// const slippage = 0.5;
/* matic -> dai */
const sellTokenAddress = "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE"; // matic, decimals 18
const sellTokenDecimals = 18;
const buyTokenAddress = "0x8f3Cf7ad23Cd3CaDbD9735AFf958023239c6A063"; // dai, decimals 18
const buyTokenDecimals = 18;
const amount = 1;
const srcAmount = new BigNumber(amount)
.times(new BigNumber(10).pow(sellTokenDecimals))
.toFixed(0);
let url = `https://avalanche.api.0x.org/swap/v1/quote`;
const params = {
buyToken: "DAI",
sellToken: "AVAX",
sellAmount: "1000000000000000000", // Always denominated in wei
};
const response = await axios
.get(url, { params: params })
.then((data: any) => data);
console.log(response);
buyTokenAmount = response.data.buyAmount;
const calldata = response.data.data;
let caculateUnitAmt = () => {
const buyTokenAmountRes = new BigNumber(buyTokenAmount)
.dividedBy(new BigNumber(10).pow(buyTokenDecimals))
.toFixed(8);
let unitAmt: any = new BigNumber(buyTokenAmountRes).dividedBy(
new BigNumber(amount)
);
unitAmt = unitAmt.multipliedBy((100 - 0.3) / 100);
unitAmt = unitAmt.multipliedBy(1e18).toFixed(0);
return unitAmt;
};
let unitAmt = caculateUnitAmt();
return [
buyTokenAddress,
sellTokenAddress,
srcAmount,
unitAmt,
calldata,
0,
];
}
let arg = await getArg();
const spells = [
{
connector: connectorName,
method: "swap",
args: arg,
},
];
const tx = await dsaWallet0
.connect(wallet0)
.cast(...encodeSpells(spells), await wallet1.getAddress());
const receipt = await tx.wait();
const daiToken = await ethers.getContractAt(
er20abi,
"0x8f3Cf7ad23Cd3CaDbD9735AFf958023239c6A063" // dai address
);
expect(await daiToken.balanceOf(dsaWallet0.address)).to.be.gte(
buyTokenAmount
);
expect(await ethers.provider.getBalance(dsaWallet0.address)).to.be.lte(
ethers.utils.parseEther("9")
);
});
});
});

View File

@ -0,0 +1,160 @@
import hre from "hardhat";
import axios from "axios";
import { expect } from "chai";
const { ethers } = hre; //check
import { BigNumber } from "bignumber.js";
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 { addresses } from "../../../scripts/tests/avalanche/addresses";
import { abis } from "../../../scripts/constant/abis";
import {ConnectV2OneInchV4Avalanche__factory } from "../../../typechain";
import er20abi from "../../../scripts/constant/abi/basics/erc20.json";
import type { Signer, Contract } from "ethers";
describe("1Inch", function() {
const connectorName = "1inch-connector-test";
let dsaWallet0: Contract;
let wallet0: Signer, wallet1: Signer;
let masterSigner: Signer;
let instaConnectorsV2: Contract;
let connector: Contract;
before(async () => {
await hre.network.provider.request({
method: "hardhat_reset",
params: [
{
forking: {
// @ts-ignore
jsonRpcUrl: hre.config.networks.hardhat.forking.url,
},
},
],
});
[wallet0, wallet1] = await ethers.getSigners();
masterSigner = await getMasterSigner();
instaConnectorsV2 = await ethers.getContractAt(
abis.core.connectorsV2,
addresses.core.connectorsV2
);
connector = await deployAndEnableConnector({
connectorName,
contractArtifact: ConnectV2OneInchV4Avalanche__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(await wallet0.getAddress());
expect(!!dsaWallet0.address).to.be.true;
});
it("Deposit avax 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")
);
});
});
describe("Main", function() {
it("should swap the tokens", async function() {
let buyTokenAmount: any;
async function getArg() {
// const slippage = 0.5;
/* avax -> dai */
const sellTokenAddress = "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE"; // avax, decimals 18
const sellTokenDecimals = 18;
const buyTokenAddress = "0xd586e7f844cea2f87f50152665bcbc2c279d8d70"; // dai, decimals 18
const buyTokenDecimals = 18;
const amount = 1;
const srcAmount = new BigNumber(amount)
.times(new BigNumber(10).pow(sellTokenDecimals))
.toFixed(0);
let url = `https://api.1inch.exchange/v4.0/43114/swap`;
const params = {
toTokenAddress: buyTokenAddress,
fromTokenAddress: sellTokenAddress,
amount: "1000000000000000000", // Always denominated in wei
fromAddress: dsaWallet0.address,
slippage:1
};
const response = await axios
.get(url, { params: params })
.then((data: any) => data);
buyTokenAmount = response.data.toTokenAmount;
const calldata = response.data.tx.data;
let caculateUnitAmt = () => {
const buyTokenAmountRes = new BigNumber(buyTokenAmount)
.dividedBy(new BigNumber(10).pow(buyTokenDecimals))
.toFixed(8);
let unitAmt: any = new BigNumber(buyTokenAmountRes).dividedBy(
new BigNumber(amount)
);
unitAmt = unitAmt.multipliedBy((100 - 0.3) / 100);
unitAmt = unitAmt.multipliedBy(1e18).toFixed(0);
return unitAmt;
};
let unitAmt = caculateUnitAmt();
return [
buyTokenAddress,
sellTokenAddress,
srcAmount,
unitAmt,
calldata,
0,
];
}
let arg = await getArg();
const spells = [
{
connector: connectorName,
method: "sell",
args: arg,
},
];
const tx = await dsaWallet0
.connect(wallet0)
.cast(...encodeSpells(spells), await wallet1.getAddress());
const receipt = await tx.wait();
const daiToken = await ethers.getContractAt(
er20abi,
"0x8f3Cf7ad23Cd3CaDbD9735AFf958023239c6A063" // dai address
);
expect(await daiToken.balanceOf(dsaWallet0.address)).to.be.gte(
buyTokenAmount
);
expect(await ethers.provider.getBalance(dsaWallet0.address)).to.be.lte(
ethers.utils.parseEther("9")
);
});
});
});

View File

@ -0,0 +1,353 @@
import { expect, should } from "chai";
import hre, { ethers, waffle } from "hardhat";
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 { buildDSAv2 } from "../../../scripts/tests/buildDSAv2";
import { addresses } from "../../../scripts/tests/avalanche/addresses";
import { deployAndEnableConnector } from "../../../scripts/tests/deployAndEnableConnector";
import { abis } from "../../../scripts/constant/abis";
import { getMasterSigner } from "../../../scripts/tests/getMasterSigner";
import { parseEther, parseUnits } from "ethers/lib/utils";
import { encodeSpells } from "../../../scripts/tests/encodeSpells";
import encodeFlashcastData from "../../../scripts/tests/encodeFlashcastData";
import { ConnectV2AaveV3ImportPermitAvalanche__factory, IERC20__factory } from "../../../typechain";
const ABI = [
"function DOMAIN_SEPARATOR() public view returns (bytes32)",
"function balanceOf(address account) public view returns (uint256)",
"function nonces(address owner) public view returns (uint256)"
];
const aDaiAddress = "0x82E64f49Ed5EC1bC6e43DAD4FC8Af9bb3A2312EE";
const aaveAddress = "0x794a61358d6845594f94dc1db02a252b5b4814ad";
// const account = "0xf04adbf75cdfc5ed26eea4bbbb991db002036bdd";
let account = "0x95eEA1Bdd19A8C40E9575048Dd0d6577D11a84e5";
const DAI = "0xd586E7F844cEa2F87f50152665BCbc2C279D8d70";
const ETH = "0x49D5c2BdFfac6CE2BFdB6640F4F80f226bc10bAB";
const mnemonic = "test test test test test test test test test test test junk";
const connectorName = "AAVE-V3-IMPORT-PERMIT-X";
let signer: any, wallet0: any;
const aaveAbi =[
{
inputs: [
{
internalType: "address",
name: "asset",
type: "address"
},
{
internalType: "uint256",
name: "amount",
type: "uint256"
},
{
internalType: "uint256",
name: "interestRateMode",
type: "uint256"
},
{
internalType: "uint16",
name: "referralCode",
type: "uint16"
},
{
internalType: "address",
name: "onBehalfOf",
type: "address"
}
],
name: "borrow",
outputs: [],
stateMutability: "nonpayable",
type: "function"
},
{
inputs: [
{
internalType: "address",
name: "asset",
type: "address"
},
{
internalType: "uint256",
name: "amount",
type: "uint256"
},
{
internalType: "address",
name: "onBehalfOf",
type: "address"
},
{
internalType: "uint16",
name: "referralCode",
type: "uint16"
}
],
name: "deposit",
outputs: [],
stateMutability: "nonpayable",
type: "function"
},
{
inputs: [
{
internalType: "address",
name: "asset",
type: "address"
},
{
internalType: "uint256",
name: "amount",
type: "uint256"
},
{
internalType: "address",
name: "onBehalfOf",
type: "address"
},
{
internalType: "uint16",
name: "referralCode",
type: "uint16"
}
],
name: "supply",
outputs: [],
stateMutability: "nonpayable",
type: "function"
}
];
const erc20Abi = [
{
constant: false,
inputs: [
{
name: "_spender",
type: "address"
},
{
name: "_value",
type: "uint256"
}
],
name: "approve",
outputs: [
{
name: "",
type: "bool"
}
],
payable: false,
stateMutability: "nonpayable",
type: "function"
},
{
constant: true,
inputs: [
{
name: "_owner",
type: "address"
}
],
name: "balanceOf",
outputs: [
{
name: "balance",
type: "uint256"
}
],
payable: false,
stateMutability: "view",
type: "function"
},
{
constant: false,
inputs: [
{
name: "_to",
type: "address"
},
{
name: "_value",
type: "uint256"
}
],
name: "transfer",
outputs: [
{
name: "",
type: "bool"
}
],
payable: false,
stateMutability: "nonpayable",
type: "function"
}
];
const token = new ethers.Contract(DAI, erc20Abi);
const aDai = new ethers.Contract(aDaiAddress, ABI);
const ethToken = new ethers.Contract(ETH, erc20Abi);
const aave = new ethers.Contract(aaveAddress, aaveAbi);
describe("Import Aave v3 Position for Avalanche", function () {
let dsaWallet0: any;
let masterSigner: Signer;
let instaConnectorsV2: Contract;
let connector: any;
const wallet = ethers.Wallet.fromMnemonic(mnemonic);
before(async () => {
await hre.network.provider.request({
method: "hardhat_reset",
params: [
{
forking: {
//@ts-ignore
jsonRpcUrl: hre.config.networks.hardhat.forking.url,
blockNumber: 13024200
}
}
]
});
masterSigner = await getMasterSigner();
[wallet0] = await ethers.getSigners();
await hre.network.provider.send("hardhat_setBalance", [account, ethers.utils.parseEther("10").toHexString()]);
await hre.network.provider.request({
method: "hardhat_impersonateAccount",
params: [account]
});
signer = await ethers.getSigner(account);
await token.connect(signer).transfer(wallet0.address, ethers.utils.parseEther("8"));
instaConnectorsV2 = await ethers.getContractAt(abis.core.connectorsV2, addresses.core.connectorsV2);
connector = await deployAndEnableConnector({
connectorName,
contractArtifact: ConnectV2AaveV3ImportPermitAvalanche__factory,
signer: masterSigner,
connectors: instaConnectorsV2
});
});
describe("check user AAVE position", async () => {
it("Should create Aave v3 position of DAI(collateral) and ETH(debt)", async () => {
// approve DAI to aavePool
await token.connect(wallet0).approve(aaveAddress, parseEther("8"));
//deposit DAI in aave
await aave.connect(wallet0).supply(DAI, parseEther("8"), wallet.address, 3228);
console.log("Supplied DAI on aave");
//borrow ETH from aave
await aave.connect(wallet0).borrow(ETH, parseUnits("3", 6), 2, 3228, wallet.address);
console.log("Borrowed ETH from aave");
});
it("Should check position of user", async () => {
expect(await aDai.connect(wallet0).balanceOf(wallet.address)).to.be.gte(
new BigNumber(8).multipliedBy(1e18).toString()
);
expect(await ethToken.connect(wallet0).balanceOf(wallet.address)).to.be.gte(
new BigNumber(3).multipliedBy(1e6).toString()
);
});
});
describe("Deployment", async () => {
it("Should set correct name", async () => {
expect(await connector.name()).to.eq("Aave-v3-import-permit-v1");
});
});
describe("DSA wallet setup", async () => {
it("Should build DSA v2", async () => {
dsaWallet0 = await buildDSAv2(wallet.address);
expect(!!dsaWallet0.address).to.be.true;
});
it("Deposit ETH into DSA wallet", async function () {
await wallet0.sendTransaction({
to: dsaWallet0.address,
value: ethers.utils.parseEther("3")
});
expect(await ethers.provider.getBalance(dsaWallet0.address)).to.be.gte(ethers.utils.parseEther("3"));
});
});
describe("Aave position migration", async () => {
it("Should migrate Aave position", async () => {
const DOMAIN_SEPARATOR = await aDai.connect(wallet0).DOMAIN_SEPARATOR();
const PERMIT_TYPEHASH = "0x6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9";
let nonce = (await aDai.connect(wallet0).nonces(wallet.address)).toNumber();
//Approving max amount
const amount = ethers.constants.MaxUint256;
const expiry = Date.now() + 20 * 60;
const digest = keccak256(
ethers.utils.solidityPack(
["bytes1", "bytes1", "bytes32", "bytes32"],
[
"0x19",
"0x01",
DOMAIN_SEPARATOR,
keccak256(
defaultAbiCoder.encode(
["bytes32", "address", "address", "uint256", "uint256", "uint256"],
[PERMIT_TYPEHASH, wallet.address, dsaWallet0.address, amount, nonce, expiry]
)
)
]
)
);
const { v, r, s } = ecsign(Buffer.from(digest.slice(2), "hex"), Buffer.from(wallet.privateKey.slice(2), "hex"));
const amount0 = new BigNumber(await ethToken.connect(wallet0).balanceOf(wallet.address));
const amountB = new BigNumber(amount0.toString()).multipliedBy(9).dividedBy(1e4);
const amountWithFee = amount0.plus(amountB);
const flashSpells = [
{
connector: "AAVE-V3-IMPORT-PERMIT-X",
method: "importAave",
args: [
wallet.address,
[[DAI], [ETH], false, [amountB.toFixed(0)]],
[[v], [ethers.utils.hexlify(r)], [ethers.utils.hexlify(s)], [expiry]]
]
},
{
connector: "INSTAPOOL-C",
method: "flashPayback",
args: [ETH, amountWithFee.toFixed(0), 0, 0]
}
];
const spells = [
{
connector: "INSTAPOOL-C",
method: "flashBorrowAndCast",
args: [ETH, amount0.toString(), 1, encodeFlashcastData(flashSpells), "0x"]
}
];
const tx = await dsaWallet0.connect(wallet0).cast(...encodeSpells(spells), wallet.address);
const receipt = await tx.wait();
});
it("Should check DSA AAVE position", async () => {
expect(await aDai.connect(wallet0).balanceOf(dsaWallet0.address)).to.be.gte(
new BigNumber(3).multipliedBy(1e18).toString()
);
});
});
});

View File

@ -0,0 +1,273 @@
import { expect, should } from "chai";
import hre, { ethers, waffle } from "hardhat";
import type { Signer, Contract } from "ethers";
import { BigNumber } from "bignumber.js";
import { buildDSAv2 } from "../../../scripts/tests/buildDSAv2";
import { addresses } from "../../../scripts/tests/avalanche/addresses";
import { deployAndEnableConnector } from "../../../scripts/tests/deployAndEnableConnector";
import { abis } from "../../../scripts/constant/abis";
import { getMasterSigner } from "../../../scripts/tests/getMasterSigner";
import { parseEther, parseUnits } from "ethers/lib/utils";
import { encodeSpells } from "../../../scripts/tests/encodeSpells";
import { ConnectV2AaveV3Avalanche__factory, IERC20__factory } from "../../../typechain";
const ABI = ["function balanceOf(address account) public view returns (uint256)"];
const aDaiAddress = "0x82E64f49Ed5EC1bC6e43DAD4FC8Af9bb3A2312EE";
const aaveAddress = "0x69FA688f1Dc47d4B5d8029D5a35FB7a548310654";
const ETH = "0xB97EF9Ef8734C71904D8002F8b6Bc66Dd9c48a6E";
let account = "0xC4Aa5b4d4049324C09376D586482c7F8fB57542a";
const DAI = "0xd586E7F844cEa2F87f50152665BCbc2C279D8d70";
const mnemonic = "test test test test test test test test test test test junk";
const connectorName = "AAVE-V3-X";
let signer: any, wallet0: any;
const aaveAbi = [
{
inputs: [
{ internalType: "address", name: "asset", type: "address" },
{ internalType: "address", name: "user", type: "address" }
],
name: "getUserReserveData",
outputs: [
{ internalType: "uint256", name: "currentATokenBalance", type: "uint256" },
{ internalType: "uint256", name: "currentStableDebt", type: "uint256" },
{ internalType: "uint256", name: "currentVariableDebt", type: "uint256" },
{ internalType: "uint256", name: "principalStableDebt", type: "uint256" },
{ internalType: "uint256", name: "scaledVariableDebt", type: "uint256" },
{ internalType: "uint256", name: "stableBorrowRate", type: "uint256" },
{ internalType: "uint256", name: "liquidityRate", type: "uint256" },
{ internalType: "uint40", name: "stableRateLastUpdated", type: "uint40" },
{ internalType: "bool", name: "usageAsCollateralEnabled", type: "bool" }
],
stateMutability: "view",
type: "function"
}
];
const erc20Abi = [
{
constant: false,
inputs: [
{
name: "_spender",
type: "address"
},
{
name: "_value",
type: "uint256"
}
],
name: "approve",
outputs: [
{
name: "",
type: "bool"
}
],
payable: false,
stateMutability: "nonpayable",
type: "function"
},
{
constant: true,
inputs: [],
name: "totalSupply",
outputs: [
{
name: "",
type: "uint256"
}
],
payable: false,
stateMutability: "view",
type: "function"
},
{
constant: true,
inputs: [
{
name: "_owner",
type: "address"
}
],
name: "balanceOf",
outputs: [
{
name: "balance",
type: "uint256"
}
],
payable: false,
stateMutability: "view",
type: "function"
},
{
constant: false,
inputs: [
{
name: "_to",
type: "address"
},
{
name: "_value",
type: "uint256"
}
],
name: "transfer",
outputs: [
{
name: "",
type: "bool"
}
],
payable: false,
stateMutability: "nonpayable",
type: "function"
}
];
const token = new ethers.Contract(DAI, erc20Abi);
const aDai = new ethers.Contract(aDaiAddress, ABI);
const ethToken = new ethers.Contract(ETH, erc20Abi);
const aave = new ethers.Contract(aaveAddress, aaveAbi);
describe("Aave v3 Position for Avalanche", function () {
let dsaWallet0: any;
let masterSigner: Signer;
let instaConnectorsV2: Contract;
let connector: any;
const wallet = ethers.Wallet.fromMnemonic(mnemonic);
before(async () => {
await hre.network.provider.request({
method: "hardhat_reset",
params: [
{
forking: {
//@ts-ignore
jsonRpcUrl: hre.config.networks.hardhat.forking.url,
blockNumber: 16201000
}
}
]
});
masterSigner = await getMasterSigner();
[wallet0] = await ethers.getSigners();
await hre.network.provider.send("hardhat_setBalance", [account, ethers.utils.parseEther("10").toHexString()]);
await hre.network.provider.request({
method: "hardhat_impersonateAccount",
params: [account]
});
signer = await ethers.getSigner(account);
await token.connect(signer).transfer(wallet0.address, ethers.utils.parseEther("8"));
instaConnectorsV2 = await ethers.getContractAt(abis.core.connectorsV2, addresses.core.connectorsV2);
connector = await deployAndEnableConnector({
connectorName,
contractArtifact: ConnectV2AaveV3Avalanche__factory,
signer: masterSigner,
connectors: instaConnectorsV2
});
});
describe("Deployment", async () => {
it("Should set correct name", async () => {
expect(await connector.name()).to.eq("AaveV3-v1.2");
});
});
describe("DSA wallet setup", async () => {
it("Should build DSA v2", async () => {
dsaWallet0 = await buildDSAv2(wallet0.address);
expect(!!dsaWallet0.address).to.be.true;
});
it("Deposit ETH into DSA wallet", async function () {
await wallet0.sendTransaction({
to: dsaWallet0.address,
value: ethers.utils.parseEther("5")
});
expect(await ethers.provider.getBalance(dsaWallet0.address)).to.be.gte(ethers.utils.parseEther("5"));
});
});
describe("check user AAVE position", async () => {
it("Should create DSA Aave v3 position of DAI(collateral) and USDC(debt)", async () => {
await token.connect(signer).transfer(dsaWallet0.address, ethers.utils.parseEther("8"));
const spells = [
//deposit DAI in aave
{
connector: connectorName,
method: "deposit",
args: [DAI, parseEther("8"), 0, 0]
},
//borrow USDC from aave
{
connector: connectorName,
method: "borrow",
args: [ETH, parseUnits("1", 6), 2, 0, 0]
}
];
const tx = await dsaWallet0.connect(wallet0).cast(...encodeSpells(spells), wallet0.address);
const receipt = await tx.wait();
});
it("Should check position of dsa", async () => {
expect(await aDai.connect(wallet0).balanceOf(dsaWallet0.address)).to.be.gte(
new BigNumber(8).multipliedBy(1e18).toString()
);
expect(await ethToken.connect(wallet0).balanceOf(dsaWallet0.address)).to.be.gte(
new BigNumber(1).multipliedBy(1e6).toString()
);
expect((await aave.connect(wallet0).getUserReserveData(ETH, dsaWallet0.address)).currentStableDebt).to.be.equal(
0
);
expect((await aave.connect(wallet0).getUserReserveData(ETH, dsaWallet0.address)).currentVariableDebt).to.be.gte(
new BigNumber(1).multipliedBy(1e6).toString()
);
console.log(`\tstable borrow before: ${(await aave.connect(wallet0).getUserReserveData(ETH, dsaWallet0.address)).currentStableDebt}`);
console.log(`\tvariable borrow before: ${(await aave.connect(wallet0).getUserReserveData(ETH, dsaWallet0.address)).currentVariableDebt}`);
});
it("Should swap borrowRateMode", async () => {
const spells = [
//deposit DAI in aave
{
connector: connectorName,
method: "swapBorrowRateMode",
args: [ETH, 2]
}
];
const tx = await dsaWallet0.connect(wallet0).cast(...encodeSpells(spells), wallet0.address);
const receipt = await tx.wait();
});
it("Should check position of dsa", async () => {
expect(await aDai.connect(wallet0).balanceOf(dsaWallet0.address)).to.be.gte(
new BigNumber(8).multipliedBy(1e18).toString()
);
expect(await ethToken.connect(wallet0).balanceOf(dsaWallet0.address)).to.be.gte(
new BigNumber(1).multipliedBy(1e6).toString()
);
expect(
(await aave.connect(wallet0).getUserReserveData(ETH, dsaWallet0.address)).currentVariableDebt
).to.be.equal(0);
expect((await aave.connect(wallet0).getUserReserveData(ETH, dsaWallet0.address)).currentStableDebt).to.be.gte(
new BigNumber(1).multipliedBy(1e6).toString()
);
console.log(`\tstable borrow after: ${(await aave.connect(wallet0).getUserReserveData(ETH, dsaWallet0.address)).currentStableDebt}`);
console.log(`\tvariable borrow after: ${(await aave.connect(wallet0).getUserReserveData(ETH, dsaWallet0.address)).currentVariableDebt}`)
});
});
});

View File

@ -0,0 +1,185 @@
import hre from "hardhat";
import axios from "axios";
import { expect } from "chai";
const { ethers } = hre; //check
import { BigNumber } from "bignumber.js";
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 { addresses } from "../../../scripts/tests/avalanche/addresses";
import { abis } from "../../../scripts/constant/abis";
import { ConnectV2DSASpellAvalanche__factory } from "../../../typechain";
import er20abi from "../../../scripts/constant/abi/basics/erc20.json";
import type { Signer, Contract } from "ethers";
describe("DSA Spell", function () {
const connectorName = "dsa-spell-test";
let dsaWallet0: any;
let dsaWallet1: any;
let dsaWallet2: any;
let walletB: any;
let wallet0: any;
let walletBsigner: any;
let masterSigner: Signer;
let instaConnectorsV2: Contract;
let connector: any;
before(async () => {
await hre.network.provider.request({
method: "hardhat_reset",
params: [
{
forking: {
// @ts-ignore
jsonRpcUrl: hre.config.networks.hardhat.forking.url
}
}
]
});
[wallet0] = await ethers.getSigners();
masterSigner = await getMasterSigner();
instaConnectorsV2 = await ethers.getContractAt(abis.core.connectorsV2, addresses.core.connectorsV2);
connector = await deployAndEnableConnector({
connectorName,
contractArtifact: ConnectV2DSASpellAvalanche__factory,
signer: masterSigner,
connectors: instaConnectorsV2
});
console.log("\tConnector 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;
walletB = await ethers.getSigner(dsaWallet0.address);
dsaWallet1 = await buildDSAv2(dsaWallet0.address);
expect(!!dsaWallet1.address).to.be.true;
console.log(`\t${dsaWallet1.address}`);
dsaWallet2 = await buildDSAv2(wallet0.address);
expect(!!dsaWallet2.address).to.be.true;
});
it("Deposit avax into DSA wallet 0", 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 avax into DSA wallet 1", async function () {
await wallet0.sendTransaction({
to: dsaWallet1.address,
value: ethers.utils.parseEther("10")
});
expect(await ethers.provider.getBalance(dsaWallet1.address)).to.be.gte(ethers.utils.parseEther("10"));
});
});
describe("Main", function () {
let AVAX = "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE";
let USDC = "0xB97EF9Ef8734C71904D8002F8b6Bc66Dd9c48a6E";
let usdc = new ethers.Contract(USDC, abis.basic.erc20);
let aAVAX = "0x6d80113e533a2C0fe82EaBD35f1875DcEA89Ea97";
let aAvax = new ethers.Contract(aAVAX, abis.basic.aToken);
var abi = [
"function withdraw(address,uint256,address,uint256,uint256)",
"function deposit(address,uint256,uint256,uint256)",
"function borrow(address,uint256,uint256,uint256,uint256)"
];
function getCallData(spell: string, params: any) {
var iface = new ethers.utils.Interface(abi);
let data = iface.encodeFunctionData(spell, params);
return ethers.utils.hexlify(data);
}
it("should cast spells", async function () {
async function getArg(connectors: any, spells: any, params: any) {
let datas = [];
for (let i = 0; i < connectors.length; i++) {
datas.push(getCallData(spells[i], params[i]));
}
return [dsaWallet1.address, connectors, datas];
}
let connectors = ["BASIC-A", "AAVE-V3-A", "AAVE-V3-A"];
let methods = ["withdraw", "deposit", "borrow"];
let params = [
[AVAX, ethers.utils.parseEther("2"), dsaWallet0.address, 0, 0],
[AVAX, ethers.constants.MaxUint256, 0, 0],
[USDC, ethers.utils.parseUnits("1", 6), 2, 0, 0]
];
let arg = await getArg(connectors, methods, params);
const spells = [
{
connector: connectorName,
method: "castOnDSA",
args: arg
}
];
const tx = await dsaWallet0.connect(wallet0).cast(...encodeSpells(spells), await wallet0.getAddress());
const receipt = await tx.wait();
});
it("should check balances after cast on DSA", async function () {
expect(await ethers.provider.getBalance(dsaWallet1.address)).to.be.lte(0);
expect(await usdc.connect(wallet0).balanceOf(dsaWallet1.address)).to.be.gte(
new BigNumber(1).multipliedBy(1e6).toString()
);
expect(await ethers.provider.getBalance(dsaWallet0.address)).to.be.gte(
new BigNumber(12).multipliedBy(1e18).toString()
);
});
it("should cast spell on the first successful", async function () {
async function getArg(connectors: any, spells: any, params: any) {
let datas = [];
for (let i = 0; i < connectors.length; i++) {
datas.push(getCallData(spells[i], params[i]));
}
return [connectors, datas];
}
let connectors = ["AAVE-V3-A", "AAVE-V2-A"];
let methods = ["deposit","deposit"];
let params = [
[AVAX, ethers.utils.parseEther("10"), 0, 0],
[AVAX, ethers.utils.parseEther("10"), 0, 0]
];
let arg = await getArg(connectors, methods, params);
const spells = [
{
connector: connectorName,
method: "castAny",
args: arg
}
];
const tx = await dsaWallet0
.connect(wallet0)
.cast(...encodeSpells(spells), await wallet0.getAddress());
const receipt = await tx.wait();
});
it("should check balances after spells on DSA", async function () {
expect(await ethers.provider.getBalance(dsaWallet0.address)).to.be.lte(
new BigNumber(2).multipliedBy(1e18).toString()
);
expect(await aAvax.connect(wallet0).balanceOf(dsaWallet0.address)).to.be.gte(
new BigNumber(10).multipliedBy(1e18).toString()
);
});
});
});

View File

@ -0,0 +1,282 @@
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 { addresses } from "../../../scripts/tests/avalanche/addresses";
import { abis } from "../../../scripts/constant/abis";
import { Signer, Contract } from "ethers";
import { ConnectV2PngAvalanche__factory } from "../../../typechain";
const PNG_ADDRESS = "0x60781C2586D68229fde47564546784ab3fACA982";
const WAVAX_ADDRESS = "0xB31f66AA3C1e785363F0875A1B74E27b85FD66c7";
const PNG_AVAX_LP_ADDRESS = "0xd7538cABBf8605BdE1f4901B47B8D42c61DE0367";
describe("Pangolin DEX - Avalanche", function () {
const pangolinConnectorName = "PANGOLIN-TEST-A"
let dsaWallet0: Contract;
let masterSigner: Signer;
let instaConnectorsV2: Contract;
let pangolinConnector: Contract;
const wallets = provider.getWallets()
const [wallet0, wallet1] = wallets
before(async () => {
await hre.network.provider.request({
method: "hardhat_reset",
params: [
{
forking: {
jsonRpcUrl: `https://api.avax.network/ext/bc/C/rpc`,
blockNumber: 8197390
},
},
],
});
masterSigner = await getMasterSigner();
instaConnectorsV2 = await ethers.getContractAt(
abis.core.connectorsV2,
addresses.core.connectorsV2
);
// Deploy and enable Pangolin Connector
pangolinConnector = await deployAndEnableConnector({
connectorName: pangolinConnectorName,
contractArtifact: ConnectV2PngAvalanche__factory,
signer: masterSigner,
connectors: instaConnectorsV2
});
console.log("Pangolin Connector address: "+ pangolinConnector.address);
})
it("Should have contracts deployed.", async function () {
expect(!!instaConnectorsV2.address).to.be.true;
expect(!!pangolinConnector.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.getAddress())
expect(!!dsaWallet0.address).to.be.true;
});
it("Deposit 10 AVAX 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"));
});
});
describe("Main - PANGOLIN PNG/AVAX Liquidity Test", function () {
it("Should use pangolin to swap AVAX for PNG, and deposit to PNG/AVAX LP", async function () {
const amount = ethers.utils.parseEther("100"); // 100 PNG
const int_slippage = 0.03
const slippage = ethers.utils.parseEther(int_slippage.toString());
const setId = "83528353";
const PangolinRouterABI = [
"function getAmountsOut(uint amountIn, address[] calldata path) external view returns (uint[] memory amounts)"
];
// Get amount of AVAX for 100 POOL from Pangolin
const PangolinRouter = await ethers.getContractAt(
PangolinRouterABI,
"0xE54Ca86531e17Ef3616d22Ca28b0D458b6C89106"
);
const amounts = await PangolinRouter.getAmountsOut(
amount,
[
PNG_ADDRESS,
WAVAX_ADDRESS
]
);
const amtA = amounts[0];
const amtB = amounts[1];
const unitAmt = (amtB * (1 + int_slippage)) / amtA;
const unitAmount = ethers.utils.parseEther(unitAmt.toString());
const spells = [
{
connector: pangolinConnectorName,
method: "buy",
args: [
PNG_ADDRESS,
"0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee",
amount,
unitAmount,
0,
setId
]
},
{
connector: pangolinConnectorName,
method: "deposit",
args: [
PNG_ADDRESS,
"0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee",
amount,
unitAmount,
slippage,
0,
setId
]
},
];
// Before Spell
let avaxBalance = await ethers.provider.getBalance(dsaWallet0.address);
expect(avaxBalance, `AVAX Balance equals 10`).to.be.eq(ethers.utils.parseEther("10"));
let pngToken = await ethers.getContractAt(abis.basic.erc20, PNG_ADDRESS);
const pngBalance = await pngToken.balanceOf(dsaWallet0.address);
expect(pngBalance, `PNG Token greater than 0`).to.be.eq(0);
let pangolinLPToken = await ethers.getContractAt(
abis.basic.erc20,
PNG_AVAX_LP_ADDRESS
);
const pangolinPoolAVAXBalance = await pangolinLPToken.balanceOf(dsaWallet0.address);
expect(pangolinPoolAVAXBalance, `Pangolin PNG/AVAX LP equals 0`).to.be.eq(0);
// Run spell transaction
const tx = await dsaWallet0.connect(wallet0).cast(
...encodeSpells(spells), wallet1.address
);
const receipt = await tx.wait();
// After spell
avaxBalance = await ethers.provider.getBalance(dsaWallet0.address);
expect(avaxBalance, `AVAX Balance less than 10`).to.be.lt(ethers.utils.parseEther("10"));
const pngBalanceAfter = await pngToken.balanceOf(dsaWallet0.address)
expect(pngBalanceAfter, `PNG Token to be same after spell`).to.be.eq(pngBalance);
const pangolinPoolAVAXBalanceAfter = await pangolinLPToken.balanceOf(dsaWallet0.address);
expect(
pangolinPoolAVAXBalanceAfter,
`Pangolin PNG/AVAX LP greater than 0`
).to.be.gt(0);
});
it("Should use pangolin to withdraw to PNG/AVAX LP, and swap PNG for AVAX", async function () {
const amount = ethers.utils.parseEther("100"); // 100 PNG
const int_slippage = 0.03
// Before Spell
let avaxBalance = await ethers.provider.getBalance(dsaWallet0.address);
let pngToken = await ethers.getContractAt(abis.basic.erc20, PNG_ADDRESS);
let pangolinLPToken = await ethers.getContractAt(
abis.basic.erc20,
PNG_AVAX_LP_ADDRESS
);
const pngBalance = await pngToken.balanceOf(dsaWallet0.address)
expect(pngBalance, `PNG Token balance equal to 0`).to.be.eq(0);
const pangolinPoolAVAXBalance = await pangolinLPToken.balanceOf(dsaWallet0.address);
expect(pangolinPoolAVAXBalance, `Pangolin PNG/AVAX LP greater than 0`).to.be.gt(0);
const PangolinRouterABI = [
"function getAmountsOut(uint amountIn, address[] calldata path) external view returns (uint[] memory amounts)"
];
// Get amount of avax for 100 PNG from Pangolin
const PangolinRouter= await ethers.getContractAt(
PangolinRouterABI,
"0xE54Ca86531e17Ef3616d22Ca28b0D458b6C89106"
);
const amounts = await PangolinRouter.getAmountsOut(
amount,
[
PNG_ADDRESS,
WAVAX_ADDRESS
]
);
const amtA = amounts[0];
const amtB = amounts[1];
const unitAmtA = ethers.utils.parseEther(
(amtA * (1 - int_slippage) / pangolinPoolAVAXBalance).toString()
);
const unitAmtB = ethers.utils.parseEther(
(amtB * (1 - int_slippage) / pangolinPoolAVAXBalance).toString()
);
let spells = [
{
connector: pangolinConnectorName,
method: "withdraw",
args: [
PNG_ADDRESS,
"0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee",
pangolinPoolAVAXBalance,
unitAmtA,
unitAmtB,
0,
[
0,
0
]
]
},
];
// Run spell transaction (withdraw token of pool)
const tx = await dsaWallet0.connect(wallet0).cast(
...encodeSpells(spells),
wallet1.address
);
const receipt = await tx.wait();
// After spell
const pangolinPoolAVAXBalanceAfter = await pangolinLPToken.balanceOf(
dsaWallet0.address
);
expect(pangolinPoolAVAXBalanceAfter, `Pangolin PNG/AVAX LP equal 0`).to.be.eq(0);
let pngBalanceAfter = await pngToken.balanceOf(dsaWallet0.address);
expect(pngBalanceAfter, `PNG Token balance greater than`).to.be.gt(0);
const unitAmt = amount.div(pngBalanceAfter);
spells = [
{
connector: pangolinConnectorName,
method: "sell",
args: [
"0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee",
PNG_ADDRESS,
pngBalanceAfter,
unitAmt,
0,
0
]
},
];
// Run spell transaction (withdraw token of pool)
const tx2 = await dsaWallet0.connect(wallet0).cast(...encodeSpells(spells), wallet1.address);
const receipt2 = await tx2.wait();
let avaxBalanceAfter = await ethers.provider.getBalance(dsaWallet0.address);
expect(
avaxBalanceAfter,
`AVAX Balance After greater than AVAX Balance Before`
).to.be.gt(avaxBalance);
pngBalanceAfter = await pngToken.balanceOf(dsaWallet0.address);
expect(pngBalanceAfter, `PNG Token balance equal 0`).to.be.eq(0);
});
})
});

View File

@ -0,0 +1,821 @@
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 { addresses } from "../../../scripts/tests/avalanche/addresses";
import { abis } from "../../../scripts/constant/abis";
import { Signer, Contract, BigNumber } from "ethers";
import { ConnectV2PngAvalanche__factory, ConnectV2PngStakeAvalanche__factory } from "../../../typechain";
const PNG_ADDRESS = "0x60781C2586D68229fde47564546784ab3fACA982";
const WAVAX_ADDRESS = "0xB31f66AA3C1e785363F0875A1B74E27b85FD66c7";
const PNG_AVAX_LP_ADDRESS = "0xd7538cABBf8605BdE1f4901B47B8D42c61DE0367";
const PNG_STAKING_ADDRESS = "0x88afdaE1a9F58Da3E68584421937E5F564A0135b";
describe("Pangolin Stake - Avalanche", function () {
const pangolinConnectorName = "PANGOLIN-TEST-A"
const pangolinStakeConnectorName = "PANGOLIN-STAKE-TEST-A"
let dsaWallet0: Contract;
let masterSigner: Signer;
let instaConnectorsV2: Contract;
let pangolinConnector: Contract;
let pangolinStakeConnector: Contract;
let PNG: Contract;
const wallets = provider.getWallets()
const [wallet0, wallet1] = wallets
before(async () => {
await hre.network.provider.request({
method: "hardhat_reset",
params: [
{
forking: {
jsonRpcUrl: `https://api.avax.network/ext/bc/C/rpc`,
blockNumber: 8197390
},
},
],
});
PNG = await ethers.getContractAt(
abis.basic.erc20,
PNG_ADDRESS
);
masterSigner = await getMasterSigner();
instaConnectorsV2 = await ethers.getContractAt(
abis.core.connectorsV2,
addresses.core.connectorsV2
);
// Deploy and enable Pangolin Connector
pangolinConnector = await deployAndEnableConnector({
connectorName: pangolinConnectorName,
contractArtifact: ConnectV2PngAvalanche__factory,
signer: masterSigner,
connectors: instaConnectorsV2
});
console.log("Pangolin Connector address: "+ pangolinConnector.address);
// Deploy and enable Pangolin Stake Connector
pangolinStakeConnector = await deployAndEnableConnector({
connectorName: pangolinStakeConnectorName,
contractArtifact: ConnectV2PngStakeAvalanche__factory,
signer: masterSigner,
connectors: instaConnectorsV2
});
console.log("Pangolin Stake Connector address: "+ pangolinStakeConnector.address);
})
it("Should have contracts deployed.", async function () {
expect(!!instaConnectorsV2.address).to.be.true;
expect(!!pangolinConnector.address).to.be.true;
expect(!!pangolinStakeConnector.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.getAddress())
expect(!!dsaWallet0.address).to.be.true;
});
it("Deposit 10 AVAX 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"));
});
});
describe("Pangolin Staking - LP Stake Test", function () {
let lpAmount: BigNumber;
let pangolinLPToken: Contract;
// Buy 100 PNG and deposity in PNG/AVAX LP
before(async () => {
const amount = ethers.utils.parseEther("100"); // 100 PNG
const int_slippage = 0.03
const slippage = ethers.utils.parseEther(int_slippage.toString());
const setId = "0";
const PangolinRouterABI = [
"function getAmountsOut(uint amountIn, address[] calldata path) external view returns (uint[] memory amounts)"
];
// Get amount of AVAX for 200 PNG from Pangolin
const PangolinRouter = await ethers.getContractAt(
PangolinRouterABI,
"0xE54Ca86531e17Ef3616d22Ca28b0D458b6C89106"
);
const amounts = await PangolinRouter.getAmountsOut(
amount,
[
PNG_ADDRESS,
WAVAX_ADDRESS
]
);
const amtA = amounts[0];
const amtB = amounts[1];
const unitAmt = (amtB * (1 + int_slippage)) / amtA;
const unitAmount = ethers.utils.parseEther(unitAmt.toString());
const spells = [
{
connector: pangolinConnectorName,
method: "buy",
args: [
PNG_ADDRESS,
"0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee",
amount,
unitAmount,
0,
0
]
},
{
connector: pangolinConnectorName,
method: "deposit",
args: [
PNG_ADDRESS,
"0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee",
amount,
unitAmount,
slippage,
0,
setId
]
},
];
// Run spell transaction
const tx = await dsaWallet0.connect(wallet0).cast(
...encodeSpells(spells), wallet1.address
);
const receipt = await tx.wait();
pangolinLPToken = await ethers.getContractAt(
abis.basic.erc20,
PNG_AVAX_LP_ADDRESS
);
});
it("Check if has PNG/AVAX LP", async function () {
const pangolinPoolAVAXBalance = await pangolinLPToken.balanceOf(dsaWallet0.address);
expect(pangolinPoolAVAXBalance, `Pangolin PNG/AVAX LP greater than 0`).to.be.gt(0);
console.log("PNG/AVAX LP: ", ethers.utils.formatUnits(pangolinPoolAVAXBalance, "ether").toString())
lpAmount = pangolinPoolAVAXBalance;
});
it("Check if all functions reverts by: Invalid pid!", async function () {
const pid = BigNumber.from("999999999999");
const amount = ethers.utils.parseEther("1");
const getId = 0;
const setId = 0;
let spells = [
{
connector: pangolinStakeConnectorName,
method: "depositLpStake",
args: [
pid,
amount,
getId,
setId
]
}
];
await expect(
dsaWallet0.connect(wallet0).cast(
...encodeSpells(spells),
wallet1.address
)
).to.be.revertedWith("Invalid pid!");
spells[0].method = "withdrawLpStake"
await expect(
dsaWallet0.connect(wallet0).cast(
...encodeSpells(spells),
wallet1.address
)
).to.be.revertedWith("Invalid pid!");
spells[0].method = "withdrawAndClaimLpRewards"
await expect(
dsaWallet0.connect(wallet0).cast(
...encodeSpells(spells),
wallet1.address
)
).to.be.revertedWith("Invalid pid!");
spells = [
{
connector: pangolinStakeConnectorName,
method: "claimLpRewards",
args: [
pid
]
}
];
await expect(
dsaWallet0.connect(wallet0).cast(
...encodeSpells(spells),
wallet1.address
)
).to.be.revertedWith("Invalid pid!");
spells[0].method = "emergencyWithdrawLpStake"
await expect(
dsaWallet0.connect(wallet0).cast(
...encodeSpells(spells),
wallet1.address
)
).to.be.revertedWith("Invalid pid!");
});
it("Check if all functions reverts by: 'Invalid amount, amount cannot be 0'", async function () {
let spells = [
{
connector: pangolinStakeConnectorName,
method: "depositLpStake",
args: [
0,
0,
0,
0
]
}
];
await expect(
dsaWallet0.connect(wallet0).cast(
...encodeSpells(spells),
wallet1.address
)
).to.be.revertedWith("Invalid amount, amount cannot be 0");
spells[0].method = "withdrawLpStake"
await expect(
dsaWallet0.connect(wallet0).cast(
...encodeSpells(spells),
wallet1.address
)
).to.be.revertedWith("Invalid amount, amount cannot be 0");
spells[0].method = "withdrawLpStake"
await expect(
dsaWallet0.connect(wallet0).cast(
...encodeSpells(spells),
wallet1.address
)
).to.be.revertedWith("Invalid amount, amount cannot be 0");
spells[0].method = "withdrawAndClaimLpRewards"
await expect(
dsaWallet0.connect(wallet0).cast(
...encodeSpells(spells),
wallet1.address
)
).to.be.revertedWith("Invalid amount, amount cannot be 0");
});
describe("depositLpStake function", function () {
it("Check if depositLpStake function reverts by: Invalid amount, amount greater than balance of LP token", async function () {
const amount = lpAmount.mul(2);
const spells = [
{
connector: pangolinStakeConnectorName,
method: "depositLpStake",
args: [
0,
amount,
0,
0
]
}
];
await expect(
dsaWallet0.connect(wallet0).cast(
...encodeSpells(spells),
wallet1.address
)
).to.be.revertedWith("Invalid amount, amount greater than balance of LP token");
});
it("Check if success in depositLpStake", async function () {
const spells = [
{
connector: pangolinStakeConnectorName,
method: "depositLpStake",
args: [
0,
lpAmount,
0,
0
]
}
];
await expect(
dsaWallet0.connect(wallet0).cast(
...encodeSpells(spells),
wallet1.address
)
).to.be.not.reverted;
// Check if PNG/AVAX LP is equal 0
const balance = await pangolinLPToken.balanceOf(dsaWallet0.address);
expect(balance).to.be.eq(0);
});
it("Check if depositLpStake function reverts by: Invalid LP token balance", async function () {
const spells = [
{
connector: pangolinStakeConnectorName,
method: "depositLpStake",
args: [
0,
lpAmount,
0,
0
]
}
];
await expect(
dsaWallet0.connect(wallet0).cast(
...encodeSpells(spells),
wallet1.address
)
).to.be.revertedWith("Invalid LP token balance");
});
});
describe("claimLpRewards function", function () {
it("Check if success in claimLpRewards", async function () {
// Increase Time in 20 seconds
await hre.network.provider.send("evm_increaseTime", [20]);
// Mine new block
await hre.network.provider.send("evm_mine");
const spells = [
{
connector: pangolinStakeConnectorName,
method: "claimLpRewards",
args: [0]
}
];
await expect(
dsaWallet0.connect(wallet0).cast(
...encodeSpells(spells),
wallet1.address
)
).to.be.not.reverted;
// Checks if the wallet has more than 100 PNG
const balance = await PNG.balanceOf(dsaWallet0.address);
expect(balance).to.be.gt(0);
});
});
describe("withdrawLpStake function", function () {
it("Check if withdrawLpStake function reverts by: Invalid amount, amount greater than balance of staking", async function () {
const amount = lpAmount.mul(2);
const spells = [
{
connector: pangolinStakeConnectorName,
method: "withdrawLpStake",
args: [
0,
amount,
0,
0
]
}
];
await expect(
dsaWallet0.connect(wallet0).cast(
...encodeSpells(spells),
wallet1.address
)
).to.be.revertedWith("Invalid amount, amount greater than balance of staking");
});
it("Check if success in withdrawLpStake", async function () {
const spells = [
{
connector: pangolinStakeConnectorName,
method: "withdrawLpStake",
args: [
0,
lpAmount.div(2),
0,
0
]
}
];
await expect(
dsaWallet0.connect(wallet0).cast(
...encodeSpells(spells),
wallet1.address
)
).to.be.not.reverted;
// Check if PNG/AVAX LP is equal 0
const balance = await pangolinLPToken.balanceOf(dsaWallet0.address);
expect(balance).to.be.eq(lpAmount.div(2));
});
});
describe("withdrawAndClaimLpRewards function", function () {
it("Check if withdrawAndClaimLpRewards function reverts by: Invalid amount, amount greater than balance of staking", async function () {
const amount = lpAmount.mul(2);
const spells = [
{
connector: pangolinStakeConnectorName,
method: "withdrawAndClaimLpRewards",
args: [
0,
amount,
0,
0
]
}
];
await expect(
dsaWallet0.connect(wallet0).cast(
...encodeSpells(spells),
wallet1.address
)
).to.be.revertedWith("Invalid amount, amount greater than balance of staking");
});
it("Check if success in withdrawAndClaimLpRewards", async function () {
let balance = await pangolinLPToken.balanceOf(dsaWallet0.address);
const png_balance = await PNG.balanceOf(dsaWallet0.address);
const amount = lpAmount.sub(balance)
const spells = [
{
connector: pangolinStakeConnectorName,
method: "withdrawAndClaimLpRewards",
args: [
0,
amount,
0,
0
]
}
];
await expect(
dsaWallet0.connect(wallet0).cast(
...encodeSpells(spells),
wallet1.address
)
).to.be.not.reverted;
// Check if PNG/AVAX LP is equal 0
balance = await pangolinLPToken.balanceOf(dsaWallet0.address);
expect(balance).to.be.eq(lpAmount);
const new_png_balance = await PNG.balanceOf(dsaWallet0.address);
expect(new_png_balance).to.be.gt(png_balance);
});
});
describe("emergencyWithdrawLpStake function", function () {
// Deposit LP again
before(async () => {
const spells = [
{
connector: pangolinStakeConnectorName,
method: "depositLpStake",
args: [
0,
lpAmount,
0,
0
]
}
];
await dsaWallet0.connect(wallet0).cast(
...encodeSpells(spells),
wallet1.address
)
});
it("Check if success in emergencyWithdrawLpStake", async function () {
let balance = await pangolinLPToken.balanceOf(dsaWallet0.address);
const amount = lpAmount.sub(balance)
const spells = [
{
connector: pangolinStakeConnectorName,
method: "emergencyWithdrawLpStake",
args: [0]
}
];
await expect(
dsaWallet0.connect(wallet0).cast(
...encodeSpells(spells),
wallet1.address
)
).to.be.not.reverted;
// Check if PNG/AVAX LP is equal 0
balance = await pangolinLPToken.balanceOf(dsaWallet0.address);
expect(balance).to.be.eq(lpAmount);
});
});
});
describe("Pangolin Staking - Single Stake Test (PNG)", function () {
let pngToken: Contract;
let stakingContract: Contract;
let stakingBalance: BigNumber;
before(async () => {
const amount = ethers.utils.parseEther("100"); // 100 PNG
const int_slippage = 0.03
const PangolinRouterABI = [
"function getAmountsOut(uint amountIn, address[] calldata path) external view returns (uint[] memory amounts)"
];
// Get amount of AVAX for 200 PNG from Pangolin
const PangolinRouter = await ethers.getContractAt(
PangolinRouterABI,
"0xE54Ca86531e17Ef3616d22Ca28b0D458b6C89106"
);
const amounts = await PangolinRouter.getAmountsOut(
amount,
[
PNG_ADDRESS,
WAVAX_ADDRESS
]
);
const amtA = amounts[0];
const amtB = amounts[1];
const unitAmt = (amtB * (1 + int_slippage)) / amtA;
const unitAmount = ethers.utils.parseEther(unitAmt.toString());
const spells = [
{
connector: pangolinConnectorName,
method: "buy",
args: [
PNG_ADDRESS,
"0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee",
amount,
unitAmount,
0,
0
]
}
];
// Run spell transaction
const tx = await dsaWallet0.connect(wallet0).cast(
...encodeSpells(spells), wallet1.address
);
const receipt = await tx.wait();
pngToken = await ethers.getContractAt(abis.basic.erc20, PNG_ADDRESS);
stakingContract = await ethers.getContractAt(abis.basic.erc20, PNG_STAKING_ADDRESS);
});
it("Check if has 100 PNG", async function () {
const amount = ethers.utils.parseEther("100");
const pngBalance = await pngToken.balanceOf(dsaWallet0.address);
expect(pngBalance, `PNG Token is equal 100`).to.be.gt(amount.toString());
});
it("Check if some functions reverts by: Invalid amount, amount cannot be 0", async function () {
const amount = 0;
const getId = 0;
const setId = 0;
let spells = [
{
connector: pangolinStakeConnectorName,
method: "depositPNGStake",
args: [
PNG_STAKING_ADDRESS,
amount,
getId,
setId
]
}
];
await expect(
dsaWallet0.connect(wallet0).cast(
...encodeSpells(spells),
wallet1.address
)
).to.be.revertedWith("Invalid amount, amount cannot be 0");
spells[0].method = "withdrawPNGStake"
await expect(
dsaWallet0.connect(wallet0).cast(
...encodeSpells(spells),
wallet1.address
)
).to.be.revertedWith("Invalid amount, amount cannot be 0");
});
describe("depositPNGStake function", function () {
it("Check if reverts by: Invalid amount, amount greater than balance of PNG", async function () {
const amount = ethers.utils.parseEther("200")
let spells = [
{
connector: pangolinStakeConnectorName,
method: "depositPNGStake",
args: [
PNG_STAKING_ADDRESS,
amount,
0,
0
]
}
];
await expect(
dsaWallet0.connect(wallet0).cast(
...encodeSpells(spells),
wallet1.address
)
).to.be.revertedWith("Invalid amount, amount greater than balance of PNG");
});
it("Check if success in depositPNGStake", async function () {
const amount = await pngToken.balanceOf(dsaWallet0.address);
let spells = [
{
connector: pangolinStakeConnectorName,
method: "depositPNGStake",
args: [
PNG_STAKING_ADDRESS,
amount,
0,
0
]
}
];
await expect(
dsaWallet0.connect(wallet0).cast(
...encodeSpells(spells),
wallet1.address
)
).to.be.not.reverted;
const new_png_balance = await pngToken.balanceOf(dsaWallet0.address);
expect(new_png_balance).to.be.eq(0);
const staking_balance = await stakingContract.balanceOf(dsaWallet0.address);
expect(staking_balance).to.be.gt(0);
stakingBalance = staking_balance
});
it("Check if reverts by: Invalid PNG balance", async function () {
const amount = ethers.utils.parseEther("100")
let spells = [
{
connector: pangolinStakeConnectorName,
method: "depositPNGStake",
args: [
PNG_STAKING_ADDRESS,
amount,
0,
0
]
}
];
await expect(
dsaWallet0.connect(wallet0).cast(
...encodeSpells(spells),
wallet1.address
)
).to.be.revertedWith("Invalid PNG balance");
});
});
describe("withdrawPNGStake function", function () {
it("Check if reverts by: Invalid amount, amount greater than balance of staking", async function () {
const amount = ethers.utils.parseEther("200")
let spells = [
{
connector: pangolinStakeConnectorName,
method: "withdrawPNGStake",
args: [
PNG_STAKING_ADDRESS,
amount,
0,
0
]
}
];
await expect(
dsaWallet0.connect(wallet0).cast(
...encodeSpells(spells),
wallet1.address
)
).to.be.revertedWith("Invalid amount, amount greater than balance of staking");
});
it("Check if success in withdrawPNGStake", async function () {
const amount = ethers.utils.parseEther("50");
let spells = [
{
connector: pangolinStakeConnectorName,
method: "withdrawPNGStake",
args: [
PNG_STAKING_ADDRESS,
amount,
0,
0
]
}
];
await expect(
dsaWallet0.connect(wallet0).cast(
...encodeSpells(spells),
wallet1.address
)
).to.be.not.reverted;
const balance = await pngToken.balanceOf(dsaWallet0.address);
expect(balance).to.be.eq(amount);
});
});
describe("claimPNGStakeReward function", function () {
it("Check if success in claimPNGStakeReward", async function () {
// Increase Time in 20 seconds
await hre.network.provider.send("evm_increaseTime", [20]);
// Mine new block
await hre.network.provider.send("evm_mine");
const amount = ethers.utils.parseEther("50");
let spells = [
{
connector: pangolinStakeConnectorName,
method: "claimPNGStakeReward",
args: [PNG_STAKING_ADDRESS]
}
];
await expect(
dsaWallet0.connect(wallet0).cast(
...encodeSpells(spells),
wallet1.address
)
).to.be.not.reverted;
const balance = await pngToken.balanceOf(dsaWallet0.address);
expect(balance).to.be.gt(amount);
});
it("Check if reverts by: No rewards to claim", async function () {
let spells = [
{
connector: pangolinStakeConnectorName,
method: "claimPNGStakeReward",
args: [PNG_STAKING_ADDRESS]
}
];
await expect(
dsaWallet0.connect(wallet0).cast(
...encodeSpells(spells),
wallet1.address
)
).to.be.revertedWith("No rewards to claim");
});
});
describe("exitPNGStake function", function () {
it("Check if success in exitPNGStake", async function () {
let spells = [
{
connector: pangolinStakeConnectorName,
method: "exitPNGStake",
args: [PNG_STAKING_ADDRESS]
}
];
await expect(
dsaWallet0.connect(wallet0).cast(
...encodeSpells(spells),
wallet1.address
)
).to.be.not.reverted;
const balance = await stakingContract.balanceOf(dsaWallet0.address);
expect(balance).to.be.eq(0);
});
it("Check if reverts by: No balance to exit", async function () {
let spells = [
{
connector: pangolinStakeConnectorName,
method: "exitPNGStake",
args: [PNG_STAKING_ADDRESS]
}
];
await expect(
dsaWallet0.connect(wallet0).cast(
...encodeSpells(spells),
wallet1.address
)
).to.be.revertedWith("No balance to exit");
});
});
});
});

View File

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

View File

@ -0,0 +1,188 @@
import hre from "hardhat";
import axios from "axios";
import { expect } from "chai";
const { ethers } = hre; //check
import { BigNumber } from "bignumber.js";
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 { addresses } from "../../../scripts/tests/avalanche/addresses";
import { abis } from "../../../scripts/constant/abis";
import { ConnectV2SwapAggregatorAvalanche__factory } from "../../../typechain";
import er20abi from "../../../scripts/constant/abi/basics/erc20.json";
import type { Signer, Contract } from "ethers";
describe("Swap | Avalanche", function () {
const connectorName = "swap-test";
let dsaWallet0: Contract;
let wallet0: Signer, wallet1: Signer;
let masterSigner: Signer;
let instaConnectorsV2: Contract;
let connector: Contract;
before(async () => {
await hre.network.provider.request({
method: "hardhat_reset",
params: [
{
forking: {
// @ts-ignore
jsonRpcUrl: hre.config.networks.hardhat.forking.url
}
}
]
});
[wallet0, wallet1] = await ethers.getSigners();
masterSigner = await getMasterSigner();
instaConnectorsV2 = await ethers.getContractAt(abis.core.connectorsV2, addresses.core.connectorsV2);
connector = await deployAndEnableConnector({
connectorName,
contractArtifact: ConnectV2SwapAggregatorAvalanche__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(await wallet0.getAddress());
console.log(dsaWallet0.address);
expect(!!dsaWallet0.address).to.be.true;
});
it("Deposit matic 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"));
});
});
describe("Main", function () {
it("should swap the tokens", async function () {
let buyTokenAmountZeroX: any;
let unitAmount1Inch: any;
let calldata1Inch: any;
// let buyTokenAmount1Inch: any;
let buyTokenAmountParaswap: any;
async function getArg() {
// const slippage = 0.5;
/* avax -> usdt */
const sellTokenAddress = "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE"; // matic, decimals 18
const sellTokenDecimals = 18;
const buyTokenAddress = "0xd586E7F844cEa2F87f50152665BCbc2C279D8d70"; // USDT, decimals 6
const buyTokenDecimals = 18;
const amount = 1;
const srcAmount = new BigNumber(amount).times(new BigNumber(10).pow(sellTokenDecimals)).toFixed(0);
let zeroXUrl = `https://avalanche.api.0x.org/swap/v1/quote`;
let paraswapUrl1 = `https://apiv5.paraswap.io/prices/`;
let paraswapUrl2 = `https://apiv5.paraswap.io/transactions/43114?ignoreChecks=true`;
//paraswap
let paramsPara = {
srcToken: sellTokenAddress,
destToken: buyTokenAddress,
srcDecimals: sellTokenDecimals,
destDecimals: buyTokenDecimals,
amount: srcAmount,
side: "SELL",
network: 43114
};
const priceRoute = (await axios.get(paraswapUrl1, { params: paramsPara })).data.priceRoute;
buyTokenAmountParaswap = priceRoute.destAmount;
let minAmount = new BigNumber(priceRoute.destAmount).times((100 - 1) / 100).toFixed(0);
let txConfig = {
priceRoute: priceRoute,
srcToken: sellTokenAddress,
destToken: buyTokenAddress,
srcDecimals: sellTokenDecimals,
destDecimals: buyTokenDecimals,
srcAmount: srcAmount,
destAmount: minAmount,
userAddress: dsaWallet0.address
};
const calldataPara = (await axios.post(paraswapUrl2, txConfig)).data.data;
// zeroX
const paramsZeroX = {
buyToken: buyTokenAddress,
sellToken: sellTokenAddress,
sellAmount: "1000000000000000000" // Always denominated in wei
};
const responseZeroX = await axios.get(zeroXUrl, { params: paramsZeroX }).then((data: any) => data);
buyTokenAmountZeroX = responseZeroX.data.buyAmount;
const calldataZeroX = responseZeroX.data.data;
let calculateUnitAmt = (buyAmount: any) => {
const buyTokenAmountRes = new BigNumber(buyAmount)
.dividedBy(new BigNumber(10).pow(buyTokenDecimals))
.toFixed(8);
let unitAmt: any = new BigNumber(buyTokenAmountRes).dividedBy(new BigNumber(amount));
unitAmt = unitAmt.multipliedBy((100 - 1) / 100);
unitAmt = unitAmt.multipliedBy(1e18).toFixed(0);
return unitAmt;
};
let unitAmt0x = calculateUnitAmt(buyTokenAmountZeroX);
let unitAmtParaswap = calculateUnitAmt(buyTokenAmountParaswap);
function getCallData(connector: string, unitAmt: any, callData: any) {
var abi = [
"function swap(address,address,uint256,uint256,bytes,uint256)",
"function sell(address,address,uint256,uint256,bytes,uint256)"
];
var iface = new ethers.utils.Interface(abi);
const spell = connector === "1INCH-A" ? "sell" : "swap";
let data = iface.encodeFunctionData(spell, [buyTokenAddress, sellTokenAddress, srcAmount, unitAmt, callData, 0]);
return data;
}
let dataPara = ethers.utils.hexlify(await getCallData("PARASWAP-A", unitAmtParaswap, calldataPara));
let dataZeroX = ethers.utils.hexlify(await getCallData("ZEROX-A", unitAmt0x, calldataZeroX));
let datas = [dataPara, dataZeroX];
let connectors = ["PARASWAP-A", "ZEROX-A"];
return [connectors, datas];
}
let arg = await getArg();
const spells = [
{
connector: connectorName,
method: "swap",
args: arg
}
];
const tx = await dsaWallet0.connect(wallet0).cast(...encodeSpells(spells), await wallet1.getAddress());
const receipt = await tx.wait();
const usdtToken = await ethers.getContractAt(
er20abi,
"0xd586E7F844cEa2F87f50152665BCbc2C279D8d70" // usdt address
);
expect(await usdtToken.balanceOf(dsaWallet0.address)).to.be.gte(buyTokenAmountParaswap);
expect(await ethers.provider.getBalance(dsaWallet0.address)).to.be.lte(ethers.utils.parseEther("9"));
});
});
});

264
test/fantom/aave/v3-test.ts Normal file
View File

@ -0,0 +1,264 @@
import { expect, should } from "chai";
import hre, { ethers, waffle } from "hardhat";
import type { Signer, Contract } from "ethers";
import { BigNumber } from "bignumber.js";
import { buildDSAv2 } from "../../../scripts/tests/buildDSAv2";
import { addresses } from "../../../scripts/tests/fantom/addresses";
import { deployAndEnableConnector } from "../../../scripts/tests/deployAndEnableConnector";
import { abis } from "../../../scripts/constant/abis";
import { getMasterSigner } from "../../../scripts/tests/getMasterSigner";
import { parseEther, parseUnits } from "ethers/lib/utils";
import { encodeSpells } from "../../../scripts/tests/encodeSpells";
import { ConnectV2AaveV3Fantom__factory, IERC20__factory } from "../../../typechain";
const ABI = ["function balanceOf(address account) public view returns (uint256)"];
const aDaiAddress = "0x82E64f49Ed5EC1bC6e43DAD4FC8Af9bb3A2312EE";
const aaveAddress = "0x69FA688f1Dc47d4B5d8029D5a35FB7a548310654";
let account = "0x1c664Bafc646510684Ba1588798c67fe22a8c7cf";
const DAI = "0x8D11eC38a3EB5E956B052f67Da8Bdc9bef8Abf3E";
const USDC = "0x04068DA6C83AFCFA0e13ba15A6696662335D5B75";
const mnemonic = "test test test test test test test test test test test junk";
const connectorName = "AAVE-V3-X";
let signer: any, wallet0: any;
const aaveAbi = [
{
inputs: [
{ internalType: "address", name: "asset", type: "address" },
{ internalType: "address", name: "user", type: "address" }
],
name: "getUserReserveData",
outputs: [
{ internalType: "uint256", name: "currentATokenBalance", type: "uint256" },
{ internalType: "uint256", name: "currentStableDebt", type: "uint256" },
{ internalType: "uint256", name: "currentVariableDebt", type: "uint256" },
{ internalType: "uint256", name: "principalStableDebt", type: "uint256" },
{ internalType: "uint256", name: "scaledVariableDebt", type: "uint256" },
{ internalType: "uint256", name: "stableBorrowRate", type: "uint256" },
{ internalType: "uint256", name: "liquidityRate", type: "uint256" },
{ internalType: "uint40", name: "stableRateLastUpdated", type: "uint40" },
{ internalType: "bool", name: "usageAsCollateralEnabled", type: "bool" }
],
stateMutability: "view",
type: "function"
}
];
const erc20Abi = [
{
constant: false,
inputs: [
{
name: "_spender",
type: "address"
},
{
name: "_value",
type: "uint256"
}
],
name: "approve",
outputs: [
{
name: "",
type: "bool"
}
],
payable: false,
stateMutability: "nonpayable",
type: "function"
},
{
constant: true,
inputs: [],
name: "totalSupply",
outputs: [
{
name: "",
type: "uint256"
}
],
payable: false,
stateMutability: "view",
type: "function"
},
{
constant: true,
inputs: [
{
name: "_owner",
type: "address"
}
],
name: "balanceOf",
outputs: [
{
name: "balance",
type: "uint256"
}
],
payable: false,
stateMutability: "view",
type: "function"
},
{
constant: false,
inputs: [
{
name: "_to",
type: "address"
},
{
name: "_value",
type: "uint256"
}
],
name: "transfer",
outputs: [
{
name: "",
type: "bool"
}
],
payable: false,
stateMutability: "nonpayable",
type: "function"
}
];
const token = new ethers.Contract(DAI, erc20Abi);
const aDai = new ethers.Contract(aDaiAddress, ABI);
const usdcToken = new ethers.Contract(USDC, erc20Abi);
const aave = new ethers.Contract(aaveAddress, aaveAbi);
describe("Aave v3 Position for Fantom", function () {
let dsaWallet0: any;
let masterSigner: Signer;
let instaConnectorsV2: Contract;
let connector: any;
const wallet = ethers.Wallet.fromMnemonic(mnemonic);
before(async () => {
await hre.network.provider.request({
method: "hardhat_reset",
params: [
{
forking: {
//@ts-ignore
jsonRpcUrl: hre.config.networks.hardhat.forking.url,
blockNumber: 40790000
}
}
]
});
masterSigner = await getMasterSigner();
[wallet0] = await ethers.getSigners();
await hre.network.provider.send("hardhat_setBalance", [account, ethers.utils.parseEther("10").toHexString()]);
await hre.network.provider.request({
method: "hardhat_impersonateAccount",
params: [account]
});
signer = await ethers.getSigner(account);
await token.connect(signer).transfer(wallet0.address, ethers.utils.parseEther("10"));
instaConnectorsV2 = await ethers.getContractAt(abis.core.connectorsV2, addresses.core.connectorsV2);
connector = await deployAndEnableConnector({
connectorName,
contractArtifact: ConnectV2AaveV3Fantom__factory,
signer: masterSigner,
connectors: instaConnectorsV2
});
});
describe("Deployment", async () => {
it("Should set correct name", async () => {
expect(await connector.name()).to.eq("AaveV3-v1.2");
});
});
describe("DSA wallet setup", async () => {
it("Should build DSA v2", async () => {
dsaWallet0 = await buildDSAv2(wallet0.address);
expect(!!dsaWallet0.address).to.be.true;
});
it("Deposit ETH into DSA wallet", async function () {
await wallet0.sendTransaction({
to: dsaWallet0.address,
value: ethers.utils.parseEther("5")
});
expect(await ethers.provider.getBalance(dsaWallet0.address)).to.be.gte(ethers.utils.parseEther("5"));
});
});
describe("check user AAVE position", async () => {
it("Should create DSA Aave v3 position of DAI(collateral) and USDC(debt)", async () => {
await token.connect(signer).transfer(dsaWallet0.address, ethers.utils.parseEther("10"));
const spells = [
//deposit DAI in aave
{
connector: connectorName,
method: "deposit",
args: [DAI, parseEther("10"), 0, 0]
},
//borrow USDC from aave
{
connector: connectorName,
method: "borrow",
args: [USDC, parseUnits("3", 6), 2, 0, 0]
}
];
const tx = await dsaWallet0.connect(wallet0).cast(...encodeSpells(spells), wallet0.address);
const receipt = await tx.wait();
});
it("Should check position of dsa", async () => {
expect(await aDai.connect(wallet0).balanceOf(dsaWallet0.address)).to.be.gte(
new BigNumber(10).multipliedBy(1e18).toString()
);
expect(await usdcToken.connect(wallet0).balanceOf(dsaWallet0.address)).to.be.gte(
new BigNumber(3).multipliedBy(1e6).toString()
);
expect((await aave.connect(wallet0).getUserReserveData(USDC, dsaWallet0.address)).currentStableDebt).to.be.equal(0);
expect((await aave.connect(wallet0).getUserReserveData(USDC, dsaWallet0.address)).currentVariableDebt).to.be.gte(
new BigNumber(3).multipliedBy(1e6).toString()
);
});
it("Should swap borrowRateMode", async () => {
const spells = [
//deposit DAI in aave
{
connector: connectorName,
method: "swapBorrowRateMode",
args: [USDC, 2]
}
];
const tx = await dsaWallet0.connect(wallet0).cast(...encodeSpells(spells), wallet0.address);
const receipt = await tx.wait();
});
it("Should check position of dsa", async () => {
expect(await aDai.connect(wallet0).balanceOf(dsaWallet0.address)).to.be.gte(
new BigNumber(10).multipliedBy(1e18).toString()
);
expect(await usdcToken.connect(wallet0).balanceOf(dsaWallet0.address)).to.be.gte(
new BigNumber(3).multipliedBy(1e6).toString()
);
expect((await aave.connect(wallet0).getUserReserveData(USDC, dsaWallet0.address)).currentVariableDebt).to.be.equal(0);
expect((await aave.connect(wallet0).getUserReserveData(USDC, dsaWallet0.address)).currentStableDebt).to.be.gte(
new BigNumber(3).multipliedBy(1e6).toString()
);
});
});
});

View File

@ -0,0 +1,182 @@
import hre from "hardhat";
import axios from "axios";
import { expect } from "chai";
const { ethers } = hre; //check
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 { addresses } from "../../../scripts/tests/fantom/addresses";
import { abis } from "../../../scripts/constant/abis";
import { ConnectV2DSASpellFantom__factory } from "../../../typechain";
import type { Signer, Contract } from "ethers";
import BigNumber from "bignumber.js";
describe("DSA Spell", function () {
const connectorName = "dsa-spell-test";
let dsaWallet0: any;
let dsaWallet1: any;
let dsaWallet2: any;
let walletB: any;
let wallet0: any;
let masterSigner: Signer;
let instaConnectorsV2: Contract;
let connector: any;
before(async () => {
await hre.network.provider.request({
method: "hardhat_reset",
params: [
{
forking: {
// @ts-ignore
jsonRpcUrl: hre.config.networks.hardhat.forking.url
}
}
]
});
[wallet0] = await ethers.getSigners();
masterSigner = await getMasterSigner();
instaConnectorsV2 = await ethers.getContractAt(abis.core.connectorsV2, addresses.core.connectorsV2);
connector = await deployAndEnableConnector({
connectorName,
contractArtifact: ConnectV2DSASpellFantom__factory,
signer: masterSigner,
connectors: instaConnectorsV2
});
console.log("\tConnector 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;
walletB = await ethers.getSigner(dsaWallet0.address);
dsaWallet1 = await buildDSAv2(dsaWallet0.address);
expect(!!dsaWallet1.address).to.be.true;
console.log(`\t${dsaWallet1.address}`);
dsaWallet2 = await buildDSAv2(wallet0.address);
expect(!!dsaWallet2.address).to.be.true;
});
it("Deposit ftm into DSA wallet 0", 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 ftm into DSA wallet 1", async function () {
await wallet0.sendTransaction({
to: dsaWallet1.address,
value: ethers.utils.parseEther("10")
});
expect(await ethers.provider.getBalance(dsaWallet1.address)).to.be.gte(ethers.utils.parseEther("10"));
});
});
describe("Main", function () {
let FTM = "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE";
let aFTM = "0x6d80113e533a2C0fe82EaBD35f1875DcEA89Ea97";
let USDC = "0x04068DA6C83AFCFA0e13ba15A6696662335D5B75";
let usdc = new ethers.Contract(USDC, abis.basic.erc20);
let aFtm = new ethers.Contract(aFTM, abis.basic.aToken);
var abi = [
"function withdraw(address,uint256,address,uint256,uint256)",
"function deposit(address,uint256,uint256,uint256)",
"function borrow(address,uint256,uint256,uint256,uint256)"
];
function getCallData(spell: string, params: any) {
var iface = new ethers.utils.Interface(abi);
let data = iface.encodeFunctionData(spell, params);
return ethers.utils.hexlify(data);
}
it("should cast spells", async function () {
async function getArg(connectors: any, spells: any, params: any) {
let datas = [];
for (let i = 0; i < connectors.length; i++) {
datas.push(getCallData(spells[i], params[i]));
}
return [dsaWallet1.address, connectors, datas];
}
let connectors = ["BASIC-A", "AAVE-V3-A", "AAVE-V3-A"];
let methods = ["withdraw", "deposit", "borrow"];
let params = [
[FTM, ethers.utils.parseEther("2"), dsaWallet0.address, 0, 0],
[FTM, ethers.constants.MaxUint256, 0, 0],
[USDC, ethers.utils.parseUnits("1", 5), 2, 0, 0]
];
let arg = await getArg(connectors, methods, params);
const spells = [
{
connector: connectorName,
method: "castOnDSA",
args: arg
}
];
const tx = await dsaWallet0.connect(wallet0).cast(...encodeSpells(spells), await wallet0.getAddress());
const receipt = await tx.wait();
});
it("should check balances after cast on DSA", async function () {
expect(await ethers.provider.getBalance(dsaWallet1.address)).to.be.lte(0);
expect(await usdc.connect(wallet0).balanceOf(dsaWallet1.address)).to.be.gte(
new BigNumber(1).multipliedBy(1e5).toString()
);
expect(await ethers.provider.getBalance(dsaWallet0.address)).to.be.gte(
new BigNumber(12).multipliedBy(1e18).toString()
);
});
it("should cast spell on the first successful", async function () {
async function getArg(connectors: any, spells: any, params: any) {
let datas = [];
for (let i = 0; i < connectors.length; i++) {
datas.push(getCallData(spells[i], params[i]));
}
return [connectors, datas];
}
let connectors = ["AAVE-V3-A"];
let methods = ["deposit"];
let params = [
[FTM, ethers.utils.parseEther("10"), 0, 0]
];
let arg = await getArg(connectors, methods, params);
const spells = [
{
connector: connectorName,
method: "castAny",
args: arg
}
];
const tx = await dsaWallet0
.connect(wallet0)
.cast(...encodeSpells(spells), await wallet0.getAddress());
const receipt = await tx.wait();
});
it("should check balances after spells on DSA", async function () {
expect(await ethers.provider.getBalance(dsaWallet0.address)).to.be.lte(
new BigNumber(2).multipliedBy(1e18).toString()
);
expect(await aFtm.connect(wallet0).balanceOf(dsaWallet0.address)).to.be.gte(
new BigNumber(10).multipliedBy(1e18).toString()
);
});
});
});

View File

@ -0,0 +1,175 @@
import hre from "hardhat";
import axios from "axios";
import { expect } from "chai";
const { ethers } = hre; //check
import { BigNumber } from "bignumber.js";
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 { addresses } from "../../../scripts/tests/fantom/addresses";
import { abis } from "../../../scripts/constant/abis";
import { ConnectV2SwapAggregatorFantom__factory } from "../../../typechain";
import er20abi from "../../../scripts/constant/abi/basics/erc20.json";
import type { Signer, Contract } from "ethers";
describe("Swap | Fantom", function () {
const connectorName = "swap-test";
let dsaWallet0: Contract;
let wallet0: Signer, wallet1: Signer;
let masterSigner: Signer;
let instaConnectorsV2: Contract;
let connector: Contract;
before(async () => {
await hre.network.provider.request({
method: "hardhat_reset",
params: [
{
forking: {
// @ts-ignore
jsonRpcUrl: hre.config.networks.hardhat.forking.url
}
}
]
});
[wallet0, wallet1] = await ethers.getSigners();
masterSigner = await getMasterSigner();
instaConnectorsV2 = await ethers.getContractAt(abis.core.connectorsV2, addresses.core.connectorsV2);
connector = await deployAndEnableConnector({
connectorName,
contractArtifact: ConnectV2SwapAggregatorFantom__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(await wallet0.getAddress());
console.log(dsaWallet0.address);
expect(!!dsaWallet0.address).to.be.true;
});
it("Deposit fantom 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"));
});
});
describe("Main", function () {
it("should swap the tokens", async function () {
let buyTokenAmountParaswap: any;
async function getArg() {
const slippage = 0.5;
/* eth -> dai */
const sellTokenAddress = "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE"; // FTM, decimals 18
const sellTokenDecimals = 18;
const buyTokenAddress = "0x8D11eC38a3EB5E956B052f67Da8Bdc9bef8Abf3E"; // DAI, decimals 18
const buyTokenDecimals = 18;
const amount = 1;
const srcAmount = new BigNumber(amount).times(new BigNumber(10).pow(sellTokenDecimals)).toFixed(0);
let paraswapUrl1 = `https://apiv5.paraswap.io/prices/`;
let paraswapUrl2 = `https://apiv5.paraswap.io/transactions/250?ignoreChecks=true`;
//paraswap
let paramsPara = {
srcToken: sellTokenAddress,
destToken: buyTokenAddress,
srcDecimals: sellTokenDecimals,
destDecimals: buyTokenDecimals,
amount: srcAmount,
side: "SELL",
network: 250
};
const priceRoute = (await axios.get(paraswapUrl1, { params: paramsPara })).data.priceRoute;
buyTokenAmountParaswap = priceRoute.destAmount;
let minAmount = new BigNumber(priceRoute.destAmount).times((100 - 1) / 100).toFixed(0);
let txConfig = {
priceRoute: priceRoute,
srcToken: sellTokenAddress,
destToken: buyTokenAddress,
srcDecimals: sellTokenDecimals,
destDecimals: buyTokenDecimals,
srcAmount: srcAmount,
destAmount: minAmount,
userAddress: dsaWallet0.address
};
const calldataPara = (await axios.post(paraswapUrl2, txConfig)).data.data;
let calculateUnitAmt = (buyAmount: any) => {
const buyTokenAmountRes = new BigNumber(buyAmount)
.dividedBy(new BigNumber(10).pow(buyTokenDecimals))
.toFixed(8);
let unitAmt: any = new BigNumber(buyTokenAmountRes).dividedBy(new BigNumber(amount));
unitAmt = unitAmt.multipliedBy((100 - 1) / 100);
unitAmt = unitAmt.multipliedBy(1e18).toFixed(0);
return unitAmt;
};
let unitAmtParaswap = calculateUnitAmt(buyTokenAmountParaswap);
function getCallData(connector: string, unitAmt: any, callData: any) {
var abi = [
"function swap(address,address,uint256,uint256,bytes,uint256)",
"function sell(address,address,uint256,uint256,bytes,uint256)"
];
var iface = new ethers.utils.Interface(abi);
const spell = connector === "1INCH-A" ? "sell" : "swap";
let data = iface.encodeFunctionData(spell, [
buyTokenAddress,
sellTokenAddress,
srcAmount,
unitAmt,
callData,
0
]);
return data;
}
let dataPara = ethers.utils.hexlify(await getCallData("PARASWAP-A", unitAmtParaswap, calldataPara));
let datas = [dataPara];
let connectors = ["PARASWAP-A"];
return [connectors, datas];
}
let arg = await getArg();
const spells = [
{
connector: connectorName,
method: "swap",
args: arg
}
];
const tx = await dsaWallet0.connect(wallet0).cast(...encodeSpells(spells), await wallet1.getAddress());
const receipt = await tx.wait();
const daiToken = await ethers.getContractAt(
er20abi,
"0x8D11eC38a3EB5E956B052f67Da8Bdc9bef8Abf3E" // dai address
);
expect(await daiToken.balanceOf(dsaWallet0.address)).to.be.gte(buyTokenAmountParaswap);
expect(await ethers.provider.getBalance(dsaWallet0.address)).to.be.lte(ethers.utils.parseEther("9"));
});
});
});

View File

@ -0,0 +1,161 @@
import hre from "hardhat";
import axios from "axios";
import { expect } from "chai";
const { ethers } = hre; //check
import { BigNumber } from "bignumber.js";
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 { addresses } from "../../../scripts/tests/mainnet/addresses";
import { abis } from "../../../scripts/constant/abis";
import { ConnectV2ZeroEx, ConnectV2ZeroEx__factory } from "../../../typechain";
import er20abi from "../../../scripts/constant/abi/basics/erc20.json";
import type { Signer, Contract } from "ethers";
describe("ZeroEx", function() {
const connectorName = "zeroEx-test";
let dsaWallet0: Contract;
let wallet0: Signer, wallet1: Signer;
let masterSigner: Signer;
let instaConnectorsV2: Contract;
let connector: Contract;
before(async () => {
await hre.network.provider.request({
method: "hardhat_reset",
params: [
{
forking: {
// @ts-ignore
jsonRpcUrl: hre.config.networks.hardhat.forking.url,
},
},
],
});
[wallet0, wallet1] = await ethers.getSigners();
masterSigner = await getMasterSigner();
instaConnectorsV2 = await ethers.getContractAt(
abis.core.connectorsV2,
addresses.core.connectorsV2
);
connector = await deployAndEnableConnector({
connectorName,
contractArtifact: ConnectV2ZeroEx__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(await wallet0.getAddress());
expect(!!dsaWallet0.address).to.be.true;
});
it("Deposit ETH into DSA wallet", async function() {
await wallet0.sendTransaction({
to: dsaWallet0.address,
value: ethers.utils.parseEther("10"),
});
// console.log(dsaWallet0.address);
expect(await ethers.provider.getBalance(dsaWallet0.address)).to.be.gte(
ethers.utils.parseEther("10")
);
});
});
describe("Main", function() {
it("should swap the tokens", async function() {
let buyTokenAmount: any;
async function getArg() {
// const slippage = 0.5;
/* Eth -> dai */
const sellTokenAddress = "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE"; // eth, decimals 18
const sellTokenDecimals = 18;
const buyTokenAddress = "0x6b175474e89094c44da98b954eedeac495271d0f"; // dai, decimals 18
const buyTokenDecimals = 18;
const amount = 1;
const srcAmount = new BigNumber(amount)
.times(new BigNumber(10).pow(sellTokenDecimals))
.toFixed(0);
const fromAddress = dsaWallet0.address;
let url = `https://api.0x.org/swap/v1/quote`;
const params = {
buyToken: "DAI",
sellToken: "ETH",
sellAmount: "1000000000000000000", // Always denominated in wei
};
const response = await axios
.get(url, { params: params })
.then((data: any) => data);
buyTokenAmount = response.data.buyAmount;
const calldata = response.data.data;
let caculateUnitAmt = () => {
const buyTokenAmountRes = new BigNumber(buyTokenAmount)
.dividedBy(new BigNumber(10).pow(buyTokenDecimals))
.toFixed(8);
let unitAmt: any = new BigNumber(buyTokenAmountRes).dividedBy(
new BigNumber(amount)
);
unitAmt = unitAmt.multipliedBy((100 - 0.3) / 100);
unitAmt = unitAmt.multipliedBy(1e18).toFixed(0);
return unitAmt;
};
let unitAmt = caculateUnitAmt();
return [
buyTokenAddress,
sellTokenAddress,
srcAmount,
unitAmt,
calldata,
0,
];
}
let arg = await getArg();
const spells = [
{
connector: connectorName,
method: "swap",
args: arg,
},
];
const tx = await dsaWallet0
.connect(wallet0)
.cast(...encodeSpells(spells), await wallet1.getAddress());
const receipt = await tx.wait();
const daiToken = await ethers.getContractAt(
er20abi,
"0x6b175474e89094c44da98b954eedeac495271d0f" // dai address
);
expect(await daiToken.balanceOf(dsaWallet0.address)).to.be.gte(
buyTokenAmount
);
expect(await ethers.provider.getBalance(dsaWallet0.address)).to.be.lte(
ethers.utils.parseEther("9")
);
});
});
});

View File

@ -0,0 +1,168 @@
import hre from "hardhat";
import { expect } from "chai";
import { abis } from "../../../scripts/constant/abis";
import { addresses } from "../../../scripts/tests/mainnet/addresses";
import { deployAndEnableConnector } from "../../../scripts/tests/deployAndEnableConnector";
import { getMasterSigner } from "../../../scripts/tests/getMasterSigner";
import { buildDSAv2 } from "../../../scripts/tests/buildDSAv2";
import { ConnectV2AaveV1, ConnectV2AaveV1__factory } from "../../../typechain";
import { parseEther } from "@ethersproject/units";
import { encodeSpells } from "../../../scripts/tests/encodeSpells";
import { tokens } from "../../../scripts/tests/mainnet/tokens";
import { constants } from "../../../scripts/constant/constant";
import { addLiquidity } from "../../../scripts/tests/addLiquidity";
const { ethers } = hre;
import type { Signer, Contract } from "ethers";
describe("Aave V1", function () {
const connectorName = "AAVEV1-TEST-A";
let wallet0: Signer, wallet1: Signer;
let dsaWallet0: Contract;
let instaConnectorsV2: Contract;
let connector: any;
let masterSigner: Signer;
before(async () => {
try {
await hre.network.provider.request({
method: "hardhat_reset",
params: [
{
forking: {
// @ts-ignore
jsonRpcUrl: hre.config.networks.hardhat.forking.url,
blockNumber: 12796965,
},
},
],
});
[wallet0, wallet1] = await ethers.getSigners();
masterSigner = await getMasterSigner();
instaConnectorsV2 = await ethers.getContractAt(
abis.core.connectorsV2,
addresses.core.connectorsV2
);
connector = await deployAndEnableConnector({
connectorName,
contractArtifact: ConnectV2AaveV1__factory,
signer: masterSigner,
connectors: instaConnectorsV2,
});
console.log("Connector address", connector.address);
} catch (err) {
console.log("error", err);
}
});
it("should have contracts deployed", async () => {
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.getAddress());
expect(!!dsaWallet0.address).to.be.true;
});
it("Deposit ETH into DSA wallet", async function () {
await wallet0.sendTransaction({
to: dsaWallet0.address,
value: parseEther("10"),
});
expect(await ethers.provider.getBalance(dsaWallet0.address)).to.be.gte(
parseEther("10")
);
});
});
describe("Main", function () {
it("should deposit ETH in Aave V1", async function () {
const amt = parseEther("1");
const spells = [
{
connector: connectorName,
method: "deposit",
args: [tokens.eth.address, amt, 0, 0],
},
];
const tx = await dsaWallet0
.connect(wallet0)
.cast(...encodeSpells(spells), wallet1.getAddress());
await tx.wait();
expect(await ethers.provider.getBalance(dsaWallet0.address)).to.eq(
parseEther("9")
);
});
it("Should borrow and payback DAI from Aave V1", async function () {
const amt = parseEther("100"); // 100 DAI
// add a little amount of dai to cover any shortfalls
await addLiquidity("dai", dsaWallet0.address, parseEther("1"));
const spells = [
{
connector: connectorName,
method: "borrow",
args: [tokens.dai.address, amt, 0, 0],
},
{
connector: connectorName,
method: "payback",
// FIXME: we need to pass max_value because of roundoff/shortfall errors
args: [tokens.dai.address, constants.max_value, 0, 0],
},
];
const tx = await dsaWallet0
.connect(wallet0)
.cast(...encodeSpells(spells), wallet1.getAddress());
await tx.wait();
expect(await ethers.provider.getBalance(dsaWallet0.address)).to.be.lte(
ethers.utils.parseEther("9")
);
});
it("Should deposit all ETH in Aave V1", async function () {
const spells = [
{
connector: connectorName,
method: "deposit",
args: [tokens.eth.address, constants.max_value, 0, 0],
},
];
const tx = await dsaWallet0
.connect(wallet0)
.cast(...encodeSpells(spells), wallet1.getAddress());
await tx.wait();
expect(await ethers.provider.getBalance(dsaWallet0.address)).to.be.lte(
ethers.utils.parseEther("0")
);
});
it("Should withdraw all ETH from Aave V1", async function () {
const spells = [
{
connector: connectorName,
method: "withdraw",
args: [tokens.eth.address, constants.max_value, 0, 0],
},
];
const tx = await dsaWallet0
.connect(wallet0)
.cast(...encodeSpells(spells), wallet1.getAddress());
await tx.wait();
expect(await ethers.provider.getBalance(dsaWallet0.address)).to.be.gte(
ethers.utils.parseEther("10")
);
});
});
});

View File

@ -0,0 +1,226 @@
import { expect } from "chai";
import hre from "hardhat";
import { abis } from "../../../scripts/constant/abis";
import { addresses } from "../../../scripts/tests/mainnet/addresses";
import { deployAndEnableConnector } from "../../../scripts/tests/deployAndEnableConnector";
import { getMasterSigner } from "../../../scripts/tests/getMasterSigner";
import { buildDSAv2 } from "../../../scripts/tests/buildDSAv2";
import { ConnectV2AaveV2, ConnectV2AaveV2__factory } from "../../../typechain";
import { parseEther } from "@ethersproject/units";
import { encodeSpells } from "../../../scripts/tests/encodeSpells";
import { tokens } from "../../../scripts/tests/mainnet/tokens";
import { constants } from "../../../scripts/constant/constant";
import { addLiquidity } from "../../../scripts/tests/addLiquidity";
const { ethers } = hre;
import type { Signer, Contract } from "ethers";
describe("Aave V2", function () {
const connectorName = "AAVEV2-TEST-A";
let connector: any;
let wallet0: Signer, wallet1:Signer;
let dsaWallet0: any;
let instaConnectorsV2: Contract;
let masterSigner: Signer;
before(async () => {
await hre.network.provider.request({
method: "hardhat_reset",
params: [
{
forking: {
// @ts-ignore
jsonRpcUrl: hre.config.networks.hardhat.forking.url,
blockNumber: 12796965,
},
},
],
});
[wallet0, wallet1] = await ethers.getSigners();
masterSigner = await getMasterSigner();
instaConnectorsV2 = await ethers.getContractAt(
abis.core.connectorsV2,
addresses.core.connectorsV2
);
connector = await deployAndEnableConnector({
connectorName,
contractArtifact: ConnectV2AaveV2__factory,
signer: masterSigner,
connectors: instaConnectorsV2,
});
console.log("Connector address", connector.address);
});
it("should have contracts deployed", async () => {
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.getAddress());
expect(!!dsaWallet0.address).to.be.true;
});
it("Deposit ETH into DSA wallet", async function () {
await wallet0.sendTransaction({
to: dsaWallet0.address,
value: parseEther("10"),
});
expect(await ethers.provider.getBalance(dsaWallet0.address)).to.be.gte(
parseEther("10")
);
});
});
describe("Main", function () {
it("should deposit ETH in Aave V2", async function () {
const amt = parseEther("1");
const spells = [
{
connector: connectorName,
method: "deposit",
args: [tokens.eth.address, amt, 0, 0],
},
];
const tx = await dsaWallet0
.connect(wallet0)
.cast(...encodeSpells(spells), wallet1.getAddress());
await tx.wait();
expect(await ethers.provider.getBalance(dsaWallet0.address)).to.eq(
parseEther("9")
);
});
it("Should borrow and payback DAI from Aave V2", async function () {
const amt = parseEther("100"); // 100 DAI
const setId = "83478237";
const spells = [
{
connector: connectorName,
method: "borrow",
args: [tokens.dai.address, amt, 2, 0, setId],
},
{
connector: connectorName,
method: "payback",
args: [tokens.dai.address, amt, 2, setId, 0],
},
];
const tx = await dsaWallet0
.connect(wallet0)
.cast(...encodeSpells(spells), wallet1.getAddress());
await tx.wait();
expect(await ethers.provider.getBalance(dsaWallet0.address)).to.be.lte(
ethers.utils.parseEther("9")
);
});
it("Should borrow and payback half DAI from Aave V2", async function () {
const amt = parseEther("100"); // 100 DAI
// const setId = "83478237";
await addLiquidity("dai", dsaWallet0.address, parseEther("1"));
let spells = [
{
connector: connectorName,
method: "borrow",
args: [tokens.dai.address, amt, 2, 0, 0],
},
{
connector: connectorName,
method: "payback",
args: [tokens.dai.address, amt.div(2), 2, 0, 0],
},
];
let tx = await dsaWallet0
.connect(wallet0)
.cast(...encodeSpells(spells), wallet1.getAddress());
await tx.wait();
expect(await ethers.provider.getBalance(dsaWallet0.address)).to.be.lte(
ethers.utils.parseEther("9")
);
spells = [
{
connector: connectorName,
method: "payback",
args: [tokens.dai.address, constants.max_value, 2, 0, 0],
},
];
tx = await dsaWallet0
.connect(wallet0)
.cast(...encodeSpells(spells), wallet1.getAddress());
await tx.wait();
expect(await ethers.provider.getBalance(dsaWallet0.address)).to.be.lte(
ethers.utils.parseEther("9")
);
});
it("Should deposit all ETH in Aave V2", async function () {
const spells = [
{
connector: connectorName,
method: "deposit",
args: [tokens.eth.address, constants.max_value, 0, 0],
},
];
const tx = await dsaWallet0
.connect(wallet0)
.cast(...encodeSpells(spells), wallet1.getAddress());
await tx.wait();
expect(await ethers.provider.getBalance(dsaWallet0.address)).to.be.lte(
ethers.utils.parseEther("0")
);
});
it("Should withdraw all ETH from Aave V2", async function () {
const spells = [
{
connector: connectorName,
method: "withdraw",
args: [tokens.eth.address, constants.max_value, 0, 0],
},
];
const tx = await dsaWallet0
.connect(wallet0)
.cast(...encodeSpells(spells), wallet1.getAddress());
await tx.wait();
expect(await ethers.provider.getBalance(dsaWallet0.address)).to.be.gte(
ethers.utils.parseEther("10")
);
});
it("should deposit and withdraw", async () => {
const amt = parseEther("1"); // 1 eth
const setId = "834782373";
const spells = [
{
connector: connectorName,
method: "deposit",
args: [tokens.eth.address, amt, 0, setId],
},
{
connector: connectorName,
method: "withdraw",
args: [tokens.eth.address, amt, setId, 0],
},
];
const tx = await dsaWallet0
.connect(wallet0)
.cast(...encodeSpells(spells), wallet1.getAddress());
await tx.wait();
expect(await ethers.provider.getBalance(dsaWallet0.address)).to.be.gte(
ethers.utils.parseEther("10")
);
});
});
});

View File

@ -0,0 +1,138 @@
import { expect } from "chai";
import hre from "hardhat";
const { web3, deployments, waffle, ethers } = hre; //check
const { provider, deployContract } = 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 { addresses } from "../../../scripts/tests/mainnet/addresses";
import { abis } from "../../../scripts/constant/abis";
import { constants } from "../../../scripts/constant/constant";
import { ConnectV2BCompound__factory } from "../../../typechain";
import type { Signer, Contract } from "ethers";
describe("B.Compound", function () {
const connectorName = "B.COMPOUND-TEST-A"
let dsaWallet0: any;
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: 13300000,
},
},
],
});
masterSigner = await getMasterSigner()
instaConnectorsV2 = await ethers.getContractAt(abis.core.connectorsV2, addresses.core.connectorsV2);
connector = await deployAndEnableConnector({
connectorName,
contractArtifact: ConnectV2BCompound__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;
expect(await connector.name()).to.be.equal("B.Compound-v1.0");
});
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 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"));
});
});
describe("Main", function () {
it("Should deposit ETH in Compound", async function () {
const amount = ethers.utils.parseEther("1") // 1 ETH
const spells = [
{
connector: connectorName,
method: "deposit",
args: ["ETH-A", amount, 0, 0]
}
]
const tx = await dsaWallet0.connect(wallet0).cast(...encodeSpells(spells), wallet1.address)
const receipt = await tx.wait()
expect(await ethers.provider.getBalance(dsaWallet0.address)).to.be.lte(ethers.utils.parseEther("9"));
});
it("Should borrow and payback DAI from Compound", async function () {
const amount = ethers.utils.parseEther("100") // 100 DAI
const setId = "83478237"
const spells = [
{
connector: connectorName,
method: "borrow",
args: ["DAI-A", amount, 0, setId]
},
{
connector: connectorName,
method: "payback",
args: ["DAI-A", 0, setId, 0]
}
]
const tx = await dsaWallet0.connect(wallet0).cast(...encodeSpells(spells), wallet1.address)
const receipt = await tx.wait()
expect(await ethers.provider.getBalance(dsaWallet0.address)).to.be.lte(ethers.utils.parseEther("9"));
});
it("Should deposit all ETH in Compound", async function () {
const spells = [
{
connector: connectorName,
method: "deposit",
args: ["ETH-A", constants.max_value, 0, 0]
}
]
const tx = await dsaWallet0.connect(wallet0).cast(...encodeSpells(spells), wallet1.address)
const receipt = await tx.wait()
expect(await ethers.provider.getBalance(dsaWallet0.address)).to.be.lte(ethers.utils.parseEther("0"));
});
it("Should withdraw all ETH from Compound", async function () {
const spells = [
{
connector: connectorName,
method: "withdraw",
args: ["ETH-A", constants.max_value, 0, 0]
}
]
const tx = await dsaWallet0.connect(wallet0).cast(...encodeSpells(spells), wallet1.address)
const receipt = await tx.wait()
expect(await ethers.provider.getBalance(dsaWallet0.address)).to.be.gte(ethers.utils.parseEther("10"));
});
})
})

View File

@ -0,0 +1,189 @@
import { expect } from "chai";
import hre from "hardhat";
const { web3, deployments, waffle, ethers } = hre; //check
const { provider, deployContract } = 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 { abis } from "../../../scripts/constant/abis";
import { ConnectV2BLiquity__factory } from "../../../typechain";
import type { Signer, Contract } from "ethers";
import { addresses } from "../../../scripts/tests/mainnet/addresses";
const LUSD_WHALE = "0x66017D22b0f8556afDd19FC67041899Eb65a21bb" // stability pool
const BAMM_ADDRESS = "0x0d3AbAA7E088C2c82f54B2f47613DA438ea8C598"
describe("B.Liquity", function () {
const connectorName = "B.LIQUITY-TEST-A"
let dsaWallet0: any;
let dsaWallet1: any;
let masterSigner: Signer;
let instaConnectorsV2: Contract;
let connector: Contract;
let manager: Contract;
let vat: Contract;
let lusd: Contract;
let bammToken: Contract;
let stabilityPool: 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: 12996875,
},
},
],
});
masterSigner = await getMasterSigner()
instaConnectorsV2 = await ethers.getContractAt(abis.core.connectorsV2, addresses.core.connectorsV2);
connector = await deployAndEnableConnector({
connectorName,
contractArtifact: ConnectV2BLiquity__factory,
signer: masterSigner,
connectors: instaConnectorsV2
})
lusd = await ethers.getContractAt("../artifacts/contracts/mainnet/common/interfaces.sol:TokenInterface", "0x5f98805A4E8be255a32880FDeC7F6728C6568bA0")
bammToken = await ethers.getContractAt("../artifacts/contracts/mainnet/connectors/b.protocol/liquity/interface.sol:BAMMLike", BAMM_ADDRESS)
stabilityPool = await ethers.getContractAt("../artifacts/contracts/mainnet/connectors/b.protocol/liquity/interface.sol:StabilityPoolLike", "0x66017D22b0f8556afDd19FC67041899Eb65a21bb")
console.log("Connector address", connector.address)
})
it("test veryClose.", async function () {
expect(veryClose(1000001, 1000000)).to.be.true
expect(veryClose(1000000, 1000001)).to.be.true
expect(veryClose(1003000, 1000001)).to.be.false
expect(veryClose(1000001, 1000300)).to.be.false
});
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;
expect(await connector.name()).to.be.equal("B.Liquity-v1");
});
describe("DSA wallet setup", function () {
it("Should build DSA v2", async function () {
dsaWallet0 = await buildDSAv2(wallet0.address)
expect(!!dsaWallet0.address).to.be.true;
dsaWallet1 = await buildDSAv2(wallet1.address)
expect(!!dsaWallet1.address).to.be.true;
});
it("Deposit LUSD into DSA wallet", async function () {
await hre.network.provider.request({
method: "hardhat_impersonateAccount",
params: [LUSD_WHALE],
});
const signer = await hre.ethers.provider.getSigner(LUSD_WHALE);
await lusd.connect(signer).transfer(dsaWallet0.address, ethers.utils.parseEther("100000"))
expect(await lusd.balanceOf(dsaWallet0.address)).to.equal(ethers.utils.parseEther("100000"));
});
});
describe("Main", function () {
it("should deposit 10k LUSD", async function () {
const totalSupplyBefore = await bammToken.totalSupply();
const lusdBalanceBefore = await stabilityPool.getCompoundedLUSDDeposit(BAMM_ADDRESS);
const amount = ethers.utils.parseEther("10000");
const spells = [
{
connector: connectorName,
method: "deposit",
args: [amount, 0, 0, 0]
}
]
const tx = await dsaWallet0.connect(wallet0).cast(...encodeSpells(spells), wallet1.address)
const receipt = await tx.wait()
const expectedBalance = totalSupplyBefore.mul(amount).div(lusdBalanceBefore)
expect(veryClose(expectedBalance, await bammToken.balanceOf(dsaWallet0.address))).to.be.true
});
it("should deposit all LUSD", async function () {
const totalSupplyBefore = await bammToken.totalSupply();
const lusdBalanceBefore = await stabilityPool.getCompoundedLUSDDeposit(BAMM_ADDRESS);
const amount = web3.utils.toBN("2").pow(web3.utils.toBN("256")).sub(web3.utils.toBN("1"));
const balanceBefore = await bammToken.balanceOf(dsaWallet0.address)
const spells = [
{
connector: connectorName,
method: "deposit",
args: [amount, 0, 0, 0]
}
]
const tx = await dsaWallet0.connect(wallet0).cast(...encodeSpells(spells), wallet1.address)
const receipt = await tx.wait()
const expectedBalance = (totalSupplyBefore.mul(ethers.utils.parseEther("90000")).div(lusdBalanceBefore)).add(balanceBefore)
expect(veryClose(expectedBalance, await bammToken.balanceOf(dsaWallet0.address))).to.be.true
});
it("should withdraw half of the shares", async function () {
const balanceBefore = await bammToken.balanceOf(dsaWallet0.address)
const halfBalance = balanceBefore.div("2")
const spells = [
{
connector: connectorName,
method: "withdraw",
args: [halfBalance, 0, 0, 0]
}
]
const tx = await dsaWallet0.connect(wallet0).cast(...encodeSpells(spells), wallet1.address)
const receipt = await tx.wait()
expect(veryClose(halfBalance, await bammToken.balanceOf(dsaWallet0.address))).to.be.true
expect(veryClose(ethers.utils.parseEther("50000"), await lusd.balanceOf(dsaWallet0.address))).to.be.true
});
it("should withdraw all the shares", async function () {
const amount = web3.utils.toBN("2").pow(web3.utils.toBN("256")).sub(web3.utils.toBN("1"));
const spells = [
{
connector: connectorName,
method: "withdraw",
args: [amount, 0, 0, 0]
}
]
const tx = await dsaWallet0.connect(wallet0).cast(...encodeSpells(spells), wallet1.address)
const receipt = await tx.wait()
expect(veryClose(ethers.utils.parseEther("100000"), await lusd.balanceOf(dsaWallet0.address))).to.be.true
});
})
})
function veryClose(n1: any, n2: any) {
n1 = web3.utils.toBN(n1)
n2 = web3.utils.toBN(n2)
let _10000 = web3.utils.toBN(10000)
let _9999 = web3.utils.toBN(9999)
if (n1.mul(_10000).lt(n2.mul(_9999))) return false
if (n2.mul(_10000).lt(n1.mul(_9999))) return false
return true
}

View File

@ -0,0 +1,336 @@
import { expect } from "chai";
import hre from "hardhat";
const { web3, deployments, waffle, ethers } = hre;
const { provider, deployContract } = 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 { addresses } from "../../../scripts/tests/mainnet/addresses";
import { abis } from "../../../scripts/constant/abis";
import { tokens } from "../../../scripts/tests/mainnet/tokens";
import { ConnectV2BMakerDAO__factory } from "../../../typechain";
import type { Signer, Contract } from "ethers";
describe("B.Maker", function () {
const connectorName = "B.MAKER-TEST-A"
let dsaWallet0: any;
let dsaWallet1: any;
let masterSigner: Signer;
let instaConnectorsV2: Contract;
let connector: any;
let manager: any;
let vat: any;
let dai: any;
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: 12696000,
},
},
],
});
masterSigner = await getMasterSigner()
instaConnectorsV2 = await ethers.getContractAt(abis.core.connectorsV2, addresses.core.connectorsV2);
connector = await deployAndEnableConnector({
connectorName,
contractArtifact: ConnectV2BMakerDAO__factory,
signer: masterSigner,
connectors: instaConnectorsV2
})
manager = await ethers.getContractAt("BManagerLike", "0x3f30c2381CD8B917Dd96EB2f1A4F96D91324BBed")
vat = await ethers.getContractAt("../artifacts/contracts/mainnet/connectors/b.protocol/makerdao/interface.sol:VatLike", await manager.vat())
dai = await ethers.getContractAt("../artifacts/contracts/mainnet/common/interfaces.sol:TokenInterface", tokens.dai.address)
console.log("Connector address", connector.address)
})
it("test veryClose.", async function () {
expect(veryClose(1000001, 1000000)).to.be.true
expect(veryClose(1000000, 1000001)).to.be.true
expect(veryClose(1003000, 1000001)).to.be.false
expect(veryClose(1000001, 1000300)).to.be.false
});
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;
expect(await connector.name()).to.be.equal("B.MakerDAO-v1.0");
});
describe("DSA wallet setup", function () {
it("Should build DSA v2", async function () {
dsaWallet0 = await buildDSAv2(wallet0.address)
expect(!!dsaWallet0.address).to.be.true;
dsaWallet1 = await buildDSAv2(wallet1.address)
expect(!!dsaWallet1.address).to.be.true;
});
it("Deposit ETH 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 wallet1.sendTransaction({
to: dsaWallet1.address,
value: ethers.utils.parseEther("10")
});
expect(await ethers.provider.getBalance(dsaWallet1.address)).to.be.gte(ethers.utils.parseEther("10"));
});
});
describe("Main", function () {
let vault: any;
let ilk: any;
let urn: any;
it("Should open ETH-A vault Maker", async function () {
vault = Number(await manager.cdpi()) + 1
const spells = [
{
connector: connectorName,
method: "open",
args: ["ETH-A"]
}
]
const tx = await dsaWallet0.connect(wallet0).cast(...encodeSpells(spells), wallet1.address)
const receipt = await tx.wait()
expect(await manager.owns(vault)).to.be.equal(dsaWallet0.address)
ilk = await manager.ilks(vault)
expect(ilk).to.be.equal("0x4554482d41000000000000000000000000000000000000000000000000000000")
urn = await manager.urns(vault)
});
it("Should deposit", async function () {
const amount = ethers.utils.parseEther("7") // 7 ETH
const setId = "83478237"
const spells = [
{
connector: connectorName,
method: "deposit",
args: [vault, amount, 0, setId]
}
]
const tx = await dsaWallet0.connect(wallet0).cast(...encodeSpells(spells), wallet1.address)
const receipt = await tx.wait()
expect(await ethers.provider.getBalance(dsaWallet0.address)).to.be.gte(ethers.utils.parseEther("3"))
const urnData = await vat.urns(ilk, urn)
expect(urnData[0]).to.be.equal(amount) // ink
expect(urnData[1]).to.be.equal("0") // art
});
it("Should withdraw", async function () {
const amount = ethers.utils.parseEther("1") // 1 ETH
const setId = "83478237"
const spells = [
{
connector: connectorName,
method: "withdraw",
args: [vault, amount, 0, setId]
}
]
const tx = await dsaWallet0.connect(wallet0).cast(...encodeSpells(spells), wallet1.address)
const receipt = await tx.wait()
expect(await ethers.provider.getBalance(dsaWallet0.address)).to.be.gte(ethers.utils.parseEther("4"))
const urnData = await vat.urns(ilk, urn)
expect(urnData[0]).to.be.equal(ethers.utils.parseEther("6")) // ink
expect(urnData[1]).to.be.equal("0") // art
});
it("Should borrow", async function () {
const amount = ethers.utils.parseEther("6000") // 6000 dai
const setId = "83478237"
const spells = [
{
connector: connectorName,
method: "borrow",
args: [vault, amount, 0, setId]
}
]
const tx = await dsaWallet0.connect(wallet0).cast(...encodeSpells(spells), wallet1.address)
const receipt = await tx.wait()
const urnData = await vat.urns(ilk, urn)
expect(urnData[0]).to.be.equal(ethers.utils.parseEther("6")) // ink
expect(urnData[1]).to.be.equal(await daiToArt(vat, ilk, amount)) // art
expect(await dai.balanceOf(dsaWallet0.address)).to.be.equal(amount)
});
it("Should repay", async function () {
const amount = ethers.utils.parseEther("500") // 500 dai
const setId = "83478237"
const spells = [
{
connector: connectorName,
method: "payback",
args: [vault, amount, 0, setId]
}
]
const tx = await dsaWallet0.connect(wallet0).cast(...encodeSpells(spells), wallet1.address)
const receipt = await tx.wait()
const urnData = await vat.urns(ilk, urn)
expect(urnData[0]).to.be.equal(ethers.utils.parseEther("6")) // ink
expect(urnData[1]).to.be.equal(await daiToArt(vat, ilk, ethers.utils.parseEther("5500"))) // art
expect(await dai.balanceOf(dsaWallet0.address)).to.be.equal(ethers.utils.parseEther("5500"))
});
it("Should depositAndBorrow", async function () {
const borrowAmount = ethers.utils.parseEther("1000") // 1000 dai
const depositAmount = ethers.utils.parseEther("1") // 1 dai
const setId = "83478237"
const spells = [
{
connector: connectorName,
method: "depositAndBorrow",
args: [vault, depositAmount, borrowAmount, 0, 0, 0, 0]
}
]
const tx = await dsaWallet0.connect(wallet0).cast(...encodeSpells(spells), wallet1.address)
const receipt = await tx.wait()
const urnData = await vat.urns(ilk, urn)
expect(urnData[0]).to.be.equal(ethers.utils.parseEther("7")) // ink
expect(await dai.balanceOf(dsaWallet0.address)).to.be.equal(ethers.utils.parseEther("6500"))
// calculation is not precise as the jug was dripped
expect(veryClose(urnData[1], await daiToArt(vat, ilk, ethers.utils.parseEther("6500")))).to.be.true
expect(await ethers.provider.getBalance(dsaWallet0.address)).to.be.gte(ethers.utils.parseEther("1"))
});
it("Should close", async function () {
// open a new vault
const newVault = vault + 1
let spells = [
{
connector: connectorName,
method: "open",
args: ["ETH-A"]
}
]
let tx = await dsaWallet1.connect(wallet1).cast(...encodeSpells(spells), wallet1.address)
let receipt = await tx.wait()
expect(await manager.owns(newVault)).to.be.equal(dsaWallet1.address)
ilk = await manager.ilks(newVault)
expect(ilk).to.be.equal("0x4554482d41000000000000000000000000000000000000000000000000000000")
urn = await manager.urns(newVault)
// deposit and borrow
const borrowAmount = ethers.utils.parseEther("6000") // 6000 dai
const depositAmount = ethers.utils.parseEther("5") // 5 ETH
spells = [
{
connector: connectorName,
method: "depositAndBorrow",
args: [newVault, depositAmount, borrowAmount, 0, 0, 0, 0]
}
]
tx = await dsaWallet1.connect(wallet1).cast(...encodeSpells(spells), wallet1.address)
receipt = await tx.wait()
const setId = 0
// repay borrow
spells = [
{
connector: connectorName,
method: "payback",
args: [newVault, borrowAmount, 0, setId]
}
]
tx = await dsaWallet1.connect(wallet1).cast(...encodeSpells(spells), wallet1.address)
receipt = await tx.wait()
// withdraw deposit
spells = [
{
connector: connectorName,
method: "withdraw",
args: [newVault, depositAmount, 0, setId]
}
]
tx = await dsaWallet1.connect(wallet1).cast(...encodeSpells(spells), wallet1.address)
receipt = await tx.wait()
// close
spells = [
{
connector: connectorName,
method: "close",
args: [newVault]
}
]
tx = await dsaWallet1.connect(wallet1).cast(...encodeSpells(spells), wallet1.address)
receipt = await tx.wait()
expect(await manager.owns(newVault)).not.to.be.equal(dsaWallet1.address)
});
})
})
async function daiToArt(vat: any, ilk: any, dai: any) {
const ilks = await vat.ilks(ilk)
const rate = ilks[1] // second parameter
const _1e27 = ethers.utils.parseEther("1000000000") // 1e9 * 1e18
const art = dai.mul(_1e27).div(rate)
return art.add(1)
}
function veryClose(n1: any, n2: any) {
n1 = web3.utils.toBN(n1)
n2 = web3.utils.toBN(n2)
let _10000 = web3.utils.toBN(10000)
let _9999 = web3.utils.toBN(9999)
if (n1.mul(_10000).lt(n2.mul(_9999))) return false
if (n2.mul(_10000).lt(n1.mul(_9999))) return false
return true
}

View File

@ -0,0 +1,135 @@
import { expect } from "chai"
import hre from "hardhat"
const { web3, deployments, waffle, ethers } = hre;
const { provider, deployContract } = waffle
import { abi } from "../../../scripts/constant/abi/core/InstaImplementations.json"
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 { addresses } from "../../../scripts/tests/mainnet/addresses"
import { abis } from "../../../scripts/constant/abis"
import type { Signer, Contract } from "ethers";
import { ConnectV2BasicERC1155__factory, IERC1155__factory } from "../../../typechain";
const TOKEN_CONTRACT_ADDR = "0x1ca3262009b21F944e6b92a2a88D039D06F1acFa";
const TOKEN_OWNER_ADDR = "0x1ca3262009b21F944e6b92a2a88D039D06F1acFa";
const TOKEN_ID = "1";
const implementationsMappingAddr = "0xCBA828153d3a85b30B5b912e1f2daCac5816aE9D"
describe("BASIC-ERC1155", function () {
const connectorName = "BASIC-ERC1155-A"
let dsaWallet0: any;
let masterSigner: Signer;
let instaConnectorsV2: Contract;
let connector: Contract;
let nftContract: Contract;
let tokenOwner: any;
let instaImplementationsMapping: any;
let InstaAccountV2DefaultImpl: any;
let instaAccountV2DefaultImpl: any;
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: 13300000,
},
},
],
});
await hre.network.provider.request({
method: "hardhat_impersonateAccount",
params: [TOKEN_OWNER_ADDR],
});
await hre.network.provider.send("hardhat_setBalance", [
TOKEN_OWNER_ADDR,
"0x10000000000000000",
]);
// get tokenOwner
tokenOwner = await ethers.getSigner(
TOKEN_OWNER_ADDR
);
nftContract = await ethers.getContractAt(IERC1155__factory.abi, TOKEN_CONTRACT_ADDR)
masterSigner = await getMasterSigner()
instaConnectorsV2 = await ethers.getContractAt(abis.core.connectorsV2, addresses.core.connectorsV2);
instaImplementationsMapping = await ethers.getContractAt(abi, implementationsMappingAddr);
InstaAccountV2DefaultImpl = await ethers.getContractFactory("InstaDefaultImplementation")
instaAccountV2DefaultImpl = await InstaAccountV2DefaultImpl.deploy(addresses.core.instaIndex);
await instaAccountV2DefaultImpl.deployed()
connector = await deployAndEnableConnector({
connectorName,
contractArtifact: ConnectV2BasicERC1155__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("Implementations", function () {
it("Should add default implementation to mapping.", async function () {
const tx = await instaImplementationsMapping.connect(masterSigner).setDefaultImplementation(instaAccountV2DefaultImpl.address);
await tx.wait()
expect(await instaImplementationsMapping.defaultImplementation()).to.be.equal(instaAccountV2DefaultImpl.address);
});
});
describe("DSA wallet setup", function () {
it("Should build DSA v2", async function () {
dsaWallet0 = await buildDSAv2(tokenOwner.address)
expect(!!dsaWallet0.address).to.be.true;
});
it("Deposit ETH 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"));
});
});
describe("Main", function () {
it("should deposit successfully", async () => {
console.log("DSA wallet address", dsaWallet0.address)
await nftContract.connect(tokenOwner).setApprovalForAll(dsaWallet0.address, true);
const spells = [
{
connector: connectorName,
method: "depositERC1155",
args: [
TOKEN_CONTRACT_ADDR,
TOKEN_ID,
1,
"0",
"0"
]
}
];
const tx = await dsaWallet0
.connect(tokenOwner)
.cast(...encodeSpells(spells), tokenOwner.address);
const receipt = await tx.wait();
});
})
})

View File

@ -0,0 +1,135 @@
import { expect } from "chai";
import hre, { network } from "hardhat";
const { web3, deployments, waffle, ethers } = hre;
const { provider, deployContract } = waffle
import { abi } from "../../../scripts/constant/abi/core/InstaImplementations.json"
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 { addresses } from "../../../scripts/tests/mainnet/addresses"
import { abis } from "../../../scripts/constant/abis"
import type { Signer, Contract } from "ethers";
import { ConnectV2BasicERC721__factory, IERC721__factory } from "../../../typechain";
const TOKEN_CONTRACT_ADDR = "0x4d695c615a7aacf2d7b9c481b66045bb2457dfde";
const TOKEN_OWNER_ADDR = "0x8c6b10d42ff08e56133fca0dac75e1931b1fcc23";
const TOKEN_ID = "38";
const implementationsMappingAddr = "0xCBA828153d3a85b30B5b912e1f2daCac5816aE9D"
describe("BASIC-ERC721", function () {
const connectorName = "BASIC-ERC721-A"
let dsaWallet0: any;
let masterSigner: Signer;
let instaConnectorsV2: Contract;
let connector: any;
let nftContract: any;
let tokenOwner: any;
let instaImplementationsMapping: any;
let InstaAccountV2DefaultImpl: any;
let instaAccountV2DefaultImpl: any;
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: 13300000,
},
},
],
});
await hre.network.provider.request({
method: "hardhat_impersonateAccount",
params: [TOKEN_OWNER_ADDR],
});
await network.provider.send("hardhat_setBalance", [
TOKEN_OWNER_ADDR,
"0x10000000000000000",
]);
// get tokenOwner
tokenOwner = await ethers.getSigner(
TOKEN_OWNER_ADDR
);
nftContract = await ethers.getContractAt(IERC721__factory.abi, TOKEN_CONTRACT_ADDR)
masterSigner = await getMasterSigner()
instaConnectorsV2 = await ethers.getContractAt(abis.core.connectorsV2, addresses.core.connectorsV2);
instaImplementationsMapping = await ethers.getContractAt(abi, implementationsMappingAddr);
InstaAccountV2DefaultImpl = await ethers.getContractFactory("InstaDefaultImplementation")
instaAccountV2DefaultImpl = await InstaAccountV2DefaultImpl.deploy(addresses.core.instaIndex);
await instaAccountV2DefaultImpl.deployed()
connector = await deployAndEnableConnector({
connectorName,
contractArtifact: ConnectV2BasicERC721__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("Implementations", function () {
it("Should add default implementation to mapping.", async function () {
const tx = await instaImplementationsMapping.connect(masterSigner).setDefaultImplementation(instaAccountV2DefaultImpl.address);
await tx.wait()
expect(await instaImplementationsMapping.defaultImplementation()).to.be.equal(instaAccountV2DefaultImpl.address);
});
});
describe("DSA wallet setup", function () {
it("Should build DSA v2", async function () {
dsaWallet0 = await buildDSAv2(tokenOwner.address)
expect(!!dsaWallet0.address).to.be.true;
});
it("Deposit ETH 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"));
});
});
describe("Main", function () {
it("should deposit successfully", async () => {
console.log("DSA wallet address", dsaWallet0.address)
await nftContract.connect(tokenOwner).setApprovalForAll(dsaWallet0.address, true);
const spells = [
{
connector: connectorName,
method: "depositERC721",
args: [
TOKEN_CONTRACT_ADDR,
TOKEN_ID,
"0",
"0"
]
}
];
const tx = await dsaWallet0
.connect(tokenOwner)
.cast(...encodeSpells(spells), tokenOwner.address);
const receipt = await tx.wait();
});
})
})

View File

@ -0,0 +1,318 @@
import { expect } from "chai";
import hre, { network } from "hardhat";
const { web3, deployments, waffle, ethers } = hre;
const { provider, deployContract } = waffle;
import type { Signer, Contract } from "ethers";
import { parseEther, parseUnits } from "ethers/lib/utils";
import { BigNumber } from "bignumber.js";
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 { addresses } from "../../../scripts/tests/mainnet/addresses";
import { abis } from "../../../scripts/constant/abis";
import { tokens } from "../../../scripts/tests/mainnet/tokens";
import { ConnectV2BasicERC4626__factory, IERC4626__factory, IERC20Minimal__factory } from "../../../typechain";
describe("BASIC-D", function () {
const connectorName = "BASIC-D";
let dsaWallet0: any;
let masterSigner: Signer;
let instaConnectorsV2: Contract;
let connector: any;
let wallet: any;
const account = "0x075e72a5edf65f0a5f44699c7654c1a76941ddc8";
const sDAIaddress = "0x83f20f44975d03b1b09e64809b757c47f942beea";
let signer: any;
const daiContract = new ethers.Contract(tokens.dai.address, IERC20Minimal__factory.abi, ethers.provider);
const erc4626Contract = new ethers.Contract(sDAIaddress, IERC4626__factory.abi, ethers.provider);
const wallets = provider.getWallets();
const [wallet0] = wallets;
before(async () => {
await hre.network.provider.request({
method: "hardhat_reset",
params: [
{
forking: {
// @ts-ignore
jsonRpcUrl: hre.config.networks.hardhat.forking?.url,
blockNumber: 17907926
}
}
]
});
masterSigner = await getMasterSigner();
instaConnectorsV2 = await ethers.getContractAt(abis.core.connectorsV2, addresses.core.connectorsV2);
connector = await deployAndEnableConnector({
connectorName,
contractArtifact: ConnectV2BasicERC4626__factory,
signer: masterSigner,
connectors: instaConnectorsV2
});
console.log("Connector address", connector.address);
await hre.network.provider.send("hardhat_setBalance", [account, ethers.utils.parseEther("10").toHexString()]);
await hre.network.provider.request({
method: "hardhat_impersonateAccount",
params: [account]
});
signer = await ethers.getSigner(account);
});
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;
wallet = await ethers.getSigner(dsaWallet0.address);
});
it("Deposit ETH into DSA wallet", async function () {
await hre.network.provider.request({
method: "hardhat_impersonateAccount",
params: [wallet.address]
});
await wallet0.sendTransaction({
to: dsaWallet0.address,
value: ethers.utils.parseEther("10")
});
let txRes = await daiContract.connect(signer).transfer(dsaWallet0.address, ethers.utils.parseEther("1000"));
await txRes.wait();
// expect(await daiContract.balanceOf(dsaWallet0.address)).to.be.eq(ethers.utils.parseEther("10000"));
});
});
describe("Main", function () {
// it("Calculate Total Asset and Total Supply", async () => {
// const totalAsset = await erc4626Contract.totalAssets();
// const totalSupply = await erc4626Contract.totalSupply();
// console.log("totalAsset :>> ", totalAsset);
// console.log("totalSupply :>> ", totalSupply);
// });
it("should deposit asset to ERC4626", async () => {
const assets = ethers.utils.parseEther("1");
// Returns the amount of shares for assets
const previewDeposit = await erc4626Contract.previewDeposit(assets);
console.log("previewDeposit :>> ", previewDeposit.toString());
const maxDeposit = await erc4626Contract.maxDeposit(dsaWallet0.address);
let minSharesPerToken = ethers.utils.parseUnits("0.95");
const beforebalance = await erc4626Contract.balanceOf(dsaWallet0.address);
console.log("Share before balance :>> ", beforebalance.toString());
let spells = [
{
connector: connectorName,
method: "deposit",
args: [sDAIaddress, assets, minSharesPerToken, 0, 0]
}
];
let tx = await dsaWallet0.connect(wallet0).cast(...encodeSpells(spells), wallet0.address);
let receipt = await tx.wait();
const afterbalance = await erc4626Contract.balanceOf(dsaWallet0.address);
console.log("Share after balance :>> ", afterbalance.toString());
expect(afterbalance.sub(beforebalance)).to.be.lte(previewDeposit)
// In case of not satisfying min rate
minSharesPerToken = ethers.utils.parseUnits("1");
spells = [
{
connector: connectorName,
method: "deposit",
args: [sDAIaddress, assets, minSharesPerToken, 0, 0]
}
];
await expect(dsaWallet0.connect(wallet0).cast(...encodeSpells(spells), wallet0.address)).to.be.reverted;
});
it("should mint asset to ERC4626", async () => {
const beforeBalance = await daiContract.balanceOf(dsaWallet0.address);
console.log("token balance before :>> ", beforeBalance.toString());
const beforeSharebalance = await erc4626Contract.balanceOf(dsaWallet0.address);
console.log("share balance before :>> ", beforeSharebalance.toString());
const shares = ethers.utils.parseEther("1");
// Returns token amount for shares
const previewMint = await erc4626Contract.previewMint(shares);
console.log("Token amount preview Mint :>> ", previewMint.toString());
let maxTokenPerShares = ethers.utils.parseUnits("1.1");
let spells = [
{
connector: connectorName,
method: "mint",
args: [sDAIaddress, shares, maxTokenPerShares, 0, 0]
}
];
let tx = await dsaWallet0.connect(wallet0).cast(...encodeSpells(spells), wallet0.address);
let receipt = await tx.wait();
const afterbalance = await daiContract.balanceOf(dsaWallet0.address);
console.log("token balance after :>> ", afterbalance.toString());
const afterSharebalance = await erc4626Contract.balanceOf(dsaWallet0.address);
console.log("share balance after :>> ", afterSharebalance.toString());
// In case of not satisfying max rate
maxTokenPerShares = ethers.utils.parseUnits("1");
spells = [
{
connector: connectorName,
method: "mint",
args: [sDAIaddress, shares, maxTokenPerShares, 0, 0]
}
];
await expect(dsaWallet0.connect(wallet0).cast(...encodeSpells(spells), wallet0.address)).to.be.reverted;
});
it("should Max redeem", async () => {
const balance = await erc4626Contract.balanceOf(dsaWallet0.address);
console.log("Share balance :>> ", balance.toString());
// Returns max Shares
const maxRedeem: BigNumber = await erc4626Contract.maxRedeem(dsaWallet0.address);
console.log("maxRedeem :>> ", maxRedeem.toString());
const beforeUnderbalance = await daiContract.balanceOf(dsaWallet0.address);
console.log("beforeUnderbalance :>> ", beforeUnderbalance.toString());
const beforeVaultbalance = await erc4626Contract.balanceOf(dsaWallet0.address);
console.log("beforeVaultbalance :>> ", beforeVaultbalance.toString());
let minTokenPerShares = ethers.utils.parseUnits("1.01");
const setId = "83478237";
let spells = [
{
connector: connectorName,
method: "redeem",
args: [sDAIaddress, ethers.constants.MaxUint256, minTokenPerShares, dsaWallet0.address, 0, setId]
}
];
let tx = await dsaWallet0.connect(wallet0).cast(...encodeSpells(spells), wallet0.address);
let receipt = await tx.wait();
const afterUnderbalance = await daiContract.balanceOf(dsaWallet0.address);
console.log("afterUnderbalance :>> ", afterUnderbalance.toString());
const afterVaultbalance = await erc4626Contract.balanceOf(dsaWallet0.address);
console.log("afterVaultbalance :>> ", afterVaultbalance.toString());
});
it("should Revert for not satisfying min redeem rate", async () => {
const balance = await erc4626Contract.balanceOf(dsaWallet0.address);
console.log("Share balance :>> ", balance.toString());
let spells = [
{
connector: connectorName,
method: "deposit",
args: [sDAIaddress, ethers.utils.parseEther("1"), ethers.utils.parseUnits("0.95"), 0, 0]
}
];
let tx = await dsaWallet0.connect(wallet0).cast(...encodeSpells(spells), wallet0.address);
let receipt = await tx.wait();
// Returns max Shares
const maxRedeem: BigNumber = await erc4626Contract.maxRedeem(dsaWallet0.address);
console.log("maxRedeem :>> ", maxRedeem.toString());
const beforeUnderbalance = await daiContract.balanceOf(dsaWallet0.address);
console.log("beforeUnderbalance :>> ", beforeUnderbalance.toString());
const beforeVaultbalance = await erc4626Contract.balanceOf(dsaWallet0.address);
console.log("beforeVaultbalance :>> ", beforeVaultbalance.toString());
expect(beforeVaultbalance).to.be.gte("950000000000000000")
// In case of not satisfying min rate
let minTokenPerShares = ethers.utils.parseUnits("1.5");
spells = [
{
connector: connectorName,
method: "redeem",
args: [sDAIaddress, ethers.constants.MaxUint256, minTokenPerShares, dsaWallet0.address, 0, 0]
}
];
await expect(dsaWallet0.connect(wallet0).cast(...encodeSpells(spells), wallet0.address)).to.be.reverted;
});
it("should withdraw asset to ERC4626", async () => {
const maxWithdraw: BigNumber = await erc4626Contract.maxWithdraw(dsaWallet0.address);
console.log("maxWithdraw :>> ", maxWithdraw.toString());
const beforeUnderbalance = await daiContract.balanceOf(dsaWallet0.address);
console.log("beforeUnderbalance :>> ", beforeUnderbalance.toString());
const beforeVaultbalance = await erc4626Contract.balanceOf(dsaWallet0.address);
console.log("beforeVaultbalance :>> ", beforeVaultbalance.toString());
let maxSharesPerToken = ethers.utils.parseUnits("0.975");
const setId = "83478237";
let spells = [
{
connector: connectorName,
method: "withdraw",
args: [sDAIaddress, maxWithdraw, maxSharesPerToken, dsaWallet0.address, 0, setId]
}
];
let tx = await dsaWallet0.connect(wallet0).cast(...encodeSpells(spells), wallet0.address);
let receipt = await tx.wait();
const afterUnderbalance = await daiContract.balanceOf(dsaWallet0.address);
console.log("afterUnderbalance :>> ", afterUnderbalance.toString());
const afterVaultbalance = await erc4626Contract.balanceOf(dsaWallet0.address);
console.log("afterVaultbalance :>> ", afterVaultbalance.toString());
// In case of not satisfying min rate
maxSharesPerToken = ethers.utils.parseUnits("0.95");
spells = [
{
connector: connectorName,
method: "withdraw",
args: [sDAIaddress, maxWithdraw, maxSharesPerToken, dsaWallet0.address, 0, setId]
}
];
await expect(dsaWallet0.connect(wallet0).cast(...encodeSpells(spells), wallet0.address)).to.be.reverted;
});
});
});

View File

@ -0,0 +1,254 @@
import { expect, should } from "chai";
import hre, { ethers, waffle } from "hardhat";
import type { Signer, Contract } from "ethers";
import { BigNumber } from "bignumber.js";
import { buildDSAv2 } from "../../../scripts/tests/buildDSAv2";
import { addresses } from "../../../scripts/tests/mainnet/addresses";
import { deployAndEnableConnector } from "../../../scripts/tests/deployAndEnableConnector";
import { abis } from "../../../scripts/constant/abis";
import { getMasterSigner } from "../../../scripts/tests/getMasterSigner";
import { parseEther, parseUnits } from "ethers/lib/utils";
import { encodeSpells } from "../../../scripts/tests/encodeSpells";
import encodeFlashcastData from "../../../scripts/tests/encodeFlashcastData";
import { ConnectV2CompoundImport__factory } from "../../../typechain";
const { provider } = waffle;
const cEthAddress = "0x4Ddc2D193948926D02f9B1fE9e1daa0718270ED5";
const cDaiAddress = "0x5d3a536E4D6DbD6114cc1Ead35777bAB948E3643";
const daiAddress = "0x6B175474E89094C44Da98b954EedeAC495271d0F";
const comptrollerAddress = "0x3d9819210A31b4961b30EF54bE2aeD79B9c9Cd3B";
describe("Import Compound", function () {
const connectorName = "COMPOUND-IMPORT-X";
const cEthAbi = [
{
constant: false,
inputs: [],
name: "mint",
outputs: [],
payable: true,
stateMutability: "payable",
type: "function",
signature: "0x1249c58b"
},
{
constant: true,
inputs: [{ internalType: "address", name: "owner", type: "address" }],
name: "balanceOf",
outputs: [{ internalType: "uint256", name: "", type: "uint256" }],
payable: false,
stateMutability: "view",
type: "function"
},
{
constant: false,
inputs: [],
name: "exchangeRateCurrent",
outputs: [{ name: "", type: "uint256" }],
payable: false,
stateMutability: "nonpayable",
type: "function"
},
{
constant: false,
inputs: [
{ internalType: "address", name: "usr", type: "address" },
{ internalType: "uint256", name: "wad", type: "uint256" }
],
name: "approve",
outputs: [{ internalType: "bool", name: "", type: "bool" }],
payable: false,
stateMutability: "nonpayable",
type: "function"
}
];
const cDaiAbi = [
{
constant: false,
inputs: [
{
internalType: "uint256",
name: "borrowAmount",
type: "uint256"
}
],
name: "borrow",
outputs: [
{
internalType: "uint256",
name: "",
type: "uint256"
}
],
payable: false,
stateMutability: "nonpayable",
type: "function",
signature: "0xc5ebeaec"
},
{
constant: false,
inputs: [{ internalType: "address", name: "account", type: "address" }],
name: "borrowBalanceCurrent",
outputs: [{ internalType: "uint256", name: "", type: "uint256" }],
payable: false,
stateMutability: "nonpayable",
type: "function"
}
];
const comptrollerAbi = [
{
constant: false,
inputs: [
{
internalType: "address[]",
name: "cTokens",
type: "address[]"
}
],
name: "enterMarkets",
outputs: [
{
internalType: "uint256[]",
name: "",
type: "uint256[]"
}
],
payable: false,
stateMutability: "nonpayable",
type: "function",
signature: "0xc2998238"
}
];
let cEth: Contract, cDai: Contract, comptroller, Dai: any;
let dsaWallet0: any;
let masterSigner: Signer;
let instaConnectorsV2: Contract;
let connector: any;
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: 14441991
}
}
]
});
masterSigner = await getMasterSigner();
instaConnectorsV2 = await ethers.getContractAt(abis.core.connectorsV2, addresses.core.connectorsV2);
connector = await deployAndEnableConnector({
connectorName,
contractArtifact: ConnectV2CompoundImport__factory,
signer: masterSigner,
connectors: instaConnectorsV2
});
console.log("Connector address", connector.address);
cEth = new ethers.Contract(cEthAddress, cEthAbi);
cDai = new ethers.Contract(cDaiAddress, cDaiAbi);
Dai = new ethers.Contract(daiAddress, abis.basic.erc20);
comptroller = new ethers.Contract(comptrollerAddress, comptrollerAbi);
// deposit ether to Compound: ETH-A
await cEth.connect(wallet0).mint({
value: parseEther("9")
});
// enter markets with deposits
const cTokens = [cEth.address];
await comptroller.connect(wallet0).enterMarkets(cTokens);
// borrow dai from Compound: DAI-A
await cDai.connect(wallet0).borrow(parseUnits("100"));
});
describe("Deployment", async () => {
it("Should set correct name", async () => {
expect(await connector.name()).to.eq("Compound-Import-v2");
});
});
describe("checks", async () => {
it("Should check user COMPOUND position", async () => {
const ethExchangeRate = (await cEth.connect(wallet0).callStatic.exchangeRateCurrent()) / 1e28;
expect(new BigNumber(await cEth.connect(wallet0).balanceOf(wallet0.address)).dividedBy(1e8).toFixed(0)).to.eq(
new BigNumber(9).dividedBy(ethExchangeRate).toFixed(0)
);
expect(await Dai.connect(wallet0).balanceOf(wallet0.address)).to.eq("100000000000000000000");
});
});
describe("DSA wallet setup", async () => {
it("Should build DSA v2", async () => {
dsaWallet0 = await buildDSAv2(wallet0.address);
expect(!!dsaWallet0.address).to.be.true;
});
it("Deposit ETH 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"));
});
});
describe("Compound position migration", async () => {
it("Should migrate Compound position", async () => {
const tx0 = await cEth
.connect(wallet0)
.approve(dsaWallet0.address, await cEth.connect(wallet0).balanceOf(wallet0.address));
await tx0.wait();
// const amount0 = await cDai.connect(wallet0).callStatic.borrowBalanceCurrent(wallet0.address);
const amount0 = new BigNumber("100000007061117456728");
const amount = new BigNumber(amount0.toString()).multipliedBy(5).dividedBy(1e4);
const amountWithFee = amount0.plus(amount);
const flashSpells = [
{
connector: "COMPOUND-IMPORT-X",
method: "importCompound",
args: [wallet0.address, ["ETH-A"], ["DAI-A"], [amount.toFixed(0)]]
},
{
connector: "INSTAPOOL-C",
method: "flashPayback",
args: [daiAddress, amountWithFee.toFixed(0), 0, 0]
}
];
const spells = [
{
connector: "INSTAPOOL-C",
method: "flashBorrowAndCast",
args: [daiAddress, amount0.toString(), 5, encodeFlashcastData(flashSpells), "0x"]
}
];
const tx = await dsaWallet0.connect(wallet0).cast(...encodeSpells(spells), wallet0.address);
const receipt = await tx.wait();
});
it("Should check DSA COMPOUND position", async () => {
const ethExchangeRate = (await cEth.connect(wallet0).callStatic.exchangeRateCurrent()) / 1e28;
expect(new BigNumber(await cEth.connect(wallet0).balanceOf(dsaWallet0.address)).dividedBy(1e8).toFixed(0)).to.eq(
new BigNumber(9).dividedBy(ethExchangeRate).toFixed(0)
);
});
});
});

View File

@ -0,0 +1,401 @@
import { expect, should } from "chai";
import hre, { ethers, waffle } from "hardhat";
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 { buildDSAv2 } from "../../../scripts/tests/buildDSAv2";
import { addresses } from "../../../scripts/tests/mainnet/addresses";
import { deployAndEnableConnector } from "../../../scripts/tests/deployAndEnableConnector";
import { abis } from "../../../scripts/constant/abis";
import { getMasterSigner } from "../../../scripts/tests/getMasterSigner";
import { parseEther, parseUnits } from "ethers/lib/utils";
import { encodeSpells } from "../../../scripts/tests/encodeSpells";
import encodeFlashcastData from "../../../scripts/tests/encodeFlashcastData";
import { ConnectV2CompoundV3__factory, IERC20__factory } from "../../../typechain";
import { tokens } from "../../../scripts/tests/mainnet/tokens";
const { provider } = waffle;
import { getChainId } from "hardhat";
const ABI = [
"function balanceOf(address account) public view returns (uint256)",
"function approve(address spender, uint256 amount) external returns(bool)",
"function transfer(address recipient, uint256 amount) external returns (bool)"
];
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" }],
name: "balanceOf",
outputs: [{ internalType: "uint256", name: "", type: "uint256" }],
stateMutability: "view",
type: "function"
},
{
inputs: [{ internalType: "address", name: "account", type: "address" }],
name: "borrowBalanceOf",
outputs: [{ internalType: "uint256", name: "", type: "uint256" }],
stateMutability: "view",
type: "function"
},
{
inputs: [
{ internalType: "address", name: "asset", type: "address" },
{ internalType: "uint256", name: "amount", type: "uint256" }
],
name: "supply",
outputs: [],
stateMutability: "nonpayable",
type: "function"
},
{
inputs: [
{ internalType: "address", name: "dst", type: "address" },
{ internalType: "address", name: "asset", type: "address" },
{ internalType: "uint256", name: "amount", type: "uint256" }
],
name: "supplyTo",
outputs: [],
stateMutability: "nonpayable",
type: "function"
},
{
inputs: [
{ internalType: "address", name: "dst", type: "address" },
{ internalType: "uint256", name: "amount", type: "uint256" }
],
name: "transfer",
outputs: [{ internalType: "bool", name: "", type: "bool" }],
stateMutability: "nonpayable",
type: "function"
},
{
inputs: [
{ internalType: "address", name: "dst", type: "address" },
{ internalType: "address", name: "asset", type: "address" },
{ internalType: "uint256", name: "amount", type: "uint256" }
],
name: "transferAsset",
outputs: [],
stateMutability: "nonpayable",
type: "function"
},
{
inputs: [
{ internalType: "address", name: "src", type: "address" },
{ internalType: "address", name: "dst", type: "address" },
{ internalType: "address", name: "asset", type: "address" },
{ internalType: "uint256", name: "amount", type: "uint256" }
],
name: "transferAssetFrom",
outputs: [],
stateMutability: "nonpayable",
type: "function"
},
{
inputs: [
{ internalType: "address", name: "", type: "address" },
{ internalType: "address", name: "", type: "address" }
],
name: "userCollateral",
outputs: [
{ internalType: "uint128", name: "balance", type: "uint128" },
{ internalType: "uint128", name: "_reserved", type: "uint128" }
],
stateMutability: "view",
type: "function"
},
{
inputs: [{ internalType: "address", name: "", type: "address" }],
name: "userNonce",
outputs: [{ internalType: "uint256", name: "", type: "uint256" }],
stateMutability: "view",
type: "function"
},
{
inputs: [
{ internalType: "address", name: "asset", type: "address" },
{ internalType: "uint256", name: "amount", type: "uint256" }
],
name: "withdraw",
outputs: [],
stateMutability: "nonpayable",
type: "function"
},
{
inputs: [
{ internalType: "address", name: "owner", type: "address" },
{ internalType: "address", name: "manager", type: "address" },
{ internalType: "bool", name: "isAllowed_", type: "bool" },
{ internalType: "uint256", name: "nonce", type: "uint256" },
{ internalType: "uint256", name: "expiry", type: "uint256" },
{ internalType: "uint8", name: "v", type: "uint8" },
{ internalType: "bytes32", name: "r", type: "bytes32" },
{ internalType: "bytes32", name: "s", type: "bytes32" }
],
name: "allowBySig",
outputs: [],
stateMutability: "nonpayable",
type: "function"
},
{
inputs: [],
name: "version",
outputs: [{ internalType: "string", name: "", type: "string" }],
stateMutability: "view",
type: "function"
},
{
inputs: [
{ internalType: "address", name: "manager", type: "address" },
{ internalType: "bool", name: "isAllowed_", type: "bool" }
],
name: "allow",
outputs: [],
stateMutability: "nonpayable",
type: "function"
}
];
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 masterSigner: Signer;
let signer: any;
let wallet0: any;
let walletSigner: any;
let instaConnectorsV2: Contract;
let connector: any;
const wallets = provider.getWallets();
const [wallet1, wallet2, wallet3] = wallets;
const wallet = ethers.Wallet.fromMnemonic(mnemonic);
before(async () => {
await hre.network.provider.request({
method: "hardhat_reset",
params: [
{
forking: {
//@ts-ignore
jsonRpcUrl: hre.config.networks.hardhat.forking.url,
blockNumber: 15469858
}
}
]
});
masterSigner = await getMasterSigner();
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({
connectorName,
contractArtifact: ConnectV2CompoundV3__factory,
signer: masterSigner,
connectors: instaConnectorsV2
});
});
describe("check user Compound position", async () => {
it("Should create Compound v3 position of WETH(collateral) and USDC(debt)", async () => {
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");
});
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()
);
expect(await comet.connect(signer).borrowBalanceOf(wallet.address)).to.be.gte(
new BigNumber(100).multipliedBy(1e6).toString()
);
});
});
describe("Deployment", async () => {
it("Should set correct name", async () => {
expect(await connector.name()).to.eq("CompoundV3-v1.0");
});
});
describe("DSA wallet setup", async () => {
it("Should build DSA v2", async () => {
dsaWallet0 = await buildDSAv2(wallet.address);
expect(!!dsaWallet0.address).to.be.true;
});
it("Deposit ETH 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"));
});
});
describe("Compound position migration - Using `toggleManagerUsingPermit` spell by Manager DSA", async () => {
let initialbal: any;
let initialborrow: any;
it("Should migrate Compound position", async () => {
initialbal = new BigNumber(
(await comet.connect(wallet0).userCollateral(dsaWallet0.address, tokens.weth.address)).balance
);
initialborrow = new BigNumber(await comet.connect(wallet0).borrowBalanceOf(dsaWallet0.address));
const DOMAIN_TYPEHASH = keccak256(
ethers.utils.toUtf8Bytes("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)")
);
const PERMIT_TYPEHASH = keccak256(
ethers.utils.toUtf8Bytes(
"Authorization(address owner,address manager,bool isAllowed,uint256 nonce,uint256 expiry)"
)
);
const name = keccak256(ethers.utils.toUtf8Bytes("Compound USDC"));
const version = keccak256(ethers.utils.toUtf8Bytes("0"));
//hardhat network chainID
const chainId = new BigNumber(await getChainId()).toFixed(0);
const DOMAIN_SEPARATOR = keccak256(
defaultAbiCoder.encode(
["bytes32", "bytes32", "bytes32", "uint256", "address"],
[DOMAIN_TYPEHASH, name, version, chainId, market]
)
);
let nonce = new BigNumber(await comet.connect(walletSigner).userNonce(wallet.address)).toFixed(0);
//Approving max amount
const amount = ethers.constants.MaxUint256;
const expiry = Date.now() + 100 * 60;
const structHash = keccak256(
defaultAbiCoder.encode(
["bytes32", "address", "address", "bool", "uint256", "uint256"],
[PERMIT_TYPEHASH, wallet.address, dsaWallet0.address, true, nonce, expiry]
)
);
const digest = keccak256(
ethers.utils.solidityPack(
["bytes1", "bytes1", "bytes32", "bytes32"],
["0x19", "0x01", DOMAIN_SEPARATOR, structHash]
)
);
const { v, r, s } = ecsign(Buffer.from(digest.slice(2), "hex"), Buffer.from(wallet.privateKey.slice(2), "hex"));
let buffer = ethers.utils.parseUnits("100", 3).toNumber();
let amount0 = new BigNumber(await comet.connect(wallet0).borrowBalanceOf(wallet.address)).plus(buffer);
let amountB = new BigNumber(amount0.toString()).multipliedBy(5).dividedBy(1e4);
let amountWithFee = amount0.plus(amountB);
console.log(`\n\tOwner: ${wallet.address}`);
console.log(`\tManager: ${dsaWallet0.address}`);
console.log(`\tdomain speparator: ${DOMAIN_SEPARATOR}`);
console.log(`\tdomain typehash: ${DOMAIN_TYPEHASH}`);
console.log(`\tpermit typehash: ${PERMIT_TYPEHASH}`);
console.log(`\tnonce: ${nonce}`);
console.log(`\texpiry: ${expiry}`);
console.log(`\tv: ${v}`);
console.log(`\tr: ${ethers.utils.hexlify(r)}`);
console.log(`\ts: ${ethers.utils.hexlify(s)}`);
console.log(`\tDigest: ${digest}`);
console.log(`\tstructHash: ${structHash}`);
console.log(`\tblock timestamp: ${(await provider.getBlock(15469858)).timestamp}`);
const flashSpells = [
{
connector: "COMPOUND-V3-X",
method: "paybackOnBehalf",
args: [market, tokens.usdc.address, wallet.address, ethers.constants.MaxUint256, 0, 0]
},
{
connector: "COMPOUND-V3-X",
method: "transferAssetOnBehalf",
args: [market, tokens.weth.address, wallet.address, dsaWallet0.address, ethers.constants.MaxUint256, 0, 0]
},
{
connector: "COMPOUND-V3-X",
method: "borrow",
args: [market, tokens.usdc.address, amountWithFee.toFixed(0), 0, 0]
},
{
connector: "INSTAPOOL-C",
method: "flashPayback",
args: [tokens.usdc.address, amountWithFee.toFixed(0), 0, 0]
}
];
const spells = [
{
connector: "COMPOUND-V3-X",
method: "toggleAccountManagerWithPermit",
args: [
market,
wallet.address,
dsaWallet0.address,
true,
nonce,
expiry,
v,
ethers.utils.hexlify(r),
ethers.utils.hexlify(s)
]
},
{
connector: "INSTAPOOL-C",
method: "flashBorrowAndCast",
args: [tokens.usdc.address, amount0.toFixed(), 5, encodeFlashcastData(flashSpells), "0x"]
}
];
let tx = await dsaWallet0.connect(walletSigner).cast(...encodeSpells(spells), wallet0.address);
await tx.wait();
});
it("Should check DSA COMPOUND position", async () => {
expect((await comet.connect(wallet0).userCollateral(dsaWallet0.address, tokens.weth.address)).balance).to.be.gte(
initialbal.plus(100 * 1e18).toFixed(0)
);
expect(await comet.connect(wallet0).borrowBalanceOf(dsaWallet0.address)).to.be.gte(
initialborrow.plus(100 * 1e6).toFixed(0)
);
expect((await comet.connect(wallet0).userCollateral(wallet.address, tokens.weth.address)).balance).to.be.lte(
ethers.utils.parseEther("0")
);
expect(await comet.connect(wallet0).borrowBalanceOf(wallet.address)).to.be.lte(ethers.utils.parseUnits("0", 6));
});
});
});

View File

@ -0,0 +1,444 @@
import { expect } from "chai";
import hre from "hardhat";
const { waffle, ethers } = hre;
const { provider, deployContract } = waffle;
import { Signer, Contract } from "ethers";
import { BigNumber } from "bignumber.js";
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 { addresses } from "../../../scripts/tests/mainnet/addresses";
import { tokens, tokenMapping } from "../../../scripts/tests/mainnet/tokens";
import { abis } from "../../../scripts/constant/abis";
import { ConnectV2CompoundV3Rewards__factory, ConnectV2CompoundV3__factory } from "../../../typechain";
describe("Compound III Rewards", function () {
let connectorName = "COMPOUND-V3-REWARDS-TEST-A";
const market = "0xc3d688B66703497DAA19211EEdff47f25384cdc3";
const rewards = "0x1B0e765F6224C21223AeA2af16c1C46E38885a40";
const base = "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48";
const account = "0x72a53cdbbcc1b9efa39c834a540550e23463aacb";
const wethWhale = "0x1c11ba15939e1c16ec7ca1678df6160ea2063bc5";
const baseWhale = "0x72a53cdbbcc1b9efa39c834a540550e23463aacb";
const ABI = [
"function balanceOf(address account) public view returns (uint256)",
"function approve(address spender, uint256 amount) external returns(bool)",
"function transfer(address recipient, uint256 amount) external returns (bool)"
];
const wethContract = new ethers.Contract(tokens.weth.address, ABI);
const baseContract = new ethers.Contract(base, ABI);
const cometABI = [
{
inputs: [
{ internalType: "address", name: "comet", type: "address" },
{ internalType: "address", name: "src", type: "address" },
{ internalType: "bool", name: "shouldAccrue", type: "bool" }
],
name: "claim",
outputs: [],
stateMutability: "nonpayable",
type: "function"
},
{
inputs: [
{ internalType: "address", name: "comet", type: "address" },
{ internalType: "address", name: "src", type: "address" },
{ internalType: "address", name: "to", type: "address" },
{ internalType: "bool", name: "shouldAccrue", type: "bool" }
],
name: "claimTo",
outputs: [],
stateMutability: "nonpayable",
type: "function"
},
{
inputs: [
{ internalType: "address", name: "comet", type: "address" },
{ internalType: "address", name: "account", type: "address" }
],
name: "getRewardOwed",
outputs: [
{
components: [
{ internalType: "address", name: "token", type: "address" },
{ internalType: "uint256", name: "owed", type: "uint256" }
],
internalType: "struct CometRewards.RewardOwed",
name: "",
type: "tuple"
}
],
stateMutability: "nonpayable",
type: "function"
},
{
inputs: [{ internalType: "address", name: "", type: "address" }],
name: "rewardConfig",
outputs: [
{ internalType: "address", name: "token", type: "address" },
{ internalType: "uint64", name: "rescaleFactor", type: "uint64" },
{ internalType: "bool", name: "shouldUpscale", type: "bool" }
],
stateMutability: "view",
type: "function"
},
{
inputs: [
{ internalType: "address", name: "", type: "address" },
{ internalType: "address", name: "", type: "address" }
],
name: "rewardsClaimed",
outputs: [{ internalType: "uint256", name: "", type: "uint256" }],
stateMutability: "view",
type: "function"
}
];
const marketABI = [
{
inputs: [{ internalType: "address", name: "account", type: "address" }],
name: "balanceOf",
outputs: [{ internalType: "uint256", name: "", type: "uint256" }],
stateMutability: "view",
type: "function"
},
{
inputs: [{ internalType: "address", name: "account", type: "address" }],
name: "borrowBalanceOf",
outputs: [{ internalType: "uint256", name: "", type: "uint256" }],
stateMutability: "view",
type: "function"
},
{
inputs: [],
name: "baseBorrowMin",
outputs: [{ internalType: "uint256", name: "", type: "uint256" }],
stateMutability: "view",
type: "function"
},
{
inputs: [],
name: "baseMinForRewards",
outputs: [{ internalType: "uint256", name: "", type: "uint256" }],
stateMutability: "view",
type: "function"
},
{
inputs: [],
name: "baseToken",
outputs: [{ internalType: "address", name: "", type: "address" }],
stateMutability: "view",
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: [
{ internalType: "address", name: "owner", type: "address" },
{ internalType: "address", name: "manager", type: "address" }
],
name: "hasPermission",
outputs: [{ internalType: "bool", name: "", type: "bool" }],
stateMutability: "view",
type: "function"
},
{
inputs: [],
name: "numAssets",
outputs: [{ internalType: "uint8", name: "", type: "uint8" }],
stateMutability: "view",
type: "function"
},
{
inputs: [
{ internalType: "address", name: "asset", type: "address" },
{ internalType: "uint256", name: "baseAmount", type: "uint256" }
],
name: "quoteCollateral",
outputs: [{ internalType: "uint256", name: "", type: "uint256" }],
stateMutability: "view",
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: [
{ internalType: "address", name: "", type: "address" },
{ internalType: "address", name: "", type: "address" }
],
name: "userCollateral",
outputs: [
{ internalType: "uint128", name: "balance", type: "uint128" },
{ internalType: "uint128", name: "_reserved", type: "uint128" }
],
stateMutability: "view",
type: "function"
}
];
let dsaWallet0: any;
let dsaWallet1: any;
let wallet: any;
let dsa0Signer: any;
let masterSigner: Signer;
let instaConnectorsV2: Contract;
let connector: any;
let connectorMain: any;
let signer: any;
let wethSigner: any;
let usdcSigner: any;
const cometReward = new ethers.Contract(rewards, cometABI);
const comet = new ethers.Contract(market, marketABI);
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: 15444500
}
}
]
});
masterSigner = await getMasterSigner();
instaConnectorsV2 = await ethers.getContractAt(abis.core.connectorsV2, addresses.core.connectorsV2);
connector = await deployAndEnableConnector({
connectorName,
contractArtifact: ConnectV2CompoundV3Rewards__factory,
signer: masterSigner,
connectors: instaConnectorsV2
});
console.log("Connector address", connector.address);
await hre.network.provider.send("hardhat_setBalance", [account, ethers.utils.parseEther("10").toHexString()]);
await hre.network.provider.request({
method: "hardhat_impersonateAccount",
params: [account]
});
signer = await ethers.getSigner(account);
await hre.network.provider.request({
method: "hardhat_impersonateAccount",
params: [wethWhale]
});
wethSigner = await ethers.getSigner(wethWhale);
await hre.network.provider.request({
method: "hardhat_impersonateAccount",
params: [baseWhale]
});
usdcSigner = await ethers.getSigner(baseWhale);
await hre.network.provider.send("hardhat_setBalance", [
usdcSigner.address,
ethers.utils.parseEther("10").toHexString()
]);
});
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;
dsaWallet1 = await buildDSAv2(wallet0.address);
expect(!!dsaWallet1.address).to.be.true;
wallet = await ethers.getSigner(dsaWallet0.address);
expect(!!dsaWallet1.address).to.be.true;
});
it("Deposit ETH into DSA wallet", async function () {
await hre.network.provider.request({
method: "hardhat_impersonateAccount",
params: [wallet.address]
});
dsa0Signer = await ethers.getSigner(wallet.address);
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 wallet0.sendTransaction({
to: dsaWallet1.address,
value: ethers.utils.parseEther("10")
});
expect(await ethers.provider.getBalance(dsaWallet1.address)).to.be.gte(ethers.utils.parseEther("10"));
});
it("should deposit USDC in dsa wallet", async function () {
await baseContract.connect(usdcSigner).transfer(dsaWallet0.address, ethers.utils.parseUnits("500", 6));
expect(await baseContract.connect(usdcSigner).balanceOf(dsaWallet0.address)).to.be.gte(
ethers.utils.parseUnits("500", 6)
);
});
});
describe("Main", function () {
//deposit asset
it("Should supply USDC in Compound V3", async function () {
connectorName = "COMPOUND-V3-TEST-A";
connectorMain = await deployAndEnableConnector({
connectorName,
contractArtifact: ConnectV2CompoundV3__factory,
signer: masterSigner,
connectors: instaConnectorsV2
});
const amount = ethers.utils.parseUnits("400", 6);
const spells = [
{
connector: "COMPOUND-V3-TEST-A",
method: "deposit",
args: [market, base, amount, 0, 0]
}
];
const tx = await dsaWallet0.connect(wallet0).cast(...encodeSpells(spells), wallet1.address);
const receipt = await tx.wait();
expect(new BigNumber(await baseContract.connect(signer).balanceOf(dsaWallet0.address)).toFixed(0)).to.be.lte(
ethers.utils.parseUnits("100", 6)
);
expect(new BigNumber(await comet.connect(signer).balanceOf(dsaWallet0.address)).toFixed(0)).to.be.gte(
ethers.utils.parseUnits("399", 6)
);
});
let connector_ = "COMPOUND-V3-REWARDS-TEST-A";
it("Should claim rewards", async function () {
let reward = (await cometReward.connect(signer).rewardConfig(market)).token;
let rewardInterface = new ethers.Contract(reward, ABI);
let owed_ = await cometReward.connect(signer).callStatic.getRewardOwed(market, dsaWallet0.address);
let amt: number = owed_.owed;
console.log(new BigNumber(amt).toFixed(0));
const spells = [
{
connector: connector_,
method: "claimRewards",
args: [market, 0]
}
];
const tx = await dsaWallet0.connect(wallet0).cast(...encodeSpells(spells), wallet1.address);
const receipt = await tx.wait();
expect(new BigNumber(await rewardInterface.connect(signer).balanceOf(dsaWallet0.address)).toFixed(0)).to.be.gte(
amt
);
});
it("Should supply USDC in Compound V3 through dsaWallet0", async function () {
const amount = ethers.utils.parseUnits("100", 6); // 1 ETH
const spells = [
{
connector: "COMPOUND-V3-TEST-A",
method: "deposit",
args: [market, base, amount, 0, 0]
}
];
const tx = await dsaWallet0.connect(wallet0).cast(...encodeSpells(spells), wallet1.address);
const receipt = await tx.wait();
expect(new BigNumber(await baseContract.connect(signer).balanceOf(dsaWallet0.address)).toFixed(0)).to.be.lte(
ethers.utils.parseUnits("0", 6)
);
expect(new BigNumber(await comet.connect(signer).balanceOf(dsaWallet0.address)).toFixed(0)).to.be.gte(
ethers.utils.parseUnits("499", 6)
);
});
it("Should claim rewards to dsa1", async function () {
let reward = (await cometReward.connect(signer).rewardConfig(market)).token;
let rewardInterface = new ethers.Contract(reward, ABI);
let owed_ = await cometReward.connect(signer).callStatic.getRewardOwed(market, dsaWallet0.address);
let amt: number = owed_.owed;
const spells = [
{
connector: connector_,
method: "claimRewardsOnBehalfOf",
args: [market, dsaWallet0.address, dsaWallet1.address, 0]
}
];
const tx = await dsaWallet0.connect(wallet0).cast(...encodeSpells(spells), wallet1.address);
const receipt = await tx.wait();
expect(new BigNumber(await rewardInterface.connect(signer).balanceOf(dsaWallet1.address)).toFixed(0)).to.be.gte(
amt
);
});
it("should allow manager for dsaWallet0's collateral and base", async function () {
const spells = [
{
connector: connectorName,
method: "toggleAccountManager",
args: [market, dsaWallet1.address, true]
}
];
const tx = await dsaWallet0.connect(wallet0).cast(...encodeSpells(spells), wallet1.address);
const receipt = await tx.wait();
});
it("Should claim rewards to dsa1 using manager", async function () {
let reward = (await cometReward.connect(signer).rewardConfig(market)).token;
let rewardInterface = new ethers.Contract(reward, ABI);
let owed_ = await cometReward.connect(signer).callStatic.getRewardOwed(market, dsaWallet0.address);
let amt: number = owed_.owed;
const spells = [
{
connector: connector_,
method: "claimRewardsOnBehalfOf",
args: [market, dsaWallet0.address, dsaWallet1.address, 0]
}
];
const tx = await dsaWallet1.connect(wallet0).cast(...encodeSpells(spells), wallet1.address);
const receipt = await tx.wait();
expect(new BigNumber(await rewardInterface.connect(signer).balanceOf(dsaWallet1.address)).toFixed(0)).to.be.gte(
amt
);
});
});
});

View File

@ -0,0 +1,653 @@
import { expect } from "chai";
import hre from "hardhat";
const { waffle, ethers } = hre;
const { provider, deployContract } = waffle;
import { Signer, Contract } from "ethers";
import { BigNumber } from "bignumber.js";
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 { addresses } from "../../../scripts/tests/mainnet/addresses";
import { tokens, tokenMapping } from "../../../scripts/tests/mainnet/tokens";
import { abis } from "../../../scripts/constant/abis";
import { constants } from "../../../scripts/constant/constant";
import { ConnectV2CompoundV3__factory } from "../../../typechain";
import { MaxUint256 } from "@uniswap/sdk-core";
import { USDC_OPTIMISTIC_KOVAN } from "@uniswap/smart-order-router";
describe("Compound III", function () {
const connectorName = "COMPOUND-V3-TEST-A";
const market = "0xc3d688B66703497DAA19211EEdff47f25384cdc3";
const base = "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48";
const account = "0x72a53cdbbcc1b9efa39c834a540550e23463aacb";
const wethWhale = "0x1c11ba15939e1c16ec7ca1678df6160ea2063bc5";
const ABI = [
"function balanceOf(address account) public view returns (uint256)",
"function approve(address spender, uint256 amount) external returns(bool)",
"function transfer(address recipient, uint256 amount) external returns (bool)"
];
const wethContract = new ethers.Contract(tokens.weth.address, ABI);
const baseContract = new ethers.Contract(base, ABI);
const linkContract = new ethers.Contract(tokens.link.address, ABI);
const cometABI = [
{
inputs: [{ internalType: "address", name: "account", type: "address" }],
name: "balanceOf",
outputs: [{ internalType: "uint256", name: "", type: "uint256" }],
stateMutability: "view",
type: "function"
},
{
inputs: [{ internalType: "address", name: "account", type: "address" }],
name: "borrowBalanceOf",
outputs: [{ internalType: "uint256", name: "", type: "uint256" }],
stateMutability: "view",
type: "function"
},
{
inputs: [],
name: "baseBorrowMin",
outputs: [{ internalType: "uint256", name: "", type: "uint256" }],
stateMutability: "view",
type: "function"
},
{
inputs: [],
name: "baseMinForRewards",
outputs: [{ internalType: "uint256", name: "", type: "uint256" }],
stateMutability: "view",
type: "function"
},
{
inputs: [],
name: "baseToken",
outputs: [{ internalType: "address", name: "", type: "address" }],
stateMutability: "view",
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: [
{ internalType: "address", name: "owner", type: "address" },
{ internalType: "address", name: "manager", type: "address" }
],
name: "hasPermission",
outputs: [{ internalType: "bool", name: "", type: "bool" }],
stateMutability: "view",
type: "function"
},
{
inputs: [],
name: "numAssets",
outputs: [{ internalType: "uint8", name: "", type: "uint8" }],
stateMutability: "view",
type: "function"
},
{
inputs: [
{ internalType: "address", name: "asset", type: "address" },
{ internalType: "uint256", name: "baseAmount", type: "uint256" }
],
name: "quoteCollateral",
outputs: [{ internalType: "uint256", name: "", type: "uint256" }],
stateMutability: "view",
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: [
{ internalType: "address", name: "", type: "address" },
{ internalType: "address", name: "", type: "address" }
],
name: "userCollateral",
outputs: [
{ internalType: "uint128", name: "balance", type: "uint128" },
{ internalType: "uint128", name: "_reserved", type: "uint128" }
],
stateMutability: "view",
type: "function"
}
];
let dsaWallet0: any;
let dsaWallet1: any;
let dsaWallet2: any;
let dsaWallet3: any;
let wallet: any;
let dsa0Signer: any;
let masterSigner: Signer;
let instaConnectorsV2: Contract;
let connector: any;
let signer: any;
let wethSigner: any;
const comet = new ethers.Contract(market, cometABI);
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: 15444500
}
}
]
});
masterSigner = await getMasterSigner();
instaConnectorsV2 = await ethers.getContractAt(abis.core.connectorsV2, addresses.core.connectorsV2);
connector = await deployAndEnableConnector({
connectorName,
contractArtifact: ConnectV2CompoundV3__factory,
signer: masterSigner,
connectors: instaConnectorsV2
});
console.log("Connector address", connector.address);
await hre.network.provider.send("hardhat_setBalance", [account, ethers.utils.parseEther("10").toHexString()]);
await hre.network.provider.request({
method: "hardhat_impersonateAccount",
params: [account]
});
signer = await ethers.getSigner(account);
await hre.network.provider.request({
method: "hardhat_impersonateAccount",
params: [wethWhale]
});
wethSigner = await ethers.getSigner(wethWhale);
});
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;
dsaWallet1 = await buildDSAv2(wallet0.address);
expect(!!dsaWallet1.address).to.be.true;
dsaWallet2 = await buildDSAv2(wallet0.address);
expect(!!dsaWallet2.address).to.be.true;
dsaWallet3 = await buildDSAv2(wallet0.address);
expect(!!dsaWallet3.address).to.be.true;
wallet = await ethers.getSigner(dsaWallet0.address);
expect(!!dsaWallet1.address).to.be.true;
});
it("Deposit ETH into DSA wallet", async function () {
await hre.network.provider.request({
method: "hardhat_impersonateAccount",
params: [wallet.address]
});
dsa0Signer = await ethers.getSigner(wallet.address);
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 wallet0.sendTransaction({
to: dsaWallet1.address,
value: ethers.utils.parseEther("10")
});
expect(await ethers.provider.getBalance(dsaWallet0.address)).to.be.gte(ethers.utils.parseEther("10"));
await wallet0.sendTransaction({
to: dsaWallet3.address,
value: ethers.utils.parseEther("10")
});
expect(await ethers.provider.getBalance(dsaWallet0.address)).to.be.gte(ethers.utils.parseEther("10"));
});
});
describe("Main", function () {
//deposit asset
it("Should supply ETH collateral in Compound V3", async function () {
const amount = ethers.utils.parseEther("5"); // 1 ETH
const spells = [
{
connector: connectorName,
method: "deposit",
args: [market, tokens.eth.address, amount, 0, 0]
}
];
const tx = await dsaWallet0.connect(wallet0).cast(...encodeSpells(spells), wallet1.address);
const receipt = await tx.wait();
expect(await ethers.provider.getBalance(dsaWallet0.address)).to.be.lte(ethers.utils.parseEther("5"));
expect((await comet.connect(signer).userCollateral(dsaWallet0.address, tokens.weth.address)).balance).to.be.gte(
ethers.utils.parseEther("5")
);
});
//deposit asset on behalf of
it("Should supply ETH collateral on behalf of dsaWallet0 in Compound V3", async function () {
const amount = ethers.utils.parseEther("1"); // 1 ETH
const spells = [
{
connector: connectorName,
method: "depositOnBehalf",
args: [market, tokens.eth.address, dsaWallet0.address, amount, 0, 0]
}
];
const tx = await dsaWallet1.connect(wallet0).cast(...encodeSpells(spells), wallet1.address);
const receipt = await tx.wait();
expect(await ethers.provider.getBalance(dsaWallet1.address)).to.be.lte(ethers.utils.parseEther("9"));
expect((await comet.connect(wallet0).userCollateral(dsaWallet0.address, tokens.weth.address)).balance).to.be.gte(
ethers.utils.parseEther("6")
);
});
it("Should borrow and payback base token from Compound", async function () {
const amount = ethers.utils.parseUnits("150", 6);
const spells = [
{
connector: connectorName,
method: "borrow",
args: [market, base, amount, 0, 0]
},
{
connector: connectorName,
method: "payback",
args: [market, base, ethers.utils.parseUnits("50", 6), 0, 0]
}
];
const tx = await dsaWallet0.connect(wallet0).cast(...encodeSpells(spells), wallet1.address);
const receipt = await tx.wait();
expect(await comet.connect(wallet0).borrowBalanceOf(dsaWallet0.address)).to.be.equal(
ethers.utils.parseUnits("100", 6)
);
expect(await baseContract.connect(wallet0).balanceOf(dsaWallet0.address)).to.be.equal(
ethers.utils.parseUnits("100", 6)
);
});
it("should allow manager for dsaWallet0's collateral and base", async function () {
const spells = [
{
connector: connectorName,
method: "toggleAccountManager",
args: [market, dsaWallet2.address, true]
}
];
const tx = await dsaWallet0.connect(wallet0).cast(...encodeSpells(spells), wallet1.address);
const receipt = await tx.wait();
});
it("should payback base token on Compound using manager", async function () {
await baseContract.connect(signer).transfer(dsaWallet0.address, ethers.utils.parseUnits("5", 6));
const amount = ethers.utils.parseUnits("102", 6);
await baseContract.connect(dsa0Signer).approve(market, amount);
const spells = [
{
connector: connectorName,
method: "paybackFromUsingManager",
args: [market, base, dsaWallet0.address, dsaWallet0.address, ethers.constants.MaxUint256, 0, 0]
}
];
const tx = await dsaWallet2.connect(wallet0).cast(...encodeSpells(spells), wallet1.address);
const receipt = await tx.wait();
expect(await comet.connect(signer).borrowBalanceOf(dsaWallet0.address)).to.be.equal(
ethers.utils.parseUnits("0", 6)
);
});
it("Should borrow to another dsa from Compound", async function () {
const amount = ethers.utils.parseUnits("100", 6);
const spells = [
{
connector: connectorName,
method: "borrowTo",
args: [market, base, dsaWallet1.address, amount, 0, 0]
}
];
const tx = await dsaWallet0.connect(wallet0).cast(...encodeSpells(spells), wallet1.address);
const receipt = await tx.wait();
expect(new BigNumber(await comet.connect(signer).borrowBalanceOf(dsaWallet0.address)).toFixed()).to.be.equal(
ethers.utils.parseUnits("100", 6)
);
});
it("Should payback on behalf of from Compound", async function () {
const spells = [
{
connector: connectorName,
method: "paybackOnBehalf",
args: [market, base, dsaWallet0.address, ethers.constants.MaxUint256, 0, 0]
}
];
const tx = await dsaWallet1.connect(wallet0).cast(...encodeSpells(spells), wallet1.address);
const receipt = await tx.wait();
expect(await comet.connect(signer).borrowBalanceOf(dsaWallet0.address)).to.be.equal(
ethers.utils.parseUnits("0", 6)
);
});
it("should withdraw some ETH collateral", async function () {
let initialBal = await ethers.provider.getBalance(dsaWallet0.address);
const amount_ = ethers.utils.parseEther("2");
const spells = [
{
connector: connectorName,
method: "withdraw",
args: [market, tokens.eth.address, amount_, 0, 0]
}
];
const tx = await dsaWallet0.connect(wallet0).cast(...encodeSpells(spells), wallet1.address);
const receipt = await tx.wait();
expect((await comet.connect(signer).userCollateral(dsaWallet0.address, tokens.weth.address)).balance).to.be.gte(
ethers.utils.parseEther("4")
);
expect(await ethers.provider.getBalance(dsaWallet0.address)).to.be.gte(initialBal.add(amount_).toString());
});
it("manager should be able to withdraw collateral from the position and transfer", async function () {
await wallet1.sendTransaction({
to: tokens.weth.address,
value: ethers.utils.parseEther("10")
});
const amount = ethers.constants.MaxUint256;
const spells = [
{
connector: connectorName,
method: "withdrawOnBehalfAndTransfer",
args: [market, tokens.eth.address, dsaWallet0.address, dsaWallet1.address, amount, 0, 0]
}
];
const tx = await dsaWallet2.connect(wallet0).cast(...encodeSpells(spells), wallet1.address);
const receipt = await tx.wait();
expect((await comet.connect(signer).userCollateral(dsaWallet0.address, tokens.weth.address)).balance).to.be.gte(
ethers.utils.parseEther("0")
);
expect(await wethContract.connect(wallet0).balanceOf(dsaWallet1.address)).to.be.gte(ethers.utils.parseEther("4"));
});
it("Should withdraw collateral to another DSA", async function () {
const spells1 = [
{
connector: connectorName,
method: "deposit",
args: [market, tokens.eth.address, ethers.utils.parseEther("5"), 0, 0]
}
];
const tx1 = await dsaWallet1.connect(wallet0).cast(...encodeSpells(spells1), wallet1.address);
let initialBal = await ethers.provider.getBalance(dsaWallet0.address);
const amount = ethers.utils.parseEther("2");
const spells = [
{
connector: connectorName,
method: "withdrawTo",
args: [market, tokens.eth.address, dsaWallet0.address, amount, 0, 0]
}
];
const tx = await dsaWallet1.connect(wallet0).cast(...encodeSpells(spells), wallet1.address);
const receipt = await tx.wait();
expect(await wethContract.connect(wallet0).balanceOf(dsaWallet0.address)).to.be.gte(amount);
expect((await comet.connect(signer).userCollateral(dsaWallet1.address, tokens.weth.address)).balance).to.be.gte(
ethers.utils.parseEther("3")
);
});
it("Should withdraw collateral to another DSA", async function () {
const spells1 = [
{
connector: connectorName,
method: "deposit",
args: [market, tokens.eth.address, ethers.utils.parseEther("3"), 0, 0]
}
];
const tx1 = await dsaWallet0.connect(wallet0).cast(...encodeSpells(spells1), wallet1.address);
let initialBal = await ethers.provider.getBalance(dsaWallet0.address);
const amount = ethers.utils.parseEther("2");
const spells = [
{
connector: connectorName,
method: "withdrawTo",
args: [market, tokens.eth.address, dsaWallet0.address, amount, 0, 0]
}
];
const tx = await dsaWallet0.connect(wallet0).cast(...encodeSpells(spells), wallet1.address);
const receipt = await tx.wait();
expect(await ethers.provider.getBalance(dsaWallet0.address)).to.be.gte(initialBal.add(amount));
expect((await comet.connect(signer).userCollateral(dsaWallet1.address, tokens.weth.address)).balance).to.be.gte(
ethers.utils.parseEther("1")
);
});
it("should transfer eth from dsaWallet1 to dsaWallet0 position", async function () {
const spells = [
{
connector: connectorName,
method: "transferAsset",
args: [market, tokens.eth.address, dsaWallet0.address, ethers.utils.parseEther("3"), 0, 0]
}
];
const tx = await dsaWallet1.connect(wallet0).cast(...encodeSpells(spells), wallet1.address);
const receipt = await tx.wait();
expect((await comet.connect(signer).userCollateral(dsaWallet1.address, tokens.weth.address)).balance).to.be.gte(
ethers.utils.parseEther("0")
);
expect((await comet.connect(signer).userCollateral(dsaWallet0.address, tokens.weth.address)).balance).to.be.gte(
ethers.utils.parseEther("3")
);
});
it("should transfer base token from dsaWallet1 to dsaWallet0 position", async function () {
await baseContract.connect(signer).transfer(dsaWallet1.address, ethers.utils.parseUnits("10", 6));
const spells = [
{
connector: connectorName,
method: "deposit",
args: [market, base, ethers.constants.MaxUint256, 0, 0]
}
];
const tx = await dsaWallet1.connect(wallet0).cast(...encodeSpells(spells), wallet1.address);
const receipt = await tx.wait();
let initialBal = await baseContract.connect(signer).balanceOf(dsaWallet1.address);
let spells1 = [
{
connector: connectorName,
method: "transferAsset",
args: [market, base, dsaWallet0.address, ethers.constants.MaxUint256, 0, 0]
}
];
const tx1 = await dsaWallet1.connect(wallet0).cast(...encodeSpells(spells1), wallet1.address);
const receipt1 = await tx.wait();
expect(await comet.connect(signer).balanceOf(dsaWallet1.address)).to.be.lte(ethers.utils.parseUnits("0", 6));
expect(await comet.connect(signer).balanceOf(dsaWallet0.address)).to.be.gte(initialBal);
});
it("should transfer base token using manager from dsaWallet0 to dsaWallet1 position", async function () {
const spells = [
{
connector: connectorName,
method: "transferAssetOnBehalf",
args: [market, base, dsaWallet0.address, dsaWallet1.address, ethers.constants.MaxUint256, 0, 0]
}
];
let initialBal = await baseContract.connect(signer).balanceOf(dsaWallet0.address);
const tx = await dsaWallet2.connect(wallet0).cast(...encodeSpells(spells), wallet1.address);
const receipt = await tx.wait();
expect(await comet.connect(signer).balanceOf(dsaWallet0.address)).to.be.lte(ethers.utils.parseUnits("0", 6));
expect(await comet.connect(signer).balanceOf(dsaWallet1.address)).to.be.gte(initialBal);
});
it("should deposit weth using manager", async function () {
await wethContract.connect(wethSigner).transfer(dsaWallet0.address, ethers.utils.parseEther("10"));
let initialBal = await wethContract.connect(wallet0).balanceOf(dsaWallet0.address);
const amount = ethers.utils.parseEther("1");
await wethContract.connect(dsa0Signer).approve(market, amount);
const spells = [
{
connector: connectorName,
method: "depositFromUsingManager",
args: [market, tokens.eth.address, dsaWallet0.address, dsaWallet1.address, amount, 0, 0]
}
];
const tx = await dsaWallet2.connect(wallet0).cast(...encodeSpells(spells), wallet1.address);
const receipt = await tx.wait();
expect((await comet.connect(signer).userCollateral(dsaWallet1.address, tokens.weth.address)).balance).to.be.gte(
ethers.utils.parseEther("1")
);
expect(await wethContract.connect(wallet0).balanceOf(dsaWallet0.address)).to.be.lte(initialBal.sub(amount));
});
it("should allow manager for dsaWallet0's collateral", async function () {
const spells = [
{
connector: connectorName,
method: "toggleAccountManager",
args: [market, dsaWallet2.address, true]
}
];
const tx = await dsaWallet3.connect(wallet0).cast(...encodeSpells(spells), wallet1.address);
const receipt = await tx.wait();
});
it("should borrow on behalf using manager", async function () {
let initialBal = await baseContract.connect(wallet0).balanceOf(dsaWallet0.address);
await wallet0.sendTransaction({
to: dsaWallet3.address,
value: ethers.utils.parseEther("15")
});
const spells1 = [
{
connector: connectorName,
method: "deposit",
args: [market, tokens.eth.address, ethers.utils.parseEther("15"), 0, 0]
}
];
const tx1 = await dsaWallet3.connect(wallet0).cast(...encodeSpells(spells1), wallet1.address);
const amount = ethers.utils.parseUnits("500", 6);
const spells = [
{
connector: connectorName,
method: "borrowOnBehalfAndTransfer",
args: [market, base, dsaWallet3.address, dsaWallet0.address, amount, 0, 0]
}
];
const tx = await dsaWallet2.connect(wallet0).cast(...encodeSpells(spells), wallet1.address);
const receipt = await tx.wait();
expect(new BigNumber(await comet.connect(signer).borrowBalanceOf(dsaWallet3.address)).toFixed()).to.be.equal(
ethers.utils.parseUnits("500", 6)
);
expect(await baseContract.connect(wallet0).balanceOf(dsaWallet0.address)).to.be.equal(initialBal.add(amount));
});
it("should transferAsset collateral using manager", async function () {
let bal1 = (await comet.connect(signer).userCollateral(dsaWallet1.address, tokens.weth.address)).balance;
let bal0 = (await comet.connect(signer).userCollateral(dsaWallet0.address, tokens.weth.address)).balance;
const spells = [
{
connector: connectorName,
method: "transferAssetOnBehalf",
args: [market, tokens.eth.address, dsaWallet0.address, dsaWallet1.address, ethers.utils.parseEther("1"), 0, 0]
}
];
const tx = await dsaWallet2.connect(wallet0).cast(...encodeSpells(spells), wallet1.address);
const receipt = await tx.wait();
expect((await comet.connect(signer).userCollateral(dsaWallet1.address, tokens.weth.address)).balance).to.be.gte(
bal1.add(ethers.utils.parseEther("1")).toString()
);
expect((await comet.connect(signer).userCollateral(dsaWallet0.address, tokens.weth.address)).balance).to.be.gte(
bal0.sub(ethers.utils.parseEther("1")).toString()
);
});
//can buy only when target reserves not reached.
// it("should buy collateral", async function () {
// //deposit 10 usdc(base token) to dsa
// await baseContract.connect(signer).transfer(dsaWallet0.address, ethers.utils.parseUnits("10", 6));
// console.log(await baseContract.connect(signer).balanceOf(dsaWallet0.address));
// //dsawallet0 --> collateral 0eth, balance 9eth 10usdc
// //dsaWallet1 --> balance 2eth coll: 3eth
// const amount = ethers.utils.parseUnits("1",6);
// const bal = await baseContract.connect(signer).balanceOf(dsaWallet0.address);
// const spells = [
// {
// connector: connectorName,
// method: "buyCollateral",
// args: [market, tokens.link.address, dsaWallet0.address, amount, bal, 0, 0]
// }
// ];
// const tx = await dsaWallet0.connect(wallet0).cast(...encodeSpells(spells), wallet1.address);
// const receipt = await tx.wait();
// expect(new BigNumber(await linkContract.connect(signer).balanceOf(dsaWallet0.address)).toFixed()).to.be.gte(
// ethers.utils.parseEther("1")
// );
// //dsawallet0 --> collateral 0eth, balance 9eth >1link
// //dsaWallet1 --> balance 2eth coll: 3eth
// });
});
});

View File

@ -0,0 +1,138 @@
import { expect } from "chai";
import hre from "hardhat";
const { waffle, ethers } = hre;
const { provider, deployContract} = waffle
import type { Signer, Contract } from "ethers";
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 { addresses } from "../../../scripts/tests/mainnet/addresses";
import { abis } from "../../../scripts/constant/abis";
import { constants } from "../../../scripts/constant/constant";
import { ConnectV2Compound__factory } from "../../../typechain";
describe("Compound", function () {
const connectorName = "COMPOUND-TEST-A"
let dsaWallet0: any;
let masterSigner: Signer;
let instaConnectorsV2: Contract;
let connector: any;
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: 13300000,
},
},
],
});
masterSigner = await getMasterSigner()
instaConnectorsV2 = await ethers.getContractAt(abis.core.connectorsV2, addresses.core.connectorsV2);
connector = await deployAndEnableConnector({
connectorName,
contractArtifact: ConnectV2Compound__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 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"));
});
});
describe("Main", function () {
it("Should deposit ETH in Compound", async function () {
const amount = ethers.utils.parseEther("1") // 1 ETH
const spells = [
{
connector: connectorName,
method: "deposit",
args: ["ETH-A", amount, 0, 0]
}
]
const tx = await dsaWallet0.connect(wallet0).cast(...encodeSpells(spells), wallet1.address)
const receipt = await tx.wait()
expect(await ethers.provider.getBalance(dsaWallet0.address)).to.be.lte(ethers.utils.parseEther("9"));
});
it("Should borrow and payback DAI from Compound", async function () {
const amount = ethers.utils.parseEther("100") // 100 DAI
const setId = "83478237"
const spells = [
{
connector: connectorName,
method: "borrow",
args: ["DAI-A", amount, 0, setId]
},
{
connector: connectorName,
method: "payback",
args: ["DAI-A", 0, setId, 0]
}
]
const tx = await dsaWallet0.connect(wallet0).cast(...encodeSpells(spells), wallet1.address)
const receipt = await tx.wait()
expect(await ethers.provider.getBalance(dsaWallet0.address)).to.be.lte(ethers.utils.parseEther("9"));
});
it("Should deposit all ETH in Compound", async function () {
const spells = [
{
connector: connectorName,
method: "deposit",
args: ["ETH-A", constants.max_value, 0, 0]
}
]
const tx = await dsaWallet0.connect(wallet0).cast(...encodeSpells(spells), wallet1.address)
const receipt = await tx.wait()
expect(await ethers.provider.getBalance(dsaWallet0.address)).to.be.lte(ethers.utils.parseEther("0"));
});
it("Should withdraw all ETH from Compound", async function () {
const spells = [
{
connector: connectorName,
method: "withdraw",
args: ["ETH-A", constants.max_value, 0, 0]
}
]
const tx = await dsaWallet0.connect(wallet0).cast(...encodeSpells(spells), wallet1.address)
const receipt = await tx.wait()
expect(await ethers.provider.getBalance(dsaWallet0.address)).to.be.gte(ethers.utils.parseEther("10"));
});
})
})

View File

@ -0,0 +1,154 @@
import { expect } from "chai";
import hre from "hardhat";
const { ethers, waffle } = 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 { addresses } from "../../../scripts/tests/mainnet/addresses";
import { abis } from "../../../scripts/constant/abis";
import { ConnectV2ConnextMainnet__factory } from "../../../typechain";
import { Signer, Contract } from "ethers";
describe("Connext Connector [Mainnet]", () => {
const connectorName = "CONNEXT-TEST-A";
let dsaWallet0: Contract;
let masterSigner: Signer;
let instaConnectorsV2: Contract;
let connector: Contract;
let usdcContract: Contract;
let signer: any;
const usdcAddr = "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48";
const ethAddr = "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE";
const account = "0x756D64Dc5eDb56740fC617628dC832DDBCfd373c";
const wallets = provider.getWallets();
const [wallet0, wallet1] = wallets;
before(async () => {
await hre.network.provider.request({
method: "hardhat_reset",
params: [
{
forking: {
// @ts-ignore
jsonRpcUrl: hre.config.networks.hardhat.forking.url,
blockNumber: 82686991
}
}
]
});
masterSigner = await getMasterSigner();
instaConnectorsV2 = await ethers.getContractAt(abis.core.connectorsV2, addresses.core.connectorsV2);
connector = await deployAndEnableConnector({
connectorName,
contractArtifact: ConnectV2ConnextMainnet__factory,
signer: masterSigner,
connectors: instaConnectorsV2
});
usdcContract = await ethers.getContractAt(abis.basic.erc20, usdcAddr);
signer = await ethers.getSigner(account);
await hre.network.provider.send("hardhat_setBalance", [account, ethers.utils.parseEther("10").toHexString()]);
await hre.network.provider.request({
method: "hardhat_impersonateAccount",
params: [account]
});
await usdcContract.connect(signer).transfer(wallet0.address, ethers.utils.parseUnits("10000", 6));
console.log("deployed connector: ", connector.address);
});
it("Should have contracts deployed.", async () => {
expect(!!instaConnectorsV2.address).to.be.true;
expect(!!connector.address).to.be.true;
expect(!!(await masterSigner.getAddress())).to.be.true;
});
describe("DSA wallet setup", () => {
it("Should build DSA v2", async () => {
dsaWallet0 = await buildDSAv2(wallet0.getAddress());
expect(!!dsaWallet0.address).to.be.true;
});
it("Deposit ETH & USDC into DSA wallet", async () => {
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 usdcContract.connect(wallet0).transfer(dsaWallet0.address, ethers.utils.parseUnits("10", 6));
expect(await usdcContract.balanceOf(dsaWallet0.address)).to.be.gte(ethers.utils.parseUnits("10", 6));
});
});
describe("Main", () => {
it("should xcall with eth", async () => {
const amount = ethers.utils.parseEther("5");
const domainId = 6648936;
const slippage = 10000;
const relayerFee = ethers.utils.parseEther("1");
const callData = "0x";
const xcallParams: any = [
domainId,
wallet1.address,
ethAddr,
wallet1.address,
amount,
slippage,
relayerFee,
callData
];
const spells = [
{
connector: connectorName,
method: "xcall",
args: [xcallParams, 0, 0]
}
];
const tx = await dsaWallet0.connect(wallet0).cast(...encodeSpells(spells), wallet1.address);
const receipt = await tx.wait();
});
it("should xcall with usdc", async () => {
const amount = ethers.utils.parseUnits("5", 6);
const domainId = 6648936;
const slippage = 10000;
const relayerFee = ethers.utils.parseEther("1");
const callData = "0x";
const xcallParams: any = [
domainId,
wallet1.address,
usdcAddr,
wallet1.address,
amount,
slippage,
relayerFee,
callData
];
const spells = [
{
connector: connectorName,
method: "xcall",
args: [xcallParams, 0, 0]
}
];
const tx = await dsaWallet0.connect(wallet0).cast(...encodeSpells(spells), wallet1.address);
const receipt = await tx.wait();
});
});
});

View File

@ -0,0 +1,445 @@
import { expect } from "chai";
import hre from "hardhat";
const { waffle, ethers } = hre;
const { provider, deployContract } = waffle;
import { Signer, Contract } from "ethers";
import { BigNumber } from "bignumber.js";
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 { addresses } from "../../../scripts/tests/mainnet/addresses";
import { tokens, dsaMaxValue } from "../../../scripts/tests/mainnet/tokens";
import { abis } from "../../../scripts/constant/abis";
import { constants } from "../../../scripts/constant/constant";
import { ConnectV2CurveUSD__factory, IERC20Minimal__factory } from "../../../typechain";
// import ABI_Ctr from "./ABI.json"
describe("CRV USD", function () {
const connectorName = "CRV_USD-TEST-A";
const market = "0xc3d688B66703497DAA19211EEdff47f25384cdc3";
const base = "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48";
const wst_whale = "0x78bB3aEC3d855431bd9289fD98dA13F9ebB7ef15";
const wethWhale = "0x78bB3aEC3d855431bd9289fD98dA13F9ebB7ef15";
const wethContract = new ethers.Contract(
tokens.weth.address,
IERC20Minimal__factory.abi,
ethers.provider
);
const baseContract = new ethers.Contract(
base,
IERC20Minimal__factory.abi,
ethers.provider
);
const linkContract = new ethers.Contract(
tokens.wbtc.address,
IERC20Minimal__factory.abi,
ethers.provider
);
const crvUSD = new ethers.Contract(
tokens.crvusd.address,
IERC20Minimal__factory.abi,
ethers.provider
);
const sfrxEth = new ethers.Contract(
tokens.sfrxeth.address,
IERC20Minimal__factory.abi,
ethers.provider
);
let dsaWallet0: any;
let dsaWallet1: any;
let dsaWallet2: any;
let dsaWallet3: any;
let wallet: any;
let dsa0Signer: any;
let masterSigner: Signer;
let instaConnectorsV2: Contract;
let connector: any;
let signer: any;
let sfrxSigner: any;
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: 17811076
}
}
]
});
masterSigner = await getMasterSigner();
instaConnectorsV2 = await ethers.getContractAt(abis.core.connectorsV2, addresses.core.connectorsV2);
connector = await deployAndEnableConnector({
connectorName,
contractArtifact: ConnectV2CurveUSD__factory,
signer: masterSigner,
connectors: instaConnectorsV2
});
console.log("Connector address", connector.address);
await hre.network.provider.send("hardhat_setBalance", [wst_whale, ethers.utils.parseEther("10").toHexString()]);
await hre.network.provider.request({
method: "hardhat_impersonateAccount",
params: [wst_whale]
});
signer = await ethers.getSigner(wst_whale);
});
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;
dsaWallet1 = await buildDSAv2(wallet0.address);
expect(!!dsaWallet1.address).to.be.true;
dsaWallet2 = await buildDSAv2(wallet0.address);
expect(!!dsaWallet2.address).to.be.true;
dsaWallet3 = await buildDSAv2(wallet0.address);
expect(!!dsaWallet3.address).to.be.true;
wallet = await ethers.getSigner(dsaWallet0.address);
expect(!!dsaWallet1.address).to.be.true;
});
it("Deposit ETH into DSA wallet", async function () {
await hre.network.provider.request({
method: "hardhat_impersonateAccount",
params: [wallet.address]
});
dsa0Signer = await ethers.getSigner(wallet.address);
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 wallet0.sendTransaction({
to: dsaWallet1.address,
value: ethers.utils.parseEther("10")
});
expect(await ethers.provider.getBalance(dsaWallet0.address)).to.be.gte(ethers.utils.parseEther("10"));
await wallet0.sendTransaction({
to: dsaWallet3.address,
value: ethers.utils.parseEther("10")
});
expect(await ethers.provider.getBalance(dsaWallet0.address)).to.be.gte(ethers.utils.parseEther("10"));
let txRes = await sfrxEth.connect(signer).transfer(dsaWallet0.address, ethers.utils.parseEther("10000"));
await txRes.wait();
txRes = await sfrxEth.connect(signer).transfer(dsaWallet1.address, ethers.utils.parseEther("1000"));
await txRes.wait();
txRes = await sfrxEth.connect(signer).transfer(dsaWallet2.address, ethers.utils.parseEther("1000"));
await txRes.wait();
});
});
describe("Main", function () {
//deposit asset
it("Create Loan", async function () {
const spells = [
{
connector: connectorName,
method: "createLoan",
args: [tokens.sfrxeth.address, ethers.utils.parseEther('1').toString(), ethers.utils.parseEther('1000'), "10", "1", "0", "0"]
}
];
const tx = await dsaWallet0.connect(wallet0).cast(...encodeSpells(spells), wallet1.address);
await tx.wait();
expect(await crvUSD.balanceOf(dsaWallet0.address)).to.be.eq(
ethers.utils.parseEther("1000")
);
});
it("add Collateral", async function () {
const balanceBefore = await sfrxEth.balanceOf(dsaWallet0.address)
const spells = [
{
connector: connectorName,
method: "addCollateral",
args: [tokens.sfrxeth.address, ethers.utils.parseEther('1').toString(), "1", 0, 0]
}
];
const tx = await dsaWallet0.connect(wallet0).cast(...encodeSpells(spells), wallet1.address);
await tx.wait();
expect(await sfrxEth.balanceOf(dsaWallet0.address)).to.be.eq(
ethers.BigNumber.from(balanceBefore).sub(ethers.utils.parseEther('1'))
);
});
it("remove Collateral", async function () {
const balance = await sfrxEth.balanceOf(dsaWallet0.address)
const spells = [
{
connector: connectorName,
method: "removeCollateral",
args: [tokens.sfrxeth.address, ethers.utils.parseEther('1').toString(), "1", 0, 0]
}
];
const tx = await dsaWallet0.connect(wallet0).cast(...encodeSpells(spells), wallet1.address);
await tx.wait();
expect(await sfrxEth.balanceOf(dsaWallet0.address)).to.be.eq(
ethers.BigNumber.from(balance).add(ethers.utils.parseEther('1'))
);
});
it("borrow more", async function () {
const balance = await crvUSD.balanceOf(dsaWallet0.address)
const spells = [
{
connector: connectorName,
method: "borrowMore",
args: [tokens.sfrxeth.address, ethers.utils.parseEther('50'), "1", 0, 0]
}
];
const tx = await dsaWallet0.connect(wallet0).cast(...encodeSpells(spells), wallet1.address);
await tx.wait();
expect(await crvUSD.balanceOf(dsaWallet0.address)).to.be.eq(
ethers.BigNumber.from(balance).add(ethers.utils.parseEther('50'))
);
});
it("addCollateralAndBorrowMore with maximum value", async function () {
const balance = await crvUSD.balanceOf(dsaWallet0.address)
const spells = [
{
connector: connectorName,
method: "addCollateralAndBorrowMore",
args: [tokens.sfrxeth.address, ethers.utils.parseEther('2'), dsaMaxValue, 1, 0, 0]
}
];
const tx = await dsaWallet0.connect(wallet0).cast(...encodeSpells(spells), wallet1.address);
await tx.wait();
expect(await crvUSD.balanceOf(dsaWallet0.address)).to.be.gt(
ethers.BigNumber.from(balance).add(ethers.utils.parseEther('100'))
);
});
it("Revert when loan exists", async function () {
const spells = [
{
connector: connectorName,
method: "createLoan",
args: [tokens.sfrxeth.address, ethers.utils.parseEther('1').toString(), dsaMaxValue, 10, "1", "0", "0"]
}
];
await expect(dsaWallet0.connect(wallet0).cast(...encodeSpells(spells), wallet1.address)).to.be.revertedWith('Loan already created');
});
it("create loan with maximum debt", async function () {
const spells = [
{
connector: connectorName,
method: "createLoan",
args: [tokens.sfrxeth.address, ethers.utils.parseEther('1').toString(), dsaMaxValue, 10, "1", "0", "0"]
}
];
const tx = await dsaWallet1.connect(wallet0).cast(...encodeSpells(spells), wallet1.address);
await tx.wait();
expect(await crvUSD.balanceOf(dsaWallet1.address)).to.be.gt(
ethers.utils.parseEther("1000")
);
console.log("maximum debt amount: ", (await crvUSD.balanceOf(dsaWallet1.address)).toString() )
});
it("Repay loans", async function () {
const balance = await crvUSD.balanceOf(dsaWallet1.address)
const spells = [
{
connector: connectorName,
method: "repay",
args: [tokens.sfrxeth.address, ethers.utils.parseEther('100').toString(), "1", "0", "0"]
}
];
const tx = await dsaWallet1.connect(wallet0).cast(...encodeSpells(spells), wallet1.address);
expect(await crvUSD.balanceOf(dsaWallet1.address)).to.be.eq(
ethers.BigNumber.from(balance).sub(ethers.utils.parseEther('100'))
);
});
it("Repay loans with max value", async function () {
const balance = await crvUSD.balanceOf(dsaWallet1.address)
const spells = [
{
connector: connectorName,
method: "repay",
args: [tokens.sfrxeth.address, dsaMaxValue, "1", "0", "0"]
}
];
await dsaWallet1.connect(wallet0).cast(...encodeSpells(spells), wallet1.address);
expect(await crvUSD.balanceOf(dsaWallet1.address)).to.be.eq(0);
});
it("Create Loan with maximum collateral and maximum debt", async function () {
const spells = [
{
connector: connectorName,
method: "createLoan",
args: [tokens.sfrxeth.address, dsaMaxValue, dsaMaxValue, 10, "1", "0", "0"]
}
];
const tx = await dsaWallet2.connect(wallet0).cast(...encodeSpells(spells), wallet1.address);
await tx.wait();
expect(await crvUSD.balanceOf(dsaWallet2.address)).to.be.gt(
ethers.utils.parseEther("1000").toString()
);
expect(await sfrxEth.balanceOf(dsaWallet2.address)).to.be.eq(
'0'
);
console.log("maximum debt amount after maximum collateral: ", (await crvUSD.balanceOf(dsaWallet2.address)).toString() )
});
it("Create Loan with eth", async function () {
const balance = await ethers.provider.getBalance(dsaWallet0.address)
const spells = [
{
connector: connectorName,
method: "createLoan",
args: [tokens.eth.address, ethers.utils.parseEther('2').toString(), dsaMaxValue, 10, "0", "0", "0"]
}
];
const tx = await dsaWallet0.connect(wallet0).cast(...encodeSpells(spells), wallet1.address);
await tx.wait();
expect(await ethers.provider.getBalance(dsaWallet0.address)).to.be.eq(
ethers.BigNumber.from(balance).sub(ethers.utils.parseEther('2'))
);
console.log("maximum debt amount after create loan with 2 eth: ", (await crvUSD.balanceOf(dsaWallet0.address)).toString() )
});
it("add Collateral eth", async function () {
const balance = await ethers.provider.getBalance(dsaWallet0.address)
const spells = [
{
connector: connectorName,
method: "addCollateral",
args: [tokens.eth.address, ethers.utils.parseEther('3').toString(), 0, 0, 0]
}
];
const tx = await dsaWallet0.connect(wallet0).cast(...encodeSpells(spells), wallet1.address);
await tx.wait();
expect(await ethers.provider.getBalance(dsaWallet0.address)).to.be.eq(
ethers.BigNumber.from(balance).sub(ethers.utils.parseEther('3'))
);
});
it("remove Collateral eth", async function () {
const balance = await ethers.provider.getBalance(dsaWallet0.address)
const spells = [
{
connector: connectorName,
method: "removeCollateral",
args: [tokens.eth.address, ethers.utils.parseEther('1').toString(), 0, 0, 0]
}
];
const tx = await dsaWallet0.connect(wallet0).cast(...encodeSpells(spells), wallet1.address);
await tx.wait();
expect(await ethers.provider.getBalance(dsaWallet0.address)).to.be.eq(
ethers.BigNumber.from(balance).add(ethers.utils.parseEther('1'))
);
});
it("borrow more", async function () {
const balance = await crvUSD.balanceOf(dsaWallet0.address)
const spells = [
{
connector: connectorName,
method: "borrowMore",
args: [tokens.eth.address, ethers.utils.parseEther('10'), 0, 0, 0]
}
];
const tx = await dsaWallet0.connect(wallet0).cast(...encodeSpells(spells), wallet1.address);
await tx.wait();
expect(await crvUSD.balanceOf(dsaWallet0.address)).to.be.eq(
ethers.BigNumber.from(balance).add(ethers.utils.parseEther('10'))
);
});
it("borrow more", async function () {
const balance = await crvUSD.balanceOf(dsaWallet0.address)
const spells = [
{
connector: connectorName,
method: "borrowMore",
args: [tokens.eth.address, dsaMaxValue, 0, 0, 0]
}
];
const tx = await dsaWallet0.connect(wallet0).cast(...encodeSpells(spells), wallet1.address);
await tx.wait();
expect(await crvUSD.balanceOf(dsaWallet0.address)).to.be.gt(
ethers.BigNumber.from(balance).add(ethers.utils.parseEther('1000'))
);
});
it("Repay loans", async function () {
const balance = await crvUSD.balanceOf(dsaWallet0.address)
const spells = [
{
connector: connectorName,
method: "repay",
args: [tokens.eth.address, ethers.utils.parseEther('100').toString(), "0", "0", "0"]
}
];
const tx = await dsaWallet0.connect(wallet0).cast(...encodeSpells(spells), wallet1.address);
expect(await crvUSD.balanceOf(dsaWallet0.address)).to.be.eq(
ethers.BigNumber.from(balance).sub(ethers.utils.parseEther('100'))
);
});
it("Repay loans with max value", async function () {
const balance = await crvUSD.balanceOf(dsaWallet0.address)
const spells = [
{
connector: connectorName,
method: "repay",
args: [tokens.eth.address, dsaMaxValue, "0", "0", "0"]
}
];
await dsaWallet0.connect(wallet0).cast(...encodeSpells(spells), wallet1.address);
console.log("crv balance after repay with max value: ",await crvUSD.balanceOf(dsaWallet0.address))
});
});
});

View File

@ -0,0 +1,176 @@
import hre from "hardhat";
import axios from "axios";
import { expect } from "chai";
const { ethers } = hre; //check
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 { addresses } from "../../../scripts/tests/mainnet/addresses";
import { abis } from "../../../scripts/constant/abis";
import { ConnectV2DSASpell__factory } from "../../../typechain";
import type { Signer, Contract } from "ethers";
import BigNumber from "bignumber.js";
describe("DSA Spell", function () {
const connectorName = "dsa-spell-test";
let dsaWallet0: any;
let dsaWallet1: any;
let dsaWallet2: any;
let walletB: any;
let wallet0: any;
let masterSigner: Signer;
let instaConnectorsV2: Contract;
let connector: any;
before(async () => {
await hre.network.provider.request({
method: "hardhat_reset",
params: [
{
forking: {
// @ts-ignore
jsonRpcUrl: hre.config.networks.hardhat.forking.url
}
}
]
});
[wallet0] = await ethers.getSigners();
masterSigner = await getMasterSigner();
instaConnectorsV2 = await ethers.getContractAt(abis.core.connectorsV2, addresses.core.connectorsV2);
connector = await deployAndEnableConnector({
connectorName,
contractArtifact: ConnectV2DSASpell__factory,
signer: masterSigner,
connectors: instaConnectorsV2
});
console.log("\tConnector 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;
walletB = await ethers.getSigner(dsaWallet0.address);
dsaWallet1 = await buildDSAv2(dsaWallet0.address);
expect(!!dsaWallet1.address).to.be.true;
console.log(`\t${dsaWallet1.address}`);
});
it("Deposit eth into DSA wallet 0", 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 into DSA wallet 1", async function () {
await wallet0.sendTransaction({
to: dsaWallet1.address,
value: ethers.utils.parseEther("10")
});
expect(await ethers.provider.getBalance(dsaWallet1.address)).to.be.gte(ethers.utils.parseEther("10"));
});
});
describe("Main", function () {
let ETH = "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE";
let USDC = "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48";
let usdc = new ethers.Contract(USDC, abis.basic.erc20);
let aETH = "0x030bA81f1c18d280636F32af80b9AAd02Cf0854e";
let aEth = new ethers.Contract(aETH, abis.basic.aToken);
var abi = [
"function withdraw(address,uint256,address,uint256,uint256)",
"function deposit(address,uint256,uint256,uint256)",
"function borrow(address,uint256,uint256,uint256,uint256)"
];
function getCallData(spell: string, params: any) {
var iface = new ethers.utils.Interface(abi);
let data = iface.encodeFunctionData(spell, params);
return ethers.utils.hexlify(data);
}
it("should cast spells", async function () {
async function getArg(connectors: any, spells: any, params: any) {
let datas = [];
for (let i = 0; i < connectors.length; i++) {
datas.push(getCallData(spells[i], params[i]));
}
return [dsaWallet1.address, connectors, datas];
}
let connectors = ["BASIC-A"];
let methods = ["withdraw"];
let params = [
[ETH, ethers.utils.parseEther("2"), dsaWallet0.address, 0, 0],
];
let arg = await getArg(connectors, methods, params);
const spells = [
{
connector: connectorName,
method: "castOnDSA",
args: arg
}
];
const tx = await dsaWallet0.connect(wallet0).cast(...encodeSpells(spells), await wallet0.getAddress());
const receipt = await tx.wait();
});
it("should check balances after cast on DSA", async function () {
expect(await ethers.provider.getBalance(dsaWallet1.address)).to.be.lte(new BigNumber(8).multipliedBy(1e18).toString());
expect(await ethers.provider.getBalance(dsaWallet0.address)).to.be.gte(
new BigNumber(12).multipliedBy(1e18).toString()
);
});
it("should cast spell on the first successful", async function () {
async function getArg(connectors: any, spells: any, params: any) {
let datas = [];
for (let i = 0; i < connectors.length; i++) {
datas.push(getCallData(spells[i], params[i]));
}
return [connectors, datas];
}
let connectors = ["AAVE-V2-A", "AAVE-V1-A"];
let methods = ["deposit", "deposit"];
let params = [
[ETH, ethers.utils.parseEther("10"), 0, 0],
[ETH, ethers.utils.parseEther("10"), 0, 0]
];
let arg = await getArg(connectors, methods, params);
const spells = [
{
connector: connectorName,
method: "castAny",
args: arg
}
];
const tx = await dsaWallet0
.connect(wallet0)
.cast(...encodeSpells(spells), await wallet0.getAddress());
const receipt = await tx.wait();
});
it("should check balances after spells on DSA", async function () {
expect(await ethers.provider.getBalance(dsaWallet0.address)).to.be.lte(
new BigNumber(2).multipliedBy(1e18).toString()
);
expect(await aEth.connect(wallet0).balanceOf(dsaWallet0.address)).to.be.gte(
new BigNumber(10).multipliedBy(1e18).toString()
);
});
});
});

View File

@ -0,0 +1,268 @@
import { expect } from "chai";
import hre from "hardhat";
import { abis } from "../../../scripts/constant/abis";
import { addresses } from "../../../scripts/tests/mainnet/addresses";
import { deployAndEnableConnector } from "../../../scripts/tests/deployAndEnableConnector";
import { getMasterSigner } from "../../../scripts/tests/getMasterSigner";
import { buildDSAv2 } from "../../../scripts/tests/buildDSAv2";
import { ConnectV2EulerImport__factory, IERC20__factory } from "../../../typechain";
import { parseEther, parseUnits } from "@ethersproject/units";
import { encodeSpells } from "../../../scripts/tests/encodeSpells";
const { ethers } = hre;
import type { Signer, Contract } from "ethers";
import { BigNumber } from "bignumber.js";
import { Address } from "@project-serum/anchor";
const DAI = '0x6b175474e89094c44da98b954eedeac495271d0f'
const Dai = parseUnits('50', 18)
const WETH = '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2'
const ACC_WETH = '0x05547D4e1A2191B91510Ea7fA8555a2788C70030'
const Weth = parseUnits('50', 18)
const ETH = '0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE'
const token_weth = new ethers.Contract(
WETH,
[{"constant":true,"inputs":[],"name":"name","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"guy","type":"address"},{"name":"wad","type":"uint256"}],"name":"approve","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"totalSupply","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"src","type":"address"},{"name":"dst","type":"address"},{"name":"wad","type":"uint256"}],"name":"transferFrom","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"wad","type":"uint256"}],"name":"withdraw","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"decimals","outputs":[{"name":"","type":"uint8"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"","type":"address"}],"name":"balanceOf","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"symbol","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"dst","type":"address"},{"name":"wad","type":"uint256"}],"name":"transfer","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"deposit","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"constant":true,"inputs":[{"name":"","type":"address"},{"name":"","type":"address"}],"name":"allowance","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"payable":true,"stateMutability":"payable","type":"fallback"},{"anonymous":false,"inputs":[{"indexed":true,"name":"src","type":"address"},{"indexed":true,"name":"guy","type":"address"},{"indexed":false,"name":"wad","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"src","type":"address"},{"indexed":true,"name":"dst","type":"address"},{"indexed":false,"name":"wad","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"dst","type":"address"},{"indexed":false,"name":"wad","type":"uint256"}],"name":"Deposit","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"src","type":"address"},{"indexed":false,"name":"wad","type":"uint256"}],"name":"Withdrawal","type":"event"}],
// IERC20__factory.abi,
ethers.provider,
)
const token_dai = new ethers.Contract(
DAI,
IERC20__factory.abi,
ethers.provider,
)
const eTokensABI = [
"function approve(address, uint256) public",
"function balanceOf(address account) public view returns (uint256)",
"function allowance(address, address) public returns (uint256)",
"function deposit(uint256,uint256) public",
"function balanceOfUnderlying(address) public view returns (uint256)",
"function mint(uint256,uint256) public",
"function approveSubAccount(uint256, address, uint256) public"
];
const dTokensABI = [
"function balanceOf(address account) public view returns (uint256)",
"function borrow(uint256,uint256) public"
];
const marketsABI = [
"function enterMarket(uint256,address) public",
"function underlyingToEToken(address) public view returns (address)",
"function underlyingToDToken(address) public view returns (address)"
]
const eWethAddress = '0x1b808F49ADD4b8C6b5117d9681cF7312Fcf0dC1D';
const eWethContract = new ethers.Contract(eWethAddress, eTokensABI);
const dWethAddress = '0x62e28f054efc24b26A794F5C1249B6349454352C'
const dWethContract = new ethers.Contract(dWethAddress, dTokensABI);
const dDaiAddress = '0x6085Bc95F506c326DCBCD7A6dd6c79FBc18d4686';
const dDaiContract = new ethers.Contract(dDaiAddress, dTokensABI);
const euler_mainnet = '0x27182842E098f60e3D576794A5bFFb0777E025d3'
const euler_markets = '0x3520d5a913427E6F0D6A83E07ccD4A4da316e4d3'
const marketsContract = new ethers.Contract(euler_markets, marketsABI);
describe("Euler", function () {
const connectorName = "EULER-IMPORT-TEST-A";
let connector: any;
let wallet0: Signer, wallet1:Signer;
let dsaWallet0: any;
let instaConnectorsV2: Contract;
let masterSigner: Signer;
let walletAddr: Address;
let subAcc1: Address;
let subAcc2DSA: Address;
before(async () => {
await hre.network.provider.request({
method: "hardhat_reset",
params: [
{
forking: {
// @ts-ignore
jsonRpcUrl: hre.config.networks.hardhat.forking.url,
blockNumber: 15379000,
},
},
],
});
[wallet0, wallet1] = await ethers.getSigners();
await hre.network.provider.send("hardhat_setBalance", [ACC_WETH, ethers.utils.parseEther("10").toHexString()]);
await hre.network.provider.request({
method: "hardhat_impersonateAccount",
params: [ACC_WETH]
});
const signer_weth = await ethers.getSigner(ACC_WETH)
await token_weth.connect(signer_weth).transfer(wallet0.getAddress(), ethers.utils.parseEther("8"));
console.log("WETH transferred to wallet0");
await hre.network.provider.request({
method: 'hardhat_stopImpersonatingAccount',
params: [ACC_WETH],
})
masterSigner = await getMasterSigner();
instaConnectorsV2 = await ethers.getContractAt(
abis.core.connectorsV2,
addresses.core.connectorsV2
);
connector = await deployAndEnableConnector({
connectorName,
contractArtifact: ConnectV2EulerImport__factory,
signer: masterSigner,
connectors: instaConnectorsV2,
});
console.log("Connector address", connector.address);
walletAddr = (await wallet0.getAddress()).toString()
console.log("walletAddr: ", walletAddr)
subAcc1 = ethers.BigNumber.from(walletAddr).xor(1).toHexString()
console.log("subAcc1: ", subAcc1)
});
it("should have contracts deployed", async () => {
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.getAddress());
expect(!!dsaWallet0.address).to.be.true;
subAcc2DSA = ethers.BigNumber.from(dsaWallet0.address).xor(2).toHexString()
console.log("subAcc2DSA: ", subAcc2DSA)
});
it("Deposit ETH into DSA wallet", async function () {
await wallet0.sendTransaction({
to: dsaWallet0.address,
value: parseEther("10"),
});
expect(await ethers.provider.getBalance(dsaWallet0.address)).to.be.gte(
parseEther("10")
);
});
describe("Create Euler position in SUBACCOUNT 0", async () => {
it("Should create Euler position of WETH(collateral) and DAI(debt)", async () => {
// approve WETH to euler
await token_weth.connect(wallet0).approve(euler_mainnet, Weth);
console.log("Approved WETH");
// deposit WETH in euler
await eWethContract.connect(wallet0).deposit("0", parseEther("2"));
expect(await eWethContract.connect(wallet0).balanceOfUnderlying(walletAddr)).to.be.gte(parseEther("1.9"));
console.log("Supplied WETH on Euler");
// enter WETH market
await marketsContract.connect(wallet0).enterMarket("0", WETH);
console.log("Entered market for WETH");
// borrow DAI from Euler
await dDaiContract.connect(wallet0).borrow("0", Dai);
console.log("Borrowed DAI from Euler");
});
it("Should check created position of user", async () => {
expect(await token_dai.connect(wallet0).balanceOf(walletAddr)).to.be.gte(
parseUnits('50', 18)
);
});
});
describe("Create Euler self-position in SUBACCOUNT 1", async () => {
it("Should create Euler self-position of WETH(collateral) and WETH(debt)", async () => {
// approve WETH to euler
await token_weth.connect(wallet0).approve(euler_mainnet, Weth);
console.log("Approved WETH");
// deposit WETH in euler
await eWethContract.connect(wallet0).deposit("1", parseEther("2"));
expect(await eWethContract.connect(wallet0).balanceOfUnderlying(subAcc1)).to.be.gte(parseEther("1.9"));
console.log("Supplied WETH on Euler");
// enter WETH market
await marketsContract.connect(wallet0).enterMarket("1", WETH);
console.log("Entered market for WETH");
// mint WETH from Euler
await eWethContract.connect(wallet0).mint("1", parseEther("1"));
expect(await eWethContract.connect(wallet0).balanceOfUnderlying(subAcc1)).to.be.gte(parseEther("2.9"));
console.log("Minted WETH from Euler");
});
it("Should check created position of user", async () => {
expect(await eWethContract.connect(wallet0).balanceOfUnderlying(subAcc1)).to.be.gte(parseEther("2.9"));
});
});
describe("Euler position migration", async () => {
it("Approve sub-account0 eTokens for import to DSA sub-account 0", async () => {
let balance = await eWethContract.connect(wallet0).balanceOf(walletAddr)
await eWethContract.connect(wallet0).approve(dsaWallet0.address, balance);
});
it("Approve sub-account1 eTokens for import to DSA sub-account 2", async () => {
let balance = await eWethContract.connect(wallet0).balanceOf(subAcc1)
await eWethContract.connect(wallet0).approveSubAccount("1", dsaWallet0.address, balance);
});
it("Should migrate euler position of sub-account 0 to DSA sub-account 0", async () => {
const spells = [
{
connector: "EULER-IMPORT-TEST-A",
method: "importEuler",
args: [
walletAddr,
"0",
"0",
[[ETH],[DAI],["true"]]
]
},
];
const tx = await dsaWallet0.connect(wallet0).cast(...encodeSpells(spells), wallet0.getAddress());
const receipt = await tx.wait();
});
it("Should check migration", async () => {
expect(await eWethContract.connect(wallet0).balanceOfUnderlying(dsaWallet0.address)).to.be.gte(parseEther("2"));
expect(await dDaiContract.connect(wallet0).balanceOf(dsaWallet0.address)).to.be.gte(parseEther("50"));
});
it("Should migrate euler position of sub-account 1 to DSA sub-account 2", async () => {
const spells = [
{
connector: "EULER-IMPORT-TEST-A",
method: "importEuler",
args: [
walletAddr,
"1",
"2",
[[ETH],[ETH],["true"]]
]
},
];
const tx = await dsaWallet0.connect(wallet0).cast(...encodeSpells(spells), wallet0.getAddress());
const receipt = await tx.wait();
});
it("Should check migration", async () => {
expect(await eWethContract.connect(wallet0).balanceOfUnderlying(subAcc2DSA)).to.be.gte(parseEther("3"));
expect(await dWethContract.connect(wallet0).balanceOf(subAcc2DSA)).to.be.gte(parseEther("1"));
});
})
});
})

Some files were not shown because too many files have changed in this diff Show More