"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 initTestEnvironment_1 = require("../../../../tests/utils/initTestEnvironment");
const deployMockSystem_1 = require("../../../../utils/deploy/deployMockSystem");
const deployContract_1 = require("../../../../utils/solidity/deployContract");
const getContract_1 = require("../../../../utils/solidity/getContract");
const Contracts_1 = require("../../../../Contracts");
const token_math_1 = require("@melonproject/token-math");
describe('feeManager', () => {
    let shared = {};
    const mockFeeRate = 5000;
    const mockFeePeriod = 1000;
    beforeAll(() => __awaiter(this, void 0, void 0, function* () {
        shared.env = yield initTestEnvironment_1.initTestEnvironment();
        shared.user = shared.env.wallet.address;
    }));
    beforeEach(() => __awaiter(this, void 0, void 0, function* () {
        shared.feeA = getContract_1.getContract(shared.env, Contracts_1.Contracts.MockFee, yield deployContract_1.deployContract(shared.env, Contracts_1.Contracts.MockFee, []));
        shared.feeB = getContract_1.getContract(shared.env, Contracts_1.Contracts.MockFee, yield deployContract_1.deployContract(shared.env, Contracts_1.Contracts.MockFee, []));
        shared.feeArray = [
            {
                feeAddress: shared.feeA.options.address,
                feePeriod: mockFeePeriod,
                feeRate: mockFeeRate,
            },
            {
                feeAddress: shared.feeB.options.address,
                feePeriod: mockFeePeriod,
                feeRate: mockFeeRate,
            },
        ];
        const deployment = yield deployMockSystem_1.deployMockSystem(shared.env, {
            feeManagerContract: Contracts_1.Contracts.FeeManager,
            fees: shared.feeArray,
        });
        shared = Object.assign(shared, deployment);
        yield shared.registry.methods // just to pass pay amgu
            .setIsFund(shared.feeManager.options.address)
            .send({ from: shared.user });
    }));
    it('Fee Manager is properly initialized', () => __awaiter(this, void 0, void 0, function* () {
        for (const fee of shared.feeArray) {
            yield expect(shared.feeManager.methods.feeIsRegistered(fee.feeAddress).call()).toBeTruthy();
        }
        for (const i of Array.from(Array(shared.feeArray.length).keys())) {
            const feeAddress = yield shared.feeManager.methods.fees(i).call();
            expect(feeAddress).toBe(shared.feeArray[i].feeAddress);
        }
    }));
    it('Total fee amount aggregates individual accumulated fee', () => __awaiter(this, void 0, void 0, function* () {
        const feeAmount = new token_math_1.BigInteger(Math.pow(10, 18));
        yield shared.feeA.methods
            .setFeeAmount(`${feeAmount}`)
            .send({ from: shared.user, gas: 8000000 });
        yield shared.feeB.methods
            .setFeeAmount(`${feeAmount}`)
            .send({ from: shared.user, gas: 8000000 });
        yield expect(shared.feeManager.methods.totalFeeAmount().call()).resolves.toEqual(token_math_1.multiply(feeAmount, new token_math_1.BigInteger(2)));
    }));
    it('Reward all fee allocates shares to the manager', () => __awaiter(this, void 0, void 0, function* () {
        const preManagerShares = new token_math_1.BigInteger(yield shared.shares.methods.balanceOf(shared.user).call());
        const feeAmount = new token_math_1.BigInteger(Math.pow(10, 18));
        yield shared.feeA.methods
            .setFeeAmount(`${feeAmount}`)
            .send({ from: shared.user, gas: 8000000 });
        yield shared.feeB.methods
            .setFeeAmount(`${feeAmount}`)
            .send({ from: shared.user, gas: 8000000 });
        yield shared.feeManager.methods
            .rewardAllFees() // can only call becasue of loose mockhub permissions
            .send({ from: shared.user, gas: 8000000 });
        const postManagerShares = new token_math_1.BigInteger(yield shared.shares.methods.balanceOf(shared.user).call());
        const postAccumulatedFee = yield shared.feeManager.methods
            .totalFeeAmount()
            .call();
        expect(postManagerShares).toEqual(token_math_1.add(preManagerShares, token_math_1.multiply(feeAmount, new token_math_1.BigInteger(2))));
        expect(postAccumulatedFee).toBe('0');
    }));
});
