Skip to content

Commit

Permalink
Fix/eng 378: add Aaave sourcing in strategies (mangrovedao#344)
Browse files Browse the repository at this point in the history
* WIP - Liquidity sourcing for AAVE strat

* add aave seeder

Signed-off-by: belbazanas <[email protected]>

* fix min provision decimals

Signed-off-by: belbazanas <[email protected]>

* Add aavekandelseeder to sow tx

Signed-off-by: belbazanas <[email protected]>

* update mgv sdk

Signed-off-by: belbazanas <[email protected]>

* filter aave on compatible networks

Signed-off-by: belbazanas <[email protected]>

* edit aave kandel strategy

Signed-off-by: belbazanas <[email protected]>

* add source infos in strategy list

Signed-off-by: belbazanas <[email protected]>

* fix infinite cancel strategy

Signed-off-by: belbazanas <[email protected]>

* fix edit form

Signed-off-by: belbazanas <[email protected]>

* fix kandelsteps hooks

Signed-off-by: belbazanas <[email protected]>

* fix use aave

Signed-off-by: belbazanas <[email protected]>

* fix decimals on strategy list min max prices

Signed-off-by: belbazanas <[email protected]>

* fix canUseAave hook

Signed-off-by: belbazanas <[email protected]>

* test fix approve on slow network

Signed-off-by: belbazanas <[email protected]>

* test fix approve on slow network

Signed-off-by: belbazanas <[email protected]>

* update launch strategy dialog button layout

Signed-off-by: belbazanas <[email protected]>

* save wip

Signed-off-by: belbazanas <[email protected]>

* add aave to arbitrum

Signed-off-by: belbazanas <[email protected]>

* update mgv sdk

Signed-off-by: belbazanas <[email protected]>

* temporary fix for strategy approvals

Signed-off-by: belbazanas <[email protected]>

* fix build related to logics type

Signed-off-by: belbazanas <[email protected]>

* fix approval on kandel

Signed-off-by: belbazanas <[email protected]>

* fix approval on kandel

Signed-off-by: belbazanas <[email protected]>

* remove loading conditions on approval

Signed-off-by: belbazanas <[email protected]>

---------

Signed-off-by: belbazanas <[email protected]>
Co-authored-by: Johan le Roch <[email protected]>
  • Loading branch information
anasbelbaz and johanleroch authored Oct 4, 2024
1 parent d8772f5 commit f600e50
Show file tree
Hide file tree
Showing 17 changed files with 390 additions and 107 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -32,15 +32,11 @@ export function MinMax({ min, max, quote, base }: Props) {
return (
<div>
<div>
{Number(formatUnits(minBigInt, quoteToken?.decimals)).toFixed(
displayedDecimals,
)}{" "}
{Number(formatUnits(minBigInt, decimals)).toFixed(displayedDecimals)}{" "}
{symbol}
</div>
<div>
{Number(formatUnits(maxBigInt, quoteToken?.decimals)).toFixed(
displayedDecimals,
)}{" "}
{Number(formatUnits(maxBigInt, decimals)).toFixed(displayedDecimals)}{" "}
{symbol}
</div>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import React from "react"
import { useAccount } from "wagmi"

import useStrategyStatus from "@/app/strategies/(shared)/_hooks/use-strategy-status"
import SourceIcon from "@/app/trade/_components/forms/limit/components/source-icon"
import { IconButton } from "@/components/icon-button"
import { Close, Pen } from "@/svgs"
import { shortenAddress } from "@/utils/wallet"
Expand Down Expand Up @@ -90,6 +91,22 @@ export function useTable({ type, data, onCancel, onManage }: Params) {
return <Market base={base} quote={quote} />
},
}),
columnHelper.display({
header: "Liquidity source",
cell: ({ row }) => {
const sourceInfo =
row.original.type === "KandelAAVE"
? { id: "Aave", name: "Aave" }
: { id: "simple", name: "Wallet" }

return (
<div className="flex items-center space-x-2">
<SourceIcon sourceId={sourceInfo.id} />
<span>{sourceInfo.name}</span>
</div>
)
},
}),
columnHelper.display({
header: "Value",
cell: ({ row }) => {
Expand Down Expand Up @@ -137,6 +154,8 @@ export function useTable({ type, data, onCancel, onManage }: Params) {
id: "actions",
header: () => <div className="text-right">Action</div>,
cell: ({ row }) => {
const hasLiveOffers = row.original.offers.some((x) => x.live)

return (
<div className="w-full h-full flex justify-end space-x-1">
<IconButton
Expand All @@ -153,6 +172,7 @@ export function useTable({ type, data, onCancel, onManage }: Params) {
<IconButton
tooltip="Cancel strategy"
className="aspect-square w-6 rounded-full"
disabled={!hasLiveOffers}
onClick={(e) => {
e.preventDefault()
e.stopPropagation()
Expand Down
42 changes: 28 additions & 14 deletions app/strategies/[address]/_hooks/use-kandel-steps.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,29 @@
import { kandelActions } from "@mangrovedao/mgv"
import { useQuery } from "@tanstack/react-query"

import { useMangroveAddresses } from "@/hooks/use-addresses"
import {
useAaveKandelSeeder,
useKandelSeeder,
useMangroveAddresses,
} from "@/hooks/use-addresses"
import useMarket from "@/providers/market"
import { getErrorMessage } from "@/utils/errors"
import { Address } from "viem"
import { useAccount, useClient, usePublicClient } from "wagmi"
import useKandel from "../_providers/kandel-strategy"

export function useKandelSteps() {
type Props = {
liquiditySourcing?: string
kandelAddress?: string
}

export function useKandelSteps({ liquiditySourcing, kandelAddress }: Props) {
const { address } = useAccount()
const { markets } = useMarket()
const { baseToken, quoteToken } = useKandel()
const client = useClient()

const kandelSeeder = useKandelSeeder()
const kandelAaveSeeder = useAaveKandelSeeder()
const addresses = useMangroveAddresses()
const publicClient = usePublicClient()

Expand All @@ -25,9 +35,13 @@ export function useKandelSteps() {
quoteToken?.address.toLocaleLowerCase(),
)

const isAave = liquiditySourcing === "Aave"
const kandelSeederAddress = isAave ? kandelAaveSeeder : kandelSeeder

return useQuery({
queryKey: [
"kandel-steps",
isAave,
address,
baseToken?.address,
quoteToken?.address,
Expand All @@ -40,19 +54,19 @@ export function useKandelSteps() {
!publicClient ||
!addresses ||
!client ||
!currentMarket
!currentMarket ||
!kandelSeederAddress ||
!kandelAddress
)
throw new Error("Could not fetch kandel steps, missing params")

const kandelInstance = client?.extend(
kandelActions(
addresses,
currentMarket, // the market object
address as Address, // the kandel seeder address
),
)
const actions = kandelActions(
addresses,
currentMarket,
kandelAddress as Address,
)(client)

const currentSteps = await kandelInstance.getKandelSteps({
const currentSteps = await actions.getKandelSteps({
user: address,
})

Expand All @@ -62,10 +76,10 @@ export function useKandelSteps() {
throw new Error("Unable to retrieve kandel steps")
}
},
enabled: !!address,
enabled: !!currentMarket,
meta: {
error: "Unable to retrieve kandel steps",
},
staleTime: 1 * 60 * 1000, // 1 minute
// staleTime: 1 * 60 * 1000, // 1 minute
})
}
19 changes: 12 additions & 7 deletions app/strategies/[address]/edit/_components/edit-strategy-dialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import { useAccount, useBalance } from "wagmi"
import useKandelInstance from "@/app/strategies/(shared)/_hooks/use-kandel-instance"

import { ApproveStep } from "@/app/trade/_components/forms/components/approve-step"
import { useSpenderAddress } from "@/app/trade/_components/forms/hooks/use-spender-address"
import Dialog from "@/components/dialogs/dialog"
import { TokenPair } from "@/components/token-pair"
import { Text } from "@/components/typography/text"
Expand Down Expand Up @@ -47,17 +46,21 @@ export default function EditStrategyDialog({
strategy,
}: Props) {
const { address } = useAccount()
const { data: kandelSteps } = useKandelSteps()
const [sow, baseApprove, quoteApprove, populateParams] = kandelSteps ?? [{}]

const { data: nativeBalance } = useBalance({
address,
})
const { data: spender } = useSpenderAddress("kandel")

const { strategyQuery, baseToken, quoteToken } = useKandel()
const kandelAddress = strategyQuery.data?.address

const { data: kandelSteps } = useKandelSteps({
liquiditySourcing: strategy?.sendFrom,
kandelAddress: kandelAddress,
})

const [sow, baseApprove, quoteApprove, populateParams] = kandelSteps ?? [{}]

const approveBaseToken = useInfiniteApproveToken()
const approveQuoteToken = useInfiniteApproveToken()

Expand Down Expand Up @@ -115,7 +118,7 @@ export default function EditStrategyDialog({
approveBaseToken.mutate(
{
token: baseToken,
spender: baseApprove?.params.spender,
spender: kandelAddress,
},
{
onSuccess: goToNextStep,
Expand Down Expand Up @@ -143,7 +146,7 @@ export default function EditStrategyDialog({
approveQuoteToken.mutate(
{
token: quoteToken,
spender: quoteApprove?.params.spender,
spender: kandelAddress,
},
{
onSuccess: goToNextStep,
Expand Down Expand Up @@ -184,6 +187,7 @@ export default function EditStrategyDialog({
Activate
</Button>
<Button
size={"lg"}
variant={"secondary"}
disabled={isRetractingOffers}
onClick={() => goToPrevStep()}
Expand Down Expand Up @@ -309,6 +313,7 @@ const Summary = ({
bountyDeposit,
priceRange,
riskAppetite,
onAave,
} = strategy ?? {}

const [minPrice, maxPrice] = priceRange ?? []
Expand All @@ -326,7 +331,7 @@ const Summary = ({

<SummaryLine
title="Liquidity source"
value={<Text>{false ? "Aave" : "Wallet"}</Text>}
value={<Text>{onAave ? "Aave" : "Wallet"}</Text>}
/>

<SummaryLine title="Risk appetite" value={<Text>Medium</Text>} />
Expand Down
71 changes: 61 additions & 10 deletions app/strategies/[address]/edit/_components/form/form.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,22 @@
"use client"

import MarketSelector from "@/app/strategies/(shared)/_components/market-selector/market-selector"
import { CustomBalance } from "@/components/stateful/token-balance/custom-balance"
import SourceIcon from "@/app/trade/_components/forms/limit/components/source-icon"
import InfoTooltip from "@/components/info-tooltip"
import { TokenBalance } from "@/components/stateful/token-balance/token-balance"
import { EnhancedNumericInput } from "@/components/token-input"
import { Caption } from "@/components/typography/caption"
import { Label } from "@/components/ui/label"
import {
Select,
SelectContent,
SelectGroup,
SelectItem,
SelectTrigger,
SelectValue,
} from "@/components/ui/select"
import { Skeleton } from "@/components/ui/skeleton"
import { cn } from "@/utils"
import { formatUnits } from "viem"
import { Fieldset } from "../fieldset"
import { MinimumRecommended } from "./components/minimum-recommended"
import { MustBeAtLeastInfo } from "./components/must-be-at-least-info"
Expand All @@ -19,12 +29,14 @@ export function Form({ className }: { className?: string }) {
minBaseAmount,
minQuoteAmount,
minProvision,
currentLiquiditySourcing,
baseDeposit,
quoteDeposit,
totalQuoteBalance,
totalBaseBalance,
fieldsDisabled,
errors,
sendFrom,
isValid,
receiveTo,
handleBaseDepositChange,
handleQuoteDepositChange,
isChangingFrom,
Expand All @@ -36,6 +48,8 @@ export function Form({ className }: { className?: string }) {
handleNumberOfOffersChange,
handleStepSizeChange,
handleBountyDepositChange,
handleSendFromChange,
handleReceiveToChange,
} = useForm()

if (!baseToken || !quoteToken)
Expand All @@ -56,6 +70,47 @@ export function Form({ className }: { className?: string }) {
<MarketSelector disabled={true} />
</Fieldset>

<Fieldset legend="Liquidity sourcing">
<div className="flex justify-between space-x-2 pt-2">
<div className="flex flex-col w-full">
<Label className="flex items-center">
Source
<InfoTooltip>
<Caption>Select the origin of the assets</Caption>
</InfoTooltip>
</Label>

<Select
name={"SendFrom"}
value={currentLiquiditySourcing}
onValueChange={(value: string) => {
handleSendFromChange(value)
}}
disabled={true} //note: we don't allow modifying liquidity sourcing
>
<SelectTrigger>
<SelectValue placeholder="Select" />
</SelectTrigger>
<SelectContent>
<SelectGroup>
<SelectItem
key={currentLiquiditySourcing}
value={currentLiquiditySourcing}
>
<div className="flex gap-2 w-full items-center">
<SourceIcon sourceId={currentLiquiditySourcing} />
<Caption className="capitalize">
{currentLiquiditySourcing}
</Caption>
</div>
</SelectItem>
</SelectGroup>
</SelectContent>
</Select>
</div>
</div>
</Fieldset>

<Fieldset className="space-y-4" legend="Edit inventory">
<div>
<EnhancedNumericInput
Expand All @@ -78,11 +133,9 @@ export function Form({ className }: { className?: string }) {
loading={fieldsDisabled}
/>

<CustomBalance
<TokenBalance
label="Wallet balance"
token={baseToken}
balance={formatUnits(totalBaseBalance || 0n, baseToken.decimals)}
tooltip="This is your current wallet balance plus your deposited liquidity"
action={{
onClick: handleBaseDepositChange,
text: "MAX",
Expand Down Expand Up @@ -111,11 +164,9 @@ export function Form({ className }: { className?: string }) {
loading={fieldsDisabled}
/>

<CustomBalance
<TokenBalance
label="Wallet balance"
token={quoteToken}
balance={formatUnits(totalQuoteBalance || 0n, quoteToken.decimals)}
tooltip="This is your current wallet balance plus your deposited liquidity"
action={{
onClick: handleQuoteDepositChange,
text: "MAX",
Expand Down
8 changes: 5 additions & 3 deletions app/strategies/[address]/edit/_components/form/use-form.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,12 @@ export default function useForm() {
const { data: nativeBalance } = useBalance({
address,
})

const logics = useLogics()
const { currentParameter } = strategyQuery.data ?? {}

const lockedBounty = formatUnits(kandelState?.totalProvision || 0n, 18)
const onAave = strategyQuery.data?.type === "KandelAAVE"
const currentLiquiditySourcing = onAave ? "Aave" : "simple"

const {
priceRange: [minPrice, maxPrice],
Expand Down Expand Up @@ -69,7 +70,7 @@ export default function useForm() {
strategyQuery.data?.offers.some((x) => x.live) &&
strategyStatusQuery.isFetched
) {
// getCurrentLiquiditySourcing()
setSendFrom(currentLiquiditySourcing)
setBaseDeposit(
formatUnits(kandelState?.baseAmount || 0n, baseToken?.decimals || 18),
)
Expand Down Expand Up @@ -130,7 +131,7 @@ export default function useForm() {

const minBase = formatUnits(minBaseAmount || 0n, baseToken?.decimals || 18)
const minQuote = formatUnits(minQuoteAmount || 0n, quoteToken?.decimals || 18)
const minProv = formatUnits(minProvision || 0n, quoteToken?.decimals || 18)
const minProv = formatUnits(minProvision || 0n, 18)

// I need the distribution to be set in the store to share it with the price range component
React.useEffect(() => {
Expand Down Expand Up @@ -331,6 +332,7 @@ export default function useForm() {
sendFrom,
receiveTo,
logics,
currentLiquiditySourcing,
handleBaseDepositChange,
handleQuoteDepositChange,
handleNumberOfOffersChange,
Expand Down
Loading

0 comments on commit f600e50

Please sign in to comment.