Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Vc/io1 2848 min collateral #24

Merged
merged 6 commits into from
Mar 22, 2023
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 0 additions & 3 deletions src/modules/clusters/cli/cluster.container.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -53,12 +53,9 @@ export class Clusters extends Component<IClustersProps, IClustersState> {
const items = await this.props.service.findAll();
const currentBlockNumber =
await this.props.web3Provider.currentBlockNumber();
const minimumBlocksBeforeLiquidation =
await this.props.web3Provider.minimumBlocksBeforeLiquidation();
this.setStateSafely({
items: transformClusterData(items, {
currentBlockNumber,
minimumBlocksBeforeLiquidation,
}),
});
}, 1000);
Expand Down
9 changes: 3 additions & 6 deletions src/modules/clusters/cli/cluster.transformer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,14 +23,12 @@ export const colorCodeStatus = status => {
};

const textStatus = (item, extra: any) => {
const { currentBlockNumber, minimumBlocksBeforeLiquidation } = extra;
const blockDiff = item.balanceToBlockNumber
? item.balanceToBlockNumber - currentBlockNumber
: null;
const { currentBlockNumber } = extra;
switch (true) {
case item.isLiquidated:
return 'Liquidated';
case blockDiff !== null && blockDiff < minimumBlocksBeforeLiquidation:
case item.liquidationBlockNumber !== null &&
item.liquidationBlockNumber <= currentBlockNumber:
return 'To liquidate';
default:
return 'Running';
Expand Down Expand Up @@ -62,7 +60,6 @@ export const transformClusterData = (items, extra: any) => {
extraPadding: 1,
},
liquidationBlockNumber: { text: item.liquidationBlockNumber },
balanceToBlockNumber: { text: item.balanceToBlockNumber },
updated: {
text: timeAgo.format(item.updatedAt, 'round-minute'),
},
Expand Down
3 changes: 0 additions & 3 deletions src/modules/clusters/cluster.entity.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,6 @@ export class Cluster {
@Column({ default: false })
isLiquidated: boolean;

@Column({ default: null })
balanceToBlockNumber: number;

@Column({ default: null })
liquidationBlockNumber: number;

Expand Down
2 changes: 1 addition & 1 deletion src/modules/clusters/cluster.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ export class ClusterService {
async findAll(): Promise<Cluster[]> {
return this._clusterRepository.find({
order: {
balanceToBlockNumber: 'ASC',
liquidationBlockNumber: 'ASC',
},
});
}
Expand Down
2 changes: 2 additions & 0 deletions src/modules/system/system.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,11 @@ import { System } from './system.entity';
export enum SystemType {
GENERAL_LAST_BLOCK_NUMBER = 'GENERAL_LAST_BLOCK_NUMBER',
EARNINGS_LAST_BLOCK_NUMBER = 'EARNINGS_LAST_BLOCK_NUMBER',
MINIMUM_LIQUIDATION_COLLATERAL = 'MINIMUM_LIQUIDATION_COLLATERAL',
// event names
EVENT_OPERATOR_ADDED = 'OperatorAdded',
EVENT_OPERATOR_REMOVED = 'OperatorRemoved',
EVENT_COLLATERAL_UPDATED = 'MinimumLiquidationCollateralUpdated',
EVENT_OPERATOR_FEE_APPROVED = 'OperatorFeeExecuted',
EVENT_VALIDATOR_ADDED = 'ValidatorAdded',
EVENT_VALIDATOR_REMOVED = 'ValidatorRemoved',
Expand Down
6 changes: 6 additions & 0 deletions src/providers/web3.provider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,12 @@ export default class Web3Provider {
.call();
}

static async getMinimumLiquidationCollateral(): Promise<string> {
return Web3Provider.contractViews.methods
.getMinimumLiquidationCollateral()
.call();
}

static toClusterTuple(obj) {
return [
obj.validatorCount,
Expand Down
35 changes: 25 additions & 10 deletions src/services/worker/tasks/burn-rates.task.ts
Original file line number Diff line number Diff line change
Expand Up @@ -205,16 +205,31 @@ export class BurnRatesTask {
// Prepare final data
record.cluster = JSON.stringify(record.cluster);
// If cluster won't be liquidated, at which block number his balance becomes zero
record.balanceToBlockNumber =
record.burnRate > 0
? currentBlockNumber +
+(record.balance / record.burnRate).toFixed(0)
: null;
// Deduct from block number where cluster balance becomes zero,
// value of Liquidation Threshold Period
record.liquidationBlockNumber = record.balanceToBlockNumber
? record.balanceToBlockNumber - minimumBlocksBeforeLiquidation
: null;
if (record.burnRate > 0 && record.balance > 0) {
const liveUntilBlockByBalance =
currentBlockNumber +
record.balance / record.burnRate -
minimumBlocksBeforeLiquidation;

const latestLiveBlockBalance =
record.balance -
(liveUntilBlockByBalance - currentBlockNumber) * record.burnRate;

const collateralAmount =
+(await Web3Provider.getMinimumLiquidationCollateral());

if (record.balance <= collateralAmount) {
record.liquidationBlockNumber = currentBlockNumber;
} else if (latestLiveBlockBalance < collateralAmount) {
record.liquidationBlockNumber =
currentBlockNumber +
(record.balance - collateralAmount) / record.burnRate;
} else {
record.liquidationBlockNumber = liveUntilBlockByBalance;
}
} else {
record.liquidationBlockNumber = null;
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add explanation comments for all the conditions for other developers to understand the logic behind with minimum efforts

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok


// Save cluster updated data to database
await this._atomicRetry(
Expand Down
10 changes: 4 additions & 6 deletions src/services/worker/tasks/liquidation.task.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,15 +35,13 @@ export class LiquidationTask {
},
})
async liquidate(): Promise<void> {
const minimumBlocksBeforeLiquidation =
+(await Web3Provider.minimumBlocksBeforeLiquidation());
const currentBlockNumber = +(await Web3Provider.currentBlockNumber());
const toLiquidateRecords = await this._clusterService.findBy({
where: {
balanceToBlockNumber: LessThanOrEqual(
// Current block + Liquidation Threshold Period should higher
liquidationBlockNumber: LessThanOrEqual(
// Current block
// than the block number when balance becomes zero if not liquidated
currentBlockNumber + minimumBlocksBeforeLiquidation,
currentBlockNumber,
),
},
});
Expand Down Expand Up @@ -81,9 +79,9 @@ export class LiquidationTask {
await this._clusterService.update(
{ owner: item.owner, operatorIds: item.operatorIds },
{
balance: null,
burnRate: null,
isLiquidated: true,
balanceToBlockNumber: null,
liquidationBlockNumber: null,
},
);
Expand Down
23 changes: 20 additions & 3 deletions src/services/worker/worker.service.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,28 @@
import { Injectable, Logger } from '@nestjs/common';
import { SystemType } from '@cli/modules/system/system.service';
import { Injectable, Logger, OnModuleInit } from '@nestjs/common';

import Web3Provider from '@cli/providers/web3.provider';

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please remove empty lines and sort all the imports from shortest to longest (project imports separately from external imports)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok

import { SystemService, SystemType } from '@cli/modules/system/system.service';
import { ClusterService } from '@cli/modules/clusters/cluster.service';
import { EarningService } from '@cli/modules/earnings/earning.service';

@Injectable()
export class WorkerService {
export class WorkerService implements OnModuleInit {
private readonly _logger = new Logger(WorkerService.name);

constructor(
private _clusterService: ClusterService,
private _earningService: EarningService,
private _systemService: SystemService,
) {}

async onModuleInit() {
await this._systemService.save(
SystemType.MINIMUM_LIQUIDATION_COLLATERAL,
await Web3Provider.getMinimumLiquidationCollateral(),
);
}

async processEvents(events: Array<any>): Promise<void> {
if (!events.length) {
this._logger.log(`There is no events in this block range`);
Expand Down Expand Up @@ -47,6 +58,12 @@ export class WorkerService {
case SystemType.EVENT_VALIDATOR_ADDED:
await this._clusterService.create(dataItem);
break;
case SystemType.EVENT_COLLATERAL_UPDATED:
await this._systemService.save(
SystemType.MINIMUM_LIQUIDATION_COLLATERAL,
await Web3Provider.getMinimumLiquidationCollateral(),
);
break;
}
}
}
Expand Down