Skip to content

Commit

Permalink
Subgraph: ensure the trove ID always increments (#706)
Browse files Browse the repository at this point in the history
1. The troves count now decrements when closed.
2. The nextOwnerIndexes field is now used to determine the next
   ownerIndex to use, rather than the troves count.

Also:

- Troves count is now updated from a shared updateBorrowerTrovesCount().
- In the app, replace useTrovesCount() by useNextOwnerIndex().
- Update sepolia addresses.
  • Loading branch information
bpierre authored Jan 18, 2025
1 parent 560a435 commit 23bced5
Show file tree
Hide file tree
Showing 12 changed files with 146 additions and 152 deletions.
4 changes: 2 additions & 2 deletions frontend/app/src/graphql/gql.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import * as types from './graphql';
* Learn more about it here: https://the-guild.dev/graphql/codegen/plugins/presets/preset-client#reducing-bundle-size
*/
const documents = {
"\n query TrovesCount($id: ID!) {\n borrowerInfo(id: $id) {\n troves\n trovesByCollateral\n }\n }\n": types.TrovesCountDocument,
"\n query BorrowerInfo($id: ID!) {\n borrowerInfo(id: $id) {\n nextOwnerIndexes\n troves\n trovesByCollateral\n }\n }\n": types.BorrowerInfoDocument,
"\n fragment FullTroveFragment on Trove {\n id\n borrower\n closedAt\n createdAt\n debt\n deposit\n interestRate\n mightBeLeveraged\n stake\n status\n troveId\n updatedAt\n collateral {\n id\n token {\n symbol\n name\n }\n minCollRatio\n collIndex\n }\n interestBatch {\n id\n annualInterestRate\n annualManagementFee\n batchManager\n }\n }\n": types.FullTroveFragmentFragmentDoc,
"\n query TrovesByAccount($account: Bytes!) {\n troves(\n where: {\n borrower: $account,\n status_in: [active,redeemed,liquidated],\n }\n orderBy: updatedAt\n orderDirection: desc\n ) {\n id\n borrower\n closedAt\n createdAt\n debt\n deposit\n interestRate\n mightBeLeveraged\n stake\n status\n troveId\n updatedAt\n collateral {\n id\n token {\n symbol\n name\n }\n minCollRatio\n collIndex\n }\n interestBatch {\n id\n annualInterestRate\n annualManagementFee\n batchManager\n }\n }\n }\n": types.TrovesByAccountDocument,
"\n query TroveById($id: ID!) {\n trove(id: $id) {\n id\n borrower\n closedAt\n createdAt\n debt\n deposit\n interestRate\n mightBeLeveraged\n stake\n status\n troveId\n updatedAt\n collateral {\n id\n token {\n symbol\n name\n }\n minCollRatio\n collIndex\n }\n interestBatch {\n id\n annualInterestRate\n annualManagementFee\n batchManager\n }\n }\n }\n": types.TroveByIdDocument,
Expand All @@ -35,7 +35,7 @@ const documents = {
/**
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
*/
export function graphql(source: "\n query TrovesCount($id: ID!) {\n borrowerInfo(id: $id) {\n troves\n trovesByCollateral\n }\n }\n"): typeof import('./graphql').TrovesCountDocument;
export function graphql(source: "\n query BorrowerInfo($id: ID!) {\n borrowerInfo(id: $id) {\n nextOwnerIndexes\n troves\n trovesByCollateral\n }\n }\n"): typeof import('./graphql').BorrowerInfoDocument;
/**
* The graphql function is used to parse GraphQL queries into a document that can be used by GraphQL clients.
*/
Expand Down
67 changes: 14 additions & 53 deletions frontend/app/src/graphql/graphql.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ export type Block_Height = {
export type BorrowerInfo = {
__typename?: 'BorrowerInfo';
id: Scalars['ID']['output'];
nextOwnerIndexes: Array<Scalars['Int']['output']>;
troves: Scalars['Int']['output'];
trovesByCollateral: Array<Scalars['Int']['output']>;
};
Expand All @@ -63,6 +64,12 @@ export type BorrowerInfo_Filter = {
id_lte?: InputMaybe<Scalars['ID']['input']>;
id_not?: InputMaybe<Scalars['ID']['input']>;
id_not_in?: InputMaybe<Array<Scalars['ID']['input']>>;
nextOwnerIndexes?: InputMaybe<Array<Scalars['Int']['input']>>;
nextOwnerIndexes_contains?: InputMaybe<Array<Scalars['Int']['input']>>;
nextOwnerIndexes_contains_nocase?: InputMaybe<Array<Scalars['Int']['input']>>;
nextOwnerIndexes_not?: InputMaybe<Array<Scalars['Int']['input']>>;
nextOwnerIndexes_not_contains?: InputMaybe<Array<Scalars['Int']['input']>>;
nextOwnerIndexes_not_contains_nocase?: InputMaybe<Array<Scalars['Int']['input']>>;
or?: InputMaybe<Array<InputMaybe<BorrowerInfo_Filter>>>;
troves?: InputMaybe<Scalars['Int']['input']>;
trovesByCollateral?: InputMaybe<Array<Scalars['Int']['input']>>;
Expand All @@ -82,6 +89,7 @@ export type BorrowerInfo_Filter = {

export enum BorrowerInfo_OrderBy {
Id = 'id',
NextOwnerIndexes = 'nextOwnerIndexes',
Troves = 'troves',
TrovesByCollateral = 'trovesByCollateral'
}
Expand Down Expand Up @@ -138,11 +146,8 @@ export type Collateral = {
collIndex: Scalars['Int']['output'];
id: Scalars['ID']['output'];
minCollRatio: Scalars['BigInt']['output'];
price: Scalars['BigInt']['output'];
stabilityPoolDeposits: Array<StabilityPoolDeposit>;
token: Token;
totalDebt: Scalars['BigInt']['output'];
totalDeposited: Scalars['BigInt']['output'];
troves: Array<Trove>;
};

Expand Down Expand Up @@ -278,9 +283,6 @@ export enum CollateralAddresses_OrderBy {
CollateralCollIndex = 'collateral__collIndex',
CollateralId = 'collateral__id',
CollateralMinCollRatio = 'collateral__minCollRatio',
CollateralPrice = 'collateral__price',
CollateralTotalDebt = 'collateral__totalDebt',
CollateralTotalDeposited = 'collateral__totalDeposited',
Id = 'id',
SortedTroves = 'sortedTroves',
StabilityPool = 'stabilityPool',
Expand Down Expand Up @@ -319,14 +321,6 @@ export type Collateral_Filter = {
minCollRatio_not?: InputMaybe<Scalars['BigInt']['input']>;
minCollRatio_not_in?: InputMaybe<Array<Scalars['BigInt']['input']>>;
or?: InputMaybe<Array<InputMaybe<Collateral_Filter>>>;
price?: InputMaybe<Scalars['BigInt']['input']>;
price_gt?: InputMaybe<Scalars['BigInt']['input']>;
price_gte?: InputMaybe<Scalars['BigInt']['input']>;
price_in?: InputMaybe<Array<Scalars['BigInt']['input']>>;
price_lt?: InputMaybe<Scalars['BigInt']['input']>;
price_lte?: InputMaybe<Scalars['BigInt']['input']>;
price_not?: InputMaybe<Scalars['BigInt']['input']>;
price_not_in?: InputMaybe<Array<Scalars['BigInt']['input']>>;
stabilityPoolDeposits_?: InputMaybe<StabilityPoolDeposit_Filter>;
token?: InputMaybe<Scalars['String']['input']>;
token_?: InputMaybe<Token_Filter>;
Expand All @@ -349,22 +343,6 @@ export type Collateral_Filter = {
token_not_starts_with_nocase?: InputMaybe<Scalars['String']['input']>;
token_starts_with?: InputMaybe<Scalars['String']['input']>;
token_starts_with_nocase?: InputMaybe<Scalars['String']['input']>;
totalDebt?: InputMaybe<Scalars['BigInt']['input']>;
totalDebt_gt?: InputMaybe<Scalars['BigInt']['input']>;
totalDebt_gte?: InputMaybe<Scalars['BigInt']['input']>;
totalDebt_in?: InputMaybe<Array<Scalars['BigInt']['input']>>;
totalDebt_lt?: InputMaybe<Scalars['BigInt']['input']>;
totalDebt_lte?: InputMaybe<Scalars['BigInt']['input']>;
totalDebt_not?: InputMaybe<Scalars['BigInt']['input']>;
totalDebt_not_in?: InputMaybe<Array<Scalars['BigInt']['input']>>;
totalDeposited?: InputMaybe<Scalars['BigInt']['input']>;
totalDeposited_gt?: InputMaybe<Scalars['BigInt']['input']>;
totalDeposited_gte?: InputMaybe<Scalars['BigInt']['input']>;
totalDeposited_in?: InputMaybe<Array<Scalars['BigInt']['input']>>;
totalDeposited_lt?: InputMaybe<Scalars['BigInt']['input']>;
totalDeposited_lte?: InputMaybe<Scalars['BigInt']['input']>;
totalDeposited_not?: InputMaybe<Scalars['BigInt']['input']>;
totalDeposited_not_in?: InputMaybe<Array<Scalars['BigInt']['input']>>;
troves_?: InputMaybe<Trove_Filter>;
};

Expand All @@ -380,15 +358,12 @@ export enum Collateral_OrderBy {
CollIndex = 'collIndex',
Id = 'id',
MinCollRatio = 'minCollRatio',
Price = 'price',
StabilityPoolDeposits = 'stabilityPoolDeposits',
Token = 'token',
TokenDecimals = 'token__decimals',
TokenId = 'token__id',
TokenName = 'token__name',
TokenSymbol = 'token__symbol',
TotalDebt = 'totalDebt',
TotalDeposited = 'totalDeposited',
Troves = 'troves'
}

Expand Down Expand Up @@ -848,9 +823,6 @@ export enum InterestBatch_OrderBy {
CollateralCollIndex = 'collateral__collIndex',
CollateralId = 'collateral__id',
CollateralMinCollRatio = 'collateral__minCollRatio',
CollateralPrice = 'collateral__price',
CollateralTotalDebt = 'collateral__totalDebt',
CollateralTotalDeposited = 'collateral__totalDeposited',
Debt = 'debt',
Id = 'id',
Troves = 'troves'
Expand Down Expand Up @@ -921,9 +893,6 @@ export enum InterestRateBracket_OrderBy {
CollateralCollIndex = 'collateral__collIndex',
CollateralId = 'collateral__id',
CollateralMinCollRatio = 'collateral__minCollRatio',
CollateralPrice = 'collateral__price',
CollateralTotalDebt = 'collateral__totalDebt',
CollateralTotalDeposited = 'collateral__totalDeposited',
Id = 'id',
Rate = 'rate',
TotalDebt = 'totalDebt'
Expand Down Expand Up @@ -1441,9 +1410,6 @@ export enum StabilityPoolDeposit_OrderBy {
CollateralCollIndex = 'collateral__collIndex',
CollateralId = 'collateral__id',
CollateralMinCollRatio = 'collateral__minCollRatio',
CollateralPrice = 'collateral__price',
CollateralTotalDebt = 'collateral__totalDebt',
CollateralTotalDeposited = 'collateral__totalDeposited',
Deposit = 'deposit',
Depositor = 'depositor',
Id = 'id',
Expand Down Expand Up @@ -1957,9 +1923,6 @@ export enum Token_OrderBy {
CollateralCollIndex = 'collateral__collIndex',
CollateralId = 'collateral__id',
CollateralMinCollRatio = 'collateral__minCollRatio',
CollateralPrice = 'collateral__price',
CollateralTotalDebt = 'collateral__totalDebt',
CollateralTotalDeposited = 'collateral__totalDeposited',
Decimals = 'decimals',
Id = 'id',
Name = 'name',
Expand Down Expand Up @@ -2149,9 +2112,6 @@ export enum Trove_OrderBy {
CollateralCollIndex = 'collateral__collIndex',
CollateralId = 'collateral__id',
CollateralMinCollRatio = 'collateral__minCollRatio',
CollateralPrice = 'collateral__price',
CollateralTotalDebt = 'collateral__totalDebt',
CollateralTotalDeposited = 'collateral__totalDeposited',
CreatedAt = 'createdAt',
Debt = 'debt',
Deposit = 'deposit',
Expand Down Expand Up @@ -2207,12 +2167,12 @@ export enum _SubgraphErrorPolicy_ {
Deny = 'deny'
}

export type TrovesCountQueryVariables = Exact<{
export type BorrowerInfoQueryVariables = Exact<{
id: Scalars['ID']['input'];
}>;


export type TrovesCountQuery = { __typename?: 'Query', borrowerInfo?: { __typename?: 'BorrowerInfo', troves: number, trovesByCollateral: Array<number> } | null };
export type BorrowerInfoQuery = { __typename?: 'Query', borrowerInfo?: { __typename?: 'BorrowerInfo', nextOwnerIndexes: Array<number>, troves: number, trovesByCollateral: Array<number> } | null };

export type FullTroveFragmentFragment = { __typename?: 'Trove', id: string, borrower: string, closedAt?: bigint | null, createdAt: bigint, debt: bigint, deposit: bigint, interestRate: bigint, mightBeLeveraged: boolean, stake: bigint, status: TroveStatus, troveId: string, updatedAt: bigint, collateral: { __typename?: 'Collateral', id: string, minCollRatio: bigint, collIndex: number, token: { __typename?: 'Token', symbol: string, name: string } }, interestBatch?: { __typename?: 'InterestBatch', id: string, annualInterestRate: bigint, annualManagementFee: bigint, batchManager: string } | null } & { ' $fragmentName'?: 'FullTroveFragmentFragment' };

Expand Down Expand Up @@ -2360,14 +2320,15 @@ export const StabilityPoolDepositFragmentFragmentDoc = new TypedDocumentString(`
}
}
`, {"fragmentName":"StabilityPoolDepositFragment"}) as unknown as TypedDocumentString<StabilityPoolDepositFragmentFragment, unknown>;
export const TrovesCountDocument = new TypedDocumentString(`
query TrovesCount($id: ID!) {
export const BorrowerInfoDocument = new TypedDocumentString(`
query BorrowerInfo($id: ID!) {
borrowerInfo(id: $id) {
nextOwnerIndexes
troves
trovesByCollateral
}
}
`) as unknown as TypedDocumentString<TrovesCountQuery, TrovesCountQueryVariables>;
`) as unknown as TypedDocumentString<BorrowerInfoQuery, BorrowerInfoQueryVariables>;
export const TrovesByAccountDocument = new TypedDocumentString(`
query TrovesByAccount($account: Bytes!) {
troves(
Expand Down
13 changes: 9 additions & 4 deletions frontend/app/src/screens/BorrowScreen/BorrowScreen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ import { getLiquidationRisk, getLoanDetails, getLtv } from "@/src/liquity-math";
import { useAccount, useBalance } from "@/src/services/Ethereum";
import { usePrice } from "@/src/services/Prices";
import { useTransactionFlow } from "@/src/services/TransactionFlow";
import { useTrovesCount } from "@/src/subgraph-hooks";
import { useNextOwnerIndex } from "@/src/subgraph-hooks";
import { isCollIndex } from "@/src/types";
import { infoTooltipProps } from "@/src/uikit-utils";
import { css } from "@/styled-system/css";
Expand Down Expand Up @@ -113,7 +113,7 @@ export function BorrowScreen() {
throw new Error(`Unknown collateral symbol: ${collateral.symbol}`);
}

const troveCount = useTrovesCount(account.address ?? null, collIndex);
const nextOwnerIndex = useNextOwnerIndex(account.address ?? null, collIndex);

const loanDetails = getLoanDetails(
deposit.isEmpty ? null : deposit.parsed,
Expand Down Expand Up @@ -396,7 +396,12 @@ export function BorrowScreen() {
size="large"
wide
onClick={() => {
if (deposit.parsed && debt.parsed && account.address) {
if (
deposit.parsed
&& debt.parsed
&& account.address
&& typeof nextOwnerIndex.data === "number"
) {
txFlow.start({
flowId: "openBorrowPosition",
backLink: ["/borrow", "Back to editing"],
Expand All @@ -405,7 +410,7 @@ export function BorrowScreen() {

collIndex,
owner: account.address,
ownerIndex: troveCount.data ?? 0,
ownerIndex: nextOwnerIndex.data,
collAmount: deposit.parsed,
boldAmount: debt.parsed,
upperHint: dnum18(0),
Expand Down
16 changes: 11 additions & 5 deletions frontend/app/src/screens/LeverageScreen/LeverageScreen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ import { getCollIndexFromSymbol } from "@/src/liquity-utils";
import { useAccount, useBalance } from "@/src/services/Ethereum";
import { usePrice } from "@/src/services/Prices";
import { useTransactionFlow } from "@/src/services/TransactionFlow";
import { useTrovesCount } from "@/src/subgraph-hooks";
import { useNextOwnerIndex } from "@/src/subgraph-hooks";
import { infoTooltipProps } from "@/src/uikit-utils";
import { css } from "@/styled-system/css";
import {
Expand Down Expand Up @@ -85,7 +85,8 @@ export function LeverageScreen() {
[symbol, useBalance(account.address, symbol)] as const
)));

const troveCount = useTrovesCount(account.address ?? null, collIndex);
const nextOwnerIndex = useNextOwnerIndex(account.address ?? null, collIndex);

const collPrice = usePrice(collToken.symbol);

const maxCollDeposit = MAX_COLLATERAL_DEPOSITS[collSymbol] ?? null;
Expand Down Expand Up @@ -147,7 +148,7 @@ export function LeverageScreen() {
collIndex,
initialDeposit: depositPreLeverage.parsed,
leverageFactor: leverageField.leverageFactor,
ownerIndex: troveCount.data ?? null,
ownerIndex: nextOwnerIndex.data ?? null,
});

const leverageSlippageElements = useSlippageElements(
Expand Down Expand Up @@ -373,14 +374,19 @@ export function LeverageScreen() {
size="large"
wide
onClick={() => {
if (depositPreLeverage.parsed && leverageField.debt && account.address) {
if (
depositPreLeverage.parsed
&& leverageField.debt
&& account.address
&& typeof nextOwnerIndex.data === "number"
) {
txFlow.start({
flowId: "openLeveragePosition",
backLink: ["/multiply", "Back to editing"],
successLink: ["/", "Go to the Dashboard"],
successMessage: "The leveraged position has been created successfully.",

ownerIndex: troveCount.data ?? 0,
ownerIndex: nextOwnerIndex.data,
leverageFactor: leverageField.leverageFactor,
loan: newLoan,
});
Expand Down
19 changes: 10 additions & 9 deletions frontend/app/src/subgraph-hooks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import { isAddress, shortenAddress } from "@liquity2/uikit";
import { useQuery } from "@tanstack/react-query";
import * as dn from "dnum";
import {
BorrowerInfoQuery,
GovernanceInitiatives,
GovernanceStats,
GovernanceUser,
Expand All @@ -27,7 +28,6 @@ import {
StabilityPoolQuery,
TroveByIdQuery,
TrovesByAccountQuery,
TrovesCountQuery,
} from "./subgraph-queries";

type Options = {
Expand All @@ -41,22 +41,23 @@ function prepareOptions(options?: Options) {
};
}

export function useTrovesCount(
export function useNextOwnerIndex(
borrower: null | Address,
collIndex?: CollIndex,
collIndex: null | CollIndex,
options?: Options,
) {
let queryFn = async () => {
if (!borrower) {
if (!borrower || collIndex === null) {
return null;
}

const { borrowerInfo } = await graphQuery(
TrovesCountQuery,
BorrowerInfoQuery,
{ id: borrower.toLowerCase() },
);
return collIndex === undefined
? borrowerInfo?.troves ?? 0
: borrowerInfo?.trovesByCollateral[collIndex] ?? null;

// if borrowerInfo doesn’t exist, start at 0
return borrowerInfo?.nextOwnerIndexes[collIndex] ?? 0;
};

if (DEMO_MODE) {
Expand All @@ -70,7 +71,7 @@ export function useTrovesCount(
}

return useQuery({
queryKey: ["TrovesCount", borrower, collIndex],
queryKey: ["NextTroveId", borrower, collIndex],
queryFn,
...prepareOptions(options),
});
Expand Down
5 changes: 3 additions & 2 deletions frontend/app/src/subgraph-queries.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,10 @@ export async function graphQuery<TResult, TVariables>(
return result.data as TResult;
}

export const TrovesCountQuery = graphql(`
query TrovesCount($id: ID!) {
export const BorrowerInfoQuery = graphql(`
query BorrowerInfo($id: ID!) {
borrowerInfo(id: $id) {
nextOwnerIndexes
troves
trovesByCollateral
}
Expand Down
8 changes: 4 additions & 4 deletions subgraph/networks.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,12 @@
},
"sepolia": {
"BoldToken": {
"address": "0x6ecf96d1f30cd98c0b58d6b12ea8ae014c52464d",
"startBlock": 7279144
"address": "0x0a69fa2a565bd6fa9c3890ecaa30b149aaf99136",
"startBlock": 7314166
},
"Governance": {
"address": "0xd7eae81178b97e49e6471f398f0486a7c2e43721",
"startBlock": 7279317
"address": "0x7eedda08119826757c98a4680e94f3b5e1f33af6",
"startBlock": 7314318
}
}
}
1 change: 1 addition & 0 deletions subgraph/schema.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ type BorrowerInfo @entity {
id: ID! # "borrowerAddress", e.g. "0x0000000000000000000000000000000000000000"
troves: Int!
trovesByCollateral: [Int!]!
nextOwnerIndexes: [Int!]!
}

type StabilityPool @entity {
Expand Down
Loading

0 comments on commit 23bced5

Please sign in to comment.