-
Notifications
You must be signed in to change notification settings - Fork 9
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
vebal staking and user balances (#539)
* vebal staking and user balances * no need for context
- Loading branch information
Showing
15 changed files
with
279 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
--- | ||
'backend': minor | ||
--- | ||
|
||
adding vebal as a staking option |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
import { prisma } from '../../../../prisma/prisma-client'; | ||
import mainnet from '../../../../config/mainnet'; | ||
|
||
export const syncVebalStakingForPools = async (): Promise<void> => { | ||
const stakingId = mainnet.veBal!.address; | ||
const chain = 'MAINNET'; | ||
const veBalPoolId = '0x5c6ee304399dbdb9c8ef030ab642b10820db8f56000200000000000000000014'; | ||
|
||
await prisma.prismaPoolStaking.upsert({ | ||
where: { id_chain: { id: stakingId, chain: chain } }, | ||
create: { | ||
id: stakingId, | ||
chain: chain, | ||
poolId: veBalPoolId, | ||
type: 'VEBAL', | ||
address: stakingId, | ||
}, | ||
update: {}, | ||
}); | ||
|
||
await prisma.prismaPoolStakingVebal.upsert({ | ||
where: { id_chain: { id: stakingId, chain: chain } }, | ||
create: { | ||
id: stakingId, | ||
chain: chain, | ||
stakingId: stakingId, | ||
vebalAddress: stakingId, | ||
}, | ||
update: { | ||
stakingId: stakingId, | ||
vebalAddress: stakingId, | ||
}, | ||
}); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
113 changes: 113 additions & 0 deletions
113
modules/user/lib/user-sync-vebal-lock-balance.service.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,113 @@ | ||
import { UserStakedBalanceService, UserSyncUserBalanceInput } from '../user-types'; | ||
import { prisma } from '../../../prisma/prisma-client'; | ||
import { getContractAt } from '../../web3/contract'; | ||
import _ from 'lodash'; | ||
import { prismaBulkExecuteOperations } from '../../../prisma/prisma-util'; | ||
import RewardsOnlyGaugeAbi from './abi/RewardsOnlyGauge.json'; | ||
import { Multicaller } from '../../web3/multicaller'; | ||
import { formatFixed } from '@ethersproject/bignumber'; | ||
import { PrismaPoolStakingType } from '@prisma/client'; | ||
import { networkContext } from '../../network/network-context.service'; | ||
import { GaugeSubgraphService } from '../../subgraphs/gauge-subgraph/gauge-subgraph.service'; | ||
import { veBalLocksSubgraphService } from '../../subgraphs/veBal-locks-subgraph/veBal-locks-subgraph.service'; | ||
import { BigNumber } from 'ethers'; | ||
import VeBalABI from '../../vebal/abi/vebal.json'; | ||
import mainnet from '../../../config/mainnet'; | ||
|
||
export class UserSyncVebalLockBalanceService implements UserStakedBalanceService { | ||
get chain() { | ||
return networkContext.chain; | ||
} | ||
|
||
private readonly veBalPoolId = '0x5c6ee304399dbdb9c8ef030ab642b10820db8f56000200000000000000000014'; | ||
|
||
public async initStakedBalances(stakingTypes: PrismaPoolStakingType[]): Promise<void> { | ||
if (!stakingTypes.includes('VEBAL') && this.chain !== 'MAINNET') { | ||
return; | ||
} | ||
|
||
console.log('initStakedVebalBalances: Starting loading users and onchain balances...'); | ||
await this.syncBalances(true); | ||
|
||
console.log('initStakedVebalBalances: finished...'); | ||
} | ||
|
||
public async syncChangedStakedBalances(): Promise<void> { | ||
await this.syncBalances(false); | ||
} | ||
|
||
private async syncBalances(init: boolean): Promise<void> { | ||
const subgraphVeBalHolders = await veBalLocksSubgraphService.getAllveBalHolders(); | ||
const metadata = await veBalLocksSubgraphService.getMetadata(); | ||
|
||
let operations: any[] = []; | ||
// for mainnet, we get the vebal balance form the vebal contract | ||
const multicall = new Multicaller(networkContext.data.multicall, networkContext.provider, VeBalABI); | ||
|
||
let response = {} as { | ||
[userAddress: string]: { | ||
balance: BigNumber; | ||
locked: BigNumber[]; | ||
}; | ||
}; | ||
|
||
for (const holder of subgraphVeBalHolders) { | ||
multicall.call(`${holder.user}.locked`, networkContext.data.veBal!.address, 'locked', [holder.user]); | ||
|
||
// so if we scheduled more than 100 calls, we execute the batch | ||
if (multicall.numCalls >= 100) { | ||
response = _.merge(response, await multicall.execute()); | ||
} | ||
} | ||
|
||
if (multicall.numCalls > 0) { | ||
response = _.merge(response, await multicall.execute()); | ||
} | ||
|
||
operations.push( | ||
prisma.prismaUser.createMany({ | ||
data: subgraphVeBalHolders.map((holder) => ({ address: holder.user.toLowerCase() })), | ||
skipDuplicates: true, | ||
}), | ||
); | ||
|
||
if (init) { | ||
operations.push( | ||
prisma.prismaUserStakedBalance.deleteMany({ where: { staking: { type: 'VEBAL' }, chain: this.chain } }), | ||
); | ||
} | ||
|
||
for (const veBalHolder in response) { | ||
operations.push( | ||
prisma.prismaUserStakedBalance.upsert({ | ||
where: { id_chain: { id: `veBal-${veBalHolder.toLowerCase()}`, chain: 'MAINNET' } }, | ||
create: { | ||
id: `veBal-${veBalHolder.toLowerCase()}`, | ||
chain: 'MAINNET', | ||
balance: formatFixed(response[veBalHolder].locked[0], 18), | ||
balanceNum: parseFloat(formatFixed(response[veBalHolder].locked[0], 18)), | ||
userAddress: veBalHolder.toLowerCase(), | ||
poolId: this.veBalPoolId, | ||
tokenAddress: mainnet.veBal!.bptAddress, | ||
stakingId: mainnet.veBal!.address, | ||
}, | ||
update: { | ||
balance: formatFixed(response[veBalHolder].locked[0], 18), | ||
balanceNum: parseFloat(formatFixed(response[veBalHolder].locked[0], 18)), | ||
}, | ||
}), | ||
); | ||
} | ||
|
||
operations.push( | ||
prisma.prismaUserBalanceSyncStatus.upsert({ | ||
where: { type_chain: { type: 'VEBAL', chain: this.chain } }, | ||
create: { type: 'VEBAL', chain: this.chain, blockNumber: metadata.block.number }, | ||
update: { blockNumber: metadata.block.number }, | ||
}), | ||
); | ||
await prismaBulkExecuteOperations(operations, true, undefined); | ||
} | ||
|
||
public async syncUserBalance({ userAddress, poolId, poolAddress, staking }: UserSyncUserBalanceInput) {} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -70,6 +70,7 @@ enum PrismaUserBalanceType { | |
STAKED | ||
RELIQUARY | ||
AURA | ||
VEBAL | ||
} | ||
|
||
model PrismaUserPoolBalanceSnapshot { | ||
|
21 changes: 21 additions & 0 deletions
21
prisma/migrations/20240704114833_add_vebal_staking/migration.sql
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
-- AlterEnum | ||
ALTER TYPE "PrismaPoolStakingType" ADD VALUE 'VEBAL'; | ||
|
||
-- AlterEnum | ||
ALTER TYPE "PrismaUserBalanceType" ADD VALUE 'VEBAL'; | ||
|
||
-- CreateTable | ||
CREATE TABLE "PrismaPoolStakingVebal" ( | ||
"id" TEXT NOT NULL, | ||
"stakingId" TEXT NOT NULL, | ||
"chain" "Chain" NOT NULL, | ||
"vebalAddress" TEXT NOT NULL, | ||
|
||
CONSTRAINT "PrismaPoolStakingVebal_pkey" PRIMARY KEY ("id","chain") | ||
); | ||
|
||
-- CreateIndex | ||
CREATE UNIQUE INDEX "PrismaPoolStakingVebal_stakingId_chain_key" ON "PrismaPoolStakingVebal"("stakingId", "chain"); | ||
|
||
-- AddForeignKey | ||
ALTER TABLE "PrismaPoolStakingVebal" ADD CONSTRAINT "PrismaPoolStakingVebal_stakingId_chain_fkey" FOREIGN KEY ("stakingId", "chain") REFERENCES "PrismaPoolStaking"("id", "chain") ON DELETE CASCADE ON UPDATE CASCADE; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.