proper veDelegation (#663)

This commit is contained in:
Alex Coseru 2023-04-28 09:36:56 +03:00 committed by GitHub
parent 68944f02a5
commit c33868d841
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 203 additions and 38 deletions

View File

@ -462,7 +462,7 @@ type VeAllocationUpdate @entity {
} }
type VeDelegation @entity { type VeDelegation @entity {
"id = tokenId" "id = VeDelegation contract + tokenId"
id: ID! id: ID!
delegator: VeOCEAN! delegator: VeOCEAN!
receiver: VeOCEAN! receiver: VeOCEAN!
@ -470,11 +470,26 @@ type VeDelegation @entity {
amount: BigInt! amount: BigInt!
cancelTime: BigInt! cancelTime: BigInt!
expireTime: BigInt! expireTime: BigInt!
updates: [VeDelegationUpdate!] @derivedFrom(field: "veDelegation")
}
type VeDelegationUpdate @entity {
"id = {tx}-{eventIndex}"
id: ID!
block: Int! block: Int!
timestamp: Int! timestamp: Int!
tx: String! tx: String!
sender: String!
amount: BigInt!
cancelTime: BigInt!
expireTime: BigInt!
"type: CREATE_BOOST = 0, EXTEND_BOOST = 1, BURN_BOOST = 2"
type:Int!
veDelegation:VeDelegation!
} }
type VeOCEAN @entity { type VeOCEAN @entity {
"id = {user address}" "id = {user address}"
id: ID! id: ID!

View File

@ -121,7 +121,11 @@ export function writeveAllocationUpdate(
return allocationUpdate return allocationUpdate
} }
export function getveDelegation(id: string): VeDelegation { export function getveDelegation(
contract: Address,
eventid: string
): VeDelegation {
const id = contract.toHex() + '-' + eventid
let veDelegation = VeDelegation.load(id) let veDelegation = VeDelegation.load(id)
if (veDelegation === null) { if (veDelegation === null) {
@ -132,9 +136,6 @@ export function getveDelegation(id: string): VeDelegation {
veDelegation.amount = BigInt.zero() veDelegation.amount = BigInt.zero()
veDelegation.receiver = '' veDelegation.receiver = ''
veDelegation.delegator = '' veDelegation.delegator = ''
veDelegation.block = 0
veDelegation.timestamp = 0
veDelegation.tx = ''
veDelegation.save() veDelegation.save()
} }
return veDelegation return veDelegation

View File

@ -1,4 +1,5 @@
import { BigInt } from '@graphprotocol/graph-ts' import { BigInt } from '@graphprotocol/graph-ts'
import { VeDelegationUpdate } from '../@types/schema'
import { import {
BurnBoost, BurnBoost,
DelegateBoost, DelegateBoost,
@ -14,19 +15,32 @@ export function handleDelegation(event: DelegateBoost): void {
const _amount = event.params._amount const _amount = event.params._amount
const _cancelTime = event.params._cancel_time const _cancelTime = event.params._cancel_time
const _expireTime = event.params._expire_time const _expireTime = event.params._expire_time
// create veOcean if does not exists
const veDelegation = getveDelegation(_tokenId.toHex())
veDelegation.delegator = _delegator
getveOCEAN(_receiver) getveOCEAN(_receiver)
getveOCEAN(_delegator)
const veDelegation = getveDelegation(event.address, _tokenId.toHex())
veDelegation.delegator = _delegator
veDelegation.receiver = _receiver veDelegation.receiver = _receiver
veDelegation.tokenId = _tokenId veDelegation.tokenId = _tokenId
veDelegation.amount = _amount veDelegation.amount = _amount
veDelegation.cancelTime = _cancelTime veDelegation.cancelTime = _cancelTime
veDelegation.expireTime = _expireTime veDelegation.expireTime = _expireTime
veDelegation.block = event.block.number.toI32()
veDelegation.timestamp = event.block.timestamp.toI32()
veDelegation.tx = event.transaction.hash.toHex()
veDelegation.save() veDelegation.save()
const veDelegationUpdate = new VeDelegationUpdate(
event.transaction.hash.toHex() + '-' + event.logIndex.toString()
)
veDelegationUpdate.type = 0
veDelegationUpdate.veDelegation = veDelegation.id
veDelegationUpdate.block = event.block.number.toI32()
veDelegationUpdate.timestamp = event.block.timestamp.toI32()
veDelegationUpdate.tx = event.transaction.hash.toHex()
veDelegationUpdate.amount = _amount
veDelegationUpdate.cancelTime = _cancelTime
veDelegationUpdate.expireTime = _expireTime
veDelegationUpdate.sender = event.transaction.from.toHex()
veDelegationUpdate.save()
} }
export function handleExtendBoost(event: ExtendBoost): void { export function handleExtendBoost(event: ExtendBoost): void {
@ -36,17 +50,33 @@ export function handleExtendBoost(event: ExtendBoost): void {
const _amount = event.params._amount const _amount = event.params._amount
const _cancelTime = event.params._cancel_time const _cancelTime = event.params._cancel_time
const _expireTime = event.params._expire_time const _expireTime = event.params._expire_time
// create veOcean if does not exists
const veDelegation = getveDelegation(_tokenId.toHex()) getveOCEAN(_receiver)
getveOCEAN(_delegator)
// it's possible to not have veDelegation object, because we missed handleDelegation
// that should not happend, but we create the object anyway
const veDelegation = getveDelegation(event.address, _tokenId.toHex())
veDelegation.delegator = _delegator veDelegation.delegator = _delegator
veDelegation.receiver = _receiver veDelegation.receiver = _receiver
veDelegation.tokenId = _tokenId veDelegation.tokenId = _tokenId
veDelegation.amount = _amount veDelegation.amount = _amount
veDelegation.cancelTime = _cancelTime veDelegation.cancelTime = _cancelTime
veDelegation.expireTime = _expireTime veDelegation.expireTime = _expireTime
veDelegation.timestamp = event.block.timestamp.toI32()
veDelegation.tx = event.transaction.hash.toHex()
veDelegation.save() veDelegation.save()
const veDelegationUpdate = new VeDelegationUpdate(
event.transaction.hash.toHex() + '-' + event.logIndex.toString()
)
veDelegationUpdate.veDelegation = veDelegation.id
veDelegationUpdate.type = 1
veDelegationUpdate.block = event.block.number.toI32()
veDelegationUpdate.timestamp = event.block.timestamp.toI32()
veDelegationUpdate.tx = event.transaction.hash.toHex()
veDelegationUpdate.amount = _amount
veDelegationUpdate.cancelTime = _cancelTime
veDelegationUpdate.expireTime = _expireTime
veDelegationUpdate.sender = event.transaction.from.toHex()
veDelegationUpdate.save()
} }
export function handleTransferBoost(event: TransferBoost): void { export function handleTransferBoost(event: TransferBoost): void {
@ -62,7 +92,21 @@ export function handleBurnBoost(event: BurnBoost): void {
const _tokenId = event.params._token_id const _tokenId = event.params._token_id
// delete // delete
const veDelegation = getveDelegation(_tokenId.toHex()) const veDelegation = getveDelegation(event.address, _tokenId.toHex())
veDelegation.amount = BigInt.zero() veDelegation.amount = BigInt.zero()
veDelegation.save() veDelegation.save()
const veDelegationUpdate = new VeDelegationUpdate(
event.transaction.hash.toHex() + '-' + event.logIndex.toString()
)
veDelegationUpdate.veDelegation = veDelegation.id
veDelegationUpdate.type = 2
veDelegationUpdate.block = event.block.number.toI32()
veDelegationUpdate.timestamp = event.block.timestamp.toI32()
veDelegationUpdate.tx = event.transaction.hash.toHex()
veDelegationUpdate.amount = veDelegation.amount
veDelegationUpdate.cancelTime = veDelegation.cancelTime
veDelegationUpdate.expireTime = veDelegation.expireTime
veDelegationUpdate.sender = event.transaction.from.toHex()
veDelegationUpdate.save()
} }

View File

@ -69,7 +69,7 @@
- event: ExtendBoost(indexed address,indexed address,indexed uint256,uint256,uint256,uint256) - event: ExtendBoost(indexed address,indexed address,indexed uint256,uint256,uint256,uint256)
handler: handleExtendBoost handler: handleExtendBoost
- event: BurnBoost(indexed address,indexed address,indexed uint256) - event: BurnBoost(indexed address,indexed address,indexed uint256)
handler: handleTransferBoost handler: handleBurnBoost
- name: veFeeDistributor - name: veFeeDistributor
kind: ethereum/contract kind: ethereum/contract

View File

@ -610,7 +610,6 @@ describe('veOcean tests', async () => {
) )
const timestamp = Math.floor(Date.now() / 1000) const timestamp = Math.floor(Date.now() / 1000)
const unlockTime = timestamp + 30 * 86400 const unlockTime = timestamp + 30 * 86400
console.log('unlock time', unlockTime)
if (parseInt(currentBalance) > 0 || currentLock > 0) { if (parseInt(currentBalance) > 0 || currentLock > 0) {
// we already have some locked tokens, so our transaction should fail // we already have some locked tokens, so our transaction should fail
@ -656,14 +655,15 @@ describe('veOcean tests', async () => {
await veOcean.increaseUnlockTime(Alice, extLockTime) await veOcean.increaseUnlockTime(Alice, extLockTime)
const estGas = await calculateEstimatedGas( const initalBoostExpiry = extLockTime - 100000
let estGas = await calculateEstimatedGas(
Alice, Alice,
delegateContract.methods.create_boost, delegateContract.methods.create_boost,
Alice, Alice,
Bob, Bob,
10000, 5000,
0, 0,
extLockTime, initalBoostExpiry,
0 0
) )
@ -675,41 +675,146 @@ describe('veOcean tests', async () => {
delegateContract.methods.create_boost, delegateContract.methods.create_boost,
Alice, Alice,
Bob, Bob,
10000, 5000,
0, 0,
extLockTime, initalBoostExpiry,
0 0
) )
assert(tx3, 'Transaction failed') assert(tx3, 'Transaction failed')
assert(tx3.events.DelegateBoost, 'No Delegate boost event') assert(tx3.events.DelegateBoost, 'No Delegate boost event')
const tokenId = tx3.events.DelegateBoost.returnValues._token_id
await evmIncreaseTime(60)
// extend boost
estGas = await calculateEstimatedGas(
Alice,
delegateContract.methods.extend_boost,
tokenId,
10000,
extLockTime,
0
)
sleep(4000) const tx4 = await sendTx(
Alice,
estGas,
web3,
1,
delegateContract.methods.extend_boost,
tokenId,
10000,
extLockTime,
0
)
assert(tx4, 'Transaction failed')
assert(tx4.events.ExtendBoost, 'No ExtendBoost event')
await evmIncreaseTime(60)
// burn it
estGas = await calculateEstimatedGas(
Alice,
delegateContract.methods.cancel_boost,
tokenId
)
const tx5 = await sendTx(
Alice,
estGas,
web3,
1,
delegateContract.methods.cancel_boost,
tokenId
)
assert(tx5, 'Transaction failed')
assert(tx5.events.BurnBoost, 'No BurnBoost event')
await sleep(3000)
const delegateQuery = { const delegateQuery = {
query: `query { query: `query{
veDelegations{ veDelegations(where:{delegator:"${Alice.toLowerCase()}"}){
id, id
delegator { delegator {
id id
}, }
receiver { receiver{
id id
}, }
tokenId, amount
amount, tokenId
cancelTime, cancelTime
expireTime expireTime
updates(orderBy:timestamp orderDirection:asc){
id
block
timestamp
tx
sender
amount
cancelTime
expireTime
type
}
} }
}` }`
} }
const delegateResponse = await fetch(subgraphUrl, { const delegateResponse = await fetch(subgraphUrl, {
method: 'POST', method: 'POST',
body: JSON.stringify(delegateQuery) body: JSON.stringify(delegateQuery)
}) })
const json = await delegateResponse.json() const resp = await delegateResponse.json()
console.log('json', json) const delegations = resp.data.veDelegations
console.log('json?.data?.veDelegations', json?.data?.veDelegations)
assert(json?.data?.veDelegations, 'No veDelegations') assert(delegations.length > 0, 'No veDelegations')
assert(
delegations[0].tokenId.toLowerCase() ==
tx3.events.DelegateBoost.returnValues._token_id.toLowerCase(),
'Invalid tokenID'
)
assert(delegations[0].amount == '0', 'Invalid amount, should be 0')
assert(delegations[0].updates.length > 0, 'No updates')
// check updates. first is create boost
assert(
delegations[0].updates[0].type == 0,
'Invalid type. should be createBoost'
)
assert(
delegations[0].updates[0].cancelTime ==
tx3.events.DelegateBoost.returnValues._cancel_time,
'Invalid cancelTime'
)
assert(
delegations[0].updates[0].expireTime ==
tx3.events.DelegateBoost.returnValues._expire_time,
'Invalid expireTime'
)
assert(
delegations[0].updates[0].amount ==
tx3.events.DelegateBoost.returnValues._amount,
'Invalid amount'
)
// check extend boos update
assert(
delegations[0].updates[1].type == 1,
'Invalid type. should be extend Boost'
)
assert(
delegations[0].updates[1].cancelTime ==
tx4.events.ExtendBoost.returnValues._cancel_time,
'Invalid cancelTime for extend boost'
)
assert(
delegations[0].updates[1].expireTime ==
tx4.events.ExtendBoost.returnValues._expire_time,
'Invalid expireTime for extend boost'
)
assert(
delegations[0].updates[1].amount ==
tx4.events.ExtendBoost.returnValues._amount,
'Invalid amount for extend boost'
)
// check burn
assert(delegations[0].updates[2].type == 2, 'Invalid type. should be burn')
}) })
}) })