mirror of
https://github.com/Instadapp/dsa-connectors.git
synced 2024-07-29 22:37:00 +00:00
Merge pull request #249 from Instadapp/Euler-import-connector
Euler import connector
This commit is contained in:
commit
5ede687dff
16
contracts/mainnet/connectors/euler/import/events.sol
Normal file
16
contracts/mainnet/connectors/euler/import/events.sol
Normal file
|
@ -0,0 +1,16 @@
|
|||
//SPDX-License-Identifier: MIT
|
||||
pragma solidity ^0.7.0;
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
contract Events {
|
||||
event LogEulerImport(
|
||||
address user,
|
||||
uint256 sourceId,
|
||||
uint256 targetId,
|
||||
address[] supplyTokens,
|
||||
uint256[] supplyAmounts,
|
||||
address[] borrowTokens,
|
||||
uint256[] borrowAmounts,
|
||||
bool[] enterMarket
|
||||
);
|
||||
}
|
111
contracts/mainnet/connectors/euler/import/helpers.sol
Normal file
111
contracts/mainnet/connectors/euler/import/helpers.sol
Normal file
|
@ -0,0 +1,111 @@
|
|||
//SPDX-License-Identifier: MIT
|
||||
pragma solidity ^0.7.0;
|
||||
pragma experimental ABIEncoderV2;
|
||||
import { TokenInterface, AccountInterface } from "../../../common/interfaces.sol";
|
||||
import { Basic } from "../../../common/basic.sol";
|
||||
import "./interface.sol";
|
||||
|
||||
contract EulerHelpers is Basic {
|
||||
/**
|
||||
* @dev Euler's Market Module
|
||||
*/
|
||||
IEulerMarkets internal constant markets =
|
||||
IEulerMarkets(0x3520d5a913427E6F0D6A83E07ccD4A4da316e4d3);
|
||||
|
||||
/**
|
||||
* @dev Euler's Execution Module
|
||||
*/
|
||||
IEulerExecute internal constant eulerExec =
|
||||
IEulerExecute(0x59828FdF7ee634AaaD3f58B19fDBa3b03E2D9d80);
|
||||
|
||||
/**
|
||||
* @dev Compute sub account address.
|
||||
* @notice Compute sub account address from sub-account id
|
||||
* @param primary primary address
|
||||
* @param subAccountId sub-account id whose address needs to be computed
|
||||
*/
|
||||
function getSubAccountAddress(address primary, uint256 subAccountId)
|
||||
public
|
||||
pure
|
||||
returns (address)
|
||||
{
|
||||
require(subAccountId < 256, "sub-account-id-too-big");
|
||||
return address(uint160(primary) ^ uint160(subAccountId));
|
||||
}
|
||||
|
||||
struct ImportInputData {
|
||||
address[] _supplyTokens;
|
||||
address[] _borrowTokens;
|
||||
bool[] _enterMarket;
|
||||
}
|
||||
|
||||
struct ImportData {
|
||||
address[] supplyTokens;
|
||||
address[] borrowTokens;
|
||||
EulerTokenInterface[] eTokens;
|
||||
EulerTokenInterface[] dTokens;
|
||||
uint256[] supplyAmts;
|
||||
uint256[] borrowAmts;
|
||||
}
|
||||
|
||||
struct ImportHelper {
|
||||
uint256 supplylength;
|
||||
uint256 borrowlength;
|
||||
uint256 totalExecutions;
|
||||
address sourceAccount;
|
||||
address targetAccount;
|
||||
}
|
||||
|
||||
function getSupplyAmounts(
|
||||
address userAccount, // user's EOA sub-account address
|
||||
ImportInputData memory inputData,
|
||||
ImportData memory data
|
||||
) internal view returns (ImportData memory) {
|
||||
data.supplyAmts = new uint256[](inputData._supplyTokens.length);
|
||||
data.supplyTokens = new address[](inputData._supplyTokens.length);
|
||||
data.eTokens = new EulerTokenInterface[](
|
||||
inputData._supplyTokens.length
|
||||
);
|
||||
uint256 length_ = inputData._supplyTokens.length;
|
||||
|
||||
for (uint256 i = 0; i < length_; i++) {
|
||||
address token_ = inputData._supplyTokens[i] == ethAddr
|
||||
? wethAddr
|
||||
: inputData._supplyTokens[i];
|
||||
data.supplyTokens[i] = token_;
|
||||
data.eTokens[i] = EulerTokenInterface(
|
||||
markets.underlyingToEToken(token_)
|
||||
);
|
||||
data.supplyAmts[i] = data.eTokens[i].balanceOf(userAccount); //All 18 dec
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
function getBorrowAmounts(
|
||||
address userAccount, // user's EOA sub-account address
|
||||
ImportInputData memory inputData,
|
||||
ImportData memory data
|
||||
) internal view returns (ImportData memory) {
|
||||
uint256 borrowTokensLength_ = inputData._borrowTokens.length;
|
||||
|
||||
if (borrowTokensLength_ > 0) {
|
||||
data.borrowTokens = new address[](borrowTokensLength_);
|
||||
data.dTokens = new EulerTokenInterface[](borrowTokensLength_);
|
||||
data.borrowAmts = new uint256[](borrowTokensLength_);
|
||||
|
||||
for (uint256 i = 0; i < borrowTokensLength_; i++) {
|
||||
address _token = inputData._borrowTokens[i] == ethAddr
|
||||
? wethAddr
|
||||
: inputData._borrowTokens[i];
|
||||
|
||||
data.borrowTokens[i] = _token;
|
||||
data.dTokens[i] = EulerTokenInterface(
|
||||
markets.underlyingToDToken(_token)
|
||||
);
|
||||
data.borrowAmts[i] = data.dTokens[i].balanceOf(userAccount);
|
||||
}
|
||||
}
|
||||
return data;
|
||||
}
|
||||
}
|
56
contracts/mainnet/connectors/euler/import/interface.sol
Normal file
56
contracts/mainnet/connectors/euler/import/interface.sol
Normal file
|
@ -0,0 +1,56 @@
|
|||
//SPDX-License-Identifier: MIT
|
||||
pragma solidity ^0.7.0;
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
interface EulerTokenInterface {
|
||||
function balanceOf(address _user) external view returns (uint256);
|
||||
|
||||
function transferFrom(
|
||||
address,
|
||||
address,
|
||||
uint256
|
||||
) external returns (bool);
|
||||
|
||||
function allowance(address, address) external returns (uint256);
|
||||
}
|
||||
|
||||
interface IEulerMarkets {
|
||||
function enterMarket(uint256 subAccountId, address newMarket) external;
|
||||
|
||||
function getEnteredMarkets(address account)
|
||||
external
|
||||
view
|
||||
returns (address[] memory);
|
||||
|
||||
function exitMarket(uint256 subAccountId, address oldMarket) external;
|
||||
|
||||
function underlyingToEToken(address underlying)
|
||||
external
|
||||
view
|
||||
returns (address);
|
||||
|
||||
function underlyingToDToken(address underlying)
|
||||
external
|
||||
view
|
||||
returns (address);
|
||||
}
|
||||
|
||||
interface IEulerExecute {
|
||||
struct EulerBatchItem {
|
||||
bool allowError;
|
||||
address proxyAddr;
|
||||
bytes data;
|
||||
}
|
||||
|
||||
struct EulerBatchItemResponse {
|
||||
bool success;
|
||||
bytes result;
|
||||
}
|
||||
|
||||
function batchDispatch(
|
||||
EulerBatchItem[] calldata items,
|
||||
address[] calldata deferLiquidityChecks
|
||||
) external;
|
||||
|
||||
function deferLiquidityCheck(address account, bytes memory data) external;
|
||||
}
|
155
contracts/mainnet/connectors/euler/import/main.sol
Normal file
155
contracts/mainnet/connectors/euler/import/main.sol
Normal file
|
@ -0,0 +1,155 @@
|
|||
//SPDX-License-Identifier: MIT
|
||||
pragma solidity ^0.7.0;
|
||||
pragma experimental ABIEncoderV2;
|
||||
import "./helpers.sol";
|
||||
import "./interface.sol";
|
||||
import "./events.sol";
|
||||
|
||||
contract EulerImport is EulerHelpers {
|
||||
/**
|
||||
* @dev Import Euler position .
|
||||
* @notice Import EOA's Euler position to DSA's Euler position
|
||||
* @param userAccount EOA address
|
||||
* @param sourceId Sub-account id of "EOA" from which the funds will be transferred
|
||||
* @param targetId Sub-account id of "DSA" to which the funds will be transferred
|
||||
* @param inputData The struct containing all the neccessary input data
|
||||
*/
|
||||
function importEuler(
|
||||
address userAccount,
|
||||
uint256 sourceId,
|
||||
uint256 targetId,
|
||||
ImportInputData memory inputData
|
||||
)
|
||||
external
|
||||
payable
|
||||
returns (string memory _eventName, bytes memory _eventParam)
|
||||
{
|
||||
require(sourceId < 256 && targetId < 256, "Id should be less than 256");
|
||||
|
||||
(_eventName, _eventParam) = _importEuler(
|
||||
userAccount,
|
||||
sourceId,
|
||||
targetId,
|
||||
inputData
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Import Euler position .
|
||||
* @notice Import EOA's Euler position to DSA's Euler position
|
||||
* @param userAccount EOA address
|
||||
* @param sourceId Sub-account id of "EOA" from which the funds will be transferred
|
||||
* @param targetId Sub-account id of "DSA" to which the funds will be transferred
|
||||
* @param inputData The struct containing all the neccessary input data
|
||||
*/
|
||||
function _importEuler(
|
||||
address userAccount,
|
||||
uint256 sourceId,
|
||||
uint256 targetId,
|
||||
ImportInputData memory inputData
|
||||
) internal returns (string memory _eventName, bytes memory _eventParam) {
|
||||
require(inputData._supplyTokens.length > 0, "0-length-not-allowed");
|
||||
require(
|
||||
AccountInterface(address(this)).isAuth(userAccount),
|
||||
"user-account-not-auth"
|
||||
);
|
||||
require(
|
||||
inputData._enterMarket.length == inputData._supplyTokens.length,
|
||||
"lengths-not-same"
|
||||
);
|
||||
|
||||
ImportData memory data;
|
||||
ImportHelper memory helper;
|
||||
|
||||
helper.sourceAccount = getSubAccountAddress(userAccount, sourceId);
|
||||
helper.targetAccount = getSubAccountAddress(address(this), targetId);
|
||||
|
||||
// BorrowAmts will be in underlying token decimals
|
||||
data = getBorrowAmounts(helper.sourceAccount, inputData, data);
|
||||
|
||||
// SupplyAmts will be in 18 decimals
|
||||
data = getSupplyAmounts(helper.sourceAccount, inputData, data);
|
||||
|
||||
helper.supplylength = data.supplyTokens.length;
|
||||
helper.borrowlength = data.borrowTokens.length;
|
||||
uint16 enterMarketsLength = 0;
|
||||
|
||||
for (uint16 i = 0; i < inputData._enterMarket.length; i++) {
|
||||
if (inputData._enterMarket[i]) {
|
||||
++enterMarketsLength;
|
||||
}
|
||||
}
|
||||
|
||||
helper.totalExecutions =
|
||||
helper.supplylength +
|
||||
enterMarketsLength +
|
||||
helper.borrowlength;
|
||||
|
||||
IEulerExecute.EulerBatchItem[]
|
||||
memory items = new IEulerExecute.EulerBatchItem[](
|
||||
helper.totalExecutions
|
||||
);
|
||||
|
||||
uint16 k = 0;
|
||||
|
||||
for (uint16 i = 0; i < helper.supplylength; i++) {
|
||||
items[k++] = IEulerExecute.EulerBatchItem({
|
||||
allowError: false,
|
||||
proxyAddr: address(data.eTokens[i]),
|
||||
data: abi.encodeWithSignature(
|
||||
"transferFrom(address,address,uint256)",
|
||||
helper.sourceAccount,
|
||||
helper.targetAccount,
|
||||
data.supplyAmts[i]
|
||||
)
|
||||
});
|
||||
|
||||
if (inputData._enterMarket[i]) {
|
||||
items[k++] = IEulerExecute.EulerBatchItem({
|
||||
allowError: false,
|
||||
proxyAddr: address(markets),
|
||||
data: abi.encodeWithSignature(
|
||||
"enterMarket(uint256,address)",
|
||||
targetId,
|
||||
data.supplyTokens[i]
|
||||
)
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
for (uint16 j = 0; j < helper.borrowlength; j++) {
|
||||
items[k++] = IEulerExecute.EulerBatchItem({
|
||||
allowError: false,
|
||||
proxyAddr: address(data.dTokens[j]),
|
||||
data: abi.encodeWithSignature(
|
||||
"transferFrom(address,address,uint256)",
|
||||
helper.sourceAccount,
|
||||
helper.targetAccount,
|
||||
data.borrowAmts[j]
|
||||
)
|
||||
});
|
||||
}
|
||||
|
||||
address[] memory deferLiquidityChecks = new address[](2);
|
||||
deferLiquidityChecks[0] = helper.sourceAccount;
|
||||
deferLiquidityChecks[1] = helper.targetAccount;
|
||||
|
||||
eulerExec.batchDispatch(items, deferLiquidityChecks);
|
||||
|
||||
_eventName = "LogEulerImport(address,uint256,uint256,address[],uint256[],address[],uint256[],bool[])";
|
||||
_eventParam = abi.encode(
|
||||
userAccount,
|
||||
sourceId,
|
||||
targetId,
|
||||
inputData._supplyTokens,
|
||||
data.supplyAmts,
|
||||
inputData._borrowTokens,
|
||||
data.borrowAmts,
|
||||
inputData._enterMarket
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
contract ConnectV2EulerImport is EulerImport {
|
||||
string public constant name = "Euler-Import-v1.0";
|
||||
}
|
268
test/mainnet/euler-import/euler-import.test.ts
Normal file
268
test/mainnet/euler-import/euler-import.test.ts
Normal 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"));
|
||||
});
|
||||
})
|
||||
});
|
||||
})
|
Loading…
Reference in New Issue
Block a user