import BigNumberJs from 'bignumber.js'; import { DeploylessViewerClient } from 'deployless-view'; import { providers } from 'ethers'; import BaseService from '../commons/BaseService'; import { DefaultTimeLockStrategy } from './typechain/DefaultTimeLockStrategy'; import { DefaultTimeLockStrategy__factory } from './typechain/DefaultTimeLockStrategy__factory'; export class DefaultTimeLockStrategyService extends BaseService { constructor(provider: providers.Provider) { super(provider, DefaultTimeLockStrategy__factory); } public async getStrategiesInBatch(strategyAddrs: string[]) { const d = new DeploylessViewerClient(this.provider); const raw = await d.multicall( strategyAddrs .map(addr => { const instance = this.getContractInstance(addr); return [ { target: addr, callData: instance.interface.encodeFunctionData( 'totalAmountInCurrentPeriod', ), }, { target: addr, callData: instance.interface.encodeFunctionData('lastResetTimestamp'), }, ]; }) .flat(), ); const results = strategyAddrs.map((addr, index) => { const instance = this.getContractInstance(addr); return { totalAmountInCurrentPeriod: instance.interface.decodeFunctionResult( 'totalAmountInCurrentPeriod', raw.resultsArray[index * 2], ), lastResetTimestamp: instance.interface.decodeFunctionResult( 'lastResetTimestamp', raw.resultsArray[index * 2 + 1], ), }; }); return results; } public calculateTimeLockParamsOffChain({ amount, timeLockStrategyData: { minThreshold, midThreshold, minWaitTime, midWaitTime, maxWaitTime, poolPeriodWaitTime, poolPeriodLimit, period, totalAmountInCurrentPeriod, lastResetTimestamp, }, }: { amount: BigNumberJs; timeLockStrategyData: { minThreshold: BigNumberJs; midThreshold: BigNumberJs; minWaitTime: number; midWaitTime: number; maxWaitTime: number; poolPeriodWaitTime: number; poolPeriodLimit: BigNumberJs; period: number; totalAmountInCurrentPeriod: BigNumberJs; lastResetTimestamp: number; }; }) { let lockTime = 0; const accumulatedAmount = Date.now() / 1000 - lastResetTimestamp > period ? new BigNumberJs(0) : totalAmountInCurrentPeriod; if (accumulatedAmount.plus(amount).gt(poolPeriodLimit)) { lockTime += poolPeriodWaitTime; } if (amount.lt(minThreshold)) { lockTime += minWaitTime; } else if (amount.lt(midThreshold)) { lockTime += midWaitTime; } else { lockTime += maxWaitTime; } return lockTime; } }