Skip to content

Commit

Permalink
Test and Update Allowances and Transferors (#71)
Browse files Browse the repository at this point in the history
* add base methods for lpb management

* reorg erc20 pool; abstract additional method

* reorganize erc20-pool

* add _handleBondWithdrawn

* wip allowances test

* fix issues with allowance mappings

* fix revokeAllowances; expand tests

* remove stale approval lists

* add shared _handleBucketTakeLPAwarded handler

* remove comments

---------

Co-authored-by: Mike <[email protected]>
  • Loading branch information
MikeHathaway and Mike authored Sep 20, 2023
1 parent c9da759 commit f0727d8
Show file tree
Hide file tree
Showing 7 changed files with 367 additions and 81 deletions.
68 changes: 44 additions & 24 deletions src/mappings/base/base-pool.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Address, BigInt, Bytes, ethereum, log } from "@graphprotocol/graph-ts"
import { Account, AddQuoteToken, BondWithdrawn, Bucket, BucketBankruptcy, Flashloan, Lend, LoanStamped, MoveQuoteToken, Pool, PositionLend, RemoveQuoteToken, ReserveAuctionKick, ReserveAuctionTake, Token, TransferLP, UpdateInterestRate } from "../../../generated/schema"
import { Account, AddQuoteToken, BondWithdrawn, Bucket, BucketBankruptcy, BucketTakeLPAwarded, Flashloan, Lend, LoanStamped, MoveQuoteToken, Pool, PositionLend, RemoveQuoteToken, ReserveAuctionKick, ReserveAuctionTake, Token, TransferLP, UpdateInterestRate } from "../../../generated/schema"
import {
AddQuoteToken as AddQuoteTokenERC20Event,
MoveQuoteToken as MoveQuoteTokenERC20Event,
Expand All @@ -23,8 +23,9 @@ import { incrementTokenTxCount as incrementTokenTxCountERC20Pool } from "../../u
import { incrementTokenTxCount as incrementTokenTxCountERC721Pool } from "../../utils/token-erc721"
import { loadOrCreateReserveAuction, reserveAuctionKickerReward } from "../../utils/pool/reserve-auction"
import { saveOrRemovePositionLend } from "../../utils/position"
import { decreaseAllowances, increaseAllowances, loadOrCreateAllowances, revokeAllowances } from "../../utils/pool/lp-allowances"
import { approveTransferors, loadOrCreateTransferors, revokeTransferors } from "../../utils/pool/lp-transferors"
import { decreaseAllowances, increaseAllowances, loadOrCreateAllowances, revokeAllowances, saveOrRemoveAllowances } from "../../utils/pool/lp-allowances"
import { approveTransferors, loadOrCreateTransferors, revokeTransferors, saveOrRemoveTranserors } from "../../utils/pool/lp-transferors"
import { loadOrCreateBucketTake } from "../../utils/pool/liquidation"


/*******************************/
Expand Down Expand Up @@ -506,70 +507,67 @@ export function _handleTransferLP(erc20Event: TransferLPERC20Event | null, erc72

export function _handleApproveLPTransferors(event: ethereum.Event, lender: Address, transferors: Address[]): void {
const poolId = addressToBytes(event.address)
const entity = loadOrCreateTransferors(poolId, lender)
approveTransferors(entity, transferors)
const lpTransferorList = loadOrCreateTransferors(poolId, addressToBytes(lender))
approveTransferors(lpTransferorList, transferors)

const pool = Pool.load(poolId)!
pool.txCount = pool.txCount.plus(ONE_BI)

// save entities to the store
pool.save()
entity.save()
lpTransferorList.save()
}

export function _handleDecreaseLPAllowance(event: ethereum.Event, spender: Address, indexes: BigInt[], amounts: BigInt[]): void {
export function _handleDecreaseLPAllowance(event: ethereum.Event, owner: Address, spender: Address, indexes: BigInt[], amounts: BigInt[]): void {
const poolId = addressToBytes(event.address)
const lender = event.transaction.from
const entity = loadOrCreateAllowances(poolId, lender, spender)
decreaseAllowances(entity, indexes, amounts)
const lpAllowanceList = loadOrCreateAllowances(poolId, addressToBytes(owner), addressToBytes(spender))
decreaseAllowances(lpAllowanceList, indexes, amounts)

const pool = Pool.load(poolId)!
pool.txCount = pool.txCount.plus(ONE_BI)

// save entities to the store
pool.save()
entity.save()
saveOrRemoveAllowances(lpAllowanceList)
}

export function _handleIncreaseLPAllowance(event: ethereum.Event, spender: Address, indexes: BigInt[], amounts: BigInt[]): void {
export function _handleIncreaseLPAllowance(event: ethereum.Event, owner: Address, spender: Address, indexes: BigInt[], amounts: BigInt[]): void {
const poolId = addressToBytes(event.address)
const lender = event.transaction.from
const entity = loadOrCreateAllowances(poolId, lender, spender)
increaseAllowances(entity, indexes, amounts)
const lpAllowanceList = loadOrCreateAllowances(poolId, addressToBytes(owner), addressToBytes(spender))
increaseAllowances(lpAllowanceList, indexes, amounts)

const pool = Pool.load(poolId)!
pool.txCount = pool.txCount.plus(ONE_BI)

// save entities to the store
pool.save()
entity.save()
lpAllowanceList.save()
}

export function _handleRevokeLPAllowance(event: ethereum.Event, spender: Address, indexes: BigInt[]): void {
export function _handleRevokeLPAllowance(event: ethereum.Event, owner: Address, spender: Address, indexes: BigInt[]): void {
const poolId = addressToBytes(event.address)
const lender = event.transaction.from
const entity = loadOrCreateAllowances(poolId, lender, spender)
revokeAllowances(entity, indexes)
const lpAllowanceList = loadOrCreateAllowances(poolId, owner, spender)
revokeAllowances(lpAllowanceList, indexes)

const pool = Pool.load(poolId)!
pool.txCount = pool.txCount.plus(ONE_BI)

// save entities to the store
pool.save()
entity.save()
saveOrRemoveAllowances(lpAllowanceList)
}

export function _handleRevokeLPTransferors(event: ethereum.Event, lender: Address, transferors: Address[]): void {
const poolId = addressToBytes(event.address)
const entity = loadOrCreateTransferors(poolId, lender)
revokeTransferors(entity, transferors)
const lpTransferorList = loadOrCreateTransferors(poolId, lender)
revokeTransferors(lpTransferorList, transferors)

const pool = Pool.load(poolId)!
pool.txCount = pool.txCount.plus(ONE_BI)

// save entities to the store
pool.save()
entity.save()
saveOrRemoveTranserors(lpTransferorList)
}

/**********************************/
Expand All @@ -591,6 +589,28 @@ export function _handleBondWithdrawn(event: ethereum.Event, kicker: Address, rec
entity.save()
}

// emitted along with BucketTake
export function _handleBucketTakeLPAwarded(event: ethereum.Event, kicker: Address, taker: Address, lpAwardedKicker: BigInt, lpAwardedTaker: BigInt): void {
const lpAwardedId = event.transaction.hash.concatI32(event.logIndex.toI32());
const bucketTakeLpAwarded = new BucketTakeLPAwarded(lpAwardedId)
bucketTakeLpAwarded.taker = taker
bucketTakeLpAwarded.pool = addressToBytes(event.address)
bucketTakeLpAwarded.kicker = kicker
bucketTakeLpAwarded.lpAwardedTaker = wadToDecimal(lpAwardedTaker)
bucketTakeLpAwarded.lpAwardedKicker = wadToDecimal(lpAwardedKicker)

bucketTakeLpAwarded.blockNumber = event.block.number
bucketTakeLpAwarded.blockTimestamp = event.block.timestamp
bucketTakeLpAwarded.transactionHash = event.transaction.hash
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()
}

/*******************************/
/*** Reserves Event Handlers ***/
/*******************************/
Expand Down
27 changes: 5 additions & 22 deletions src/mappings/erc-20-pool.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ import { getLiquidationAuctionId, getAuctionInfoERC20Pool, loadOrCreateLiquidati
import { updatePool, addLiquidationToPool } from "../utils/pool/pool"
import { lpbValueInQuote } from "../utils/pool/lend"
import { incrementTokenTxCount } from "../utils/token-erc20"
import { _handleAddQuoteToken, _handleApproveLPTransferors, _handleBondWithdrawn, _handleBucketBankruptcy, _handleDecreaseLPAllowance, _handleFlashLoan, _handleIncreaseLPAllowance, _handleInterestRateEvent, _handleLoanStamped, _handleMoveQuoteToken, _handleRemoveQuoteToken, _handleReserveAuctionKick, _handleReserveAuctionTake, _handleRevokeLPAllowance, _handleRevokeLPTransferors, _handleTransferLP } from "./base/base-pool"
import { _handleAddQuoteToken, _handleApproveLPTransferors, _handleBondWithdrawn, _handleBucketBankruptcy, _handleBucketTakeLPAwarded, _handleDecreaseLPAllowance, _handleFlashLoan, _handleIncreaseLPAllowance, _handleInterestRateEvent, _handleLoanStamped, _handleMoveQuoteToken, _handleRemoveQuoteToken, _handleReserveAuctionKick, _handleReserveAuctionTake, _handleRevokeLPAllowance, _handleRevokeLPTransferors, _handleTransferLP } from "./base/base-pool"


/*******************************/
Expand Down Expand Up @@ -514,24 +514,7 @@ export function handleBucketTake(event: BucketTakeEvent): void {
export function handleBucketTakeLPAwarded(
event: BucketTakeLPAwardedEvent
): void {
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.transactionHash = event.transaction.hash
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()
_handleBucketTakeLPAwarded(event, event.params.kicker, event.params.taker, event.params.lpAwardedKicker, event.params.lpAwardedTaker)
}

export function handleTake(event: TakeEvent): void {
Expand Down Expand Up @@ -704,15 +687,15 @@ export function handleApproveLPTransferors(
}

export function handleDecreaseLPAllowance(event: DecreaseLPAllowanceEvent): void {
_handleDecreaseLPAllowance(event, event.params.spender, event.params.indexes, event.params.amounts)
_handleDecreaseLPAllowance(event, event.params.owner, event.params.spender, event.params.indexes, event.params.amounts)
}

export function handleIncreaseLPAllowance(event: IncreaseLPAllowanceEvent): void {
_handleIncreaseLPAllowance(event, event.params.spender, event.params.indexes, event.params.amounts)
_handleIncreaseLPAllowance(event, event.params.owner, event.params.spender, event.params.indexes, event.params.amounts)
}

export function handleRevokeLPAllowance(event: RevokeLPAllowanceEvent): void {
_handleRevokeLPAllowance(event, event.params.spender, event.params.indexes)
_handleRevokeLPAllowance(event, event.params.owner, event.params.spender, event.params.indexes)
}

export function handleRevokeLPTransferors(
Expand Down
31 changes: 5 additions & 26 deletions src/mappings/erc-721-pool.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ import { getBorrowerInfoERC721Pool, getLoanId, loadOrCreateLoan, saveOrRemoveLoa
import { getLiquidationAuctionId, loadOrCreateLiquidationAuction, updateLiquidationAuction, getAuctionStatus, loadOrCreateBucketTake, getAuctionInfoERC721Pool } from "../utils/pool/liquidation"
import { updatePool, addLiquidationToPool, getLenderInfoERC721Pool } from "../utils/pool/pool"
import { lpbValueInQuote } from "../utils/pool/lend"
import { _handleAddQuoteToken, _handleApproveLPTransferors, _handleBondWithdrawn, _handleBucketBankruptcy, _handleDecreaseLPAllowance, _handleFlashLoan, _handleIncreaseLPAllowance, _handleInterestRateEvent, _handleLoanStamped, _handleMoveQuoteToken, _handleRemoveQuoteToken, _handleReserveAuctionKick, _handleReserveAuctionTake, _handleRevokeLPAllowance, _handleRevokeLPTransferors, _handleTransferLP } from "./base/base-pool"
import { _handleAddQuoteToken, _handleApproveLPTransferors, _handleBondWithdrawn, _handleBucketBankruptcy, _handleBucketTakeLPAwarded, _handleDecreaseLPAllowance, _handleFlashLoan, _handleIncreaseLPAllowance, _handleInterestRateEvent, _handleLoanStamped, _handleMoveQuoteToken, _handleRemoveQuoteToken, _handleReserveAuctionKick, _handleReserveAuctionTake, _handleRevokeLPAllowance, _handleRevokeLPTransferors, _handleTransferLP } from "./base/base-pool"


/*******************************/
Expand Down Expand Up @@ -161,12 +161,10 @@ export function handleRepayDebt(event: RepayDebtEvent): void {
repayDebt.save()
}

// identical to ERC20Pool
export function handleFlashloan(event: FlashloanEvent): void {
_handleFlashLoan(event, event.params.token, event.params.receiver, event.params.amount)
}

// identical to ERC20Pool
export function handleLoanStamped(event: LoanStampedEvent): void {
_handleLoanStamped(event, event.params.borrower)
}
Expand Down Expand Up @@ -524,7 +522,6 @@ export function handleSettle(event: SettleEvent): void {
settle.save()
}

// TODO: can this be abstracted?
export function handleKick(event: KickEvent): void {
const kick = new Kick(
event.transaction.hash.concatI32(event.logIndex.toI32())
Expand Down Expand Up @@ -716,26 +713,8 @@ export function handleBucketTake(event: BucketTakeEvent): void {
takerLend.save()
}

// identical to ERC20Pool
export function handleBucketTakeLPAwarded(event: BucketTakeLPAwardedEvent): void {
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.transactionHash = event.transaction.hash
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()
_handleBucketTakeLPAwarded(event, event.params.kicker, event.params.taker, event.params.lpAwardedKicker, event.params.lpAwardedTaker)
}

export function handleTake(event: TakeEvent): void {
Expand Down Expand Up @@ -834,15 +813,15 @@ export function handleApproveLPTransferors(
}

export function handleDecreaseLPAllowance(event: DecreaseLPAllowanceEvent): void {
_handleDecreaseLPAllowance(event, event.params.spender, event.params.indexes, event.params.amounts)
_handleDecreaseLPAllowance(event, event.params.owner, event.params.spender, event.params.indexes, event.params.amounts)
}

export function handleIncreaseLPAllowance(event: IncreaseLPAllowanceEvent): void {
_handleIncreaseLPAllowance(event, event.params.spender, event.params.indexes, event.params.amounts)
_handleIncreaseLPAllowance(event, event.params.owner, event.params.spender, event.params.indexes, event.params.amounts)
}

export function handleRevokeLPAllowance(event: RevokeLPAllowanceEvent): void {
_handleRevokeLPAllowance(event, event.params.spender, event.params.indexes)
_handleRevokeLPAllowance(event, event.params.owner, event.params.spender, event.params.indexes)
}

export function handleRevokeLPTransferors(
Expand Down
24 changes: 21 additions & 3 deletions src/utils/pool/lp-allowances.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { BigInt, Bytes } from "@graphprotocol/graph-ts"
import { BigInt, Bytes, store } from "@graphprotocol/graph-ts"
import { LPAllowance, LPAllowanceList } from "../../../generated/schema";
import { wadToDecimal } from "../convert";

Expand Down Expand Up @@ -27,17 +27,20 @@ export function increaseAllowances(entity: LPAllowanceList, indexes: Array<BigIn
const id = entity.id;
const entityAllowances = entity.allowances;
for (var i=0; i<indexes.length; ++i) {
const aid = getAllowanceId(id, indexes[i])
const index = indexes[i]
const aid = getAllowanceId(id, index)
let allowance = LPAllowance.load(aid)
if (allowance == null) {
// create a new allowance if first time
allowance = new LPAllowance(aid)
allowance.amount = wadToDecimal(amounts[i])
allowance.index = index.toI32()
entityAllowances.push(aid)
} else {
// increase existing allowance
allowance.amount = allowance.amount.plus(wadToDecimal(amounts[i]))
}
allowance.save()
}
entity.allowances = entityAllowances
}
Expand All @@ -53,11 +56,15 @@ export function decreaseAllowances(entity: LPAllowanceList, indexes: Array<BigIn
if (decrease.lt(allowance.amount)) {
// decrease existing allowance
allowance.amount = allowance.amount.minus(decrease)
allowance.save()
} else {
// delete the allowance
const indexToRemove = entityAllowances.indexOf(aid)
if (indexToRemove != -1)
entityAllowances.splice(indexToRemove, 1)

// remove allowance from the store
store.remove('LPAllowance', aid.toHexString())
}
}
}
Expand All @@ -75,7 +82,18 @@ export function revokeAllowances(entity: LPAllowanceList, indexes: Array<BigInt>
const indexToRemove = entityAllowances.indexOf(aid)
if (indexToRemove != -1)
entityAllowances.splice(indexToRemove, 1)

// remove allowance from the store
store.remove('LPAllowance', aid.toHexString())
}
}
entity.allowances = entityAllowances
}
}

export function saveOrRemoveAllowances(entity: LPAllowanceList): void {
if (entity.allowances.length == 0) {
store.remove('LPAllowanceList', entity.id.toHexString())
} else {
entity.save()
}
}
17 changes: 13 additions & 4 deletions src/utils/pool/lp-transferors.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { Address, Bytes } from "@graphprotocol/graph-ts"
import { LPTransferorList, Pool } from "../../../generated/schema";
import { Address, Bytes, store } from "@graphprotocol/graph-ts"
import { LPTransferorList} from "../../../generated/schema";
import { addressToBytes } from "../convert";

export function getTransferorId(poolId: Bytes, lenderId: Bytes): Bytes {
return poolId.concat(Bytes.fromUTF8('|' + lenderId.toString()));
Expand All @@ -21,7 +22,7 @@ export function approveTransferors(entity: LPTransferorList, transferorsApproved
// iterate through newly-approved transferors, pushing each transfer if not already there
const entityTransferors = entity.transferors
for (var i=0; i<transferorsApproved.length; ++i) {
const approved = transferorsApproved[i]
const approved = addressToBytes(transferorsApproved[i])
if (entityTransferors.indexOf(approved) == -1)
entityTransferors.push(approved)
}
Expand All @@ -38,4 +39,12 @@ export function revokeTransferors(entity: LPTransferorList, transferorsRevoked:
entityTransferors.splice(indexToRemove, 1)
}
entity.transferors = entityTransferors
}
}

export function saveOrRemoveTranserors(entity: LPTransferorList): void {
if (entity.transferors.length == 0) {
store.remove('LPTransferorList', entity.id.toHexString())
} else {
entity.save()
}
}
Loading

0 comments on commit f0727d8

Please sign in to comment.