olympus-module
Version:
Module made by Olympus Labs for easier access to the Olympus protocol through Javascript/Typescript
85 lines (67 loc) • 3.17 kB
text/typescript
import BigNumber from 'bignumber.js';
import { getLatestABI } from '../../services/AbiService';
import Promisify from '../../utils/Promisify';
import { WithdrawService } from '../../services/WithdrawService';
import Mutex from '../../utils/MutexChecker';
import Services from '../../Services';
import { Derivative } from '../Derivative';
import { DerivativeStatus, DerivativeProviders } from '../../interfaces/Enums';
export class SellTokensOnCloseService extends Services {
private derivativeFunctions: Derivative;
private productAddress;
constructor(productAddress: string) {
super();
this.productAddress = productAddress;
this.derivativeFunctions = new Derivative(productAddress);
}
public async canSellTokensOnClose(): Promise<boolean> {
const productContract = await this.rpcService.contract(await getLatestABI('FUND_ABI'), this.productAddress);
const mutex = new Mutex(this.productAddress);
const productStatusType = mutex.getProductStatusType();
const mutexResult = await mutex.checkMutex(productStatusType.SELLING_TOKENS);
if (!mutexResult.flag) {
return false;
}
// Check whether or not the fund is closed. If it isn't, this function cannot be used yet.
const status = (await Promisify<BigNumber>(async (cb) => productContract.status(cb))).toNumber();
if (status !== DerivativeStatus.Closed) {
return false;
}
const assetsValue = (await Promisify<BigNumber>
(async (cb) => productContract.getAssetsValue(cb))).toNumber();
// Even if assets value is 0, we need to make sure there is nothing pending to withdraw before close
if (assetsValue === 0) {
const withdrawAddress = await this.derivativeFunctions.getComponentAddress(DerivativeProviders.WITHDRAW);
const needToWithdraw = await new WithdrawService(this.productAddress).
needToWithdraw(this.productAddress, withdrawAddress);
if (needToWithdraw) {
return false;
}
// If we don't need to withdraw either, function never needs to be called again
return false;
}
return true;
}
public async isForeverFinished() {
const productContract = await this.rpcService.contract(await getLatestABI('FUND_ABI'), this.productAddress);
const assetsValue = (await Promisify<BigNumber>
(async (cb) => productContract.getAssetsValue(cb))).toNumber();
if (assetsValue !== 0) {
return false;
} else {
// Even if assets value is 0, we need to make sure there is nothing pending to withdraw before close
const withdrawAddress = await this.derivativeFunctions.getComponentAddress(DerivativeProviders.WITHDRAW);
const needToWithdraw = await new WithdrawService(this.productAddress).
needToWithdraw(this.productAddress, withdrawAddress);
if (needToWithdraw) {
return false;
}
// If we don't need to withdraw either, function never needs to be called again
return true;
}
}
public async getSellTokensOnCloseTxData() {
return (await this.rpcService.contract(await getLatestABI('FUND_ABI'), this.productAddress))
.sellAllTokensOnClosedFund.getData();
}
}