Skip to content

Commit

Permalink
Merge pull request #8 from clober-dex/fix/remove-contract-calls
Browse files Browse the repository at this point in the history
fix: remove contract calls
  • Loading branch information
Dorvin authored Aug 19, 2024
2 parents fd07e6d + e0daf26 commit 85c0d4d
Show file tree
Hide file tree
Showing 3 changed files with 138 additions and 75 deletions.
8 changes: 8 additions & 0 deletions schema.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,14 @@ type Depth @entity {
unitAmount: BigInt!
baseAmount: BigInt!
quoteAmount: BigInt!
}

type OrderIndex @entity {
# `${bookId}-${tick}`
id: ID!
book: Book!
tick: BigInt!
price: BigInt!
latestTakenOrderIndex: BigInt!
}

Expand Down
199 changes: 125 additions & 74 deletions src/book-manager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@ import {
BigDecimal,
BigInt,
ethereum,
log,
store,
} from '@graphprotocol/graph-ts'

import {
BookManager,
Cancel,
Claim,
Make,
Expand All @@ -21,6 +21,7 @@ import {
Depth,
LatestBlock,
OpenOrder,
OrderIndex,
Token,
} from '../generated/schema'
import { Controller } from '../generated/BookManager/Controller'
Expand All @@ -37,6 +38,7 @@ import {
formatInvertedPrice,
formatPrice,
formatUnits,
getPendingAmount,
unitToBase,
unitToQuote,
} from './helpers'
Expand Down Expand Up @@ -72,10 +74,10 @@ export function handleOpen(event: Open): void {
export function handleMake(event: Make): void {
const book = Book.load(event.params.bookId.toString())
if (book === null) {
log.error('[MAKE] Book not found: {}', [event.params.bookId.toString()])
return
}
const controller = Controller.bind(Address.fromString(getControllerAddress()))
const bookManager = BookManager.bind(event.address)
const user = event.params.user.toHexString()
const tick = BigInt.fromI32(event.params.tick)
const orderIndex = event.params.orderIndex
Expand All @@ -84,7 +86,6 @@ export function handleMake(event: Make): void {
const baseAmount = unitToBase(book, unitAmount, price)
const quoteAmount = unitToQuote(book, unitAmount)
const orderId = encodeOrderId(book.id, tick, orderIndex)
const orderInfo = bookManager.getOrder(orderId)

// update open order
const openOrder = new OpenOrder(orderId.toString())
Expand All @@ -104,46 +105,50 @@ export function handleMake(event: Make): void {
openOrder.unitClaimedAmount = BigInt.zero()
openOrder.baseClaimedAmount = BigInt.zero()
openOrder.quoteClaimedAmount = BigInt.zero()
openOrder.unitClaimableAmount = orderInfo.claimable
openOrder.baseClaimableAmount = unitToBase(book, orderInfo.claimable, price)
openOrder.quoteClaimableAmount = unitToQuote(book, orderInfo.claimable)
openOrder.unitOpenAmount = orderInfo.open
openOrder.baseOpenAmount = unitToBase(book, orderInfo.open, price)
openOrder.quoteOpenAmount = unitToQuote(book, orderInfo.open)
openOrder.unitClaimableAmount = BigInt.zero()
openOrder.baseClaimableAmount = BigInt.zero()
openOrder.quoteClaimableAmount = BigInt.zero()
openOrder.unitOpenAmount = unitAmount
openOrder.baseOpenAmount = baseAmount
openOrder.quoteOpenAmount = quoteAmount
openOrder.save()

// update depth
const unitDepthAmount = bookManager.getDepth(
BigInt.fromString(book.id),
tick.toI32(),
)
const depthId = buildDepthId(book.id, tick)
let depth = Depth.load(depthId)
let orderIndexEntity = OrderIndex.load(depthId)
if (depth === null) {
depth = new Depth(depthId)
depth.book = book.id
depth.tick = tick
depth.price = price
depth.latestTakenOrderIndex = BigInt.zero()
depth.unitAmount = BigInt.zero()
depth.baseAmount = BigInt.zero()
depth.quoteAmount = BigInt.zero()
}
depth.unitAmount = unitDepthAmount
depth.baseAmount = unitToBase(book, unitDepthAmount, price)
depth.quoteAmount = unitToQuote(book, unitDepthAmount)

if (unitDepthAmount.isZero()) {
store.remove('Depth', depthId)
} else {
depth.save()
if (orderIndexEntity === null) {
orderIndexEntity = new OrderIndex(depthId)
orderIndexEntity.book = book.id
orderIndexEntity.tick = tick
orderIndexEntity.price = price
orderIndexEntity.latestTakenOrderIndex = BigInt.zero()
}
const newUnitAmount = depth.unitAmount.plus(unitAmount)
depth.unitAmount = newUnitAmount
depth.baseAmount = unitToBase(book, newUnitAmount, price)
depth.quoteAmount = unitToQuote(book, newUnitAmount)

depth.save()
orderIndexEntity.save()
}

export function handleTake(event: Take): void {
const bookManager = BookManager.bind(event.address)
const controller = Controller.bind(Address.fromString(getControllerAddress()))

// update book
const book = Book.load(event.params.bookId.toString())
if (book === null) {
log.error('[TAKE] Book not found: {}', [event.params.bookId.toString()])
return
}
const tick = BigInt.fromI32(event.params.tick)
Expand All @@ -156,18 +161,22 @@ export function handleTake(event: Take): void {
// update depth & open order
const depthId = buildDepthId(book.id, tick)
const depth = Depth.load(depthId)
if (depth === null) {
const orderIndexEntity = OrderIndex.load(depthId)
if (depth === null || orderIndexEntity === null) {
log.error('[TAKE] Depth or OrderIndex not found: {}', [depthId])
return
}
const unitDepthAmount = bookManager.getDepth(
BigInt.fromString(book.id),
tick.toI32(),
)
depth.unitAmount = unitDepthAmount
depth.baseAmount = unitToBase(book, unitDepthAmount, price)
depth.quoteAmount = unitToQuote(book, unitDepthAmount)
const takenUnitAmount = event.params.unit
const newUnitAmount = depth.unitAmount.minus(takenUnitAmount)
depth.unitAmount = newUnitAmount
depth.baseAmount = unitToBase(book, newUnitAmount, price)
depth.quoteAmount = unitToQuote(book, newUnitAmount)

if (newUnitAmount.lt(BigInt.zero())) {
log.error('[TAKE] Negative depth unit amount: {}', [depthId])
}

let currentOrderIndex = depth.latestTakenOrderIndex
let currentOrderIndex = orderIndexEntity.latestTakenOrderIndex
let remainingTakenUnitAmount = event.params.unit
while (remainingTakenUnitAmount.gt(BigInt.zero())) {
const orderId = encodeOrderId(book.id, tick, currentOrderIndex)
Expand All @@ -176,17 +185,6 @@ export function handleTake(event: Take): void {
currentOrderIndex = currentOrderIndex.plus(BigInt.fromI32(1))
continue
}
const orderInfo = bookManager.getOrder(orderId)
openOrder.unitClaimableAmount = orderInfo.claimable
openOrder.baseClaimableAmount = unitToBase(
book,
orderInfo.claimable,
openOrder.price,
)
openOrder.quoteClaimableAmount = unitToQuote(book, orderInfo.claimable)
openOrder.unitOpenAmount = orderInfo.open
openOrder.baseOpenAmount = unitToBase(book, orderInfo.open, openOrder.price)
openOrder.quoteOpenAmount = unitToQuote(book, orderInfo.open)

const openOrderRemainingUnitAmount = openOrder.unitAmount.minus(
openOrder.unitFilledAmount,
Expand All @@ -207,20 +205,37 @@ export function handleTake(event: Take): void {
openOrder.price,
)
openOrder.quoteFilledAmount = unitToQuote(book, newUnitFilledAmount)

const newUnitClaimableAmount =
openOrder.unitClaimableAmount.plus(filledUnitAmount)
openOrder.unitClaimableAmount = newUnitClaimableAmount
openOrder.baseClaimableAmount = unitToBase(
book,
newUnitClaimableAmount,
openOrder.price,
)
openOrder.quoteClaimableAmount = unitToQuote(book, newUnitClaimableAmount)

const newUnitOpenAmount = openOrder.unitOpenAmount.minus(filledUnitAmount)
openOrder.unitOpenAmount = newUnitOpenAmount
openOrder.baseOpenAmount = unitToBase(
book,
newUnitOpenAmount,
openOrder.price,
)
openOrder.quoteOpenAmount = unitToQuote(book, newUnitOpenAmount)
if (newUnitOpenAmount.lt(BigInt.zero())) {
log.error('[TAKE] Negative open unit amount: {}', [orderId.toString()])
}
openOrder.save()

if (openOrder.unitAmount == openOrder.unitFilledAmount) {
currentOrderIndex = currentOrderIndex.plus(BigInt.fromI32(1))
}
}

depth.latestTakenOrderIndex = currentOrderIndex

if (unitDepthAmount.isZero()) {
store.remove('Depth', depthId)
} else {
depth.save()
}
orderIndexEntity.latestTakenOrderIndex = currentOrderIndex
orderIndexEntity.save()

// update chart
const baseTakenAmount = unitToBase(book, event.params.unit, price)
Expand Down Expand Up @@ -326,65 +341,91 @@ export function handleTake(event: Take): void {
}
invertedChartLog.save()
}

if (depth.unitAmount.isZero()) {
store.remove('Depth', depthId)
} else {
depth.save()
}
}

export function handleCancel(event: Cancel): void {
const bookManager = BookManager.bind(event.address)
const orderId = event.params.orderId
const bookId = decodeBookIdFromOrderId(orderId)
const book = Book.load(bookId)
const openOrder = OpenOrder.load(orderId.toString())
if (openOrder === null || book === null) {
log.error('[CANCEL] Book or OpenOrder not found: {} {}', [
bookId,
orderId.toString(),
])
return
}
const orderInfo = bookManager.getOrder(orderId)
const newUnitAmount = openOrder.unitAmount.minus(event.params.unit)
openOrder.unitAmount = newUnitAmount
openOrder.baseAmount = unitToBase(book, newUnitAmount, openOrder.price)
openOrder.quoteAmount = unitToQuote(book, newUnitAmount)

openOrder.unitOpenAmount = orderInfo.open
openOrder.baseOpenAmount = unitToBase(book, orderInfo.open, openOrder.price)
openOrder.quoteOpenAmount = unitToQuote(book, orderInfo.open)
if (newUnitAmount.lt(BigInt.zero())) {
log.error('[CANCEL] Negative unit amount: {}', [orderId.toString()])
}

const unitPendingAmount = orderInfo.open.plus(orderInfo.claimable)
if (unitPendingAmount.isZero()) {
store.remove('OpenOrder', orderId.toString())
} else {
openOrder.save()
const newUnitOpenAmount = openOrder.unitOpenAmount.minus(event.params.unit)
openOrder.unitOpenAmount = newUnitOpenAmount
openOrder.baseOpenAmount = unitToBase(
book,
newUnitOpenAmount,
openOrder.price,
)
openOrder.quoteOpenAmount = unitToQuote(book, newUnitOpenAmount)

if (newUnitOpenAmount.lt(BigInt.zero())) {
log.error('[CANCEL] Negative open unit amount: {}', [orderId.toString()])
}

const unitPendingAmount = getPendingAmount(openOrder)

// update depth
const depthId = buildDepthId(book.id, openOrder.tick)
const depth = Depth.load(depthId)
if (depth === null) {
log.error('[CANCEL] Depth not found: {}', [depthId])
return
}
const unitDepthAmount = bookManager.getDepth(
BigInt.fromString(book.id),
openOrder.tick.toI32(),
)
depth.unitAmount = unitDepthAmount
depth.baseAmount = unitToBase(book, unitDepthAmount, openOrder.price)
depth.quoteAmount = unitToQuote(book, unitDepthAmount)
const newUnitDepthAmount = depth.unitAmount.minus(event.params.unit)
depth.unitAmount = newUnitDepthAmount
depth.baseAmount = unitToBase(book, newUnitDepthAmount, openOrder.price)
depth.quoteAmount = unitToQuote(book, newUnitDepthAmount)

if (newUnitDepthAmount.lt(BigInt.zero())) {
log.error('[CANCEL] Negative depth unit amount: {}', [depthId])
}

if (unitPendingAmount.isZero()) {
store.remove('OpenOrder', orderId.toString())
} else {
openOrder.save()
}

if (unitDepthAmount.isZero()) {
if (newUnitDepthAmount.isZero()) {
store.remove('Depth', depthId)
} else {
depth.save()
}
}

export function handleClaim(event: Claim): void {
const bookManager = BookManager.bind(event.address)
const orderId = event.params.orderId
const bookId = decodeBookIdFromOrderId(orderId)
const openOrder = OpenOrder.load(orderId.toString())
const book = Book.load(bookId)
if (openOrder === null || book === null) {
log.error('[CLAIM] Book or OpenOrder not found: {} {}', [
bookId,
orderId.toString(),
])
return
}
const orderInfo = bookManager.getOrder(orderId)
const newUnitClaimedAmount = openOrder.unitClaimedAmount.plus(
event.params.unit,
)
Expand All @@ -397,15 +438,24 @@ export function handleClaim(event: Claim): void {
)
openOrder.quoteClaimedAmount = unitToQuote(book, newUnitClaimedAmount)

openOrder.unitClaimableAmount = orderInfo.claimable
const newUnitClaimableAmount = openOrder.unitClaimableAmount.minus(
event.params.unit,
)
openOrder.unitClaimableAmount = newUnitClaimableAmount
openOrder.baseClaimableAmount = unitToBase(
book,
orderInfo.claimable,
newUnitClaimableAmount,
openOrder.price,
)
openOrder.quoteClaimableAmount = unitToQuote(book, orderInfo.claimable)
openOrder.quoteClaimableAmount = unitToQuote(book, newUnitClaimableAmount)

if (newUnitClaimableAmount.lt(BigInt.zero())) {
log.error('[CLAIM] Negative claimable unit amount: {}', [
orderId.toString(),
])
}

const unitPendingAmount = orderInfo.open.plus(orderInfo.claimable)
const unitPendingAmount = getPendingAmount(openOrder)
if (unitPendingAmount.isZero()) {
store.remove('OpenOrder', orderId.toString())
} else {
Expand All @@ -426,6 +476,7 @@ export function handleTransfer(event: Transfer): void {
const openOrder = OpenOrder.load(orderId.toString())

if (openOrder === null) {
log.error('[TRANSFER] OpenOrder not found: {}', [orderId.toString()])
return
}

Expand Down
6 changes: 5 additions & 1 deletion src/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { Address, BigDecimal, BigInt, TypedMap } from '@graphprotocol/graph-ts'
import { ERC20 } from '../generated/BookManager/ERC20'
import { ERC20SymbolBytes } from '../generated/BookManager/ERC20SymbolBytes'
import { ERC20NameBytes } from '../generated/BookManager/ERC20NameBytes'
import { Book, Token } from '../generated/schema'
import { Book, OpenOrder, Token } from '../generated/schema'

export const ADDRESS_ZERO = '0x0000000000000000000000000000000000000000'

Expand Down Expand Up @@ -39,6 +39,10 @@ export function decodeBookIdFromOrderId(orderId: BigInt): string {
return orderId.div(BigInt.fromI32(2).pow(64)).toString()
}

export function getPendingAmount(openOrder: OpenOrder): BigInt {
return openOrder.unitOpenAmount.plus(openOrder.unitClaimableAmount)
}

export function unitToBase(
book: Book,
unitAmount: BigInt,
Expand Down

0 comments on commit 85c0d4d

Please sign in to comment.