From ee54a98ee92b3ca65338b70443b7970f575624a7 Mon Sep 17 00:00:00 2001 From: brucedonovan Date: Tue, 19 Apr 2022 09:15:40 +0100 Subject: [PATCH 001/109] merge tokenwrapping PR --- src/components/views/VaultPosition.tsx | 4 +- src/config/assets.ts | 50 +++++++------ src/contexts/ChainContext.tsx | 32 ++++++--- src/hooks/actionHooks/useAddCollateral.ts | 39 ++++++----- src/hooks/actionHooks/useAddRemoveEth.ts | 4 +- src/hooks/actionHooks/useBorrow.ts | 51 +++++++++----- src/hooks/actionHooks/useRemoveCollateral.ts | 38 ++++------ src/hooks/actionHooks/useRepayDebt.ts | 74 ++++++++++++++------ src/hooks/actionHooks/useWrapUnwrapAsset.ts | 45 +++++++----- src/hooks/useApr.ts | 2 +- src/types/index.ts | 34 ++++----- 11 files changed, 221 insertions(+), 152 deletions(-) diff --git a/src/components/views/VaultPosition.tsx b/src/components/views/VaultPosition.tsx index 6ebce77c2..bfc10cdaa 100644 --- a/src/components/views/VaultPosition.tsx +++ b/src/components/views/VaultPosition.tsx @@ -269,7 +269,9 @@ const VaultPosition = () => { const _series = seriesMap.get(_selectedVault?.seriesId!) || null; const _base = assetMap.get(_selectedVault?.baseId!) || null; const _ilk = assetMap.get(_selectedVault?.ilkId!) || null; - const _ilkToUse = _ilk?.isWrappedToken && _ilk.unwrappedTokenId ? assetMap.get(_ilk.unwrappedTokenId) : _ilk; // use the unwrapped token if applicable + + // handle using ilk + const _ilkToUse = _ilk; // use the unwrapped token if applicable _selectedVault && setSelectedSeries(_series); _selectedVault && setSelectedBase(_base); diff --git a/src/config/assets.ts b/src/config/assets.ts index d533a4441..d91514bda 100644 --- a/src/config/assets.ts +++ b/src/config/assets.ts @@ -75,10 +75,11 @@ ASSET_INFO.set(UNKNOWN, { decimals: 18, symbol: 'UNKNOWN', showToken: false, - isWrappedToken: false, + // isWrappedToken: false, color: '#FFFFFFFF', digitFormat: 2, tokenType: TokenType.ERC20_, + }); ASSET_INFO.set(DAI, { @@ -87,7 +88,7 @@ ASSET_INFO.set(DAI, { decimals: 18, symbol: 'DAI', showToken: true, - isWrappedToken: false, + // isWrappedToken: false, color: '#F5AC37', digitFormat: 2, tokenType: TokenType.ERC20_DaiPermit, @@ -99,7 +100,7 @@ ASSET_INFO.set(USDC, { decimals: 18, symbol: 'USDC', showToken: true, - isWrappedToken: false, + // isWrappedToken: false, color: '#2775CA', digitFormat: 2, tokenType: TokenType.ERC20_Permit, @@ -111,7 +112,7 @@ ASSET_INFO.set(WBTC, { decimals: 18, symbol: 'WBTC', showToken: true, - isWrappedToken: false, + // isWrappedToken: false, color: '#5A5564', digitFormat: 6, tokenType: TokenType.ERC20_, @@ -123,7 +124,7 @@ ASSET_INFO.set(ENS, { decimals: 18, symbol: 'ENS', showToken: true, - isWrappedToken: false, + // isWrappedToken: false, color: '#000000', digitFormat: 2, tokenType: TokenType.ERC20_Permit, @@ -136,7 +137,7 @@ ASSET_INFO.set(WETH, { symbol: 'WETH', displaySymbol: 'ETH', showToken: true, - isWrappedToken: false, + // isWrappedToken: false, color: '#FFFFFF', digitFormat: 6, tokenType: TokenType.ERC20_, @@ -149,14 +150,18 @@ ASSET_INFO.set(wstETH, { symbol: 'wstETH', displaySymbol: 'wstETH', showToken: true, - isWrappedToken: true, - wrapHandlerAddress: '', - wrappedTokenId: '', - wrappedTokenAddress: '', + // isWrappedToken: true, + // wrapHandlerAddress: undefined, + // unwrapHandlerAddress: '0x491aB93faa921C8E634F891F96512Be14fD3DbB1', + // linkedAsset: '0x303500000000', + // wrappedTokenId: '', color: '#00A3FF', digitFormat: 6, - unwrappedTokenId: '0x303500000000', + // unwrappedTokenId: '0x303500000000', tokenType: TokenType.ERC20_Permit, + + wrapHandlerAddresses:new Map([]), + unwrapHandlerAddresses:new Map([[4,'0x491aB93faa921C8E634F891F96512Be14fD3DbB1'], ]) }); ASSET_INFO.set(stETH, { @@ -165,14 +170,17 @@ ASSET_INFO.set(stETH, { decimals: 18, symbol: 'stETH', showToken: false, - isWrappedToken: false, - wrapHandlerAddress: '0x491aB93faa921C8E634F891F96512Be14fD3DbB1', - wrappedTokenId: '0x303400000000', - wrappedTokenAddress: '0xB12C63eD91e901995E68023293AC1A308ffA6c3c', + // wrapHandlerAddress: '0x491aB93faa921C8E634F891F96512Be14fD3DbB1', + // unwrapHandlerAddress: undefined, + // wrappedTokenId: '0x303400000000', color: '#00A3FF', digitFormat: 6, - unwrappedTokenId: '0x303500000000', + // unwrappedTokenId: '0x303500000000', tokenType: TokenType.ERC20_Permit, + + // proxyId: '0x303500000000', + wrapHandlerAddresses:new Map([[4,'0x491aB93faa921C8E634F891F96512Be14fD3DbB1'], ]), + unwrapHandlerAddresses:new Map([]) }); ASSET_INFO.set(LINK, { @@ -181,7 +189,6 @@ ASSET_INFO.set(LINK, { decimals: 18, symbol: 'LINK', showToken: true, - isWrappedToken: false, color: '#2A5ADA', digitFormat: 6, tokenType: TokenType.ERC20_, @@ -193,7 +200,6 @@ ASSET_INFO.set(yvUSDC, { decimals: 18, symbol: 'yvUSDC', showToken: true, - isWrappedToken: false, color: '#3366CC', digitFormat: 2, tokenType: TokenType.ERC20_, @@ -206,7 +212,6 @@ ASSET_INFO.set(UNI, { decimals: 18, symbol: 'UNI', showToken: true, - isWrappedToken: false, color: '#FF007A', digitFormat: 6, tokenType: TokenType.ERC20_Permit, @@ -218,7 +223,6 @@ ASSET_INFO.set(MKR, { decimals: 18, symbol: 'MKR', showToken: false, - isWrappedToken: false, color: '#FF007A', digitFormat: 6, tokenType: TokenType.ERC20_MKR, @@ -230,7 +234,6 @@ ASSET_INFO.set(FDAI2203, { decimals: 8, symbol: 'FDAI2203', showToken: false, - isWrappedToken: false, color: '#FF007A', digitFormat: 6, tokenType: TokenType.ERC1155_, @@ -244,7 +247,6 @@ ASSET_INFO.set(FUSDC2203, { decimals: 8, symbol: 'FUSDC2203', showToken: false, - isWrappedToken: false, color: '#FF007A', digitFormat: 6, tokenType: TokenType.ERC1155_, @@ -258,7 +260,6 @@ ASSET_INFO.set(FDAI2206, { decimals: 8, symbol: 'FDAI2206', showToken: true, - isWrappedToken: false, color: '#FF007A', digitFormat: 6, tokenType: TokenType.ERC1155_, @@ -272,7 +273,6 @@ ASSET_INFO.set(FUSDC2206, { decimals: 8, symbol: 'FUSDC2206', showToken: true, - isWrappedToken: false, color: '#FF007A', digitFormat: 6, tokenType: TokenType.ERC1155_, @@ -286,7 +286,6 @@ ASSET_INFO.set(FDAI2209, { decimals: 8, symbol: 'FDAI2209', showToken: true, - isWrappedToken: false, color: '#FF007A', digitFormat: 6, tokenType: TokenType.ERC1155_, @@ -300,7 +299,6 @@ ASSET_INFO.set(FUSDC2209, { decimals: 8, symbol: 'FUSDC2209', showToken: true, - isWrappedToken: false, color: '#FF007A', digitFormat: 6, tokenType: TokenType.ERC1155_, diff --git a/src/contexts/ChainContext.tsx b/src/contexts/ChainContext.tsx index 0a9f8dd12..cc16c4acc 100644 --- a/src/contexts/ChainContext.tsx +++ b/src/contexts/ChainContext.tsx @@ -337,11 +337,13 @@ const ChainProvider = ({ children }: any) => { assetsAdded.map(async (x) => { const { assetId: id, asset: address } = x; - /* Get the basic hardcoded token info */ - const assetInfo = ASSET_INFO.has(id) ? ASSET_INFO.get(id) : ASSET_INFO.get(UNKNOWN); + /* Get the basic hardcoded token info, if tooken is known, else get 'UNKNOWN' token */ + const assetInfo = ASSET_INFO.has(id) + ? (ASSET_INFO.get(id) as IAssetInfo) + : (ASSET_INFO.get(UNKNOWN) as IAssetInfo); let { name, symbol, decimals, version } = assetInfo; - /* On first load Checks/Corrects the ERC20 name/symbol/decimals (if possible ) */ + /* On first load checks & corrects the ERC20 name/symbol/decimals (if possible ) */ if ( assetInfo.tokenType === TokenType.ERC20_ || assetInfo.tokenType === TokenType.ERC20_Permit || @@ -358,7 +360,7 @@ const ChainProvider = ({ children }: any) => { } } - /* Checks/Corrects the version for ERC20Permit tokens */ + /* checks & corrects the version for ERC20Permit/ DAI permit tokens */ if (assetInfo.tokenType === TokenType.ERC20_Permit || assetInfo.tokenType === TokenType.ERC20_DaiPermit) { const contract = contracts.ERC20Permit__factory.connect(address, fallbackProvider); try { @@ -366,12 +368,22 @@ const ChainProvider = ({ children }: any) => { } catch (e) { console.log( address, - ': contract version auto-validation unsuccessfull. Please manually ensure version is correct.' + ': contract VERSION auto-validation unsuccessfull. Please manually ensure version is correct.' ); } } - const idToUse = assetInfo?.wrappedTokenId || id; // here we are using the unwrapped id + // const idToUse = assetInfo?.wrappedTokenId || id; // here we are using the unwrapped id + const idToUse = id; // here we are using the unwrapped id + + /* check if a unwrapping handler is provided, if so, the token is considered to be a wrpaped token */ + const isWrappedToken = + assetInfo.unwrapHandlerAddresses && assetInfo.unwrapHandlerAddresses.has(chainId as number); + + /* check if a wrapping handler is provided, if so, wrapping is required */ + const wrappingRequired = + assetInfo.wrapHandlerAddresses && assetInfo.wrapHandlerAddresses.has(chainId as number); + // const unwrappingRequired = assetInfo.wrapHandlerAddresses && assetInfo.wrapHandlerAddresses.has(chainId as number); const newAsset = { ...assetInfo, @@ -382,11 +394,15 @@ const ChainProvider = ({ children }: any) => { decimals, version, - /* redirect the id/join if required due to using wrapped tokens */ + /* Redirect the id/join if required due to using wrapped tokens */ joinAddress: joinMap.get(idToUse), idToUse, - /* default setting of assetInfo fields if required */ + isWrappedToken, + wrappingRequired, + // unwrappingRequired, + + /* Default setting of assetInfo fields if required */ displaySymbol: assetInfo.displaySymbol || symbol, showToken: assetInfo.showToken || false, }; diff --git a/src/hooks/actionHooks/useAddCollateral.ts b/src/hooks/actionHooks/useAddCollateral.ts index c905f35f1..41f90c78a 100644 --- a/src/hooks/actionHooks/useAddCollateral.ts +++ b/src/hooks/actionHooks/useAddCollateral.ts @@ -34,8 +34,7 @@ export const useAddCollateral = () => { const { updateAssets, updateVaults } = userActions; const { sign, transact } = useChain(); - const { wrapAssetToJoin } = useWrapUnwrapAsset(); - + const { wrapAsset } = useWrapUnwrapAsset(); const { addEth } = useAddRemoveEth(); const addCollateral = async (vault: IVault | undefined, input: string) => { @@ -44,10 +43,6 @@ export const useAddCollateral = () => { /* set the ilk based on if a vault has been selected or it's a new vault */ const ilk: IAsset | null | undefined = vault ? assetMap.get(vault.ilkId) : selectedIlk; - - const ilkForWrap: IAsset | null | undefined = - ilk?.isWrappedToken && ilk.unwrappedTokenId ? assetMap.get(ilk.unwrappedTokenId) : selectedIlk; // use the unwrapped token as ilk - const base: IAsset | null | undefined = vault ? assetMap.get(vault.baseId) : selectedBase; const ladleAddress = contractMap.get('Ladle').address; @@ -62,26 +57,34 @@ export const useAddCollateral = () => { const _isEthCollateral = ETH_BASED_ASSETS.includes(ilk?.id!); const _pourTo = _isEthCollateral ? ladleAddress : account; - /* handle wrapped tokens: */ - const wrapping: ICallData[] = await wrapAssetToJoin(_input, ilkForWrap!, txCode); // note: selected ilk used here, not wrapped version - /* if approveMAx, check if signature is required : note: getAllowance may return FALSE if ERC1155 */ const _allowance = await ilk?.getAllowance(account!, ilk.joinAddress); const alreadyApproved = ethers.BigNumber.isBigNumber(_allowance) ? _allowance.gte(_input) : _allowance; + /* handle wrapped tokens: */ + const wrapAssetCallData: ICallData[] = await wrapAsset(_input, ilk!, txCode); + /* Gather all the required signatures - sign() processes them and returns them as ICallData types */ - const permits: ICallData[] = await sign( + const permitCallData: ICallData[] = await sign( [ { target: ilk!, spender: ilk?.joinAddress!, amount: _input, - ignoreIf: _isEthCollateral || alreadyApproved === true || wrapping.length > 0, + /* ignore if: 1) collateral is ETH 2) approved already 3) wrapAssets call is > 0 (because the permit is handled with wrapping) */ + ignoreIf: _isEthCollateral || alreadyApproved === true || wrapAssetCallData.length > 0, }, ], txCode ); + /* Handle adding eth if required (ie. if the ilk is ETH_BASED). If not, else simply sent ZERO to the addEth fn */ + const addEthCallData: ICallData[] = addEth( + ETH_BASED_ASSETS.includes(selectedIlk?.idToUse!) ? _input : ZERO_BN, + undefined, + selectedIlk?.idToUse + ); + /** * BUILD CALL DATA ARRAY * */ @@ -92,14 +95,16 @@ export const useAddCollateral = () => { args: [selectedSeries?.id, selectedIlk?.idToUse, '0'] as LadleActions.Args.BUILD, ignoreIf: !!vault, // ignore if vault exists }, + /* handle wrapped token deposit, if required */ - ...wrapping, + ...wrapAssetCallData, - /* Handle adding eth if required (ie. if the ilk is ETH_BASED). If not, else simply sent ZERO to the addEth fn */ - ...addEth(ETH_BASED_ASSETS.includes(selectedIlk?.idToUse!) ? _input : ZERO_BN, undefined, selectedIlk?.idToUse), + /* add in add ETH calls */ + ...addEthCallData, /* handle permits if required */ - ...permits, + ...permitCallData, + { operation: LadleActions.Fn.POUR, args: [ @@ -114,8 +119,10 @@ export const useAddCollateral = () => { /* TRANSACT */ await transact(calls, txCode); + + /* then update UI */ updateVaults([vault!]); - updateAssets([base!, ilk!, ilkForWrap!]); + updateAssets([base!, ilk!]); }; return { addCollateral }; diff --git a/src/hooks/actionHooks/useAddRemoveEth.ts b/src/hooks/actionHooks/useAddRemoveEth.ts index b73105856..b024b4bc3 100644 --- a/src/hooks/actionHooks/useAddRemoveEth.ts +++ b/src/hooks/actionHooks/useAddRemoveEth.ts @@ -2,7 +2,6 @@ import { BigNumber } from 'ethers'; import { useContext } from 'react'; import { ChainContext } from '../../contexts/ChainContext'; import { UserContext } from '../../contexts/UserContext'; - import { ICallData, LadleActions, IUserContext, IUserContextState, IUserContextActions } from '../../types'; import { ModuleActions } from '../../types/operations'; import { ZERO_BN } from '../../utils/constants'; @@ -20,7 +19,6 @@ export const useAddRemoveEth = () => { const { activeAccount: account } = userState; const WrapEtherModuleContract = contractMap.get('WrapEtherModule'); - const addEth = ( value: BigNumber, to: string | undefined = undefined, @@ -48,7 +46,7 @@ export const useAddRemoveEth = () => { }, ] - // NOTE: EXIT_ETHER sweeps all out of the ladle, so *value* is not important > it must just be bigger than zero to not be ignored + // NOTE: EXIT_ETHER sweeps all out of the ladle, so *value* is not important > it must just be bigger than zero to not be ignored const removeEth = (value: BigNumber, to: string|undefined = undefined): ICallData[] => [ { operation: LadleActions.Fn.EXIT_ETHER, diff --git a/src/hooks/actionHooks/useBorrow.ts b/src/hooks/actionHooks/useBorrow.ts index c0ed0053b..80b956656 100644 --- a/src/hooks/actionHooks/useBorrow.ts +++ b/src/hooks/actionHooks/useBorrow.ts @@ -43,22 +43,27 @@ export const useBorrow = () => { const { addEth, removeEth } = useAddRemoveEth(); - const { wrapAssetToJoin } = useWrapUnwrapAsset(); + const { wrapAsset } = useWrapUnwrapAsset(); const { sign, transact } = useChain(); - const borrow = async (vault: IVault | undefined, input: string | undefined, collInput: string | undefined) => { + const borrow = async ( + vault: IVault | undefined, + input: string | undefined, + collInput: string | undefined, + getValuesFromNetwork: boolean = true // get market values by network call or offline calc (default: NETWORK) + ) => { /* generate the reproducible txCode for tx tracking and tracing */ const txCode = getTxCode(ActionCodes.BORROW, selectedSeries?.id!); /* use the vault id provided OR 0 if new/ not provided */ const vaultId = vault?.id || BLANK_VAULT; + const ladleAddress = contractMap.get('Ladle').address; + /* Set the series and ilk based on the vault that has been selected or if it's a new vault, get from the globally selected SeriesId */ const series: ISeries = vault ? seriesMap.get(vault.seriesId)! : selectedSeries!; const base: IAsset = assetMap.get(series.baseId)!; const ilk: IAsset = vault ? assetMap.get(vault.ilkId)! : assetMap.get(selectedIlk?.idToUse!)!; // note: we use the wrapped version if required - const ladleAddress = contractMap.get('Ladle').address; - /* is ETH used as collateral */ const isEthCollateral = ETH_BASED_ASSETS.includes(selectedIlk?.idToUse!); /* is ETH being Borrowed */ @@ -74,8 +79,10 @@ export const useBorrow = () => { const cleanCollInput = cleanValue(collInput, ilk.decimals); const _collInput = collInput ? ethers.utils.parseUnits(cleanCollInput, ilk.decimals) : ethers.constants.Zero; - /* Calculate expected debt (fytokens) */ - const _expectedFyToken = buyBase( + /* Calculate expected debt (fytokens) from either network or calculated */ + const _expectedFyToken = getValuesFromNetwork + ? await series.poolContract.buyBasePreview(_input) + : buyBase( series.baseReserves, series.fyTokenReserves, _input, @@ -89,13 +96,17 @@ export const useBorrow = () => { /* if approveMAx, check if signature is required : note: getAllowance may return FALSE if ERC1155 */ const _allowance = await ilk.getAllowance(account!, ilk.joinAddress); const alreadyApproved = ethers.BigNumber.isBigNumber(_allowance) ? _allowance.gte(_collInput) : _allowance; - - const wrapping: ICallData[] = await wrapAssetToJoin(_collInput, selectedIlk!, txCode); // note: selected ilk used here, not wrapped version - console.log('Already approved', alreadyApproved); + /* handle ETH deposit as Collateral, if required (only if collateral used is ETH-based ), else send ZERO_BN */ + const addEthCallData: ICallData[] = addEth(isEthCollateral ? _collInput : ZERO_BN); + /* handle remove/unwrap WETH > if ETH is what is being borrowed */ + const removeEthCallData: ICallData[] = removeEth(isEthBase ? ONE_BN : ZERO_BN); // (exit_ether sweeps all the eth out the ladle, so exact amount is not importnat -> just greater than zero) + /* handle wrapping of collateral if required */ + const wrapAssetCallData: ICallData[] = await wrapAsset(_collInput, selectedIlk!, txCode); // note: selected ilk used here, not wrapped version + /* Gather all the required signatures - sign() processes them and returns them as ICallData types */ - const permits: ICallData[] = await sign( + const permitCallData: ICallData[] = await sign( [ { target: ilk, @@ -105,19 +116,26 @@ export const useBorrow = () => { alreadyApproved === true || ETH_BASED_ASSETS.includes(selectedIlk?.idToUse!) || _collInput.eq(ethers.constants.Zero) || - wrapping.length > 0, + wrapAssetCallData.length > 0, }, ], txCode ); - /* Collate all the calls required for the process (including depositing ETH, signing permits, and building vault if needed) */ + /** + * + * Collate all the calls required for the process (including depositing ETH, signing permits, and building vault if needed) + * + * */ const calls: ICallData[] = [ /* handle wrapped token deposit, if required */ - ...wrapping, + ...wrapAssetCallData, /* Include all the signatures gathered, if required */ - ...permits, + ...permitCallData, + + /* add in the ETH deposit if required */ + ...addEthCallData, /* If vault is null, build a new vault, else ignore */ { @@ -150,11 +168,10 @@ export const useBorrow = () => { ignoreIf: false, // never ignore }, - /* handle remove/unwrap WETH > if ETH is what is being borrowed */ - ...removeEth(isEthBase ? ONE_BN : ZERO_BN), // (exit_ether sweeps all the eth out the ladle, so exact amount is not importnat -> just greater than zero) + ...removeEthCallData, ]; - /* handle the transaction */ + /* finally, handle the transaction */ await transact(calls, txCode); /* When complete, update vaults. diff --git a/src/hooks/actionHooks/useRemoveCollateral.ts b/src/hooks/actionHooks/useRemoveCollateral.ts index e4967e4a1..72cb6fba2 100644 --- a/src/hooks/actionHooks/useRemoveCollateral.ts +++ b/src/hooks/actionHooks/useRemoveCollateral.ts @@ -1,7 +1,6 @@ -import { BigNumber, ethers } from 'ethers'; +import { ethers } from 'ethers'; import { useContext } from 'react'; import { ChainContext } from '../../contexts/ChainContext'; -import { SettingsContext } from '../../contexts/SettingsContext'; import { UserContext } from '../../contexts/UserContext'; import { ICallData, @@ -11,7 +10,6 @@ import { IUserContext, IUserContextActions, IUserContextState, - ISettingsContext, } from '../../types'; import { cleanValue, getTxCode } from '../../utils/appUtils'; import { ETH_BASED_ASSETS } from '../../config/assets'; @@ -23,23 +21,19 @@ import { ONE_BN, ZERO_BN } from '../../utils/constants'; // TODO will fail if balance of join is less than amount export const useRemoveCollateral = () => { const { - chainState: { contractMap }, + chainState: { contractMap, connection : { chainId } }, } = useContext(ChainContext); const { userState, userActions }: { userState: IUserContextState; userActions: IUserContextActions } = useContext( UserContext ) as IUserContext; const { activeAccount: account, selectedIlk, assetMap } = userState; const { updateAssets, updateVaults } = userActions; - const { - settingsState: { unwrapTokens }, - } = useContext(SettingsContext) as ISettingsContext; - const { transact } = useChain(); - const { removeEth } = useAddRemoveEth(); const { unwrapAsset } = useWrapUnwrapAsset(); - const removeCollateral = async (vault: IVault, input: string) => { + const removeCollateral = async (vault: IVault, input: string, unwrapOnRemove: boolean = true ) => { + /* generate the txCode for tx tracking and tracing */ const txCode = getTxCode(ActionCodes.REMOVE_COLLATERAL, vault.id); @@ -47,36 +41,34 @@ export const useRemoveCollateral = () => { const ilk = assetMap.get(vault.ilkId)!; const ladleAddress = contractMap.get('Ladle').address; + const unwrapHandlerAddress = ilk.unwrapHandlerAddresses?.get(chainId); + /* parse inputs to BigNumber in Wei, and NEGATE */ const cleanedInput = cleanValue(input, ilk.decimals); - const _input = ethers.utils.parseUnits(cleanedInput, ilk.decimals).mul(-1); + const _input = ethers.utils.parseUnits(cleanedInput, ilk.decimals).mul(-1); // NOTE: negated value! /* check if the ilk/asset is an eth asset variety OR if it is wrapped token, if so pour to Ladle */ const isEthCollateral = ETH_BASED_ASSETS.includes(ilk.id); - // const isEthBase = ETH_BASED_ASSETS.includes(selectedIlk?.idToUse!); - - let _pourTo = isEthCollateral ? ladleAddress : account; + const _pourTo = isEthCollateral ? ladleAddress : account; /* handle wrapped tokens: */ - let unwrap: ICallData[] = []; - if (ilk.wrapHandlerAddress && unwrapTokens) { - _pourTo = ilk.wrapHandlerAddress; - unwrap = await unwrapAsset(ilk, account!); - } + const unwrappingCallData: ICallData[] = unwrapOnRemove ? await unwrapAsset(ilk, account!) : []; + const removeEthCallData: ICallData[] = removeEth(isEthCollateral ? ONE_BN : ZERO_BN) // (exit_ether sweeps all the eth out the ladle, so exact amount is not importnat -> just greater than zero) const calls: ICallData[] = [ { operation: LadleActions.Fn.POUR, args: [ vault.id, - _pourTo /* pour destination based on ilk/asset is an eth asset variety */, + /* pour destination based on ilk/asset is an eth asset variety ( or unwrapHadnler address if unwrapping) */ + unwrappingCallData.length ? unwrapHandlerAddress : _pourTo , _input, - ethers.constants.Zero, + ZERO_BN, ] as LadleActions.Args.POUR, ignoreIf: false, }, - ...removeEth(isEthCollateral ? ONE_BN : ZERO_BN), // (exit_ether sweeps all the eth out the ladle, so exact amount is not importnat -> just greater than zero) - ...unwrap, + ...removeEthCallData, + ...unwrappingCallData, ]; await transact(calls, txCode); diff --git a/src/hooks/actionHooks/useRepayDebt.ts b/src/hooks/actionHooks/useRepayDebt.ts index e596692d9..a26aee003 100644 --- a/src/hooks/actionHooks/useRepayDebt.ts +++ b/src/hooks/actionHooks/useRepayDebt.ts @@ -34,11 +34,10 @@ export const useRepayDebt = () => { const { updateVaults, updateAssets } = userActions; const { - chainState: { contractMap }, + chainState: { contractMap, connection:{ chainId } }, } = useContext(ChainContext); const { addEth, removeEth } = useAddRemoveEth(); - const { unwrapAsset } = useWrapUnwrapAsset(); const { sign, transact } = useChain(); @@ -97,14 +96,26 @@ export const useRepayDebt = () => { const isEthCollateral = ETH_BASED_ASSETS.includes(vault.ilkId); const isEthBase = ETH_BASED_ASSETS.includes(series.baseId); - /* address to send the funds to either ladle ( if eth is used as collateral ) or account */ - let reclaimToAddress = reclaimCollateral && isEthCollateral ? ladleAddress : account; - - /* handle wrapped tokens: */ - let unwrap: ICallData[] = []; - if (ilk.wrapHandlerAddress && unwrapTokens && reclaimCollateral) { - reclaimToAddress = ilk.wrapHandlerAddress; - unwrap = await unwrapAsset(ilk, account!); + const unwraphandlerAddress = ilk.unwrapHandlerAddresses?.get(chainId); + + // let reclaimToAddress = reclaimCollateral && isEthCollateral ? ladleAddress : account; + // /* handle wrapped tokens: */ + // let unwrap: ICallData[] = []; + // if (ilk.wrapHandlerAddress && unwrapTokens && reclaimCollateral) { + // reclaimToAddress = ilk.wrapHandlerAddress; + // unwrap = await unwrapAsset(ilk, account!); + // } + // if (isEthBase) { + // reclaimToAddress = ladleAddress; + // } + + /* logic to determine the 'to' Address to send the reclaimed funds */ + const getReclaimToAddress = () : string => { + if (unwraphandlerAddress && reclaimCollateral) return unwraphandlerAddress // if there is an unwrap handler send it there for unwrapping + if (!unwraphandlerAddress && reclaimCollateral && isEthCollateral) return ladleAddress // if no unwrap handler, and eth-based collateral send to ladle + // Eth is the base ( ) + if (!unwraphandlerAddress && isEthBase) return ladleAddress + return account!; } const alreadyApproved = !series.seriesIsMature && ( @@ -114,6 +125,7 @@ export const useRepayDebt = () => { ) ).gte(_input); + /* a bit hacky fix this logic */ const alreadyApprovedPostMaturity = series.seriesIsMature && ( await base.getAllowance( account!, @@ -121,7 +133,9 @@ export const useRepayDebt = () => { ) ).gte(_inputforClose.mul(2)); - const permits: ICallData[] = await sign( + const unwrapAssetCallData : ICallData[] = reclaimCollateral ? await unwrapAsset(ilk, account!): [] ; + + const permitCallData: ICallData[] = await sign( [ { // before maturity @@ -138,7 +152,7 @@ export const useRepayDebt = () => { ignoreIf: series.seriesIsMature || alreadyApproved === true || !inputGreaterThanMaxBaseIn, }, { - // after maturity + // After maturity target: base, spender: base.joinAddress, amount: MAX_256, @@ -148,17 +162,30 @@ export const useRepayDebt = () => { txCode ); - const calls: ICallData[] = [ - ...permits, + const addEthCallData = addEth(isEthBase && !inputGreaterThanMaxBaseIn ? _input : ZERO_BN, transferToAddress); + const removeEthCallData = removeEth(isEthCollateral ? ONE_BN : ZERO_BN); - /* BEFORE MATURITY - !series.seriesIsMature */ - ...addEth(isEthBase && !series.seriesIsMature ? _input : ZERO_BN, transferToAddress ), // destination = either join or series depending if tradeable + /** + * + * Collate the call data + * + * */ + const calls: ICallData[] = [ + + /* add in the the permit calls */ + ...permitCallData, + + /** + * + * BEFORE MATURITY + * + * */ + ...addEthCallData, /* the add eth calldata if repaying in ETH */ { operation: LadleActions.Fn.TRANSFER, args: [base.address, transferToAddress, _input] as LadleActions.Args.TRANSFER, ignoreIf: series.seriesIsMature || isEthBase, }, - { operation: LadleActions.Fn.REPAY, args: [vault.id, account, ethers.constants.Zero, _inputAsFyTokenWithSlippage] as LadleActions.Args.REPAY, @@ -170,17 +197,17 @@ export const useRepayDebt = () => { { operation: LadleActions.Fn.REPAY_VAULT, - args: [vault.id, reclaimToAddress, _collateralToRemove, _input] as LadleActions.Args.REPAY_VAULT, + args: [vault.id, getReclaimToAddress(), _collateralToRemove, _input] as LadleActions.Args.REPAY_VAULT, ignoreIf: series.seriesIsMature || !inputGreaterThanDebt || // use if input IS more than debt OR inputGreaterThanMaxBaseIn, }, - /* EdgeCase in lowLiq situations : Input GreaterThanMaxbaseIn */ + /* !! EDGECASE !! in lowLiq situations : Input GreaterThanMaxbaseIn */ { operation: LadleActions.Fn.CLOSE, - args: [vault.id, reclaimToAddress, _collateralToRemove, _input.mul(-1)] as LadleActions.Args.CLOSE, + args: [vault.id, getReclaimToAddress(), _collateralToRemove, _input.mul(-1)] as LadleActions.Args.CLOSE, ignoreIf: series.seriesIsMature || !inputGreaterThanMaxBaseIn, }, @@ -188,12 +215,13 @@ export const useRepayDebt = () => { /* No Transfer? */ { operation: LadleActions.Fn.CLOSE, - args: [vault.id, reclaimToAddress, _collateralToRemove, _inputforClose.mul(-1)] as LadleActions.Args.CLOSE, + args: [vault.id, getReclaimToAddress(), _collateralToRemove, _inputforClose.mul(-1)] as LadleActions.Args.CLOSE, ignoreIf: !series.seriesIsMature, }, - ...removeEth(isEthCollateral ? ONE_BN : ZERO_BN), // after the complete tranasction, this will remove all the ETH collateral (if requested). (exit_ether sweeps all the eth out of the ladle, so exact amount is not importnat -> just greater than zero) - ...unwrap, + // after the complete tranasction, this will remove all the ETH collateral (if requested). (exit_ether sweeps all the eth out of the ladle, so exact amount is not importnat -> just greater than zero) + ...removeEthCallData, + ...unwrapAssetCallData, ]; await transact(calls, txCode); updateVaults([vault]); diff --git a/src/hooks/actionHooks/useWrapUnwrapAsset.ts b/src/hooks/actionHooks/useWrapUnwrapAsset.ts index 37994b4be..75fd4df8e 100644 --- a/src/hooks/actionHooks/useWrapUnwrapAsset.ts +++ b/src/hooks/actionHooks/useWrapUnwrapAsset.ts @@ -3,13 +3,13 @@ import { useContext } from 'react'; import { ChainContext } from '../../contexts/ChainContext'; import { SettingsContext } from '../../contexts/SettingsContext'; import { ICallData, LadleActions, IAsset, RoutedActions } from '../../types'; -import { MAX_256, ZERO_BN } from '../../utils/constants'; +import { ZERO_BN } from '../../utils/constants'; import { useChain } from '../useChain'; export const useWrapUnwrapAsset = () => { const { chainState: { - connection: { account, provider }, + connection: { account, provider, chainId }, contractMap, assetRootMap, }, @@ -24,19 +24,27 @@ export const useWrapUnwrapAsset = () => { const wrapHandlerAbi = ['function wrap(address to)', 'function unwrap(address to)']; - const wrapAssetToJoin = async (value: BigNumber, asset: IAsset, txCode: string): Promise => { + const wrapAsset = async ( + value: BigNumber, + asset: IAsset, + txCode: string, + to?: string | undefined // optional send destination : DEFAULT is assetJoin address + ): Promise => { const ladleAddress = contractMap.get('Ladle').address; + const toAddress = to || asset.joinAddress + const wrapHandlerAddress = asset.wrapHandlerAddresses?.get(chainId) - if (!asset.isWrappedToken && asset.wrappedTokenId && asset.wrapHandlerAddress && value.gt(ZERO_BN)) { - const wraphandlerContract: Contract = new Contract(asset.wrapHandlerAddress, wrapHandlerAbi, signer); - const unwrappedAssetContract = assetRootMap.get(asset.id); - diagnostics && console.log('Asset Contract to be signed for wrapping: ', unwrappedAssetContract); + if (wrapHandlerAddress && value.gt(ZERO_BN)) { + + const wrapHandlerContract: Contract = new Contract(wrapHandlerAddress, wrapHandlerAbi, signer); + const assetContract = assetRootMap.get(asset.id); + diagnostics && console.log('Asset Contract to be signed for wrapping: ', assetContract); /* Gather all the required signatures - sign() processes them and returns them as ICallData types */ - const permit: ICallData[] = await sign( + const permitCallData: ICallData[] = await sign( [ { - target: unwrappedAssetContract, // full target contract + target: assetContract, // full target contract spender: ladleAddress, amount: value, ignoreIf: false, @@ -46,29 +54,32 @@ export const useWrapUnwrapAsset = () => { ); return [ - ...permit, + ...permitCallData, { operation: LadleActions.Fn.TRANSFER, - args: [asset.address, asset.wrapHandlerAddress, value] as LadleActions.Args.TRANSFER, + args: [asset.address, wrapHandlerAddress, value] as LadleActions.Args.TRANSFER, ignoreIf: false, }, { operation: LadleActions.Fn.ROUTE, - args: [asset.joinAddress] as RoutedActions.Args.WRAP, + args: [toAddress] as RoutedActions.Args.WRAP, fnName: RoutedActions.Fn.WRAP, - targetContract: wraphandlerContract, + targetContract: wrapHandlerContract, ignoreIf: false, }, ]; } - /* else if not a wrapped asset simply return empty array */ + /* else if not a wrapped asset, (or value is 0) simply return empty array */ return []; }; const unwrapAsset = async (asset: IAsset, receiver: string): Promise => { - if (unwrapTokens && asset.wrapHandlerAddress) { + + const unwrapHandlerAddress = asset.unwrapHandlerAddresses?.get(chainId) + + if (unwrapTokens && unwrapHandlerAddress) { diagnostics && console.log('Unwrapping tokens before return'); - const wraphandlerContract: Contract = new Contract(asset.wrapHandlerAddress, wrapHandlerAbi, signer); + const wraphandlerContract: Contract = new Contract(unwrapHandlerAddress, wrapHandlerAbi, signer); return [ { @@ -85,5 +96,5 @@ export const useWrapUnwrapAsset = () => { return []; }; - return { wrapAssetToJoin, unwrapAsset }; + return { wrapAsset, unwrapAsset }; }; diff --git a/src/hooks/useApr.ts b/src/hooks/useApr.ts index e2cfae5ff..f528495bc 100644 --- a/src/hooks/useApr.ts +++ b/src/hooks/useApr.ts @@ -48,7 +48,7 @@ export const useApr = (input: string | undefined, actionType: ActionType, series const _apr = calculateAPR(baseAmount, preview, _selectedSeries?.maturity); _apr ? setApr(cleanValue(_apr, 2)) : setApr(_selectedSeries.apr); } - }, [_selectedSeries, _input, actionType]); + }, [_selectedSeries, _input, actionType, _fallbackInput]); /* Get the min APR from all the series */ const aprArray = Array.from(seriesMap.values()) diff --git a/src/types/index.ts b/src/types/index.ts index 9f33ccf8f..1be91228d 100644 --- a/src/types/index.ts +++ b/src/types/index.ts @@ -184,6 +184,8 @@ export enum TokenType { export interface IAssetInfo { tokenType: TokenType; + // approvalType?: ApprovalType; + tokenIdentifier?: number; // used for identifying tokens in a multitoken contract name: string; @@ -191,23 +193,24 @@ export interface IAssetInfo { symbol: string; decimals: number; - showToken: boolean; - isWrappedToken: boolean; // Note: this is if it a token wrapped by the yield protocol (except ETH - which is handled differently) + showToken: boolean; // Display/hide the token on the UI + // isWrappedToken: boolean; // Note: this is if it a token used in wrapped form by the yield protocol (except ETH - which is handled differently) color: string; digitFormat: number; // this is the 'reasonable' number of digits to show. accuracy equivalent to +- 1 us cent. displaySymbol?: string; // override for symbol display - wrapHandlerAddress?: string; + // wrapHandlerAddress?: string; + // unwrapHandlerAddress?: string; + // wrappedTokenId?: string; + // unwrappedTokenId?: string; - wrappedTokenId?: string; - wrappedTokenAddress?: string; + limitToSeries?: string[]; - unwrappedTokenId?: string; - unwrappedTokenAddress?: string; + wrapHandlerAddresses?: Map; + unwrapHandlerAddresses?: Map; - limitToSeries?: string[]; } export interface IAssetRoot extends IAssetInfo, ISignable { @@ -224,7 +227,11 @@ export interface IAssetRoot extends IAssetInfo, ISignable { baseContract: Contract; isYieldBase: boolean; - idToUse: string; + + isWrappedToken: boolean; // Note: this is if it a token used in wrapped form by the yield protocol (except ETH - which is handled differently) + wrappingRequired: boolean; + + idToUse: string; // idToUse for wrapped tokens? // baked in token fns getBalance: (account: string) => Promise; @@ -235,14 +242,12 @@ export interface IAssetRoot extends IAssetInfo, ISignable { export interface IAssetPair { baseId: string; ilkId: string; - oracle: string; baseDecimals: number; limitDecimals: number; minRatio: number; - minDebtLimit: BigNumber; maxDebtLimit: BigNumber; pairPrice: BigNumber; @@ -391,12 +396,7 @@ export interface IDomain { export enum ApprovalType { TX = 'TX', SIG = 'SIG', -} - -export enum SignType { - ERC2612 = 'ERC2612_TYPE', - DAI = 'DAI_TYPE', - FYTOKEN = 'FYTOKEN_TYPE', + DAI_SIG = 'DAI_SIG', } export enum TxState { From b3d4b25e793dba87aa6f8ecb1ae130957b2b2d19 Mon Sep 17 00:00:00 2001 From: brucedonovan Date: Tue, 19 Apr 2022 10:10:00 +0100 Subject: [PATCH 002/109] add tokenType to ISignable --- src/types/index.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/types/index.ts b/src/types/index.ts index 1be91228d..3ff218300 100644 --- a/src/types/index.ts +++ b/src/types/index.ts @@ -132,6 +132,7 @@ export interface ISignable { version: string; address: string; symbol: string; + tokenType: TokenType; } export interface ISeriesRoot extends ISignable { From 0f2eb03bbd906d2628b58b64a6b40ea8e139a2b6 Mon Sep 17 00:00:00 2001 From: brucedonovan Date: Tue, 19 Apr 2022 10:10:23 +0100 Subject: [PATCH 003/109] remove redundant asset info --- src/config/assets.ts | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/src/config/assets.ts b/src/config/assets.ts index d91514bda..50d9f136e 100644 --- a/src/config/assets.ts +++ b/src/config/assets.ts @@ -75,11 +75,9 @@ ASSET_INFO.set(UNKNOWN, { decimals: 18, symbol: 'UNKNOWN', showToken: false, - // isWrappedToken: false, color: '#FFFFFFFF', digitFormat: 2, tokenType: TokenType.ERC20_, - }); ASSET_INFO.set(DAI, { @@ -88,7 +86,6 @@ ASSET_INFO.set(DAI, { decimals: 18, symbol: 'DAI', showToken: true, - // isWrappedToken: false, color: '#F5AC37', digitFormat: 2, tokenType: TokenType.ERC20_DaiPermit, @@ -100,7 +97,6 @@ ASSET_INFO.set(USDC, { decimals: 18, symbol: 'USDC', showToken: true, - // isWrappedToken: false, color: '#2775CA', digitFormat: 2, tokenType: TokenType.ERC20_Permit, @@ -112,7 +108,6 @@ ASSET_INFO.set(WBTC, { decimals: 18, symbol: 'WBTC', showToken: true, - // isWrappedToken: false, color: '#5A5564', digitFormat: 6, tokenType: TokenType.ERC20_, @@ -124,7 +119,6 @@ ASSET_INFO.set(ENS, { decimals: 18, symbol: 'ENS', showToken: true, - // isWrappedToken: false, color: '#000000', digitFormat: 2, tokenType: TokenType.ERC20_Permit, @@ -150,11 +144,6 @@ ASSET_INFO.set(wstETH, { symbol: 'wstETH', displaySymbol: 'wstETH', showToken: true, - // isWrappedToken: true, - // wrapHandlerAddress: undefined, - // unwrapHandlerAddress: '0x491aB93faa921C8E634F891F96512Be14fD3DbB1', - // linkedAsset: '0x303500000000', - // wrappedTokenId: '', color: '#00A3FF', digitFormat: 6, // unwrappedTokenId: '0x303500000000', @@ -170,14 +159,9 @@ ASSET_INFO.set(stETH, { decimals: 18, symbol: 'stETH', showToken: false, - // wrapHandlerAddress: '0x491aB93faa921C8E634F891F96512Be14fD3DbB1', - // unwrapHandlerAddress: undefined, - // wrappedTokenId: '0x303400000000', color: '#00A3FF', digitFormat: 6, - // unwrappedTokenId: '0x303500000000', tokenType: TokenType.ERC20_Permit, - // proxyId: '0x303500000000', wrapHandlerAddresses:new Map([[4,'0x491aB93faa921C8E634F891F96512Be14fD3DbB1'], ]), unwrapHandlerAddresses:new Map([]) @@ -312,7 +296,6 @@ ASSET_INFO.set(FUSDC2209, { // decimals: 18, // symbol: 'cvx3crv', // showToken: false, -// isWrappedToken: false, // color: '#3A3A3A', // digitFormat: 6, // tokenType: TokenType.ERC20_, @@ -325,7 +308,6 @@ ASSET_INFO.set(FRAX, { decimals: 18, symbol: 'FRAX', showToken: true, - isWrappedToken: false, color: '#ffffff', digitFormat: 6, tokenType: TokenType.ERC20_, From 03d5300380fee60b269870bf526b57860c97f072 Mon Sep 17 00:00:00 2001 From: brucedonovan Date: Tue, 19 Apr 2022 10:20:15 +0100 Subject: [PATCH 004/109] remove PERMIT_TYPE LISTS --- src/config/assets.ts | 35 ----------------------------------- src/contexts/ChainContext.tsx | 3 +-- src/hooks/useChain.ts | 15 ++++++++------- 3 files changed, 9 insertions(+), 44 deletions(-) diff --git a/src/config/assets.ts b/src/config/assets.ts index 50d9f136e..bcdf2ba89 100644 --- a/src/config/assets.ts +++ b/src/config/assets.ts @@ -32,41 +32,6 @@ export const CONVEX_BASED_ASSETS = ['CVX3CRV', CVX3CRV, 'CVX3CRV MOCK']; export const ETH_BASED_ASSETS = ['WETH', 'ETH', WETH]; export const IGNORE_BASE_ASSETS = ['ENS']; -export const DAI_PERMIT_ASSETS = ['DAI', DAI]; -export const NON_PERMIT_ASSETS = [ - 'WBTC', - 'LINK', - WBTC, - LINK, - 'ETH', - 'WETH', - WETH, - yvUSDC, - 'yvUSDC', - FDAI2203, - 'FDAI2203', - FUSDC2203, - 'FUSDC2203', - FDAI2206, - 'FDAI2206', - FUSDC2206, - 'FUSDC2206', - FUSDC2209, - 'FUSDC2209', - FDAI2209, - 'FDAI2209', - 'fDAI2203', - 'fUSDC2203', - 'fDAI2206', - 'fUSDC2206', - 'fUSDC2209', - 'fDAI2209', - // CVX3CRV, - 'CVX3CRV', - 'Cvx3Crv Mock', - FRAX, -]; - export const ASSET_INFO = new Map(); ASSET_INFO.set(UNKNOWN, { diff --git a/src/contexts/ChainContext.tsx b/src/contexts/ChainContext.tsx index cc16c4acc..b9894b515 100644 --- a/src/contexts/ChainContext.tsx +++ b/src/contexts/ChainContext.tsx @@ -8,7 +8,7 @@ import { useConnection } from '../hooks/useConnection'; import yieldEnv from './yieldEnv.json'; import * as contracts from '../contracts'; -import { IAssetRoot, IChainContextState, ISeriesRoot, IStrategyRoot, TokenType } from '../types'; +import { IAssetInfo, IAssetRoot, IChainContextState, ISeriesRoot, IStrategyRoot, TokenType } from '../types'; import { ASSET_INFO, ETH_BASED_ASSETS, UNKNOWN, yvUSDC } from '../config/assets'; import { nameFromMaturity, getSeason, SeasonType, clearCachedItems } from '../utils/appUtils'; @@ -400,7 +400,6 @@ const ChainProvider = ({ children }: any) => { isWrappedToken, wrappingRequired, - // unwrappingRequired, /* Default setting of assetInfo fields if required */ displaySymbol: assetInfo.displaySymbol || symbol, diff --git a/src/hooks/useChain.ts b/src/hooks/useChain.ts index 88b0fd394..5a7696680 100644 --- a/src/hooks/useChain.ts +++ b/src/hooks/useChain.ts @@ -4,11 +4,9 @@ import { useContext } from 'react'; import { ChainContext } from '../contexts/ChainContext'; import { TxContext } from '../contexts/TxContext'; -import { ApprovalType, ICallData, ISettingsContext, ISignData, LadleActions } from '../types'; +import { ApprovalType, ICallData, ISettingsContext, ISignData, LadleActions, TokenType } from '../types'; import { MAX_256, ZERO_BN } from '../utils/constants'; -import { DAI_PERMIT_ASSETS, NON_PERMIT_ASSETS } from '../config/assets'; - import { ERC1155__factory, ERC20Permit__factory, Ladle } from '../contracts'; import { useApprovalMethod } from './useApprovalMethod'; import { SettingsContext } from '../contexts/SettingsContext'; @@ -97,8 +95,8 @@ export const useChain = () => { console.log('Auto gas estimate:', gasEst.mul(120).div(100).toString()); } catch (e: any) { gasEst = BigNumber.from(500000); - /* handle if the tx if going to fail and transactions aren't forced */ - if (!forceTransactions) return handleTxWillFail(e.error, txCode, e.transaction) + /* handle if the tx if going to fail and transactions aren't forced */ + if (!forceTransactions) return handleTxWillFail(e.error, txCode, e.transaction); } /* Finally, send out the transaction */ @@ -144,7 +142,7 @@ export const useChain = () => { diagnostics && console.log('Sign: Amount', _amount?.toString()); /* Request the signature if using DaiType permit style */ - if (DAI_PERMIT_ASSETS.includes(reqSig.target.symbol) && chainId !== 42161) { + if (reqSig.target.tokenType === TokenType.ERC20_DaiPermit && chainId !== 42161) { // dai in arbitrum uses regular permits const { v, r, s, nonce, expiry, allowed } = await handleSign( /* We are pass over the generated signFn and sigData to the signatureHandler for tracking/tracing/fallback handling */ () => @@ -222,7 +220,10 @@ export const useChain = () => { true ), txCode, - NON_PERMIT_ASSETS.includes(reqSig.target.symbol) ? ApprovalType.TX : approvalMethod + + reqSig.target.tokenType === TokenType.ERC20_DaiPermit || reqSig.target.tokenType === TokenType.ERC20_Permit + ? approvalMethod + : ApprovalType.TX ); const args = [ From 6bee4e0f0418adec1e4871300ec915f43105fdc8 Mon Sep 17 00:00:00 2001 From: brucedonovan Date: Tue, 19 Apr 2022 10:34:03 +0100 Subject: [PATCH 005/109] unwrapp setting toggle --- src/components/settings/UnwrapSetting.tsx | 44 +++++++++++++++++++++++ src/config/assets.ts | 7 ++-- src/contexts/SettingsContext.tsx | 12 +++---- 3 files changed, 52 insertions(+), 11 deletions(-) create mode 100644 src/components/settings/UnwrapSetting.tsx diff --git a/src/components/settings/UnwrapSetting.tsx b/src/components/settings/UnwrapSetting.tsx new file mode 100644 index 000000000..e5b3928ed --- /dev/null +++ b/src/components/settings/UnwrapSetting.tsx @@ -0,0 +1,44 @@ +import { useContext } from 'react'; +import { Box, Text } from 'grommet'; +import Switch from 'react-switch'; +import { ApprovalType } from '../../types'; +import { Settings, SettingsContext } from '../../contexts/SettingsContext'; +import { ChainContext } from '../../contexts/ChainContext'; + +const UnwrapSetting = () => { + const { + chainState: { + connection: { connectionName }, + }, + } = useContext(ChainContext); + + const { + settingsState: { unwrapToken }, + settingsActions: { updateSetting }, + } = useContext(SettingsContext); + + return ( + // + + + + Automatically unwrap wrapped tokens + + updateSetting(Settings.UNWRAP_TOKENS, val)} + handleDiameter={20} + borderRadius={20} + disabled={connectionName !== 'metamask'} + /> + + + ); +}; + +export default UnwrapSetting; diff --git a/src/config/assets.ts b/src/config/assets.ts index bcdf2ba89..91780e09b 100644 --- a/src/config/assets.ts +++ b/src/config/assets.ts @@ -27,13 +27,14 @@ export const FUSDC2209 = '0x313700000000'; /* Convex Curve LP token assets */ export const CVX3CRV = ''; -export const CONVEX_BASED_ASSETS = ['CVX3CRV', CVX3CRV, 'CVX3CRV MOCK']; +export const CONVEX_BASED_ASSETS = ['CVX3CRV', CVX3CRV, 'CVX3CRV MOCK']; export const ETH_BASED_ASSETS = ['WETH', 'ETH', WETH]; export const IGNORE_BASE_ASSETS = ['ENS']; export const ASSET_INFO = new Map(); +/* Unknown token for temporarily handling new tokens added */ ASSET_INFO.set(UNKNOWN, { version: '1', name: 'UNKNOWN', @@ -96,7 +97,6 @@ ASSET_INFO.set(WETH, { symbol: 'WETH', displaySymbol: 'ETH', showToken: true, - // isWrappedToken: false, color: '#FFFFFF', digitFormat: 6, tokenType: TokenType.ERC20_, @@ -111,9 +111,7 @@ ASSET_INFO.set(wstETH, { showToken: true, color: '#00A3FF', digitFormat: 6, - // unwrappedTokenId: '0x303500000000', tokenType: TokenType.ERC20_Permit, - wrapHandlerAddresses:new Map([]), unwrapHandlerAddresses:new Map([[4,'0x491aB93faa921C8E634F891F96512Be14fD3DbB1'], ]) }); @@ -127,7 +125,6 @@ ASSET_INFO.set(stETH, { color: '#00A3FF', digitFormat: 6, tokenType: TokenType.ERC20_Permit, - // proxyId: '0x303500000000', wrapHandlerAddresses:new Map([[4,'0x491aB93faa921C8E634F891F96512Be14fD3DbB1'], ]), unwrapHandlerAddresses:new Map([]) }); diff --git a/src/contexts/SettingsContext.tsx b/src/contexts/SettingsContext.tsx index 71e156274..95413895c 100644 --- a/src/contexts/SettingsContext.tsx +++ b/src/contexts/SettingsContext.tsx @@ -2,7 +2,7 @@ import React, { useContext, useEffect, useReducer } from 'react'; import { ApprovalType, IChainContext, ISettingsContextState } from '../types'; import { ChainContext } from './ChainContext'; -enum SettingsState { +export enum Settings { APPROVAL_METHOD = 'approvalMethod', APPROVAL_MAX = 'approveMax', SLIPPAGE_TOLERANCE = 'slippageTolerance', @@ -56,7 +56,7 @@ const initState: ISettingsContextState = { showWrappedTokens: true, /* Always Unwrap tokens when removing them */ - unwrapTokens: false, + unwrapTokens: true, /* Dashboard settings */ dashHideEmptyVaults: false, @@ -91,7 +91,7 @@ const SettingsProvider = ({ children }: any) => { /* watch & handle linked approval and effect appropriate settings */ useEffect(() => { if (settingsState.approvalMethod === ApprovalType.SIG) { - updateState({ type: SettingsState.APPROVAL_MAX, payload: false }); + updateState({ type: Settings.APPROVAL_MAX, payload: false }); } }, [settingsState.approvalMethod]); @@ -99,11 +99,11 @@ const SettingsProvider = ({ children }: any) => { useEffect(() => { if (connection.connectionName && connection.connectionName !== 'metamask') { console.log('Using manual ERC20 approval transactions'); - updateState({ type: SettingsState.APPROVAL_MAX, payload: ApprovalType.TX }); + updateState({ type: Settings.APPROVAL_MAX, payload: ApprovalType.TX }); } else if (connection.connectionName === 'metamask') { /* On metamask default to SIG */ console.log('Using ERC20Permit signing (EIP-2612) '); - updateState({ type: SettingsState.APPROVAL_METHOD, payload: ApprovalType.SIG }); + updateState({ type: Settings.APPROVAL_METHOD, payload: ApprovalType.SIG }); } }, [connection.connectionName]); @@ -115,7 +115,7 @@ const SettingsProvider = ({ children }: any) => { /* Update all settings in state based on localStorage */ useEffect(() => { if (typeof window !== 'undefined') { - Object.values(SettingsState).forEach((setting) => { + Object.values(Settings).forEach((setting) => { if (JSON.parse(localStorage.getItem(setting)) !== null) { updateState({ type: setting, payload: JSON.parse(localStorage.getItem(setting)) }); } From 1d59f5a757a0566cec164eae0b8b396975254601 Mon Sep 17 00:00:00 2001 From: brucedonovan Date: Tue, 19 Apr 2022 10:41:17 +0100 Subject: [PATCH 006/109] type updateSettings --- src/components/Connect.tsx | 4 ++-- src/components/CurrencyToggle.tsx | 6 +++--- src/components/DashboardSettings.tsx | 4 ++-- src/components/settings/ApprovalSetting.tsx | 8 +++++--- src/components/settings/SlippageSetting.tsx | 6 +++--- src/components/settings/ThemeSetting.tsx | 6 +++--- src/components/views/Dashboard.tsx | 8 ++++---- 7 files changed, 22 insertions(+), 20 deletions(-) diff --git a/src/components/Connect.tsx b/src/components/Connect.tsx index bb302a46a..ec0a54064 100644 --- a/src/components/Connect.tsx +++ b/src/components/Connect.tsx @@ -4,7 +4,7 @@ import { FiX } from 'react-icons/fi'; import { ChainContext } from '../contexts/ChainContext'; import BackButton from './buttons/BackButton'; import Disclaimer from './Disclaimer'; -import { SettingsContext } from '../contexts/SettingsContext'; +import { Settings, SettingsContext } from '../contexts/SettingsContext'; import { ISettingsContext } from '../types'; import GeneralButton from './buttons/GeneralButton'; @@ -66,7 +66,7 @@ const Connect = ({ setSettingsOpen, setConnectOpen }: any) => { updateSetting('disclaimerChecked', event.target.checked)} + onChange={(event: any) => updateSetting(Settings.DISCLAIMER_CHECKED, event.target.checked)} /> )} diff --git a/src/components/CurrencyToggle.tsx b/src/components/CurrencyToggle.tsx index 628cc8ee3..6fcc308f5 100644 --- a/src/components/CurrencyToggle.tsx +++ b/src/components/CurrencyToggle.tsx @@ -1,6 +1,6 @@ import { useContext } from 'react'; import { Box, Text } from 'grommet'; -import { SettingsContext } from '../contexts/SettingsContext'; +import { Settings, SettingsContext } from '../contexts/SettingsContext'; import { ISettingsContext } from '../types'; const CurrencyToggle = () => { @@ -17,7 +17,7 @@ const CurrencyToggle = () => { // border={dashCurrency === 'USDC' ? undefined : { color: 'lightgrey' }} background={dashCurrency === 'USDC' ? 'gradient-transparent' : undefined} round={{ corner: 'left' }} - onClick={() => updateSetting('dashCurrency', 'USDC')} + onClick={() => updateSetting(Settings.DASH_CURRENCY, 'USDC')} align="center" justify="center" elevation={dashCurrency === 'USDC' ? 'xsmall' : 'small'} @@ -30,7 +30,7 @@ const CurrencyToggle = () => { // border={dashCurrency === 'ETH' ? undefined : { color: 'lightgrey' }} background={dashCurrency === 'ETH' ? 'gradient-transparent' : undefined} round={{ corner: 'right' }} - onClick={() => updateSetting('dashCurrency', 'ETH')} + onClick={() => updateSetting(Settings.DASH_CURRENCY, 'ETH')} align="center" justify="center" elevation={dashCurrency === 'ETH' ? 'xsmall' : 'small'} diff --git a/src/components/DashboardSettings.tsx b/src/components/DashboardSettings.tsx index 009998950..6e0443b8b 100644 --- a/src/components/DashboardSettings.tsx +++ b/src/components/DashboardSettings.tsx @@ -2,7 +2,7 @@ import { useState, useContext } from 'react'; import { Button, DropButton, Text, Box } from 'grommet'; import { FiMoreVertical } from 'react-icons/fi'; import { ActionType } from '../types'; -import { SettingsContext } from '../contexts/SettingsContext'; +import { Settings, SettingsContext } from '../contexts/SettingsContext'; const DashboardSettings = ({ actionType }: { actionType: string }) => { const { @@ -18,7 +18,7 @@ const DashboardSettings = ({ actionType }: { actionType: string }) => {