Skip to content

Commit

Permalink
add liquidation adapters
Browse files Browse the repository at this point in the history
  • Loading branch information
0xngmi committed Jun 23, 2022
1 parent 7d7a1a5 commit 36fbcb2
Show file tree
Hide file tree
Showing 3 changed files with 158 additions and 0 deletions.
98 changes: 98 additions & 0 deletions liquidations/aave-v2/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
const { gql, request } = require("graphql-request")
const { getPagedGql } = require("../utils/gql")

const query = gql`
query users($lastId: String) {
users(first: 1000, where:{
borrowedReservesCount_gt: 0,
id_gt: $lastId
}) {
id
reserves{
usageAsCollateralEnabledOnUser
reserve{
symbol
usageAsCollateralEnabled
underlyingAsset
price {
priceInEth
}
decimals
reserveLiquidationThreshold
}
currentATokenBalance
currentTotalDebt
}
}
}
`

const ethPriceQuery = gql`
{
priceOracleAsset(id: "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48"){
priceInEth
}
}
`

const subgraphUrl = "https://api.thegraph.com/subgraphs/name/aave/protocol-v2"

const liqs = async () => {
const users = await getPagedGql(subgraphUrl, query, "users")
const ethPrice = 1 / ((await request(subgraphUrl, ethPriceQuery)).priceOracleAsset.priceInEth / 1e18)
const badDebt = []
const positions = users.map(user => {
let totalDebt = 0, totalCollateral = 0;
const debts = user.reserves.map(reserve => {
const decimals = 10 ** reserve.reserve.decimals
const price = (Number(reserve.reserve.price.priceInEth) / (1e18)) * ethPrice
const liqThreshold = Number(reserve.reserve.reserveLiquidationThreshold) / 1e4
let debt = Number(reserve.currentTotalDebt)
if (reserve.usageAsCollateralEnabledOnUser === true) {
debt -= Number(reserve.currentATokenBalance) * liqThreshold
}
debt *= price / decimals
if (debt > 0) {
totalDebt += debt
} else {
totalCollateral -= debt
}
return {
debt,
price,
token: reserve.reserve.underlyingAsset,
totalBal: reserve.currentATokenBalance,
decimals
}
})

const liquidablePositions = debts.filter(({ debt }) => debt < 0).map(pos => {
const otherCollateral = totalCollateral + pos.debt;
const diffDebt = totalDebt - otherCollateral
if (diffDebt > 0) {
const amountCollateral = -pos.debt / pos.price // accounts for liqThreshold
const liqPrice = diffDebt / amountCollateral;
if (liqPrice > pos.price) {
badDebt.push([totalDebt, liqPrice, pos.price, user.id])
} else {
return {
liqPrice,
collateral: pos.token,
collateralAmount: pos.totalBal,
}
}
}
}).filter(t => t !== undefined)

return liquidablePositions
}).flat()
//console.log(badDebt.sort((a,b)=>b[0]-a[0]))
return positions
}

module.exports = {
ethereum: {
liquidations: liqs
}
}
liqs()
41 changes: 41 additions & 0 deletions liquidations/maker/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
const { gql } = require("graphql-request")
const {getPagedGql} = require("../utils/gql")

const cdpQuery = gql`
query cdps($lastId: String) {
vaults(where:{
debt_gt: 0,
id_gt: $lastId
}, first:1000){
id
collateral
collateralType{
liquidationRatio
rate
id
price{
spotPrice
}
}
debt
}
}
`

const liqs = async () => {
const cdps = await getPagedGql("https://api.thegraph.com/subgraphs/name/protofire/maker-protocol", cdpQuery, "vaults")
return cdps.map(cdp=>{
return {
liqPrice: cdp.debt * cdp.collateralType.liquidationRatio / cdp.collateral,
collateral: cdp.collateralType.id,
collateralAmount: cdp.collateral,
}
})
}

module.exports = {
ethereum: {
liquidations: liqs
}
}
liqs()
19 changes: 19 additions & 0 deletions liquidations/utils/gql.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
const { request } = require("graphql-request")

async function getPagedGql(url, query, itemName){
let lastId = "";
let all = []
let page;
do {
page = (await request(url, query, {
lastId
}))[itemName]
all = all.concat(page)
lastId = page[page.length - 1]?.id
} while (page.length === 1e3);
return all
}

module.exports={
getPagedGql
}

0 comments on commit 36fbcb2

Please sign in to comment.