Skip to content

Commit

Permalink
feat: add support for deposit and requestWithdrawal events on xvsvault
Browse files Browse the repository at this point in the history
  • Loading branch information
coreyar committed Oct 5, 2023
1 parent 1300a99 commit e276429
Show file tree
Hide file tree
Showing 18 changed files with 254 additions and 111 deletions.
2 changes: 2 additions & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,5 @@ generated
hardhat.config.ts
/subgraphs/isolated-pools/subgraph-client/.graphclient
/subgraphs/venus-governance/subgraph-client/.graphclient
typechain-types

3 changes: 2 additions & 1 deletion subgraphs/venus-governance/config/bsc.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,6 @@
"governorBravoDelegateAddress": "0x2d56dC077072B53571b8252008C60e945108c75a",
"governorBravoDelegateStartBlock": "13729317",
"xvsVaultAddress": "0x6eF49b4e0772Fe78128F981d42D54172b55eCF9F",
"xvsVaultStartBlock": "13018718"
"xvsVaultStartBlock": "13018718",
"xvsVaultPid": "0"
}
3 changes: 2 additions & 1 deletion subgraphs/venus-governance/config/chapel.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,6 @@
"governorBravoDelegateAddress": "0x5573422a1a59385c247ec3a66b93b7c08ec2f8f2",
"governorBravoDelegateStartBlock": "16002994",
"xvsVaultAddress": "0xa4Fd54cACdA379FB7CaA783B83Cc846f8ac0Faa6",
"xvsVaultStartBlock": "13937802"
"xvsVaultStartBlock": "13937802",
"xvsVaultPid": "1"
}
3 changes: 2 additions & 1 deletion subgraphs/venus-governance/config/local.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,6 @@
"governorBravoDelegateAddress": "0x1c9fD50dF7a4f066884b58A05D91e4b55005876A",
"governorBravoDelegateStartBlock": "0",
"xvsVaultAddress": "0xe1708FA6bb2844D5384613ef0846F9Bc1e8eC55E",
"xvsVaultStartBlock": "0"
"xvsVaultStartBlock": "0",
"xvsVaultPid": "0"
}
3 changes: 3 additions & 0 deletions subgraphs/venus-governance/src/constants/config-template
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
// Use yarn prepare commands to generate config typescript file per env

export const governorBravoDelegateAddress = '{{ governorBravoDelegateAddress }}';

export const xvsVaultPid = '{{ xvsVaultPid }}';

1 change: 0 additions & 1 deletion subgraphs/venus-governance/src/constants/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { BigDecimal, BigInt } from '@graphprotocol/graph-ts';


export const BIGINT_ZERO = BigInt.fromI32(0);
export const BIGINT_ONE = BigInt.fromI32(1);
export const BIGDECIMAL_ZERO = new BigDecimal(BIGINT_ZERO);
Expand Down
41 changes: 40 additions & 1 deletion subgraphs/venus-governance/src/mappings/xvsVault.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,17 @@
/* eslint-disable @typescript-eslint/no-unused-vars */

/* eslint-disable @typescript-eslint/no-empty-function */
import { DelegateChangedV2, DelegateVotesChangedV2 } from '../../generated/XVSVault/XVSVault';
import { BigInt } from '@graphprotocol/graph-ts';
import { store } from '@graphprotocol/graph-ts';

import {
DelegateChangedV2,
DelegateVotesChangedV2,
Deposit,
ReqestedWithdrawal,
} from '../../generated/XVSVault/XVSVault';
import { xvsVaultPid } from '../constants/config';
import { getOrCreateDelegate } from '../operations/getOrCreate';
import { updateDelegateChanged, updateDelegateVoteChanged } from '../operations/update';

// - event: DelegateChanged(indexed address,indexed address,indexed address)
Expand All @@ -17,3 +27,32 @@ export function handleDelegateChanged(event: DelegateChangedV2): void {
export function handleDelegateVotesChanged(event: DelegateVotesChangedV2): void {
updateDelegateVoteChanged<DelegateVotesChangedV2>(event);
}

export function handleDeposit(event: Deposit): void {
// Only care about XVS Vault
if (event.params.pid.equals(BigInt.fromString(xvsVaultPid))) {
const user = event.params.user;
const amount = event.params.amount;
// Update user's staked XVS
const result = getOrCreateDelegate(user.toHex());
result.entity.stakedXvsMantissa = result.entity.stakedXvsMantissa.plus(amount);
result.entity.save();
}
}

export function handleRequestedWithdrawal(event: ReqestedWithdrawal): void {
// Only care about XVS Vault
if (event.params.pid.equals(BigInt.fromString(xvsVaultPid))) {
const user = event.params.user;
const amount = event.params.amount;
const result = getOrCreateDelegate(user.toHex());
const newAmount = result.entity.stakedXvsMantissa.minus(amount);
// Update their delegate
if (newAmount.equals(new BigInt(0))) {
store.remove('Delegate', user.toHex());
} else {
result.entity.stakedXvsMantissa = newAmount;
result.entity.save();
}
}
}
2 changes: 1 addition & 1 deletion subgraphs/venus-governance/src/operations/getOrCreate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ export const getOrCreateDelegate = (id: string): GetOrCreateDelegateReturn => {
delegate.delegateCount = 0;
delegate.delegates = [];

if (id != nullAddress.toString()) {
if (id != nullAddress.toHex()) {
const governance = getGovernanceEntity();
governance.totalDelegates = governance.totalDelegates.plus(BIGINT_ONE);
governance.totalVoters = governance.totalVoters.plus(BIGINT_ONE);
Expand Down
2 changes: 2 additions & 0 deletions subgraphs/venus-governance/template.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,8 @@ dataSources:
eventHandlers:
- event: Deposit(indexed address,indexed address,indexed uint256,uint256)
handler: handleDeposit
- event: ReqestedWithdrawal(indexed address,indexed address,indexed uint256,uint256)
handler: handleRequestedWithdrawal
- event: DelegateChangedV2(indexed address,indexed address,indexed address)
handler: handleDelegateChanged
- event: DelegateVotesChangedV2(indexed address,uint256,uint256)
Expand Down
50 changes: 50 additions & 0 deletions subgraphs/venus-governance/tests/XVSVault/events.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import { Address, BigInt, ethereum } from '@graphprotocol/graph-ts';
import { newMockEvent } from 'matchstick-as';

import { Deposit, ReqestedWithdrawal } from '../../generated/XVSVault/XVSVault';
import { mockXvsAddress } from '../common/constants';

export function createXvsDepositEvent(user: Address, amount: BigInt): Deposit {
const event = changetype<Deposit>(newMockEvent());
event.parameters = [];

const userParam = new ethereum.EventParam('user', ethereum.Value.fromAddress(user));
event.parameters.push(userParam);

const rewardTokenParam = new ethereum.EventParam(
'rewardToken',
ethereum.Value.fromAddress(mockXvsAddress),
);
event.parameters.push(rewardTokenParam);

const pidParam = new ethereum.EventParam('pid', ethereum.Value.fromUnsignedBigInt(new BigInt(0)));
event.parameters.push(pidParam);

const amountParam = new ethereum.EventParam('amount', ethereum.Value.fromUnsignedBigInt(amount));
event.parameters.push(amountParam);
return event;
}

export function createXvsWithdrawlRequestedEvent(
user: Address,
amount: BigInt,
): ReqestedWithdrawal {
const event = changetype<ReqestedWithdrawal>(newMockEvent());
event.parameters = [];

const userParam = new ethereum.EventParam('user', ethereum.Value.fromAddress(user));
event.parameters.push(userParam);

const rewardTokenParam = new ethereum.EventParam(
'rewardToken',
ethereum.Value.fromAddress(mockXvsAddress),
);
event.parameters.push(rewardTokenParam);

const pidParam = new ethereum.EventParam('pid', ethereum.Value.fromUnsignedBigInt(new BigInt(0)));
event.parameters.push(pidParam);

const amountParam = new ethereum.EventParam('amount', ethereum.Value.fromUnsignedBigInt(amount));
event.parameters.push(amountParam);
return event;
}
117 changes: 117 additions & 0 deletions subgraphs/venus-governance/tests/XVSVault/index.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
import { Address, BigInt } from '@graphprotocol/graph-ts';
import { assert, beforeAll, beforeEach, describe, test } from 'matchstick-as/assembly/index';

import { ProposalCreated } from '../../generated/GovernorBravoDelegate/GovernorBravoDelegate';
import { DelegateChangedV2 } from '../../generated/XVSVault/XVSVault';
import { handleProposalCreated } from '../../src/mappings/bravo';
import {
handleDelegateChanged,
handleDeposit,
handleRequestedWithdrawal,
} from '../../src/mappings/xvsVault';
import { getOrCreateDelegate } from '../../src/operations/getOrCreate';
import { user1, user2, user3 } from '../common/constants';
import { createDelegateChangedEvent, createProposalCreatedEvent } from '../common/events';
import { createGovernorBravoMocks } from '../common/mocks';
import { createXvsDepositEvent, createXvsWithdrawlRequestedEvent } from './events';

const startBlock = 4563820;
const endBlock = 4593820;
const description = 'Very creative Proposal';

beforeAll(() => {
createGovernorBravoMocks();
});

beforeEach(() => {
/** setup test */
getOrCreateDelegate(user1.toHexString());
const proposalCreatedEvent = createProposalCreatedEvent<ProposalCreated>(
1,
user1,
[],
[],
[],
[],
BigInt.fromI64(startBlock),
BigInt.fromI64(endBlock),
description,
);
handleProposalCreated(proposalCreatedEvent);
});

describe('XVS Vault', () => {
test('should create new delegate on first deposit', () => {
const user = Address.fromString('0x0000000000000000000000000000000000000404');
const amount = '1000000000000000000';
/** run handler */
const depositEvent = createXvsDepositEvent(user, BigInt.fromString(amount));
// Expect delete not to exist
assert.entityCount('Delegate', 1);

handleDeposit(depositEvent);

// Expect value to be updated
assert.entityCount('Delegate', 2);
assert.fieldEquals('Delegate', user.toHex(), 'stakedXvsMantissa', amount);
});

test("should update delegate's total after withdrawl requested", () => {
const user = Address.fromString('0x0000000000000000000000000000000000000404');
const amount = '200000000000000000';
/** run handler */
const withdrawRequestedEvent = createXvsWithdrawlRequestedEvent(
user,
BigInt.fromString(amount),
);
// Expect delete not to exist
assert.entityCount('Delegate', 2);

handleRequestedWithdrawal(withdrawRequestedEvent);

// Expect value to be updated
assert.entityCount('Delegate', 2);
assert.fieldEquals('Delegate', user.toHex(), 'stakedXvsMantissa', '800000000000000000');
});

test('removes delegate after withdrawing everything', () => {
const user = Address.fromString('0x0000000000000000000000000000000000000404');
const amount = '800000000000000000';
/** run handler */
const withdrawRequestedEvent = createXvsWithdrawlRequestedEvent(
user,
BigInt.fromString(amount),
);
// Expect delete not to exist
assert.entityCount('Delegate', 2);

handleRequestedWithdrawal(withdrawRequestedEvent);

// Expect delegate to have been removed
assert.entityCount('Delegate', 1);
});

test('delegate changed', () => {
const delegator = user1;
const fromDelegate = user2;
const toDelegate = user3;
/** run handler */
const delegateChangedEvent = createDelegateChangedEvent<DelegateChangedV2>(
delegator,
fromDelegate,
toDelegate,
);
handleDelegateChanged(delegateChangedEvent);
// OldDelegate
const assertOldDelegateDocument = (key: string, value: string): void => {
assert.fieldEquals('Delegate', user2.toHex(), key, value);
};
assertOldDelegateDocument('delegateCount', '-1');

// New Delegate
const assertNewDelegateDocument = (key: string, value: string): void => {
assert.fieldEquals('Delegate', user3.toHex(), key, value);
};
assertNewDelegateDocument('delegateCount', '1');
});
});
6 changes: 5 additions & 1 deletion subgraphs/venus-governance/tests/common/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,13 @@ export const mockContractAddress = Address.fromString('0x00000000000000000000000
export const mockFunctionSig = 'mockFunc()';

// Mocked Governor return values
export const mockImplementationAddress = Address.fromString('0x000000000000000000000000000000000000c0DE');
export const mockImplementationAddress = Address.fromString(
'0x000000000000000000000000000000000000c0DE',
);
export const mockAdminAddress = Address.fromString('0x000000000000000000000000000000000000ad53');
export const mockGuardianAddress = Address.fromString('0x000000000000000000000000000000000000536d');
export const timelockAddress0 = Address.fromString('0x0000000000000000000000000000000000070c50');
export const timelockAddress1 = Address.fromString('0x0000000000000000000000000000000000070c51');
export const timelockAddress2 = Address.fromString('0x0000000000000000000000000000000000070c52');

export const mockXvsAddress = Address.fromString('0x00000000000000000000000000000000000003c5');
78 changes: 0 additions & 78 deletions subgraphs/venus-governance/tests/unit/Bravo/xvsVault.test.ts

This file was deleted.

1 change: 1 addition & 0 deletions subgraphs/venus/src/constants/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { BigDecimal, BigInt } from '@graphprotocol/graph-ts';

import { exponentToBigDecimal } from '../utilities';

export const BORROW = 'BORROW';
Expand Down
2 changes: 1 addition & 1 deletion subgraphs/venus/src/mappings/comptroller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,11 @@ import {
} from '../../generated/Comptroller/Comptroller';
import { Account, Market } from '../../generated/schema';
import { VToken } from '../../generated/templates';
import { mantissaFactorBigDecimal } from '../constants';
import { createAccount, createMarket } from '../operations/create';
import { getOrCreateComptroller } from '../operations/getOrCreate';
import { updateCommonVTokenStats } from '../operations/update';
import { ensureComptrollerSynced } from '../utilities';
import { mantissaFactorBigDecimal } from '../constants';

export const handleMarketListed = (event: MarketListed): void => {
// Dynamically index all new listed tokens
Expand Down
Loading

0 comments on commit e276429

Please sign in to comment.