UNPKG

@melonproject/protocol

Version:

Technology Regulated and Operated Investment Funds

164 lines (163 loc) 11 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 token_math_1 = require("@melonproject/token-math"); const initTestEnvironment_1 = require("../../../tests/utils/initTestEnvironment"); const getToken_1 = require("../../dependencies/token/calls/getToken"); const deploy_1 = require("../../dependencies/token/transactions/deploy"); const approve_1 = require("../../dependencies/token/transactions/approve"); const deployTestingPriceFeed_1 = require("../../prices/transactions/deployTestingPriceFeed"); const update_1 = require("../../prices/transactions/update"); const getContract_1 = require("../../../utils/solidity/getContract"); const deployContract_1 = require("../../../utils/solidity/deployContract"); const Contracts_1 = require("../../../Contracts"); const evm_1 = require("../../../utils/evm"); const thaw_1 = require("./thaw"); const sellAndBurnMln_1 = require("./sellAndBurnMln"); const deployEngine_1 = require("./deployEngine"); describe('sellAndBurnMln', () => { const shared = {}; beforeAll(() => __awaiter(this, void 0, void 0, function* () { shared.env = yield initTestEnvironment_1.initTestEnvironment(); shared.accounts = yield shared.env.eth.getAccounts(); const wethAddress = yield deploy_1.deployToken(shared.env, 'ETH'); shared.mln = getContract_1.getContract(shared.env, Contracts_1.Contracts.BurnableToken, yield deployContract_1.deployContract(shared.env, Contracts_1.Contracts.BurnableToken, [ 'MLN', 18, '', ])); shared.weth = yield getContract_1.getContract(shared.env, Contracts_1.Contracts.StandardToken, wethAddress); shared.version = getContract_1.getContract(shared.env, Contracts_1.Contracts.MockVersion, yield deployContract_1.deployContract(shared.env, Contracts_1.Contracts.MockVersion)); shared.registry = getContract_1.getContract(shared.env, Contracts_1.Contracts.MockRegistry, yield deployContract_1.deployContract(shared.env, Contracts_1.Contracts.MockRegistry)); const feedAddress = yield deployTestingPriceFeed_1.deployTestingPriceFeed(shared.env, yield getToken_1.getToken(shared.env, wethAddress)); shared.feed = yield getContract_1.getContract(shared.env, Contracts_1.Contracts.TestingPriceFeed, feedAddress); shared.delay = 30 * 24 * 60 * 60; shared.engineAddress = yield deployEngine_1.deployEngine(shared.env, { delay: shared.delay, registry: shared.registry.options.address, }); shared.priceSource = yield getContract_1.getContract(shared.env, Contracts_1.Contracts.TestingPriceFeed, feedAddress); shared.engine = getContract_1.getContract(shared.env, Contracts_1.Contracts.Engine, shared.engineAddress); yield shared.registry.methods .setPriceSource(shared.priceSource.options.address) .send({ from: shared.accounts[0] }); yield shared.registry.methods .setMlnToken(shared.mln.options.address) .send({ from: shared.accounts[0] }); yield shared.engine.methods .setRegistry(shared.registry.options.address) .send({ from: shared.accounts[0], gas: 8000000 }); yield update_1.update(shared.env, feedAddress, [ token_math_1.createPrice(token_math_1.createQuantity(yield getToken_1.getToken(shared.env, wethAddress), 1), token_math_1.createQuantity(yield getToken_1.getToken(shared.env, wethAddress), 1)), token_math_1.createPrice(token_math_1.createQuantity(yield getToken_1.getToken(shared.env, shared.mln.options.address), 1), token_math_1.createQuantity(yield getToken_1.getToken(shared.env, wethAddress), 2.94)), ]); })); it('directly sending eth fails', () => __awaiter(this, void 0, void 0, function* () { yield expect(shared.env.eth.sendTransaction({ from: shared.env.wallet.address, to: shared.engine.options.address, value: 1, })).rejects.toThrow('revert'); })); it('eth sent via contract selfdestruct is not tracked', () => __awaiter(this, void 0, void 0, function* () { const sendEth = new token_math_1.BigInteger('100000000'); const destructing = getContract_1.getContract(shared.env, Contracts_1.Contracts.SelfDestructing, yield deployContract_1.deployContract(shared.env, Contracts_1.Contracts.SelfDestructing)); const preHeldEth = yield shared.env.eth.getBalance(shared.engine.options.address); expect(Number(preHeldEth)).toBe(0); yield shared.env.eth.sendTransaction({ from: shared.env.wallet.address, to: destructing.options.address, value: Number(sendEth), }); yield destructing.methods .bequeath(shared.engine.options.address) .send({ from: shared.env.wallet.address }); const postHeldEth = yield shared.env.eth.getBalance(shared.engine.options.address); const frozenEth = yield shared.engine.methods.frozenEther().call(); const liquidEth = yield shared.engine.methods.liquidEther().call(); expect(token_math_1.isEqual(new token_math_1.BigInteger(postHeldEth), sendEth)); expect(Number(frozenEth)).toBe(0); expect(Number(liquidEth)).toBe(0); })); it('AMGU payment fails when sender not fund', () => __awaiter(this, void 0, void 0, function* () { const sender = shared.env.wallet.address; const isFund = yield shared.registry.methods.isFund(sender).call(); expect(isFund).toBe(false); yield expect(shared.engine.methods .payAmguInEther() .send({ from: sender, value: 1000000 })).rejects.toThrow('revert'); })); it('eth sent as AMGU from a "fund" thaws and can be bought', () => __awaiter(this, void 0, void 0, function* () { const sender = shared.env.wallet.address; const sendEth = new token_math_1.BigInteger('100000'); yield shared.registry.methods.setIsFund(sender).send({ from: sender }); const isFund = yield shared.registry.methods.isFund(sender).call(); expect(isFund).toBe(true); yield shared.engine.methods .payAmguInEther() .send({ from: sender, value: Number(sendEth) }); const frozenEth = yield shared.engine.methods.frozenEther().call(); const liquidEth = yield shared.engine.methods.liquidEther().call(); expect(token_math_1.isEqual(new token_math_1.BigInteger(frozenEth), sendEth)); expect(Number(liquidEth)).toBe(0); yield expect( // early call to thaw fails shared.engine.methods.thaw().send({ from: shared.accounts[1] })).rejects.toThrow('revert'); const enginePrice = yield shared.engine.methods.enginePrice().call(); const premiumPercent = new token_math_1.BigInteger(yield shared.engine.methods.premiumPercent().call()); const ethPerMln = new token_math_1.BigInteger((yield shared.feed.methods .getPrice(shared.mln.options.address) .call()).price); const premiumPrice = token_math_1.add(ethPerMln, token_math_1.divide(token_math_1.multiply(ethPerMln, premiumPercent), new token_math_1.BigInteger(100))); expect(`${enginePrice}`).toBe(`${premiumPrice}`); const sendMln = token_math_1.createQuantity(yield getToken_1.getToken(shared.env, shared.mln.options.address), token_math_1.divide(token_math_1.multiply(sendEth, new token_math_1.BigInteger('1000000000000000000')), premiumPrice)); yield approve_1.approve(shared.env, { howMuch: sendMln, spender: shared.engine.options.address, }); yield expect( // throws when trying to burn without liquid ETH sellAndBurnMln_1.sellAndBurnMln(shared.env, shared.engine.options.address, { quantity: sendMln, })).rejects.toThrow('revert'); yield evm_1.increaseTime(shared.env, shared.delay); yield thaw_1.thaw(shared.env, shared.engine.options.address); const frozenEthPost = yield shared.engine.methods.frozenEther().call(); const liquidEthPost = yield shared.engine.methods.liquidEther().call(); expect(Number(frozenEthPost)).toBe(0); expect(token_math_1.isEqual(new token_math_1.BigInteger(liquidEthPost), sendEth)); const burnerPreMln = yield shared.mln.methods.balanceOf(sender).call(); const burnerPreEth = yield shared.env.eth.getBalance(sender); const enginePreEth = yield shared.env.eth.getBalance(shared.engine.options.address); const preMlnTotalSupply = yield shared.mln.methods.totalSupply().call(); const ethPurchased = yield shared.engine.methods .ethPayoutForMlnAmount(`${sendMln.quantity}`) .call(); const receipt = yield sellAndBurnMln_1.sellAndBurnMln(shared.env, shared.engine.options.address, { quantity: sendMln, }); const gasUsed = receipt.gasUsed; const burnerPostMln = yield shared.mln.methods.balanceOf(sender).call(); const burnerPostEth = yield shared.env.eth.getBalance(sender); const enginePostMln = yield shared.mln.methods .balanceOf(shared.engine.options.address) .call(); const enginePostEth = yield shared.env.eth.getBalance(shared.engine.options.address); const postMlnTotalSupply = yield shared.mln.methods.totalSupply().call(); expect(burnerPostMln).toBe(`${token_math_1.subtract(token_math_1.toBI(burnerPreMln), sendMln.quantity)}`); expect(burnerPostEth).toBe(`${token_math_1.subtract(token_math_1.add(token_math_1.toBI(burnerPreEth), token_math_1.toBI(ethPurchased)), token_math_1.multiply(token_math_1.toBI(gasUsed), token_math_1.toBI(shared.env.options.gasPrice)))}`); expect(enginePostMln).toBe(enginePostMln); expect(`${enginePostMln}`).toBe('0'); expect(enginePostEth).toBe(`${token_math_1.subtract(token_math_1.toBI(enginePreEth), token_math_1.toBI(ethPurchased))}`); expect(postMlnTotalSupply).toBe(`${token_math_1.subtract(token_math_1.toBI(preMlnTotalSupply), sendMln.quantity)}`); })); it('Other contracts can pay amgu on function calls', () => __awaiter(this, void 0, void 0, function* () { })); it('Engine price and premium computes at multiple values', () => __awaiter(this, void 0, void 0, function* () { })); });