This repository has been archived by the owner on May 7, 2024. It is now read-only.
forked from centrifuge/api
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
74 index loanentity data types (#86)
* feat: create loanService * refactor: improved service getters * feat: increase outstandingDebt on borrowings * feat: basics for handle loan prices * feat: save priced loans * feat: activate loan when priced * feat: handle writeoffs * feat: handle loan closed and write offs
- Loading branch information
Showing
9 changed files
with
201 additions
and
29 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,13 +1,74 @@ | ||
import { SubstrateEvent } from '@subql/types' | ||
import { LoanBorrowedEvent } from '../../helpers/types' | ||
import { | ||
LoanBorrowedRepaidEvent, | ||
LoanCreatedClosedEvent, | ||
LoanPricedEvent, | ||
LoanWrittenOffEvent, | ||
} from '../../helpers/types' | ||
import { errorHandler } from '../../helpers/errorHandler' | ||
import { PoolService } from '../services/poolService' | ||
import { LoanService } from '../services/loanService' | ||
|
||
export const handleBorrowings = errorHandler(_handleBorrowings) | ||
async function _handleBorrowings(event: SubstrateEvent<LoanBorrowedEvent>): Promise<void> { | ||
const [poolId, , amount] = event.event.data | ||
logger.info(`Pool: ${poolId.toString()} borrowed ${amount.toString()}`) | ||
export const handleLoanCreated = errorHandler(_handleLoanCreated) | ||
async function _handleLoanCreated(event: SubstrateEvent<LoanCreatedClosedEvent>) { | ||
const [poolId, loanId] = event.event.data | ||
logger.info(`Loan created event for pool: ${poolId.toString()} loan: ${loanId.toString()}`) | ||
|
||
const loan = await LoanService.init(poolId.toString(), loanId.toString(), event.block.timestamp) | ||
await loan.save() | ||
} | ||
|
||
export const handleLoanBorrowed = errorHandler(_handleLoanBorrowed) | ||
async function _handleLoanBorrowed(event: SubstrateEvent<LoanBorrowedRepaidEvent>): Promise<void> { | ||
const [poolId, loanId, amount] = event.event.data | ||
logger.info(`Loan borrowed event for pool: ${poolId.toString()} amount: ${amount.toString()}`) | ||
|
||
// Update loan amount | ||
const loan = await LoanService.getById(poolId.toString(), loanId.toString()) | ||
await loan.borrow(amount.toBigInt()) | ||
await loan.save() | ||
|
||
// Update poolState info | ||
const poolService = await PoolService.getById(poolId.toString()) | ||
await poolService.increaseTotalBorrowings(amount.toBigInt()) | ||
await poolService.save() | ||
} | ||
|
||
export const handleLoanPriced = errorHandler(_handleLoanPriced) | ||
async function _handleLoanPriced(event: SubstrateEvent<LoanPricedEvent>) { | ||
const [poolId, loanId, interestRatePerSec, loanType] = event.event.data | ||
logger.info(`Loan priced event for pool: ${poolId.toString()} loan: ${loanId.toString()}`) | ||
const loan = await LoanService.getById(poolId.toString(), loanId.toString()) | ||
await loan.activate() | ||
await loan.updateInterestRate(interestRatePerSec.toBigInt()) | ||
await loan.updateLoanType(loanType.type, loanType.inner.toJSON()) | ||
await loan.save() | ||
} | ||
|
||
export const handleLoanRepaid = errorHandler(_handleLoanRepaid) | ||
async function _handleLoanRepaid(event: SubstrateEvent<LoanBorrowedRepaidEvent>) { | ||
const [poolId, loanId, amount] = event.event.data | ||
logger.info(`Loan borrowed event for pool: ${poolId.toString()} amount: ${amount.toString()}`) | ||
const loan = await LoanService.getById(poolId.toString(), loanId.toString()) | ||
await loan.repay(amount.toBigInt()) | ||
await loan.save() | ||
} | ||
|
||
export const handleLoanWrittenOff = errorHandler(_handleLoanWrittenOff) | ||
async function _handleLoanWrittenOff(event: SubstrateEvent<LoanWrittenOffEvent>) { | ||
const [poolId, loanId, percentage, penaltyInterestRatePerSec, writeOffGroupIndex] = event.event.data | ||
logger.info(`Loan writtenoff event for pool: ${poolId.toString()} loanId: ${loanId.toString()}`) | ||
const loan = await LoanService.getById(poolId.toString(), loanId.toString()) | ||
const writeOffIndex = writeOffGroupIndex.isSome ? writeOffGroupIndex.unwrap().toNumber() : null | ||
await loan.writeOff(percentage.toBigInt(), penaltyInterestRatePerSec.toBigInt(), writeOffIndex) | ||
await loan.save() | ||
} | ||
|
||
export const handleLoanClosed = errorHandler(_handleLoanClosed) | ||
async function _handleLoanClosed(event: SubstrateEvent<LoanCreatedClosedEvent>) { | ||
const [poolId, loanId] = event.event.data | ||
logger.info(`Loan closed event for pool: ${poolId.toString()} loanId: ${loanId.toString()}`) | ||
const loan = await LoanService.getById(poolId.toString(), loanId.toString()) | ||
await loan.close() | ||
await loan.save() | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
import { AnyJson } from '@polkadot/types/types' | ||
import { Loan, LoanStatus } from '../../types' | ||
|
||
export class LoanService { | ||
readonly loan: Loan | ||
|
||
constructor(loan: Loan) { | ||
this.loan = loan | ||
} | ||
|
||
static init = async (poolId: string, loanId: string, timestamp: Date) => { | ||
logger.info(`Initialising loan ${loanId} for pool ${poolId}`) | ||
const loan = new Loan(`${poolId}-${loanId}`) | ||
|
||
loan.createdAt = timestamp | ||
loan.poolId = poolId | ||
loan.status = LoanStatus.CREATED | ||
loan.outstandingDebt = BigInt(0) | ||
loan.totalBorrowed = BigInt(0) | ||
loan.totalRepaid = BigInt(0) | ||
|
||
return new LoanService(loan) | ||
} | ||
|
||
static getById = async (poolId: string, loanId: string) => { | ||
const loan = await Loan.get(`${poolId}-${loanId}`) | ||
if (loan === undefined) return undefined | ||
return new LoanService(loan) | ||
} | ||
|
||
public save = async () => { | ||
await this.loan.save() | ||
} | ||
|
||
public borrow = (amount: bigint) => { | ||
logger.info(`Increasing outstanding debt for loan ${this.loan.id} by ${amount}`) | ||
this.loan.totalBorrowed = this.loan.totalBorrowed + amount | ||
} | ||
|
||
public repay = (amount: bigint) => { | ||
logger.info(`Decreasing outstanding debt for loan ${this.loan.id} by ${amount}`) | ||
this.loan.outstandingDebt = this.loan.totalRepaid + amount | ||
} | ||
|
||
public updateInterestRate = (interestRatePerSec: bigint) => { | ||
logger.info(`Updating interest rate for loan ${this.loan.id} to ${interestRatePerSec}`) | ||
this.loan.interestRatePerSec = interestRatePerSec | ||
} | ||
|
||
public writeOff = (percentage: bigint, penaltyInterestRatePerSec: bigint, writeOffIndex: number) => { | ||
logger.info(`Writing off loan ${this.loan.id} with ${percentage}`) | ||
this.loan.writtenOffPercentage = percentage | ||
this.loan.penaltyInterestRatePerSec = penaltyInterestRatePerSec | ||
this.loan.writeOffIndex = writeOffIndex | ||
} | ||
|
||
public updateLoanType = (loanType: string, loanSpec?: AnyJson) => { | ||
logger.info(`Updating loan type for loan ${this.loan.id} to ${loanType}`) | ||
this.loan.type = loanType | ||
const specBuff = Buffer.from(JSON.stringify(loanSpec)) | ||
this.loan.spec = specBuff.toString('base64') | ||
} | ||
|
||
public activate = () => { | ||
logger.info(`Activating loan ${this.loan.id}`) | ||
this.loan.status = LoanStatus.ACTIVE | ||
} | ||
|
||
public close = () => { | ||
logger.info(`Closing loan ${this.loan.id}`) | ||
this.loan.status = LoanStatus.CLOSED | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters