Skip to content

Commit

Permalink
Merge pull request #736 from liquity/hints
Browse files Browse the repository at this point in the history
App: calculate hints and use them to open troves
  • Loading branch information
danielattilasimon authored Jan 22, 2025
2 parents 7fa7ba6 + f29e325 commit 6cb3ed9
Show file tree
Hide file tree
Showing 4 changed files with 95 additions and 16 deletions.
52 changes: 52 additions & 0 deletions frontend/app/src/liquity-utils.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import type { Contracts } from "@/src/contracts";
import type { StabilityPoolDepositQuery } from "@/src/graphql/graphql";
import type { CollIndex, Dnum, PositionEarn, PositionStake, PrefixedTroveId, TroveId } from "@/src/types";
import type { Address, CollateralSymbol, CollateralToken } from "@liquity2/uikit";
import type { Config as WagmiConfig } from "wagmi";

import { DATA_REFRESH_INTERVAL, INTEREST_RATE_INCREMENT, INTEREST_RATE_MAX, INTEREST_RATE_MIN } from "@/src/constants";
import { getCollateralContract, getContracts, getProtocolContract } from "@/src/contracts";
Expand All @@ -25,6 +27,7 @@ import * as dn from "dnum";
import { useMemo } from "react";
import { encodeAbiParameters, keccak256, parseAbiParameters } from "viem";
import { useBalance, useReadContract, useReadContracts } from "wagmi";
import { readContract } from "wagmi/actions";

export function shortenTroveId(troveId: TroveId, chars = 8) {
return troveId.length < chars * 2 + 2
Expand Down Expand Up @@ -452,3 +455,52 @@ export function usePredictAdjustInterestRateUpfrontFee(
},
});
}

// from https://github.com/liquity/bold/blob/204a3dec54a0e8689120ca48faf4ece5cf8ccd22/README.md#example-opentrove-transaction-with-hints
export async function getTroveOperationHints({
wagmiConfig,
contracts,
collIndex,
interestRate,
}: {
wagmiConfig: WagmiConfig;
contracts: Contracts;
collIndex: number;
interestRate: bigint;
}): Promise<{
upperHint: bigint;
lowerHint: bigint;
}> {
const collateral = contracts.collaterals[collIndex];
if (!collateral) {
throw new Error(`Invalid collateral index: ${collIndex}`);
}

const numTroves = await readContract(wagmiConfig, {
...collateral.contracts.SortedTroves,
functionName: "getSize",
});

const [approxHint] = await readContract(wagmiConfig, {
...contracts.HintHelpers,
functionName: "getApproxHint",
args: [
BigInt(collIndex),
interestRate,
BigInt(10 * Math.sqrt(Number(numTroves))), // (10 * sqrt(troves)) gives a hint close to the right position
42n, // random seed
],
});

const [upperHint, lowerHint] = await readContract(wagmiConfig, {
...collateral.contracts.SortedTroves,
functionName: "findInsertPosition",
args: [
interestRate,
approxHint,
approxHint,
],
});

return { upperHint, lowerHint };
}
2 changes: 0 additions & 2 deletions frontend/app/src/screens/BorrowScreen/BorrowScreen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -413,8 +413,6 @@ export function BorrowScreen() {
ownerIndex: nextOwnerIndex.data,
collAmount: deposit.parsed,
boldAmount: debt.parsed,
upperHint: dnum18(0),
lowerHint: dnum18(0),
annualInterestRate: interestRate,
maxUpfrontFee: dnum18(maxUint256),
interestRateDelegate: interestRateMode === "manual" || !interestRateDelegate ? null : [
Expand Down
39 changes: 28 additions & 11 deletions frontend/app/src/tx-flows/openBorrowPosition.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,12 @@ import { Amount } from "@/src/comps/Amount/Amount";
import { ETH_GAS_COMPENSATION } from "@/src/constants";
import { dnum18 } from "@/src/dnum-utils";
import { fmtnum } from "@/src/formatting";
import { getCollToken, getPrefixedTroveId, usePredictOpenTroveUpfrontFee } from "@/src/liquity-utils";
import {
getCollToken,
getPrefixedTroveId,
getTroveOperationHints,
usePredictOpenTroveUpfrontFee,
} from "@/src/liquity-utils";
import { LoanCard } from "@/src/screens/TransactionsScreen/LoanCard";
import { TransactionDetailsRow } from "@/src/screens/TransactionsScreen/TransactionsScreen";
import { TransactionStatus } from "@/src/screens/TransactionsScreen/TransactionStatus";
Expand All @@ -27,8 +32,6 @@ const RequestSchema = createRequestSchema(
ownerIndex: v.number(),
collAmount: vDnum(),
boldAmount: vDnum(),
upperHint: vDnum(),
lowerHint: vDnum(),
annualInterestRate: vDnum(),
maxUpfrontFee: vDnum(),
interestRateDelegate: v.union([
Expand Down Expand Up @@ -223,17 +226,24 @@ export const openBorrowPosition: FlowDeclaration<OpenBorrowPositionRequest> = {
if (!collateral) {
throw new Error(`Invalid collateral index: ${request.collIndex}`);
}
const { LeverageLSTZapper } = collateral.contracts;

const { upperHint, lowerHint } = await getTroveOperationHints({
wagmiConfig,
contracts,
collIndex: request.collIndex,
interestRate: request.annualInterestRate[0],
});

return writeContract(wagmiConfig, {
...LeverageLSTZapper,
...collateral.contracts.LeverageLSTZapper,
functionName: "openTroveWithRawETH" as const,
args: [{
owner: request.owner,
ownerIndex: BigInt(request.ownerIndex),
collAmount: request.collAmount[0],
boldAmount: request.boldAmount[0],
upperHint: request.upperHint[0],
lowerHint: request.lowerHint[0],
upperHint,
lowerHint,
annualInterestRate: request.interestRateDelegate
? 0n
: request.annualInterestRate[0],
Expand Down Expand Up @@ -295,17 +305,24 @@ export const openBorrowPosition: FlowDeclaration<OpenBorrowPositionRequest> = {
if (!collateral) {
throw new Error(`Invalid collateral index: ${request.collIndex}`);
}
const { LeverageWETHZapper } = collateral.contracts;

const { upperHint, lowerHint } = await getTroveOperationHints({
wagmiConfig,
contracts,
collIndex: request.collIndex,
interestRate: request.annualInterestRate[0],
});

return writeContract(wagmiConfig, {
...LeverageWETHZapper,
...collateral.contracts.LeverageWETHZapper,
functionName: "openTroveWithRawETH",
args: [{
owner: request.owner,
ownerIndex: BigInt(request.ownerIndex),
collAmount: 0n,
boldAmount: request.boldAmount[0],
upperHint: request.upperHint[0],
lowerHint: request.lowerHint[0],
upperHint,
lowerHint,
annualInterestRate: request.interestRateDelegate
? 0n
: request.annualInterestRate[0],
Expand Down
18 changes: 15 additions & 3 deletions frontend/app/src/tx-flows/openLeveragePosition.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,12 @@ import { ETH_GAS_COMPENSATION, MAX_UPFRONT_FEE } from "@/src/constants";
import { dnum18 } from "@/src/dnum-utils";
import { fmtnum } from "@/src/formatting";
import { getOpenLeveragedTroveParams } from "@/src/liquity-leverage";
import { getCollToken, getPrefixedTroveId, usePredictOpenTroveUpfrontFee } from "@/src/liquity-utils";
import {
getCollToken,
getPrefixedTroveId,
getTroveOperationHints,
usePredictOpenTroveUpfrontFee,
} from "@/src/liquity-utils";
import { AccountButton } from "@/src/screens/TransactionsScreen/AccountButton";
import { LoanCard } from "@/src/screens/TransactionsScreen/LoanCard";
import { TransactionDetailsRow } from "@/src/screens/TransactionsScreen/TransactionsScreen";
Expand Down Expand Up @@ -186,14 +191,21 @@ export const openLeveragePosition: FlowDeclaration<OpenLeveragePositionRequest>
wagmiConfig,
);

const { upperHint, lowerHint } = await getTroveOperationHints({
wagmiConfig,
contracts,
collIndex: loan.collIndex,
interestRate: loan.interestRate[0],
});

const txParams = {
owner: loan.borrower,
ownerIndex: BigInt(request.ownerIndex),
collAmount: initialDeposit[0],
flashLoanAmount: openLeveragedParams.flashLoanAmount,
boldAmount: openLeveragedParams.effectiveBoldAmount,
upperHint: 0n,
lowerHint: 0n,
upperHint,
lowerHint,
annualInterestRate: loan.batchManager ? 0n : loan.interestRate[0],
batchManager: loan.batchManager ?? ADDRESS_ZERO,
maxUpfrontFee: MAX_UPFRONT_FEE,
Expand Down

0 comments on commit 6cb3ed9

Please sign in to comment.