UNPKG

@melonproject/protocol

Version:

Technology Regulated and Operated Investment Funds

193 lines (192 loc) 12.6 kB
"use strict"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; Object.defineProperty(exports, "__esModule", { value: true }); const orderSignatures_1 = require("../../utils/constants/orderSignatures"); const token_math_1 = require("@melonproject/token-math"); const updateTestingPriceFeed_1 = require("../utils/updateTestingPriceFeed"); const getAllBalances_1 = require("../utils/getAllBalances"); const initTestEnvironment_1 = require("../utils/initTestEnvironment"); const getToken_1 = require("../../contracts/dependencies/token/calls/getToken"); const beginSetup_1 = require("../../contracts/factory/transactions/beginSetup"); const completeSetup_1 = require("../../contracts/factory/transactions/completeSetup"); const createAccounting_1 = require("../../contracts/factory/transactions/createAccounting"); const createFeeManager_1 = require("../../contracts/factory/transactions/createFeeManager"); const createParticipation_1 = require("../../contracts/factory/transactions/createParticipation"); const createPolicyManager_1 = require("../../contracts/factory/transactions/createPolicyManager"); const createShares_1 = require("../../contracts/factory/transactions/createShares"); const createTrading_1 = require("../../contracts/factory/transactions/createTrading"); const createVault_1 = require("../../contracts/factory/transactions/createVault"); const getFundComponents_1 = require("../../utils/getFundComponents"); const randomHexOfSize_1 = require("../../utils/helpers/randomHexOfSize"); const Contracts_1 = require("../../Contracts"); const withDifferentAccount_1 = require("../../utils/environment/withDifferentAccount"); const deployAndGetSystem_1 = require("../utils/deployAndGetSystem"); // mock data const NULL_ADDRESS = '0x0000000000000000000000000000000000000000'; const precisionUnits = token_math_1.power(new token_math_1.BigInteger(10), new token_math_1.BigInteger(18)); const kyberEthAddress = '0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE'; let s = {}; beforeAll(() => __awaiter(this, void 0, void 0, function* () { s.environment = yield initTestEnvironment_1.initTestEnvironment(); s.accounts = yield s.environment.eth.getAccounts(); const { addresses, contracts } = yield deployAndGetSystem_1.deployAndGetSystem(s.environment); s = Object.assign(s, contracts); s.addresses = addresses; s.mlnTokenInterface = yield getToken_1.getToken(s.environment, s.mln.options.address); s.wethTokenInterface = yield getToken_1.getToken(s.environment, s.weth.options.address); s.eurTokenInterface = yield getToken_1.getToken(s.environment, s.eur.options.address); [s.deployer, s.manager, s.investor] = s.accounts; s.exchanges = [s.kyberNetwork]; // , matchingMarket2]; s.gas = 8000000; s.opts = { from: s.deployer, gas: s.gas }; s.numberofExchanges = 1; const exchangeConfigs = { [Contracts_1.Exchanges.KyberNetwork]: { adapter: s.kyberAdapter.options.address, exchange: s.kyberNetwork.options.address, takesCustody: false, }, }; const envManager = withDifferentAccount_1.withDifferentAccount(s.environment, s.manager); yield updateTestingPriceFeed_1.updateTestingPriceFeed(s, s.environment); yield beginSetup_1.beginSetup(envManager, s.version.options.address, { defaultTokens: [s.wethTokenInterface, s.mlnTokenInterface], exchangeConfigs, fees: [], fundName: 'Test fund', quoteToken: s.wethTokenInterface, }); yield createAccounting_1.createAccounting(envManager, s.version.options.address); yield createFeeManager_1.createFeeManager(envManager, s.version.options.address); yield createParticipation_1.createParticipation(envManager, s.version.options.address); yield createPolicyManager_1.createPolicyManager(envManager, s.version.options.address); yield createShares_1.createShares(envManager, s.version.options.address); yield createTrading_1.createTrading(envManager, s.version.options.address); yield createVault_1.createVault(envManager, s.version.options.address); const hubAddress = yield completeSetup_1.completeSetup(envManager, s.version.options.address); s.fund = yield getFundComponents_1.getFundComponents(envManager, hubAddress); yield updateTestingPriceFeed_1.updateTestingPriceFeed(s, s.environment); yield updateTestingPriceFeed_1.updateTestingPriceFeed(s, s.environment); [, s.mlnPrice] = Object.values(yield s.priceSource.methods .getReferencePriceInfo(s.mln.options.address, s.weth.options.address) .call()).map(e => new token_math_1.BigInteger(e)); })); const initialTokenAmount = token_math_1.power(new token_math_1.BigInteger(10), new token_math_1.BigInteger(19)); test('investor gets initial ethToken for testing)', () => __awaiter(this, void 0, void 0, function* () { const pre = yield getAllBalances_1.getAllBalances(s, s.accounts, s.fund, s.environment); yield s.weth.methods .transfer(s.investor, `${initialTokenAmount}`) .send(s.opts); const post = yield getAllBalances_1.getAllBalances(s, s.accounts, s.fund, s.environment); expect(post.investor.weth).toEqual(token_math_1.add(pre.investor.weth, initialTokenAmount)); })); test('fund receives ETH from investment', () => __awaiter(this, void 0, void 0, function* () { const offeredValue = token_math_1.power(new token_math_1.BigInteger(10), new token_math_1.BigInteger(18)); const wantedShares = token_math_1.power(new token_math_1.BigInteger(10), new token_math_1.BigInteger(18)); const pre = yield getAllBalances_1.getAllBalances(s, s.accounts, s.fund, s.environment); yield s.weth.methods .approve(s.fund.participation.options.address, `${offeredValue}`) .send({ from: s.investor, gas: s.gas }); yield s.fund.participation.methods .requestInvestment(`${offeredValue}`, `${wantedShares}`, s.weth.options.address) .send({ from: s.investor, gas: s.gas, value: '10000000000000000' }); yield s.fund.participation.methods .executeRequestFor(s.investor) .send({ from: s.investor, gas: s.gas }); const post = yield getAllBalances_1.getAllBalances(s, s.accounts, s.fund, s.environment); expect(post.investor.weth).toEqual(token_math_1.subtract(pre.investor.weth, offeredValue)); expect(post.fund.weth).toEqual(token_math_1.add(pre.fund.weth, offeredValue)); })); test('swap ethToken for mln with specific order price (minRate)', () => __awaiter(this, void 0, void 0, function* () { const pre = yield getAllBalances_1.getAllBalances(s, s.accounts, s.fund, s.environment); const srcAmount = token_math_1.power(new token_math_1.BigInteger(10), new token_math_1.BigInteger(17)); const [bestRate] = Object.values(yield s.kyberNetwork.methods .getExpectedRate(kyberEthAddress, s.mln.options.address, `${srcAmount}`) .call()).map(e => new token_math_1.BigInteger(e)); const destAmount = token_math_1.divide(token_math_1.multiply(new token_math_1.BigInteger(srcAmount), bestRate), precisionUnits); yield s.fund.trading.methods .callOnExchange(0, orderSignatures_1.takeOrderSignature, [ NULL_ADDRESS, NULL_ADDRESS, s.mln.options.address, s.weth.options.address, NULL_ADDRESS, NULL_ADDRESS, ], [`${destAmount}`, `${srcAmount}`, 0, 0, 0, 0, `${srcAmount}`, 0], randomHexOfSize_1.randomHexOfSize(20), '0x0', '0x0', '0x0') .send({ from: s.manager, gas: s.gas }); const expectedMln = token_math_1.divide(token_math_1.multiply(srcAmount, bestRate), new token_math_1.BigInteger(Math.pow(10, 18))); const post = yield getAllBalances_1.getAllBalances(s, s.accounts, s.fund, s.environment); expect(post.fund.weth).toEqual(token_math_1.subtract(pre.fund.weth, srcAmount)); expect(post.fund.mln).toEqual(token_math_1.add(pre.fund.mln, expectedMln)); })); test('swap mlnToken for ethToken with specific order price (minRate)', () => __awaiter(this, void 0, void 0, function* () { const pre = yield getAllBalances_1.getAllBalances(s, s.accounts, s.fund, s.environment); const srcAmount = token_math_1.power(new token_math_1.BigInteger(10), new token_math_1.BigInteger(16)); const [bestRate] = Object.values(yield s.kyberNetwork.methods .getExpectedRate(s.mln.options.address, kyberEthAddress, `${srcAmount}`) .call()).map(e => new token_math_1.BigInteger(e)); const destAmount = token_math_1.divide(token_math_1.multiply(srcAmount, bestRate), precisionUnits); yield s.fund.trading.methods .callOnExchange(0, orderSignatures_1.takeOrderSignature, [ NULL_ADDRESS, NULL_ADDRESS, s.weth.options.address, s.mln.options.address, NULL_ADDRESS, NULL_ADDRESS, ], [`${destAmount}`, `${srcAmount}`, 0, 0, 0, 0, `${srcAmount}`, 0], randomHexOfSize_1.randomHexOfSize(20), '0x0', '0x0', '0x0') .send({ from: s.manager, gas: s.gas }); const expectedWeth = token_math_1.divide(token_math_1.multiply(srcAmount, bestRate), new token_math_1.BigInteger(Math.pow(10, 18))); const post = yield getAllBalances_1.getAllBalances(s, s.accounts, s.fund, s.environment); expect(post.fund.mln).toEqual(token_math_1.subtract(pre.fund.mln, srcAmount)); expect(post.fund.weth).toEqual(token_math_1.add(pre.fund.weth, expectedWeth)); })); test('swap mlnToken directly to eurToken without minimum destAmount', () => __awaiter(this, void 0, void 0, function* () { const srcAmount = new token_math_1.BigInteger(Math.pow(10, 16)); const pre = yield getAllBalances_1.getAllBalances(s, s.accounts, s.fund, s.environment); const preFundEur = new token_math_1.BigInteger(yield s.eur.methods.balanceOf(s.fund.vault.options.address).call()); const [bestRate] = Object.values(yield s.kyberNetwork.methods .getExpectedRate(s.mln.options.address, s.eur.options.address, `${srcAmount}`) .call()).map(e => new token_math_1.BigInteger(e)); const destAmount = token_math_1.divide(token_math_1.multiply(srcAmount, bestRate), precisionUnits); yield s.fund.trading.methods .callOnExchange(0, orderSignatures_1.takeOrderSignature, [ NULL_ADDRESS, NULL_ADDRESS, s.eur.options.address, s.mln.options.address, NULL_ADDRESS, NULL_ADDRESS, ], [`${destAmount}`, `${srcAmount}`, 0, 0, 0, 0, `${srcAmount}`, 0], randomHexOfSize_1.randomHexOfSize(20), '0x0', '0x0', '0x0') .send({ from: s.manager, gas: s.gas }); const expectedEur = token_math_1.divide(token_math_1.multiply(srcAmount, bestRate), new token_math_1.BigInteger(Math.pow(10, 18))); const post = yield getAllBalances_1.getAllBalances(s, s.accounts, s.fund, s.environment); const postFundEur = new token_math_1.BigInteger(yield s.eur.methods.balanceOf(s.fund.vault.options.address).call()); expect(post.fund.weth).toEqual(pre.fund.weth); expect(post.fund.mln).toEqual(token_math_1.subtract(pre.fund.mln, srcAmount)); expect(postFundEur).toEqual(token_math_1.add(preFundEur, expectedEur)); })); test('takeOrder fails if minPrice is not satisfied', () => __awaiter(this, void 0, void 0, function* () { const srcAmount = new token_math_1.BigInteger(Math.pow(10, 17)); const [bestRate] = Object.values(yield s.kyberNetwork.methods .getExpectedRate(s.mln.options.address, s.eur.options.address, `${srcAmount}`) .call()).map(e => new token_math_1.BigInteger(e)); const destAmount = token_math_1.divide(token_math_1.multiply(token_math_1.multiply(srcAmount, bestRate), new token_math_1.BigInteger(2)), precisionUnits); expect(s.fund.trading.methods .callOnExchange(0, orderSignatures_1.takeOrderSignature, [ NULL_ADDRESS, NULL_ADDRESS, s.eur.options.address, s.mln.options.address, NULL_ADDRESS, NULL_ADDRESS, ], [`${destAmount}`, `${srcAmount}`, 0, 0, 0, 0, `${srcAmount}`, 0], randomHexOfSize_1.randomHexOfSize(20), '0x0', '0x0', '0x0') .send({ from: s.manager, gas: s.gas })).resolves.toThrow(); }));