@melonproject/protocol
Version:
Technology Regulated and Operated Investment Funds
137 lines (136 loc) • 8.63 kB
JavaScript
"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 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 Contracts_1 = require("../../Contracts");
const withDifferentAccount_1 = require("../../utils/environment/withDifferentAccount");
const deployAndGetSystem_1 = require("../utils/deployAndGetSystem");
const deployContract_1 = require("../../utils/solidity/deployContract");
const registerAsset_1 = require("../../contracts/version/transactions/registerAsset");
const getContract_1 = require("../../utils/solidity/getContract");
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.deployer, s.manager, s.investor] = s.accounts;
s.gas = 8000000;
s.opts = { from: s.deployer, gas: s.gas };
const exchangeConfigs = {};
const maliciousTokenAddress = yield deployContract_1.deployContract(s.environment, Contracts_1.Contracts.MaliciousToken, ['MLC', 18, 'Malicious']);
yield registerAsset_1.registerAsset(s.environment, s.registry.options.address, {
assetAddress: maliciousTokenAddress.toLowerCase(),
assetSymbol: 'MLC',
name: '',
reserveMin: '',
sigs: [],
standards: [],
url: '',
});
s.maliciousToken = yield getContract_1.getContract(s.environment, Contracts_1.Contracts.MaliciousToken, maliciousTokenAddress);
s.maliciousTokenInterface = yield getToken_1.getToken(s.environment, maliciousTokenAddress.toLowerCase());
const envManager = withDifferentAccount_1.withDifferentAccount(s.environment, s.manager);
yield beginSetup_1.beginSetup(envManager, s.version.options.address, {
defaultTokens: [
s.wethTokenInterface,
s.mlnTokenInterface,
s.maliciousTokenInterface,
],
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);
}));
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(`General redeem fails in presence of malicious token`, () => __awaiter(this, void 0, void 0, function* () {
yield s.maliciousToken.methods
.transfer(s.fund.vault.options.address, 1000000)
.send({ from: s.deployer, gas: s.gas });
yield s.maliciousToken.methods
.startReverting()
.send({ from: s.deployer, gas: s.gas });
expect(s.fund.participation.methods
.redeem()
.send({ from: s.investor, gas: s.gas })).rejects.toThrow();
}));
test(`Redeem with constraints works as expected`, () => __awaiter(this, void 0, void 0, function* () {
const pre = yield getAllBalances_1.getAllBalances(s, s.accounts, s.fund, s.environment);
const investorShares = yield s.fund.shares.methods
.balanceOf(s.investor)
.call();
const preTotalSupply = yield s.fund.shares.methods.totalSupply().call();
yield s.fund.participation.methods
.redeemWithConstraints(investorShares, [s.weth.options.address])
.send({ from: s.investor, gas: s.gas });
const postFundGav = new token_math_1.BigInteger(yield s.fund.accounting.methods.calcGav().call());
const post = yield getAllBalances_1.getAllBalances(s, s.accounts, s.fund, s.environment);
const postTotalSupply = yield s.fund.shares.methods.totalSupply().call();
expect(postTotalSupply).toEqual(token_math_1.subtract(token_math_1.toBI(preTotalSupply), token_math_1.toBI(investorShares)));
expect(post.investor.weth).toEqual(token_math_1.add(pre.investor.weth, pre.fund.weth));
expect(post.fund.weth).toEqual(new token_math_1.BigInteger(0));
expect(post.fund.mln).toEqual(pre.fund.mln);
expect(post.investor.mln).toEqual(pre.investor.mln);
expect(postFundGav).toEqual(new token_math_1.BigInteger(0));
}));