diff --git a/schema.graphql b/schema.graphql index 60243d4b..1676347d 100644 --- a/schema.graphql +++ b/schema.graphql @@ -338,6 +338,9 @@ type GlobalStatistic @entity { "number of dispensers created" dispenserCount: Int! + "total ocean locked in veOcean" + totalOceanLocked:BigDecimal! + "current version" version: String } @@ -504,6 +507,7 @@ type VeDeposit @entity { block: Int! tx: String! veOcean: VeOCEAN! + totalOceanLocked:BigDecimal! } diff --git a/src/mappings/utils/globalUtils.ts b/src/mappings/utils/globalUtils.ts index d631c290..5263e86d 100644 --- a/src/mappings/utils/globalUtils.ts +++ b/src/mappings/utils/globalUtils.ts @@ -19,6 +19,7 @@ export function getGlobalStats(): GlobalStatistic { globalStats.datatokenCount = 0 globalStats.dispenserCount = 0 globalStats.nftCount = 0 + globalStats.totalOceanLocked = BigDecimal.zero() globalStats.save() } return globalStats @@ -33,6 +34,11 @@ export function getOPC(): OPC { return globalStats } +export function getTotalOceanLocked(): BigDecimal { + const globalStats = getGlobalStats() + return globalStats.totalOceanLocked +} + export function getTemplates(): Template { let templates = Template.load(GLOBAL_ID) if (!templates) { @@ -42,6 +48,12 @@ export function getTemplates(): Template { return templates } +export function updateTotalOceanLocked(amount: BigDecimal): void { + const globalStats = getGlobalStats() + globalStats.totalOceanLocked = amount + globalStats.save() +} + export function addOrder(): void { const globalStats = getGlobalStats() globalStats.orderCount = globalStats.orderCount + 1 diff --git a/src/mappings/veOCEAN.ts b/src/mappings/veOCEAN.ts index 4e4cb087..25344196 100644 --- a/src/mappings/veOCEAN.ts +++ b/src/mappings/veOCEAN.ts @@ -2,6 +2,10 @@ import { BigDecimal, BigInt } from '@graphprotocol/graph-ts' import { Deposit, Supply, Withdraw } from '../@types/veOCEAN/veOCEAN' import { weiToDecimal } from './utils/generic' import { getDeposit, getveOCEAN } from './utils/veUtils' +import { + getTotalOceanLocked, + updateTotalOceanLocked +} from './utils/globalUtils' export function handleDeposit(event: Deposit): void { const provider = event.params.provider @@ -9,7 +13,7 @@ export function handleDeposit(event: Deposit): void { const locktime = event.params.locktime const type = event.params.type const ts = event.params.ts - + const totalOceanLocked = getTotalOceanLocked() const veOCEAN = getveOCEAN(provider.toHex()) // Create new Deposit entity const deposit = getDeposit( @@ -28,6 +32,10 @@ export function handleDeposit(event: Deposit): void { deposit.tx = event.transaction.hash.toHex() deposit.sender = event.transaction.from.toHex() deposit.veOcean = veOCEAN.id + + deposit.totalOceanLocked = totalOceanLocked.plus(deposit.value) + updateTotalOceanLocked(deposit.totalOceanLocked) + deposit.save() // -------------------------------------------- @@ -39,6 +47,7 @@ export function handleDeposit(event: Deposit): void { } export function handleSupply(event: Supply): void {} export function handleWithdraw(event: Withdraw): void { + const totalOceanLocked = getTotalOceanLocked() const provider = event.params.provider const value = event.params.value const ts = event.params.ts @@ -61,6 +70,8 @@ export function handleWithdraw(event: Withdraw): void { deposit.tx = event.transaction.hash.toHex() deposit.sender = event.transaction.from.toHex() deposit.veOcean = veOCEAN.id + deposit.totalOceanLocked = totalOceanLocked.plus(deposit.value) // it's already negated above + updateTotalOceanLocked(deposit.totalOceanLocked) deposit.save() // -------------------------------------------- diff --git a/test/integration/VeOcean.test.ts b/test/integration/VeOcean.test.ts index eb2dbdda..93044caf 100644 --- a/test/integration/VeOcean.test.ts +++ b/test/integration/VeOcean.test.ts @@ -70,6 +70,23 @@ function evmIncreaseTime(seconds) { }) } +async function getTotalLockedOcean() { + const initialQuery = { + query: `query{ + globalStatistics{ + totalOceanLocked + } + }` + } + const initialResponse = await fetch(subgraphUrl, { + method: 'POST', + body: JSON.stringify(initialQuery) + }) + const data = (await initialResponse.json()).data.globalStatistics + if (data.length == 0) return 0 + + return data[0].totalOceanLocked +} const minAbi = [ { constant: false, @@ -144,6 +161,7 @@ describe('veOcean tests', async () => { it('Alice should lock 100 Ocean', async () => { // since we can only lock once, we test if tx fails or not // so if there is already a lock, skip it + const totalOceanLockedBefore = await getTotalLockedOcean() let currentBalance = await veOcean.getLockedAmount(Alice) let currentLock = await veOcean.lockEnd(Alice) const amount = '100' @@ -172,6 +190,19 @@ describe('veOcean tests', async () => { currentBalance = await veOcean.getLockedAmount(Alice) currentLock = await veOcean.lockEnd(Alice) await sleep(2000) + const totalOceanLockedAfter = await getTotalLockedOcean() + assert( + parseFloat(totalOceanLockedAfter) > parseFloat(totalOceanLockedBefore), + 'After (' + + totalOceanLockedAfter + + ') shold be higher then ' + + totalOceanLockedBefore + ) + assert( + parseFloat(totalOceanLockedAfter) == + parseFloat(totalOceanLockedBefore + amount), + 'Invalid totalOceanLockedAfter (' + totalOceanLockedAfter + ')' + ) const initialQuery = { query: `query { veOCEANs(id:"${Alice.toLowerCase()}"){ @@ -550,7 +581,17 @@ describe('veOcean tests', async () => { }) it('Alice should withdraw locked tokens', async () => { await evmIncreaseTime(60 * 60 * 24 * 7) + const totalOceanLockedBefore = await getTotalLockedOcean() await veOcean.withdraw(Alice) + await sleep(2000) + const totalOceanLockedAfter = await getTotalLockedOcean() + assert( + parseFloat(totalOceanLockedAfter) < parseFloat(totalOceanLockedBefore), + 'After (' + + totalOceanLockedAfter + + ') shold be lower then ' + + totalOceanLockedBefore + ) }) it('Alice should lock 100 Ocean and Delegate them to Bob', async () => {