diff --git a/package.json b/package.json index 318532ad6..541ea95eb 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "app-v2", - "version": "2.0.60", + "version": "2.0.62", "private": true, "dependencies": { "@multiavatar/multiavatar": "^1.0.6", diff --git a/src/components/settings/SlippageSetting.tsx b/src/components/settings/SlippageSetting.tsx index 47d6d52a9..ab1437a41 100644 --- a/src/components/settings/SlippageSetting.tsx +++ b/src/components/settings/SlippageSetting.tsx @@ -76,6 +76,7 @@ const SlippageSetting = () => { reverse plain type="number" + inputMode="decimal" value={input || ''} onChange={(event: any) => setInput(event.target.value)} /> diff --git a/src/contexts/yieldEnv.json b/src/contexts/yieldEnv.json index 9b22231d1..e2183fe93 100644 --- a/src/contexts/yieldEnv.json +++ b/src/contexts/yieldEnv.json @@ -6,29 +6,29 @@ "CompoundMultiOracle" : "0x53FBa816BD69a7f2a096f58687f87dd3020d0d5c", "ChainlinkMultiOracle": "0xcDCe5C87f691058B61f3A65913f1a3cBCbAd9F52", "CompositeMultiOracle": "0xA81414a544D0bd8a28257F4038D3D24B08Dd9Bb4", - "YearnVaultMultiOracle": "0xC597E9cA52Afc13F7F5EDdaC9e53DEF569236016", "Witch": "0x53C3760670f6091E1eC76B4dd27f73ba4CAd5061", - "lidoWrapHandler": "0x491aB93faa921C8E634F891F96512Be14fD3DbB1" + "lidoWrapHandler": "0x491aB93faa921C8E634F891F96512Be14fD3DbB1", + "YearnVaultMultiOracle": "0xC597E9cA52Afc13F7F5EDdaC9e53DEF569236016" }, "4": { - "Cauldron": "0x8390Cd98C116F269a6E6A3b50Fb03B0931423164", - "Ladle": "0xbC0200F0AAD7C1c0bBB1CC7885E1e796DFFac3e0", + "Cauldron": "0xb2cf78ccA863675Ef61a0c696885DED0C833F8f3", + "Ladle": "0x45f502A7358ec631c7a422270922d7dFA142cb9C", "CompoundMultiOracle" : "0xeCA876c39DF7b75281Ea78eB35912fa1CC8f9482", "ChainlinkMultiOracle": "0xBDBF01Ee32485aF94e316C395765F5Af2bf4b4dB", "CompositeMultiOracle": "0x8482BF1e17ceF57109F34C259d39d5B9BB9A4e13", - "YearnVaultMultiOracle": "0x88175a3e14F905ecCe464aF2A8E99f26159d4Cb8", - "Witch": "0x458098338c136D1c4410910e6F893316D86Ba837", - "lidoWrapHandler": "0x80d0CfceE7dfa135189e44d617032d5A7Cc2705b" + "Witch": "0x5cEe0925647722e7ed32dcaf5A2DeFD3872Edb6F", + "lidoWrapHandler": "0x80d0CfceE7dfa135189e44d617032d5A7Cc2705b", + "YearnVaultMultiOracle": "0x88175a3e14F905ecCe464aF2A8E99f26159d4Cb8" }, "42": { - "Cauldron": "0xacb1fb5E88ba69E12BDE76A4c373F1935d9fe912", + "Cauldron": "0x82Dfaef826C8c190E9b472896a9a99165Ccee35a", "Ladle": "0xe7bae0445B9a1DBE834a7379fbE23C6d2Bd61C59", "CompoundMultiOracle" : "0x23F5F7a17117ba794Fcc5F46Fbf635edD2596Bb6", "ChainlinkMultiOracle": "0xBcdc8bad83ca8053DFA6B1CBAEB7E71699254a3b", "CompositeMultiOracle": "0xaF45D0277399E79Bf599d72fF4521f8Dc4A060E1", - "YearnVaultMultiOracle": "0xaF45D0277399E79Bf599d72fF4521f8Dc4A060E1", "Witch": "0xA421B81481e0d150740f8F137FB10b1b747974a8", - "lidoWrapHandler": "0x491aB93faa921C8E634F891F96512Be14fD3DbB1" + "lidoWrapHandler": "0x491aB93faa921C8E634F891F96512Be14fD3DbB1", + "YearnVaultMultiOracle": "0xaF45D0277399E79Bf599d72fF4521f8Dc4A060E1" }, "421611": { "Cauldron": "0x589fb605D165D0cd32608cC44dAcB87151d3B913", @@ -46,12 +46,10 @@ "0x8e8D6aB093905C400D583EfD37fbeEB1ee1c0c39" ], "4": [ - "0x1B496E901263b1EFa32880D6d13e325A8cb2D5c1", - "0x3a333FEc691DFCa0907Bc80024C27d0bbe7D022f", - "0x455F45e240436B75218E71B72472fad1a28Bc7A9", - "0xE40D644017BfC8b233bEf9cE2Eab55b512B964B4", - "0x4ABe302854c59546E37f46a8aa5DF482cFC683B0", - "0xccf1374c3d12AE3aAd51419e2CDed785C39d47A7" + "0x8468B9154D777Dc4520fDA275d30D8D663841C1d", + "0x6020a656a0421aFd96b02523D17fA23E206CD453", + "0x1a017DBc08317b105E266139F888c7ae6eDd6a0F", + "0xc946e0b5e815a7b22F563a569895663BE54f152A" ], "42": [ "0xad1fBd05f4FDB81C1bAE82172E9913a7c4152154", diff --git a/src/hooks/actionHooks/useAddLiquidity.ts b/src/hooks/actionHooks/useAddLiquidity.ts index ddcf15739..26772858f 100644 --- a/src/hooks/actionHooks/useAddLiquidity.ts +++ b/src/hooks/actionHooks/useAddLiquidity.ts @@ -14,6 +14,7 @@ import { IUserContext, IUserContextActions, IUserContextState, + ISettingsContext, } from '../../types'; import { cleanValue, getTxCode } from '../../utils/appUtils'; import { BLANK_VAULT } from '../../utils/constants'; @@ -27,12 +28,12 @@ import { ChainContext } from '../../contexts/ChainContext'; export const useAddLiquidity = () => { const { settingsState: { slippageTolerance, diagnostics, approveMax }, - } = useContext(SettingsContext); + } = useContext(SettingsContext) as ISettingsContext; const { chainState: { contractMap }, } = useContext(ChainContext); - const { userState, userActions }: { userState: IUserContextState; userActions: IUserContextActions } = useContext( + const { userState, userActions }: { userState: IUserContextState; userActions: IUserContextActions } = useContext( UserContext ) as IUserContext; const { activeAccount: account, assetMap, seriesMap } = userState; @@ -59,12 +60,12 @@ export const useAddLiquidity = () => { const cleanInput = cleanValue(input, base?.decimals!); const _input = ethers.utils.parseUnits(cleanInput, base?.decimals); - const _inputLessSlippage = calculateSlippage(_input, slippageTolerance, true); + const _inputLessSlippage = calculateSlippage(_input, slippageTolerance.toString(), true); const [cachedBaseReserves, cachedFyTokenReserves] = await series?.poolContract.getCache()!; const cachedRealReserves = cachedFyTokenReserves.sub(series?.totalSupply!); - const _fyTokenToBeMinted = fyTokenForMint( + const [_fyTokenToBeMinted] = fyTokenForMint( cachedBaseReserves, cachedRealReserves, cachedFyTokenReserves, @@ -76,8 +77,7 @@ export const useAddLiquidity = () => { slippageTolerance ); - console.log(cachedBaseReserves.toString(), cachedRealReserves.toString()) - + console.log(cachedBaseReserves.toString(), cachedRealReserves.toString()); const [minRatio, maxRatio] = calcPoolRatios(cachedBaseReserves, cachedRealReserves); const [_baseToPool, _baseToFyToken] = splitLiquidity( @@ -87,37 +87,36 @@ export const useAddLiquidity = () => { true ) as [BigNumber, BigNumber]; - const _baseToPoolWithSlippage = BigNumber.from(calculateSlippage(_baseToPool, slippageTolerance)); + const _baseToPoolWithSlippage = BigNumber.from(calculateSlippage(_baseToPool, slippageTolerance.toString())); /* if approveMAx, check if signature is still required */ const alreadyApproved = (await base.getAllowance(account!, ladleAddress)).gt(_input); /* DIAGNOSITCS */ - - console.log( - 'input: ', - _input.toString(), - 'inputLessSlippage: ', - _inputLessSlippage.toString(), - 'base: ', - cachedBaseReserves.toString(), - 'real: ', - cachedRealReserves.toString(), - 'virtual: ', - cachedFyTokenReserves.toString(), - '>> baseSplit: ', - _baseToPool.toString(), - '>> fyTokenSplit: ', - _baseToFyToken.toString(), - '>> baseSplitWithSlippage: ', - _baseToPoolWithSlippage.toString(), - '>> minRatio', - minRatio.toString(), - '>> maxRatio', - maxRatio.toString(), - 'matching vault id', - matchingVaultId - ); + console.log( + 'input: ', + _input.toString(), + 'inputLessSlippage: ', + _inputLessSlippage.toString(), + 'base: ', + cachedBaseReserves.toString(), + 'real: ', + cachedRealReserves.toString(), + 'virtual: ', + cachedFyTokenReserves.toString(), + '>> baseSplit: ', + _baseToPool.toString(), + '>> fyTokenSplit: ', + _baseToFyToken.toString(), + '>> baseSplitWithSlippage: ', + _baseToPoolWithSlippage.toString(), + '>> minRatio', + minRatio.toString(), + '>> maxRatio', + maxRatio.toString(), + 'matching vault id', + matchingVaultId + ); /** * GET SIGNTURE/APPROVAL DATA @@ -128,7 +127,7 @@ export const useAddLiquidity = () => { target: base, spender: 'LADLE', amount: _input, - ignoreIf: alreadyApproved===true, + ignoreIf: alreadyApproved === true, }, ], txCode diff --git a/src/hooks/viewHelperHooks/usePoolHelpers.ts b/src/hooks/viewHelperHooks/usePoolHelpers.ts index 05725460d..043527e31 100644 --- a/src/hooks/viewHelperHooks/usePoolHelpers.ts +++ b/src/hooks/viewHelperHooks/usePoolHelpers.ts @@ -1,7 +1,7 @@ import { useContext, useEffect, useState } from 'react'; import { ethers, BigNumber } from 'ethers'; import { UserContext } from '../../contexts/UserContext'; -import { IAsset, ISeries, IStrategy, IVault } from '../../types'; +import { IAsset, ISeries, ISettingsContext, IStrategy, IVault } from '../../types'; import { cleanValue } from '../../utils/appUtils'; import { fyTokenForMint, @@ -10,6 +10,7 @@ import { maxFyTokenOut, burnFromStrategy, burn, + calculateSlippage, } from '../../utils/yieldMath'; import { SettingsContext } from '../../contexts/SettingsContext'; @@ -17,7 +18,7 @@ export const usePoolHelpers = (input: string | undefined, removeLiquidityView: b /* STATE FROM CONTEXT */ const { settingsState: { slippageTolerance, diagnostics }, - } = useContext(SettingsContext); + } = useContext(SettingsContext) as ISettingsContext; const { userState: { selectedSeries, selectedBase, selectedStrategy, seriesMap, vaultMap, assetMap, activeAccount }, @@ -120,11 +121,11 @@ export const usePoolHelpers = (input: string | undefined, removeLiquidityView: b strategySeries.decimals ); - _fyTokenToBuy = fyTokenForMint( + [_fyTokenToBuy] = fyTokenForMint( strategySeries.baseReserves, strategySeries.fyTokenRealReserves, strategySeries.fyTokenReserves, - _input, + calculateSlippage(_input, slippageTolerance.toString(), true), strategySeries.getTimeTillMaturity(), strategySeries.ts, strategySeries.g1, @@ -217,7 +218,6 @@ export const usePoolHelpers = (input: string | undefined, removeLiquidityView: b setRemoveBaseReceived_(ethers.utils.formatUnits(_baseVal, strategySeries.decimals)); setRemoveFyTokenReceived(_fyTokenVal); setRemoveFyTokenReceived_(ethers.utils.formatUnits(_fyTokenVal, strategySeries.decimals)); - } else { /* CASE> fytokenReceived less than debt : USE REMOVE OPTION 1 */ diagnostics && diff --git a/src/utils/yieldMath.ts b/src/utils/yieldMath.ts index fe0a9ca10..65082be44 100644 --- a/src/utils/yieldMath.ts +++ b/src/utils/yieldMath.ts @@ -28,9 +28,6 @@ const g1_default = new Decimal(950 / 1000).mul(2 ** 64); const g2_default = new Decimal(1000 / 950).mul(2 ** 64); const precisionFee = new Decimal(1000000000000); -// console.log(g1_default.div(2 ** 64).toString()); -// console.log(g2_default.div(2 ** 64).toString()); - /** ************************* Support functions *************************** */ @@ -245,10 +242,9 @@ export function burnFromStrategy( } /** - * @param { BigNumber | string } baseReserves - * @param { BigNumber | string } fyTokenReservesVirtual - * @param { BigNumber | string } fyTokenReservesReal - * @param { BigNumber | string } totalSupply + * @param { BigNumber } baseReserves + * @param { BigNumber } fyTokenReservesVirtual + * @param { BigNumber } fyTokenReservesReal * @param { BigNumber | string } fyToken * @param { BigNumber | string } timeTillMaturity * @param { BigNumber | string } ts @@ -258,10 +254,9 @@ export function burnFromStrategy( * @returns {[BigNumber, BigNumber]} */ export function mintWithBase( - baseReserves: BigNumber | string, - fyTokenReservesVirtual: BigNumber | string, - fyTokenReservesReal: BigNumber | string, - supply: BigNumber | string, + baseReserves: BigNumber, + fyTokenReservesVirtual: BigNumber, + fyTokenReservesReal: BigNumber, fyToken: BigNumber | string, timeTillMaturity: BigNumber | string, ts: BigNumber | string, @@ -270,7 +265,7 @@ export function mintWithBase( ): [BigNumber, BigNumber] { const Z = new Decimal(baseReserves.toString()); const YR = new Decimal(fyTokenReservesReal.toString()); - const S = new Decimal(supply.toString()); + const supply = fyTokenReservesVirtual.sub(fyTokenReservesReal); const y = new Decimal(fyToken.toString()); // buyFyToken: const z1 = new Decimal( @@ -280,9 +275,9 @@ export function mintWithBase( const YR2 = YR.sub(y); // FYToken reserves after the trade // Mint specifying how much fyToken to take in. Reverse of `mint`. - const [m, z2] = mint(Z2.floor().toFixed(), YR2.floor().toFixed(), supply, fyToken, false); + const [minted, z2] = mint(toBn(Z2), toBn(YR2), supply, fyToken, false); - return [m, toBn(z1).add(z2)]; + return [minted, toBn(z1).add(z2)]; } /** @@ -302,13 +297,13 @@ export function burnForBase( baseReserves: BigNumber, fyTokenReservesVirtual: BigNumber, fyTokenReservesReal: BigNumber, - supply: BigNumber, lpTokens: BigNumber, timeTillMaturity: BigNumber | string, ts: BigNumber | string, g2: BigNumber | string, decimals: number ): BigNumber { + const supply = fyTokenReservesVirtual.sub(fyTokenReservesReal); // Burn FyToken const [z1, y] = burn(baseReserves, fyTokenReservesReal, supply, lpTokens); // Sell FyToken for base @@ -507,8 +502,8 @@ export function buyFYToken( * */ export function maxBaseIn( - baseReserves: BigNumber | string, - fyTokenReserves: BigNumber | string, + baseReserves: BigNumber, + fyTokenReserves: BigNumber, timeTillMaturity: BigNumber | string, ts: BigNumber | string, g1: BigNumber | string, @@ -518,9 +513,9 @@ export function maxBaseIn( const fyTokenAmountOut = maxFyTokenOut(baseReserves, fyTokenReserves, timeTillMaturity, ts, g1, decimals); /* convert to 18 decimals, if required */ - const baseReserves18 = decimalNToDecimal18(BigNumber.from(baseReserves), decimals); - const fyTokenReserves18 = decimalNToDecimal18(BigNumber.from(fyTokenReserves), decimals); - const fyTokenAmountOut18 = decimalNToDecimal18(BigNumber.from(fyTokenAmountOut), decimals); + const baseReserves18 = decimalNToDecimal18(baseReserves, decimals); + const fyTokenReserves18 = decimalNToDecimal18(fyTokenReserves, decimals); + const fyTokenAmountOut18 = decimalNToDecimal18(fyTokenAmountOut, decimals); const baseReserves_ = new Decimal(baseReserves18.toString()); const fyTokenReserves_ = new Decimal(fyTokenReserves18.toString()); @@ -565,8 +560,8 @@ export function maxBaseIn( * */ export function maxBaseOut( - baseReserves: BigNumber | string, - fyTokenReserves: BigNumber | string, + baseReserves: BigNumber, + fyTokenReserves: BigNumber, timeTillMaturity: BigNumber | string, ts: BigNumber | string, g2: BigNumber | string, @@ -576,9 +571,9 @@ export function maxBaseOut( const fyTokenAmountIn = maxFyTokenIn(baseReserves, fyTokenReserves, timeTillMaturity, ts, g2, decimals); /* convert to 18 decimals, if required */ - const baseReserves18 = decimalNToDecimal18(BigNumber.from(baseReserves), decimals); - const fyTokenReserves18 = decimalNToDecimal18(BigNumber.from(fyTokenReserves), decimals); - const fyTokenAmountIn18 = decimalNToDecimal18(BigNumber.from(fyTokenAmountIn), decimals); + const baseReserves18 = decimalNToDecimal18(baseReserves, decimals); + const fyTokenReserves18 = decimalNToDecimal18(fyTokenReserves, decimals); + const fyTokenAmountIn18 = decimalNToDecimal18(fyTokenAmountIn, decimals); const baseReserves_ = new Decimal(baseReserves18.toString()); const fyTokenReserves_ = new Decimal(fyTokenReserves18.toString()); @@ -618,16 +613,16 @@ export function maxBaseOut( * @returns { BigNumber } */ export function maxFyTokenIn( - baseReserves: BigNumber | string, - fyTokenReserves: BigNumber | string, + baseReserves: BigNumber, + fyTokenReserves: BigNumber, timeTillMaturity: BigNumber | string, ts: BigNumber | string, g2: BigNumber | string, decimals: number ): BigNumber { /* convert to 18 decimals, if required */ - const baseReserves18 = decimalNToDecimal18(BigNumber.from(baseReserves), decimals); - const fyTokenReserves18 = decimalNToDecimal18(BigNumber.from(fyTokenReserves), decimals); + const baseReserves18 = decimalNToDecimal18(baseReserves, decimals); + const fyTokenReserves18 = decimalNToDecimal18(fyTokenReserves, decimals); const baseReserves_ = new Decimal(baseReserves18.toString()); const fyTokenReserves_ = new Decimal(fyTokenReserves18.toString()); @@ -660,16 +655,18 @@ export function maxFyTokenIn( * @returns { BigNumber } */ export function maxFyTokenOut( - baseReserves: BigNumber | string, - fyTokenReserves: BigNumber | string, + baseReserves: BigNumber, + fyTokenReserves: BigNumber, timeTillMaturity: BigNumber | string, ts: BigNumber | string, g1: BigNumber | string, decimals: number ): BigNumber { /* convert to 18 decimals, if required */ - const baseReserves18 = decimalNToDecimal18(BigNumber.from(baseReserves), decimals); - const fyTokenReserves18 = decimalNToDecimal18(BigNumber.from(fyTokenReserves), decimals); + const baseReserves18 = decimalNToDecimal18(baseReserves, decimals); + const fyTokenReserves18 = decimalNToDecimal18(fyTokenReserves, decimals); + + /* convert to decimal for the math */ const baseReserves_ = new Decimal(baseReserves18.toString()); const fyTokenReserves_ = new Decimal(fyTokenReserves18.toString()); @@ -689,7 +686,92 @@ export function maxFyTokenOut( return decimal18ToDecimalN(toBn(safeRes), decimals); } +/** + * Calculate the amount of fyToken that should be bought when providing liquidity with only underlying. + * The amount bought leaves a bit of unused underlying, to allow for the pool reserves to change between + * the calculation and the mint. The pool returns any unused underlying. + * + * @param baseReserves + * @param fyTokenRealReserves + * @param fyTokenVirtualReserves + * @param base + * @param timeTillMaturity + * @param ts + * @param g1 + * @param decimals + * @param slippage How far from the optimum we want to be + * @param precision How wide the range in which we will accept a value + * @returns fyTokenToBuy, surplus + */ + export function fyTokenForMint( + baseReserves: BigNumber, + fyTokenRealReserves: BigNumber, + fyTokenVirtualReserves: BigNumber, + base: BigNumber | string, + timeTillMaturity: BigNumber | string, + ts: BigNumber | string, + g1: BigNumber | string, + decimals: number, + slippage: number = 0.01, // 1% default + precision: number = 0.0001 // 0.01% default +): [BigNumber, BigNumber] { + const base_ = new Decimal(base.toString()); + const minSurplus = base_.mul(slippage); + const maxSurplus = minSurplus.add(base_.mul(precision)); + + let maxFYToken = new Decimal( + maxFyTokenOut(baseReserves, fyTokenVirtualReserves, timeTillMaturity, ts, g1, decimals).toString() + ); + let minFYToken = ZERO_DEC; + + let i = 0; + while (true) { + /* NB return ZERO when not converging > not mintable */ + // eslint-disable-next-line no-plusplus + if (i++ > 100) { + console.log('No solution'); + return [ZERO_BN, ZERO_BN]; + } + + const fyTokenToBuy = minFYToken.add(maxFYToken).div(2); + // console.log('fyToken tobuy', fyTokenToBuy.toFixed() ) + + const baseIn = mintWithBase( + baseReserves, + fyTokenVirtualReserves, + fyTokenRealReserves, + toBn(fyTokenToBuy), + timeTillMaturity, + ts, + g1, + decimals + )[1]; + + const surplus = base_.sub(new Decimal(baseIn.toString())); + // console.log( 'min:', minSurplus.toFixed() , 'max:', maxSurplus.toFixed() , 'surplus: ', surplus.toFixed() ) + + // Just right + if (minSurplus.lt(surplus) && surplus.lt(maxSurplus)) { + // console.log('fyToken to buy: ', fyTokenToBuy.toFixed(), 'surplus: ', surplus.toFixed()); + return [toBn(fyTokenToBuy), toBn(surplus)]; + } + + // Bought too much, lower the max and the buy + if (baseIn.gt(base) || surplus.lt(minSurplus)) { + // console.log('Bought too much'); + maxFYToken = fyTokenToBuy; + } + + // Bought too little, raise the min and the buy + if (surplus.gt(maxSurplus)) { + // console.log('Bought too little'); + minFYToken = fyTokenToBuy; + } + } +} + +export function fyTokenForMintOld( baseReserves: BigNumber | string, fyTokenRealReserves: BigNumber | string, fyTokenVirtualReserves: BigNumber | string, @@ -710,7 +792,7 @@ export function fyTokenForMint( const fyDaiRealReserves_ = new Decimal(fyTokenRealReserves18.toString()); const base_ = new Decimal(base18.toString()); const timeTillMaturity_ = new Decimal(timeTillMaturity.toString()); - const slippage_ = new Decimal(slippage).mul(new Decimal(10)); /* multiply the user slippage by 10 */ + const slippage_ = new Decimal(slippage); // .mul(new Decimal(10)); /* multiply the user slippage by 10 */ let min = ZERO; let max = base_.mul(TWO); @@ -735,6 +817,7 @@ export function fyTokenForMint( 18 ).toString() ); + const Z_1 = baseReserves_.add(zIn); // New base balance const z_1 = base_.sub(zIn); // My remaining base const Y_1 = fyDaiRealReserves_.sub(yOut); // New fyToken balance @@ -760,6 +843,9 @@ export function fyTokenForMint( } } + // console.log( 'yOut : ', yOut.toFixed()); + // console.log( 'buyFyTOKEN: ', zIn.toString() ); + return decimal18ToDecimalN( // (converted back to original decimals) BigNumber.from(yOut.floor().toFixed()), diff --git a/src/views/Borrow.tsx b/src/views/Borrow.tsx index 83c3075d1..89e950db0 100644 --- a/src/views/Borrow.tsx +++ b/src/views/Borrow.tsx @@ -305,6 +305,7 @@ const Borrow = () => { diff --git a/src/views/Lend.tsx b/src/views/Lend.tsx index a0ea118a5..960eeb1ed 100644 --- a/src/views/Lend.tsx +++ b/src/views/Lend.tsx @@ -63,10 +63,7 @@ const Lend = () => { const { txProcess: lendProcess, resetProcess: resetLendProcess } = useProcess(ActionCodes.LEND, selectedSeries?.id!); /* input validation hooks */ - const { inputError: lendError } = useInputValidation(lendInput, ActionCodes.LEND, selectedSeries, [ - 0, - maxLend_, - ]); + const { inputError: lendError } = useInputValidation(lendInput, ActionCodes.LEND, selectedSeries, [0, maxLend_]); /* LOCAL FNS */ const handleLend = () => { @@ -144,6 +141,7 @@ const Lend = () => { diff --git a/src/views/LendPosition.tsx b/src/views/LendPosition.tsx index 0ff2af04a..556125be8 100644 --- a/src/views/LendPosition.tsx +++ b/src/views/LendPosition.tsx @@ -37,7 +37,7 @@ const LendPosition = () => { /* STATE FROM CONTEXT */ const { userState, - userActions: { setSelectedSeries }, + userActions: { setSelectedSeries, setSelectedBase }, } = useContext(UserContext) as IUserContext; const { selectedSeries, seriesMap, assetMap, seriesLoading } = userState; @@ -129,8 +129,12 @@ const LendPosition = () => { useEffect(() => { const _series = seriesMap.get(idFromUrl) || null; - idFromUrl && setSelectedSeries(_series); - }, [idFromUrl, seriesMap, setSelectedSeries]); + const _base = assetMap.get(_series?.baseId!); + if (idFromUrl) { + setSelectedSeries(_series); + setSelectedBase(_base!); + } + }, [idFromUrl, seriesMap, setSelectedSeries, assetMap, setSelectedBase]); return ( <> @@ -236,6 +240,7 @@ const LendPosition = () => { diff --git a/src/views/Pool.tsx b/src/views/Pool.tsx index 6957fa6f3..6fea36e8a 100644 --- a/src/views/Pool.tsx +++ b/src/views/Pool.tsx @@ -127,6 +127,7 @@ function Pool() { @@ -248,7 +249,7 @@ function Pool() { {stepPosition === 1 && poolProcess?.stage === ProcessStage.PROCESS_COMPLETE && poolProcess?.tx.status === TxState.SUCCESSFUL && ( - + View strategy Position: diff --git a/src/views/PoolPosition.tsx b/src/views/PoolPosition.tsx index 55394e6d0..cd47ca87f 100644 --- a/src/views/PoolPosition.tsx +++ b/src/views/PoolPosition.tsx @@ -257,6 +257,7 @@ const PoolPosition = () => { diff --git a/src/views/VaultPosition.tsx b/src/views/VaultPosition.tsx index 54f4167d2..f55877223 100644 --- a/src/views/VaultPosition.tsx +++ b/src/views/VaultPosition.tsx @@ -456,6 +456,7 @@ const VaultPosition = () => { { el && !repayOpen && !rateLockOpen && !mobile && el.focus(); setInputRef(el); }} value={repayInput || ''} @@ -581,6 +582,7 @@ const VaultPosition = () => { // disabled={removeCollatInput} plain type="number" + inputMode="decimal" placeholder="Collateral to add" value={addCollatInput || ''} onChange={(event: any) => @@ -649,6 +651,7 @@ const VaultPosition = () => { // disabled={addCollatInput} plain type="number" + inputMode="decimal" placeholder="Collateral to remove" value={removeCollatInput || ''} onChange={(event: any) =>