Skip to content

Commit

Permalink
Merge pull request #30 from ajna-finance/1220
Browse files Browse the repository at this point in the history
Fix issue handling bucketTake events
  • Loading branch information
EdNoepel authored Jul 13, 2023
2 parents 314e9b2 + 25b6954 commit 245bf7c
Show file tree
Hide file tree
Showing 6 changed files with 118 additions and 104 deletions.
2 changes: 1 addition & 1 deletion clean-container.sh
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#!/bin/bash
docker-compose down -v
docker compose down -v
docker rm ajna-testnet-subgraph
sudo rm -rf data
3 changes: 2 additions & 1 deletion schema.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -331,17 +331,18 @@ type BucketBankruptcy @entity(immutable: true) {

type BucketTake @entity(immutable: true) {
id: Bytes!
borrower: Bytes! # address
taker: Bytes! # address of the taker
liquidationAuction: LiquidationAuction! # liquidation auction in which the take is occuring
loan: Loan! # loan which was taken
pool: Pool! # pool in which the take is occuring
borrower: Bytes! # address
index: Int! # uint256
auctionPrice: BigDecimal! # price of auction when taken
amount: BigDecimal! # uint256
collateral: BigDecimal! # uint256
bondChange: BigDecimal! # uint256
isReward: Boolean! # bool
lpAwarded: BucketTakeLPAwarded!
blockNumber: BigInt!
blockTimestamp: BigInt!
transactionHash: Bytes!
Expand Down
109 changes: 50 additions & 59 deletions src/erc-20-pool.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ import { loadOrCreateAccount, updateAccountLends, updateAccountLoans, updateAcco
import { getBucketId, getBucketInfo, loadOrCreateBucket } from "./utils/bucket"
import { getLendId, loadOrCreateLend } from "./utils/lend"
import { getBorrowerInfo, getLoanId, loadOrCreateLoan } from "./utils/loan"
import { getBucketTakeLPAwardedId, getLiquidationAuctionId, getAuctionInfoERC20Pool, loadOrCreateLiquidationAuction, updateLiquidationAuction, getAuctionStatus } from "./utils/liquidation"
import { getLiquidationAuctionId, getAuctionInfoERC20Pool, loadOrCreateLiquidationAuction, updateLiquidationAuction, getAuctionStatus, loadOrCreateBucketTake } from "./utils/liquidation"
import { getBurnInfo, updatePool, addLiquidationToPool, addReserveAuctionToPool, getLenderInfo, getRatesAndFees } from "./utils/pool"
import { lpbValueInQuote } from "./utils/common"
import { loadOrCreateReserveAuction, reserveAuctionKickerReward } from "./utils/reserve-auction"
Expand Down Expand Up @@ -313,9 +313,8 @@ export function handleBucketBankruptcy(event: BucketBankruptcyEvent): void {
}

export function handleBucketTake(event: BucketTakeEvent): void {
const bucketTake = new BucketTake(
event.transaction.hash.concatI32(event.block.number.toI32())
)
const bucketTakeId = event.transaction.hash.concatI32(event.logIndex.toI32());
const bucketTake = BucketTake.load(bucketTakeId)!
bucketTake.borrower = event.params.borrower
bucketTake.taker = event.transaction.from
bucketTake.index = event.params.index.toU32()
Expand Down Expand Up @@ -373,6 +372,34 @@ export function handleBucketTake(event: BucketTakeEvent): void {
kick.locked = kick.locked.minus(wadToDecimal(event.params.bondChange))
}

// update bucket state
const bucketId = getBucketId(pool.id, bucketTake.index)
const bucket = loadOrCreateBucket(pool.id, bucketId, bucketTake.index)
const bucketInfo = getBucketInfo(pool.id, bucket.bucketIndex)
bucket.collateral = wadToDecimal(bucketInfo.collateral)
bucket.deposit = wadToDecimal(bucketInfo.quoteTokens)
bucket.lpb = wadToDecimal(bucketInfo.lpb)
bucket.exchangeRate = wadToDecimal(bucketInfo.exchangeRate)

// update lend state for kicker
const lpAwardedId = event.transaction.hash.concatI32(event.logIndex.toI32() - 1);
const bucketTakeLpAwarded = BucketTakeLPAwarded.load(lpAwardedId)!
const kickerLendId = getLendId(bucketId, bucketTakeLpAwarded.kicker)
const kickerLend = loadOrCreateLend(bucketId, kickerLendId, pool.id, bucketTakeLpAwarded.kicker)
kickerLend.lpb = kickerLend.lpb.plus(bucketTakeLpAwarded.lpAwardedTaker)
kickerLend.lpbValueInQuote = lpbValueInQuote(pool.id, bucket.bucketIndex, kickerLend.lpb)

// update kicker account state if they weren't a lender already
const kickerAccountId = bucketTakeLpAwarded.kicker
const kickerAccount = loadOrCreateAccount(kickerAccountId)
updateAccountLends(kickerAccount, kickerLend)

// update lend state for taker
const takerLendId = getLendId(bucketId, bucketTakeLpAwarded.taker)
const takerLend = loadOrCreateLend(bucketId, takerLendId, pool.id, bucketTakeLpAwarded.taker)
takerLend.lpb = takerLend.lpb.plus(bucketTakeLpAwarded.lpAwardedTaker)
takerLend.lpbValueInQuote = lpbValueInQuote(pool.id, bucket.bucketIndex, takerLend.lpb)

// update bucketTake pointers
bucketTake.liquidationAuction = auction.id
bucketTake.loan = loanId
Expand All @@ -381,72 +408,37 @@ export function handleBucketTake(event: BucketTakeEvent): void {
// save entities to the store
account.save()
auction.save()
bucket.save()
bucketTake.save()
loan.save()
pool.save()
bucketTake.save()
kickerAccount.save()
kickerLend.save()
takerLend.save()
}

export function handleBucketTakeLPAwarded(
event: BucketTakeLPAwardedEvent
): void {
const bucketTakeLpAwarded = new BucketTakeLPAwarded(
event.transaction.hash.concatI32(event.logIndex.toI32())
)
bucketTakeLpAwarded.taker = event.params.taker
bucketTakeLpAwarded.kicker = event.params.kicker
bucketTakeLpAwarded.lpAwardedTaker = wadToDecimal(event.params.lpAwardedTaker)
const lpAwardedId = event.transaction.hash.concatI32(event.logIndex.toI32());
const bucketTakeLpAwarded = new BucketTakeLPAwarded(lpAwardedId)
bucketTakeLpAwarded.taker = event.params.taker
bucketTakeLpAwarded.pool = addressToBytes(event.address)
bucketTakeLpAwarded.kicker = event.params.kicker
bucketTakeLpAwarded.lpAwardedTaker = wadToDecimal(event.params.lpAwardedTaker)
bucketTakeLpAwarded.lpAwardedKicker = wadToDecimal(event.params.lpAwardedKicker)

bucketTakeLpAwarded.blockNumber = event.block.number
bucketTakeLpAwarded.blockTimestamp = event.block.timestamp
bucketTakeLpAwarded.blockNumber = event.block.number
bucketTakeLpAwarded.blockTimestamp = event.block.timestamp
bucketTakeLpAwarded.transactionHash = event.transaction.hash
bucketTakeLpAwarded.save()

// update entities
const pool = Pool.load(addressToBytes(event.address))
if (pool != null) {
// pool doesn't need to be updated as it was already updated in the concurrent BucketTake event

// load BucketTake entity to access the index used for bucketTake
const bucketTakeId = getBucketTakeLPAwardedId(event.transaction.hash, event.logIndex)
const bucketTake = BucketTake.load(bucketTakeId)!

// update bucket state
const bucketId = getBucketId(pool.id, bucketTake.index)
const bucket = loadOrCreateBucket(pool.id, bucketId, bucketTake.index)
const bucketInfo = getBucketInfo(pool.id, bucket.bucketIndex)
bucket.collateral = wadToDecimal(bucketInfo.collateral)
bucket.deposit = wadToDecimal(bucketInfo.quoteTokens)
bucket.lpb = wadToDecimal(bucketInfo.lpb)
bucket.exchangeRate = wadToDecimal(bucketInfo.exchangeRate)

// update lend state for kicker
const kickerLendId = getLendId(bucketId, bucketTakeLpAwarded.kicker)
const kickerLend = loadOrCreateLend(bucketId, kickerLendId, pool.id, bucketTakeLpAwarded.kicker)
kickerLend.lpb = kickerLend.lpb.plus(bucketTakeLpAwarded.lpAwardedTaker)
kickerLend.lpbValueInQuote = lpbValueInQuote(pool.id, bucket.bucketIndex, kickerLend.lpb)

// update kicker account state if they weren't a lender already
const kickerAccountId = bucketTakeLpAwarded.kicker
const kickerAccount = loadOrCreateAccount(kickerAccountId)
updateAccountLends(kickerAccount, kickerLend)

// update lend state for taker
const takerLendId = getLendId(bucketId, bucketTakeLpAwarded.taker)
const takerLend = loadOrCreateLend(bucketId, takerLendId, pool.id, bucketTakeLpAwarded.taker)
takerLend.lpb = takerLend.lpb.plus(bucketTakeLpAwarded.lpAwardedTaker)
takerLend.lpbValueInQuote = lpbValueInQuote(pool.id, bucket.bucketIndex, takerLend.lpb)

// save entities to store
bucket.save()
kickerAccount.save()
kickerLend.save()
takerLend.save()
pool.save()

bucketTakeLpAwarded.pool = pool.id
}

bucketTakeLpAwarded.save()
// since this is emitted immediately before BucketTakeEvent, create BucketTake entity to associate it with this LP award
const bucketTakeId = event.transaction.hash.concatI32(event.logIndex.toI32() + 1)
const bucketTake = loadOrCreateBucketTake(bucketTakeId)
bucketTake.lpAwarded = lpAwardedId
bucketTake.save()
}

export function handleDecreaseLPAllowance(event: DecreaseLPAllowanceEvent): void {
Expand Down Expand Up @@ -902,7 +894,6 @@ export function handleRepayDebt(event: RepayDebtEvent): void {
repayDebt.save()
}


// called on both start and take reserves
export function handleReserveAuctionKick(event: KickReserveAuctionEvent): void {
// create the ReserveAuctionKick entity (immutable) and ReserveAuction entity (mutable)
Expand Down
37 changes: 28 additions & 9 deletions src/utils/liquidation.ts
Original file line number Diff line number Diff line change
@@ -1,22 +1,16 @@
import { Address, BigDecimal, BigInt, Bytes, Value, dataSource } from "@graphprotocol/graph-ts"

import { LiquidationAuction, Kick, Loan, Pool } from "../../generated/schema"
import { LiquidationAuction, Kick, Loan, Pool, BucketTake } from "../../generated/schema"
import { ERC20Pool } from '../../generated/templates/ERC20Pool/ERC20Pool'

import { wadToDecimal } from "./convert"
import { ONE_BI, ZERO_BD, poolInfoUtilsAddressTable } from "./constants"
import { ONE_BI, ZERO_ADDRESS, ZERO_BD, ZERO_BI, poolInfoUtilsAddressTable } from "./constants"
import { PoolInfoUtils } from "../../generated/templates/ERC20Pool/PoolInfoUtils"

export function getLiquidationAuctionId(poolId: Bytes, loanId: Bytes, kickBlock: BigInt): Bytes {
return poolId.concat(Bytes.fromUTF8('|' + loanId.toString() + '|' + kickBlock.toString()))
}

export function getBucketTakeLPAwardedId(transactionHash: Bytes, logIndex: BigInt): Bytes {
// assume that the logIndex is always one greater given the order of emitted events
// should handle case where multiple BucketTakes are performed in a single multicall TX
return transactionHash.concatI32(logIndex.toI32())
}

export function loadOrCreateLiquidationAuction(poolId: Bytes, liquidationAuctionId: Bytes, kick: Kick, loan: Loan): LiquidationAuction {
let liquidationAuction = LiquidationAuction.load(liquidationAuctionId)
if (liquidationAuction == null) {
Expand Down Expand Up @@ -134,4 +128,29 @@ export function getAuctionStatus(pool: Pool, borrower: Address): AuctionStatus {
result.value4,
result.value5
)
}
}

export function loadOrCreateBucketTake(id: Bytes): BucketTake {
let bucketTake = BucketTake.load(id)
if (bucketTake == null) {
// create new account if account hasn't already been stored
bucketTake = new BucketTake(id) as BucketTake

bucketTake.borrower = ZERO_ADDRESS
bucketTake.taker = ZERO_ADDRESS
bucketTake.liquidationAuction = Bytes.fromI32(0)
bucketTake.loan = Bytes.fromI32(0)
bucketTake.pool = Bytes.fromI32(0)
bucketTake.index = 0
bucketTake.auctionPrice = ZERO_BD
bucketTake.amount = ZERO_BD
bucketTake.collateral = ZERO_BD
bucketTake.bondChange = ZERO_BD
bucketTake.isReward = false
bucketTake.lpAwarded = Bytes.fromI32(0)
bucketTake.blockNumber = ZERO_BI
bucketTake.blockTimestamp = ZERO_BI
bucketTake.transactionHash = Bytes.fromI32(0)
}
return bucketTake;
}
32 changes: 16 additions & 16 deletions subgraph.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ dataSources:
name: PositionManager
source:
abi: PositionManager
address: "0x0000000000000000000000000000000000000000"
startBlock: 17622995
address: "0x37048D43A65748409B04f4051eEd9480BEf68c82"
startBlock: 9289397
mapping:
kind: ethereum/events
apiVersion: 0.0.7
Expand Down Expand Up @@ -46,13 +46,13 @@ dataSources:
- event: Transfer(indexed address,indexed address,indexed uint256)
handler: handleTransfer
file: ./src/position-manager.ts
network: mainnet
network: goerli
- kind: ethereum
name: ERC20PoolFactory
source:
abi: ERC20PoolFactory
address: "0xe6F4d9711121e5304b30aC2Aae57E3b085ad3c4d"
startBlock: 17622995
address: "0x01Da8a85A5B525D476cA2b51e44fe7087fFafaFF"
startBlock: 9289397
mapping:
kind: ethereum/events
apiVersion: 0.0.7
Expand All @@ -72,13 +72,13 @@ dataSources:
- event: PoolCreated(address)
handler: handlePoolCreated
file: ./src/erc-20-pool-factory.ts
network: mainnet
network: goerli
- kind: ethereum
name: RewardsManager
source:
abi: RewardsManager
address: "0x0000000000000000000000000000000000000000"
startBlock: 17622995
address: "0x994dE190dd763Af3126FcC8EdC139275937d800b"
startBlock: 9289397
mapping:
kind: ethereum/events
apiVersion: 0.0.7
Expand Down Expand Up @@ -107,13 +107,13 @@ dataSources:
- event: UpdateExchangeRates(indexed address,indexed address,uint256[],uint256)
handler: handleUpdateExchangeRates
file: ./src/rewards-manager.ts
network: mainnet
network: goerli
- kind: ethereum
name: ERC721PoolFactory
source:
abi: ERC721PoolFactory
address: "0xb8DA113516bfb986B7b8738a76C136D1c16c5609"
startBlock: 17622995
address: "0x37048D43A65748409B04f4051eEd9480BEf68c82"
startBlock: 9289397
mapping:
kind: ethereum/events
apiVersion: 0.0.7
Expand All @@ -131,13 +131,13 @@ dataSources:
- event: PoolCreated(address)
handler: handlePoolCreated
file: ./src/erc-721-pool-factory.ts
network: mainnet
network: goerli
- kind: ethereum
name: GrantFund
source:
abi: GrantFund
address: "0x0000000000000000000000000000000000000000"
startBlock: 17622995
address: "0x881b4dFF6C72babA6f5eA60f34A61410c1EA1ec2"
startBlock: 9297080
mapping:
kind: ethereum/events
apiVersion: 0.0.7
Expand Down Expand Up @@ -169,7 +169,7 @@ dataSources:
- event: VoteCast(indexed address,uint256,uint8,uint256,string)
handler: handleVoteCast
file: ./src/grant-fund.ts
network: mainnet
network: goerli
templates:
- kind: ethereum
name: ERC20Pool
Expand Down Expand Up @@ -273,4 +273,4 @@ templates:
- event: UpdateInterestRate(uint256,uint256)
handler: handleUpdateInterestRate
file: ./src/erc-20-pool.ts
network: mainnet
network: goerli
Loading

0 comments on commit 245bf7c

Please sign in to comment.