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 {
"id = tokenId"
"id = VeDelegation contract + tokenId"
id: ID!
delegator: VeOCEAN!
receiver: VeOCEAN!
@ -470,11 +470,26 @@ type VeDelegation @entity {
amount: BigInt!
cancelTime: BigInt!
expireTime: BigInt!
updates: [VeDelegationUpdate!] @derivedFrom(field: "veDelegation")
}
type VeDelegationUpdate @entity {
"id = {tx}-{eventIndex}"
id: ID!
block: Int!
timestamp: Int!
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 {
"id = {user address}"
id: ID!

View File

@ -121,7 +121,11 @@ export function writeveAllocationUpdate(
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)
if (veDelegation === null) {
@ -132,9 +136,6 @@ export function getveDelegation(id: string): VeDelegation {
veDelegation.amount = BigInt.zero()
veDelegation.receiver = ''
veDelegation.delegator = ''
veDelegation.block = 0
veDelegation.timestamp = 0
veDelegation.tx = ''
veDelegation.save()
}
return veDelegation

View File

@ -1,4 +1,5 @@
import { BigInt } from '@graphprotocol/graph-ts'
import { VeDelegationUpdate } from '../@types/schema'
import {
BurnBoost,
DelegateBoost,
@ -14,19 +15,32 @@ export function handleDelegation(event: DelegateBoost): void {
const _amount = event.params._amount
const _cancelTime = event.params._cancel_time
const _expireTime = event.params._expire_time
const veDelegation = getveDelegation(_tokenId.toHex())
veDelegation.delegator = _delegator
// create veOcean if does not exists
getveOCEAN(_receiver)
getveOCEAN(_delegator)
const veDelegation = getveDelegation(event.address, _tokenId.toHex())
veDelegation.delegator = _delegator
veDelegation.receiver = _receiver
veDelegation.tokenId = _tokenId
veDelegation.amount = _amount
veDelegation.cancelTime = _cancelTime
veDelegation.expireTime = _expireTime
veDelegation.block = event.block.number.toI32()
veDelegation.timestamp = event.block.timestamp.toI32()
veDelegation.tx = event.transaction.hash.toHex()
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 {
@ -36,17 +50,33 @@ export function handleExtendBoost(event: ExtendBoost): void {
const _amount = event.params._amount
const _cancelTime = event.params._cancel_time
const _expireTime = event.params._expire_time
const veDelegation = getveDelegation(_tokenId.toHex())
// create veOcean if does not exists
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.receiver = _receiver
veDelegation.tokenId = _tokenId
veDelegation.amount = _amount
veDelegation.cancelTime = _cancelTime
veDelegation.expireTime = _expireTime
veDelegation.timestamp = event.block.timestamp.toI32()
veDelegation.tx = event.transaction.hash.toHex()
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 {
@ -62,7 +92,21 @@ export function handleBurnBoost(event: BurnBoost): void {
const _tokenId = event.params._token_id
// delete
const veDelegation = getveDelegation(_tokenId.toHex())
const veDelegation = getveDelegation(event.address, _tokenId.toHex())
veDelegation.amount = BigInt.zero()
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)
handler: handleExtendBoost
- event: BurnBoost(indexed address,indexed address,indexed uint256)
handler: handleTransferBoost
handler: handleBurnBoost
- name: veFeeDistributor
kind: ethereum/contract

View File

@ -610,7 +610,6 @@ describe('veOcean tests', async () => {
)
const timestamp = Math.floor(Date.now() / 1000)
const unlockTime = timestamp + 30 * 86400
console.log('unlock time', unlockTime)
if (parseInt(currentBalance) > 0 || currentLock > 0) {
// we already have some locked tokens, so our transaction should fail
@ -656,14 +655,15 @@ describe('veOcean tests', async () => {
await veOcean.increaseUnlockTime(Alice, extLockTime)
const estGas = await calculateEstimatedGas(
const initalBoostExpiry = extLockTime - 100000
let estGas = await calculateEstimatedGas(
Alice,
delegateContract.methods.create_boost,
Alice,
Bob,
10000,
5000,
0,
extLockTime,
initalBoostExpiry,
0
)
@ -675,41 +675,146 @@ describe('veOcean tests', async () => {
delegateContract.methods.create_boost,
Alice,
Bob,
10000,
5000,
0,
extLockTime,
initalBoostExpiry,
0
)
assert(tx3, 'Transaction failed')
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 = {
query: `query {
veDelegations{
id,
query: `query{
veDelegations(where:{delegator:"${Alice.toLowerCase()}"}){
id
delegator {
id
},
receiver {
}
receiver{
id
},
tokenId,
amount,
cancelTime,
}
amount
tokenId
cancelTime
expireTime
updates(orderBy:timestamp orderDirection:asc){
id
block
timestamp
tx
sender
amount
cancelTime
expireTime
type
}
}
}`
}`
}
const delegateResponse = await fetch(subgraphUrl, {
method: 'POST',
body: JSON.stringify(delegateQuery)
})
const json = await delegateResponse.json()
console.log('json', json)
console.log('json?.data?.veDelegations', json?.data?.veDelegations)
assert(json?.data?.veDelegations, 'No veDelegations')
const resp = await delegateResponse.json()
const delegations = resp.data.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')
})
})