Skip to content

Commit 105409d

Browse files
committed
feat: add erc4626 check and warning to token selector
1 parent d517730 commit 105409d

File tree

11 files changed

+306
-138
lines changed

11 files changed

+306
-138
lines changed

apps/main/src/dex/components/PageCreatePool/Summary/OracleSummary.tsx

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { styled } from 'styled-components'
22
import { isAddress } from 'viem'
3+
import { NG_ASSET_TYPE } from '@/dex/components/PageCreatePool/constants'
34
import {
45
CategoryDataRow,
56
SummaryDataTitle,
@@ -39,28 +40,28 @@ const OracleSummary = ({ chainId }: Props) => {
3940

4041
return (
4142
<OraclesWrapper>
42-
{tokenA.ngAssetType === 1 && tokenA.address !== '' && (
43+
{tokenA.ngAssetType === NG_ASSET_TYPE.ORACLE && tokenA.address !== '' && (
4344
<OracleTokenSummary chainId={chainId} token={tokenA} title={t`Token A`} />
4445
)}
45-
{tokenB.ngAssetType === 1 && tokenB.address !== '' && (
46+
{tokenB.ngAssetType === NG_ASSET_TYPE.ORACLE && tokenB.address !== '' && (
4647
<OracleTokenSummary chainId={chainId} token={tokenB} title={t`Token B`} />
4748
)}
48-
{tokenC.ngAssetType === 1 && tokenC.address !== '' && (
49+
{tokenC.ngAssetType === NG_ASSET_TYPE.ORACLE && tokenC.address !== '' && (
4950
<OracleTokenSummary chainId={chainId} token={tokenC} title={t`Token C`} />
5051
)}
51-
{tokenD.ngAssetType === 1 && tokenD.address !== '' && (
52+
{tokenD.ngAssetType === NG_ASSET_TYPE.ORACLE && tokenD.address !== '' && (
5253
<OracleTokenSummary chainId={chainId} token={tokenD} title={t`Token D`} />
5354
)}
54-
{tokenD.ngAssetType === 1 && tokenE.address !== '' && (
55+
{tokenD.ngAssetType === NG_ASSET_TYPE.ORACLE && tokenE.address !== '' && (
5556
<OracleTokenSummary chainId={chainId} token={tokenE} title={t`Token E`} />
5657
)}
57-
{tokenD.ngAssetType === 1 && tokenF.address !== '' && (
58+
{tokenD.ngAssetType === NG_ASSET_TYPE.ORACLE && tokenF.address !== '' && (
5859
<OracleTokenSummary chainId={chainId} token={tokenF} title={t`Token F`} />
5960
)}
60-
{tokenD.ngAssetType === 1 && tokenG.address !== '' && (
61+
{tokenD.ngAssetType === NG_ASSET_TYPE.ORACLE && tokenG.address !== '' && (
6162
<OracleTokenSummary chainId={chainId} token={tokenG} title={t`Token G`} />
6263
)}
63-
{tokenD.ngAssetType === 1 && tokenH.address !== '' && (
64+
{tokenD.ngAssetType === NG_ASSET_TYPE.ORACLE && tokenH.address !== '' && (
6465
<OracleTokenSummary chainId={chainId} token={tokenH} title={t`Token H`} />
6566
)}
6667
</OraclesWrapper>

apps/main/src/dex/components/PageCreatePool/Summary/TokensInPoolSummary.tsx

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { styled } from 'styled-components'
2-
import { STABLESWAP } from '@/dex/components/PageCreatePool/constants'
32
import {
3+
STABLESWAP,
44
TOKEN_A,
55
TOKEN_B,
66
TOKEN_C,
@@ -9,6 +9,7 @@ import {
99
TOKEN_F,
1010
TOKEN_G,
1111
TOKEN_H,
12+
NG_ASSET_TYPE,
1213
} from '@/dex/components/PageCreatePool/constants'
1314
import OracleSummary from '@/dex/components/PageCreatePool/Summary/OracleSummary'
1415
import {
@@ -208,10 +209,10 @@ const TokenSummary = ({ blockchainId, token, chainId, swapType }: TokenSummary)
208209
</TokenSymbol>
209210
{swapType === STABLESWAP && network.stableswapFactory && (
210211
<TokenType>
211-
{token.ngAssetType === 0 && t`Standard`}
212-
{token.ngAssetType === 1 && t`Oracle`}
213-
{token.ngAssetType === 2 && t`Rebasing`}
214-
{token.ngAssetType === 3 && t`ERC4626`}
212+
{token.ngAssetType === NG_ASSET_TYPE.STANDARD && t`Standard`}
213+
{token.ngAssetType === NG_ASSET_TYPE.ORACLE && t`Oracle`}
214+
{token.ngAssetType === NG_ASSET_TYPE.REBASING && t`Rebasing`}
215+
{token.ngAssetType === NG_ASSET_TYPE.ERC4626 && t`ERC4626`}
215216
</TokenType>
216217
)}
217218
</Box>

apps/main/src/dex/components/PageCreatePool/TokensInPool/SelectToken.tsx

Lines changed: 27 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import {
1111
TOKEN_F,
1212
TOKEN_G,
1313
TOKEN_H,
14+
NG_ASSET_TYPE,
1415
} from '@/dex/components/PageCreatePool/constants'
1516
import {
1617
CreateToken,
@@ -27,6 +28,7 @@ import Button from '@ui/Button'
2728
import Checkbox from '@ui/Checkbox'
2829
import Icon from '@ui/Icon'
2930
import { t } from '@ui-kit/lib/i18n'
31+
import WarningBox from '../components/WarningBox'
3032
import SelectTokenButton from './SelectTokenButton'
3133

3234
type Props = {
@@ -116,28 +118,31 @@ const SelectToken = ({
116118
onSelectionChange={(value: Key) => handleInpChange(tokenId, value as string, tokensInPool)}
117119
/>
118120
{swapType === STABLESWAP && (network.stableswapFactory || network.stableswapFactoryOld) && !token.basePool && (
119-
<StableSwapTogglesRow>
120-
<StyledCheckbox
121-
isSelected={token.ngAssetType === 0}
122-
onChange={() => updateNgAssetType(tokenId, 0)}
123-
isDisabled={false}
124-
>{t`Standard`}</StyledCheckbox>
125-
<StyledCheckbox
126-
isSelected={token.ngAssetType === 1}
127-
isDisabled={false}
128-
onChange={() => updateNgAssetType(tokenId, 1)}
129-
>{t`Oracle`}</StyledCheckbox>
130-
<StyledCheckbox
131-
isSelected={token.ngAssetType === 2}
132-
onChange={() => updateNgAssetType(tokenId, 2)}
133-
isDisabled={false}
134-
>{t`Rebasing`}</StyledCheckbox>
135-
<StyledCheckbox
136-
isSelected={token.ngAssetType === 3}
137-
isDisabled={false}
138-
onChange={() => updateNgAssetType(tokenId, 3)}
139-
>{t`ERC4626`}</StyledCheckbox>
140-
</StableSwapTogglesRow>
121+
<>
122+
<StableSwapTogglesRow>
123+
<StyledCheckbox
124+
isSelected={token.ngAssetType === NG_ASSET_TYPE.STANDARD}
125+
onChange={() => updateNgAssetType(tokenId, NG_ASSET_TYPE.STANDARD)}
126+
>{t`Standard`}</StyledCheckbox>
127+
<StyledCheckbox
128+
isSelected={token.ngAssetType === NG_ASSET_TYPE.ORACLE}
129+
onChange={() => updateNgAssetType(tokenId, NG_ASSET_TYPE.ORACLE)}
130+
>{t`Oracle`}</StyledCheckbox>
131+
<StyledCheckbox
132+
isSelected={token.ngAssetType === NG_ASSET_TYPE.REBASING}
133+
onChange={() => updateNgAssetType(tokenId, NG_ASSET_TYPE.REBASING)}
134+
>{t`Rebasing`}</StyledCheckbox>
135+
<StyledCheckbox
136+
isSelected={token.ngAssetType === NG_ASSET_TYPE.ERC4626}
137+
onChange={() => updateNgAssetType(tokenId, NG_ASSET_TYPE.ERC4626)}
138+
>{t`ERC4626`}</StyledCheckbox>
139+
</StableSwapTogglesRow>
140+
{token.erc4626.isErc4626 && token.ngAssetType !== NG_ASSET_TYPE.ERC4626 && (
141+
<WarningBox
142+
message={t`${token.symbol} is identified as an ERC4626 token, please select ERC4626 as the asset type.`}
143+
/>
144+
)}
145+
</>
141146
)}
142147
</TokenPickerContainer>
143148
)

apps/main/src/dex/components/PageCreatePool/TokensInPool/SetOracle.tsx

Lines changed: 16 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import {
1212
TOKEN_F,
1313
TOKEN_G,
1414
TOKEN_H,
15+
NG_ASSET_TYPE,
1516
} from '@/dex/components/PageCreatePool/constants'
1617
import type { TokenState, TokenId } from '@/dex/components/PageCreatePool/types'
1718
import { validateOracleFunction } from '@/dex/components/PageCreatePool/utils'
@@ -26,41 +27,24 @@ type OracleInputProps = {
2627
}
2728

2829
const SetOracle = () => {
29-
const tokenA = useStore((state) => state.createPool.tokensInPool.tokenA)
30-
const tokenB = useStore((state) => state.createPool.tokensInPool.tokenB)
31-
const tokenC = useStore((state) => state.createPool.tokensInPool.tokenC)
32-
const tokenD = useStore((state) => state.createPool.tokensInPool.tokenD)
33-
const tokenE = useStore((state) => state.createPool.tokensInPool.tokenE)
34-
const tokenF = useStore((state) => state.createPool.tokensInPool.tokenF)
35-
const tokenG = useStore((state) => state.createPool.tokensInPool.tokenG)
36-
const tokenH = useStore((state) => state.createPool.tokensInPool.tokenH)
30+
const tokens = useStore((state) => state.createPool.tokensInPool)
31+
32+
const oracleTokens: { token: TokenState; tokenId: TokenId; title: string }[] = [
33+
{ token: tokens.tokenA, tokenId: TOKEN_A as TokenId, title: t`Token A` },
34+
{ token: tokens.tokenB, tokenId: TOKEN_B as TokenId, title: t`Token B` },
35+
{ token: tokens.tokenC, tokenId: TOKEN_C as TokenId, title: t`Token C` },
36+
{ token: tokens.tokenD, tokenId: TOKEN_D as TokenId, title: t`Token D` },
37+
{ token: tokens.tokenE, tokenId: TOKEN_E as TokenId, title: t`Token E` },
38+
{ token: tokens.tokenF, tokenId: TOKEN_F as TokenId, title: t`Token F` },
39+
{ token: tokens.tokenG, tokenId: TOKEN_G as TokenId, title: t`Token G` },
40+
{ token: tokens.tokenH, tokenId: TOKEN_H as TokenId, title: t`Token H` },
41+
].filter(({ token }) => token.ngAssetType === NG_ASSET_TYPE.ORACLE && token.address !== '')
3742

3843
return (
3944
<OracleWrapper>
40-
{tokenA.ngAssetType === 1 && tokenA.address !== '' && (
41-
<OracleInputs token={tokenA} tokenId={TOKEN_A} title={t`Token A`} />
42-
)}
43-
{tokenB.ngAssetType === 1 && tokenB.address !== '' && (
44-
<OracleInputs token={tokenB} tokenId={TOKEN_B} title={t`Token B`} />
45-
)}
46-
{tokenC.ngAssetType === 1 && tokenC.address !== '' && (
47-
<OracleInputs token={tokenC} tokenId={TOKEN_C} title={t`Token C`} />
48-
)}
49-
{tokenD.ngAssetType === 1 && tokenD.address !== '' && (
50-
<OracleInputs token={tokenD} tokenId={TOKEN_D} title={t`Token D`} />
51-
)}
52-
{tokenD.ngAssetType === 1 && tokenD.address !== '' && (
53-
<OracleInputs token={tokenE} tokenId={TOKEN_E} title={t`Token E`} />
54-
)}
55-
{tokenD.ngAssetType === 1 && tokenD.address !== '' && (
56-
<OracleInputs token={tokenF} tokenId={TOKEN_F} title={t`Token F`} />
57-
)}
58-
{tokenD.ngAssetType === 1 && tokenD.address !== '' && (
59-
<OracleInputs token={tokenG} tokenId={TOKEN_G} title={t`Token G`} />
60-
)}
61-
{tokenD.ngAssetType === 1 && tokenD.address !== '' && (
62-
<OracleInputs token={tokenH} tokenId={TOKEN_H} title={t`Token H`} />
63-
)}
45+
{oracleTokens.map(({ token, tokenId, title }) => (
46+
<OracleInputs key={tokenId} token={token} tokenId={tokenId} title={title} />
47+
))}
6448
</OracleWrapper>
6549
)
6650
}

apps/main/src/dex/components/PageCreatePool/TokensInPool/index.tsx

Lines changed: 29 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,9 @@ import {
1515
TOKEN_G,
1616
TOKEN_H,
1717
FXSWAP,
18+
NG_ASSET_TYPE,
1819
} from '@/dex/components/PageCreatePool/constants'
20+
import { useAutoDetectErc4626 } from '@/dex/components/PageCreatePool/hooks/useAutoDetectErc4626'
1921
import SelectToken from '@/dex/components/PageCreatePool/TokensInPool/SelectToken'
2022
import SetOracle from '@/dex/components/PageCreatePool/TokensInPool/SetOracle'
2123
import { CreateToken, TokenId, TokensInPoolState } from '@/dex/components/PageCreatePool/types'
@@ -47,11 +49,12 @@ const TokensInPool = ({ curve, chainId, haveSigner }: Props) => {
4749
const updateTokensInPool = useStore((state) => state.createPool.updateTokensInPool)
4850
const updateTokenAmount = useStore((state) => state.createPool.updateTokenAmount)
4951
const updateSwapType = useStore((state) => state.createPool.updateSwapType)
52+
const updateNgAssetType = useStore((state) => state.createPool.updateNgAssetType)
5053
const basePools = useStore((state) => state.pools.basePools[chainId]) ?? DEFAULT_POOLS
5154
const userBalances = useStore((state) => state.userBalances.userBalancesMapper)
5255
const { tokensMapper } = useTokensMapper(chainId)
5356
const nativeToken = curve.getNetworkConstants().NATIVE_TOKEN
54-
57+
const { scheduleCheck: scheduleErc4626Check } = useAutoDetectErc4626({ tokensInPool })
5558
const {
5659
data: { createDisabledTokens, stableswapFactory, tricryptoFactory, twocryptoFactory },
5760
} = useNetworkByChain({ chainId })
@@ -99,7 +102,15 @@ const TokensInPool = ({ curve, chainId, haveSigner }: Props) => {
99102

100103
const handleInpChange = useCallback(
101104
(name: TokenId, value: string, tokensInPoolState: TokensInPoolState) => {
102-
if (!value.startsWith('0x')) return
105+
const normalizedValue = value.toLowerCase()
106+
107+
if (!normalizedValue.startsWith('0x')) return
108+
const previousAddress = tokensInPoolState[name].address.toLowerCase()
109+
110+
if (normalizedValue === previousAddress) return
111+
112+
// reset the ngAssetType to Standard by default
113+
updateNgAssetType(name, NG_ASSET_TYPE.STANDARD)
103114

104115
const basePoolCoins: string[] = getBasepoolCoins(
105116
value,
@@ -144,7 +155,7 @@ const TokensInPool = ({ curve, chainId, haveSigner }: Props) => {
144155
...updatedFormValues,
145156
[TOKEN_A]: {
146157
...updatedFormValues[TOKEN_A],
147-
ngAssetType: 0,
158+
ngAssetType: NG_ASSET_TYPE.STANDARD,
148159
address: value,
149160
basePool: true,
150161
},
@@ -163,7 +174,7 @@ const TokensInPool = ({ curve, chainId, haveSigner }: Props) => {
163174
...updatedFormValues,
164175
[TOKEN_A]: {
165176
...updatedFormValues[TOKEN_A],
166-
ngAssetType: 0,
177+
ngAssetType: NG_ASSET_TYPE.STANDARD,
167178
symbol: findSymbol(value),
168179
address: value,
169180
basePool: true,
@@ -217,7 +228,7 @@ const TokensInPool = ({ curve, chainId, haveSigner }: Props) => {
217228
...updatedFormValues,
218229
[TOKEN_B]: {
219230
...updatedFormValues[TOKEN_B],
220-
ngAssetType: 0,
231+
ngAssetType: NG_ASSET_TYPE.STANDARD,
221232
address: value,
222233
symbol: findSymbol(value),
223234
basePool: true,
@@ -237,7 +248,7 @@ const TokensInPool = ({ curve, chainId, haveSigner }: Props) => {
237248
...updatedFormValues,
238249
[TOKEN_B]: {
239250
...updatedFormValues[TOKEN_B],
240-
ngAssetType: 0,
251+
ngAssetType: NG_ASSET_TYPE.STANDARD,
241252
address: value,
242253
symbol: findSymbol(value),
243254
basePool: true,
@@ -291,7 +302,7 @@ const TokensInPool = ({ curve, chainId, haveSigner }: Props) => {
291302
...updatedFormValues,
292303
[TOKEN_A]: {
293304
...updatedFormValues[TOKEN_A],
294-
ngAssetType: 0,
305+
ngAssetType: NG_ASSET_TYPE.STANDARD,
295306
address: value,
296307
symbol: findSymbol(value),
297308
basePool: true,
@@ -327,7 +338,7 @@ const TokensInPool = ({ curve, chainId, haveSigner }: Props) => {
327338
...updatedFormValues,
328339
[TOKEN_A]: {
329340
...updatedFormValues[TOKEN_A],
330-
ngAssetType: 0,
341+
ngAssetType: NG_ASSET_TYPE.STANDARD,
331342
address: value,
332343
symbol: findSymbol(value),
333344
basePool: true,
@@ -363,7 +374,7 @@ const TokensInPool = ({ curve, chainId, haveSigner }: Props) => {
363374
...updatedFormValues,
364375
[TOKEN_A]: {
365376
...updatedFormValues[TOKEN_A],
366-
ngAssetType: 0,
377+
ngAssetType: NG_ASSET_TYPE.STANDARD,
367378
address: value,
368379
symbol: findSymbol(value),
369380
basePool: true,
@@ -399,7 +410,7 @@ const TokensInPool = ({ curve, chainId, haveSigner }: Props) => {
399410
...updatedFormValues,
400411
[TOKEN_A]: {
401412
...updatedFormValues[TOKEN_A],
402-
ngAssetType: 0,
413+
ngAssetType: NG_ASSET_TYPE.STANDARD,
403414
address: value,
404415
symbol: findSymbol(value),
405416
basePool: true,
@@ -435,7 +446,7 @@ const TokensInPool = ({ curve, chainId, haveSigner }: Props) => {
435446
...updatedFormValues,
436447
[TOKEN_A]: {
437448
...updatedFormValues[TOKEN_A],
438-
ngAssetType: 0,
449+
ngAssetType: NG_ASSET_TYPE.STANDARD,
439450
address: value,
440451
symbol: findSymbol(value),
441452
basePool: true,
@@ -471,7 +482,7 @@ const TokensInPool = ({ curve, chainId, haveSigner }: Props) => {
471482
...updatedFormValues,
472483
[TOKEN_A]: {
473484
...updatedFormValues[TOKEN_A],
474-
ngAssetType: 0,
485+
ngAssetType: NG_ASSET_TYPE.STANDARD,
475486
address: value,
476487
symbol: findSymbol(value),
477488
basePool: true,
@@ -511,8 +522,12 @@ const TokensInPool = ({ curve, chainId, haveSigner }: Props) => {
511522
updatedFormValues[TOKEN_G],
512523
updatedFormValues[TOKEN_H],
513524
)
525+
526+
if (updatedFormValues[name].address.toLowerCase() === normalizedValue) {
527+
scheduleErc4626Check(name, value)
528+
}
514529
},
515-
[tokensInPool, updateTokensInPool, curve, findSymbol, swapType, basePools],
530+
[tokensInPool, updateTokensInPool, curve, findSymbol, swapType, basePools, updateNgAssetType, scheduleErc4626Check],
516531
)
517532

518533
const addToken = useCallback(() => {
@@ -538,7 +553,7 @@ const TokensInPool = ({ curve, chainId, haveSigner }: Props) => {
538553
...tokensInPoolState[token],
539554
address: tokenId === token ? '' : tokensInPoolState[token].address,
540555
symbol: tokenId === token ? '' : tokensInPoolState[token].symbol,
541-
ngAssetType: tokenId === token ? 0 : tokensInPoolState[token].ngAssetType,
556+
ngAssetType: tokenId === token ? NG_ASSET_TYPE.STANDARD : tokensInPoolState[token].ngAssetType,
542557
oracleAddress: tokenId === token ? '' : tokensInPoolState[token].oracleAddress,
543558
oracleFunction: tokenId === token ? '' : tokensInPoolState[token].oracleFunction,
544559
})

apps/main/src/dex/components/PageCreatePool/constants.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import BigNumber from 'bignumber.js'
22
import { t } from '@ui-kit/lib/i18n'
3+
import type { NgAssetType } from './types'
34

45
export const CRYPTOSWAP = 'Cryptoswap'
56
export const STABLESWAP = 'Stableswap'
@@ -35,6 +36,13 @@ export type PRESETS = {
3536
}
3637
}
3738

39+
export const NG_ASSET_TYPE: Record<string, NgAssetType> = {
40+
STANDARD: 0,
41+
ORACLE: 1,
42+
REBASING: 2,
43+
ERC4626: 3,
44+
}
45+
3846
const fillerParams = {
3947
stableSwapFee: '',
4048
stableA: '',

0 commit comments

Comments
 (0)