diff --git a/apps/oeth/src/main.tsx b/apps/oeth/src/main.tsx index 06a3f1d51..b31f5f3d7 100644 --- a/apps/oeth/src/main.tsx +++ b/apps/oeth/src/main.tsx @@ -34,13 +34,7 @@ root.render( [CssVarsProvider, { theme: theme, defaultMode: 'dark' }], [WagmiConfig, { config: wagmiConfig }], [RainbowKitProvider, { chains: chains, theme: darkTheme() }], - [ - CurveProvider, - { - alchemyApiKey: import.meta.env.VITE_ALCHEMY_ID, - customRpcUrl: import.meta.env.VITE_CUSTOM_RPC, - }, - ], + [CurveProvider], ], , ), diff --git a/libs/oeth/swap/src/actions/defaultApi.ts b/libs/oeth/swap/src/actions/defaultApi.ts index bf90bab98..e502e6582 100644 --- a/libs/oeth/swap/src/actions/defaultApi.ts +++ b/libs/oeth/swap/src/actions/defaultApi.ts @@ -5,53 +5,38 @@ import type { Swap, } from '../types'; -const estimateAmount: EstimateAmount = async ( - _tokenIn, - _tokenOut, - amountIn, -) => { +const estimateAmount: EstimateAmount = async ({ amountIn }) => { console.log('Amount estimation not implemented'); return amountIn; }; -const estimateGas: EstimateGas = async ( - _tokenIn, - _tokenOut, - _amountIn, - _slippage, -) => { +const estimateGas: EstimateGas = async () => { console.log('Gas estimation not implemented'); return 0n; }; -const estimateRoute: EstimateRoute = async ( - tokenIn, - tokenOut, +const estimateRoute: EstimateRoute = async ({ amountIn, route, + tokenIn, + tokenOut, slippage, -) => { +}) => { if (amountIn === 0n) { return { ...route, estimatedAmount: 0n, gas: 0n, rate: 0 }; } const [estimatedAmount, gas] = await Promise.all([ - estimateAmount(tokenIn, tokenOut, amountIn), - estimateGas(tokenIn, tokenOut, amountIn, slippage), + estimateAmount({ tokenIn, tokenOut, amountIn }), + estimateGas({ tokenIn, tokenOut, amountIn, slippage }), ]); return { ...route, estimatedAmount, gas, rate: 0 }; }; -const swap: Swap = async ( - _tokenIn, - _tokenOut, - _amountIn, - _route, - _slippage, -) => { +const swap: Swap = async () => { console.log('Route swap operation not implemented'); }; diff --git a/libs/oeth/swap/src/actions/mintVault.ts b/libs/oeth/swap/src/actions/mintVault.ts index 35515b2c3..6f7258a4a 100644 --- a/libs/oeth/swap/src/actions/mintVault.ts +++ b/libs/oeth/swap/src/actions/mintVault.ts @@ -16,7 +16,11 @@ import { formatUnits, parseUnits } from 'viem'; import type { EstimateGas, EstimateRoute, Swap } from '../types'; import type { EstimateAmount } from '../types'; -const estimateAmount: EstimateAmount = async (tokenIn, tokenOut, amountIn) => { +const estimateAmount: EstimateAmount = async ({ + tokenIn, + tokenOut, + amountIn, +}) => { if (amountIn === 0n) { return 0n; } @@ -37,13 +41,13 @@ const estimateAmount: EstimateAmount = async (tokenIn, tokenOut, amountIn) => { ); }; -const estimateGas: EstimateGas = async ( +const estimateGas: EstimateGas = async ({ tokenIn, tokenOut, amountIn, slippage, amountOut, -) => { +}) => { let gasEstimate = 0n; if (amountIn === 0n) { @@ -110,25 +114,25 @@ const estimateGas: EstimateGas = async ( return gasEstimate; }; -const estimateRoute: EstimateRoute = async ( +const estimateRoute: EstimateRoute = async ({ tokenIn, tokenOut, amountIn, route, slippage, -) => { +}) => { if (amountIn === 0n) { return { ...route, estimatedAmount: 0n, gas: 0n, rate: 0 }; } - const estimatedAmount = await estimateAmount(tokenIn, tokenOut, amountIn); - const gas = await estimateGas( + const estimatedAmount = await estimateAmount({ tokenIn, tokenOut, amountIn }); + const gas = await estimateGas({ tokenIn, tokenOut, amountIn, slippage, - estimatedAmount, - ); + amountOut: estimatedAmount, + }); return { ...route, @@ -140,14 +144,13 @@ const estimateRoute: EstimateRoute = async ( }; }; -const swap: Swap = async ( +const swap: Swap = async ({ tokenIn, tokenOut, amountIn, - _route, slippage, amountOut, -) => { +}) => { const { address } = getAccount(); if (amountIn === 0n || isNilOrEmpty(address)) { diff --git a/libs/oeth/swap/src/actions/redeemVault.ts b/libs/oeth/swap/src/actions/redeemVault.ts index faccafc2e..ffd674de8 100644 --- a/libs/oeth/swap/src/actions/redeemVault.ts +++ b/libs/oeth/swap/src/actions/redeemVault.ts @@ -22,11 +22,7 @@ import type { Swap, } from '../types'; -const estimateAmount: EstimateAmount = async ( - _tokenIn, - _tokenOut, - amountIn, -) => { +const estimateAmount: EstimateAmount = async ({ amountIn }) => { if (amountIn === 0n) { return 0n; } @@ -71,13 +67,12 @@ const estimateAmount: EstimateAmount = async ( }, 0n); }; -const estimateGas: EstimateGas = async ( - _tokenIn, +const estimateGas: EstimateGas = async ({ tokenOut, amountIn, slippage, amountOut, -) => { +}) => { let gasEstimate = 0n; if (amountIn === 0n) { @@ -108,25 +103,25 @@ const estimateGas: EstimateGas = async ( return gasEstimate; }; -const estimateRoute: EstimateRoute = async ( +const estimateRoute: EstimateRoute = async ({ tokenIn, tokenOut, amountIn, route, slippage, -) => { +}) => { if (amountIn === 0n) { return { ...route, estimatedAmount: 0n, gas: 0n, rate: 0 }; } - const estimatedAmount = await estimateAmount(tokenIn, tokenOut, amountIn); - const gas = await estimateGas( + const estimatedAmount = await estimateAmount({ tokenIn, tokenOut, amountIn }); + const gas = await estimateGas({ tokenIn, tokenOut, amountIn, slippage, - estimatedAmount, - ); + amountOut: estimatedAmount, + }); return { ...route, @@ -138,14 +133,7 @@ const estimateRoute: EstimateRoute = async ( }; }; -const swap: Swap = async ( - _tokenIn, - tokenOut, - amountIn, - _route, - slippage, - amountOut, -) => { +const swap: Swap = async ({ tokenOut, amountIn, slippage, amountOut }) => { const { address } = getAccount(); if (amountIn === 0n || isNilOrEmpty(address)) { diff --git a/libs/oeth/swap/src/actions/swapCurve.ts b/libs/oeth/swap/src/actions/swapCurve.ts deleted file mode 100644 index 2922be9af..000000000 --- a/libs/oeth/swap/src/actions/swapCurve.ts +++ /dev/null @@ -1,141 +0,0 @@ -import curve from '@curvefi/api'; -import { tokens } from '@origin/shared/contracts'; -import { waitForTransaction } from '@wagmi/core'; -import { formatUnits, parseUnits } from 'viem'; - -import type { HexAddress } from '@origin/shared/utils'; - -import type { - EstimateAmount, - EstimateGas, - EstimateRoute, - Swap, -} from '../types'; - -const ETH = '0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE'; - -const estimateAmount: EstimateAmount = async (tokenIn, tokenOut, amountIn) => { - if (amountIn === 0n) { - return 0n; - } - - console.time('curve getBestRouteAndOutput'); - const routes = await curve.router.getBestRouteAndOutput( - tokenIn?.address ?? ETH, - tokenOut?.address ?? ETH, - formatUnits(amountIn, tokenIn.decimals), - ); - console.timeEnd('curve getBestRouteAndOutput'); - console.log( - `curve found ${routes.route.length} routes: ${JSON.stringify( - routes.route, - null, - 2, - )}`, - ); - - return parseUnits(routes.output, tokenOut.decimals); -}; - -const estimateGas: EstimateGas = async ( - tokenIn, - tokenOut, - amountIn, - _slippage, -) => { - let gasEstimate = 0n; - - if (amountIn === 0n) { - return gasEstimate; - } - - try { - console.time('curve gas estimate'); - const res = await curve.router.estimateGas.swap( - tokenIn?.address ?? ETH, - tokenOut?.address ?? ETH, - formatUnits(amountIn, tokenIn.decimals), - ); - gasEstimate = parseUnits(res.toString(), tokens.mainnet.ETH.decimals); - console.timeEnd('curve gas estimate'); - } catch {} - - return gasEstimate; -}; - -const estimateRoute: EstimateRoute = async ( - tokenIn, - tokenOut, - amountIn, - route, - slippage, -) => { - if (amountIn === 0n) { - return { ...route, estimatedAmount: 0n, gas: 0n, rate: 0 }; - } - - const [estimatedAmount, gas] = await Promise.all([ - estimateAmount(tokenIn, tokenOut, amountIn), - estimateGas(tokenIn, tokenOut, amountIn, slippage), - ]); - - return { - ...route, - estimatedAmount, - gas, - rate: - +formatUnits(amountIn, tokenIn.decimals) / - +formatUnits(estimatedAmount, tokenOut.decimals), - }; -}; - -const swap: Swap = async (tokenIn, tokenOut, amountIn) => { - if (amountIn === 0n) { - return; - } - - let isApproved = false; - try { - isApproved = await curve.router.isApproved( - tokenIn?.address ?? ETH, - formatUnits(amountIn, tokenIn.decimals), - ); - } catch (e) { - console.log(`swap curve isApproved error!\n${e.message}`); - } - - if (!isApproved) { - try { - const [hash] = await curve.router.approve( - tokenIn?.address ?? ETH, - formatUnits(amountIn, tokenIn.decimals), - ); - await waitForTransaction({ hash: hash as HexAddress }); - // TODO trigger notification - console.log('swap curve approval done!'); - } catch (e) { - console.log(`swap curve approve error!\n${e.message}`); - return; - } - } - - try { - const { hash } = await curve.router.swap( - tokenIn?.address ?? ETH, - tokenOut?.address ?? ETH, - formatUnits(amountIn, tokenIn.decimals), - ); - await waitForTransaction({ hash: hash as HexAddress }); - // TODO trigger notification - console.log(`swap curve done!`); - } catch (e) { - // TODO trigger notification - console.log(`swap curve error!\n${e.message}`); - } -}; - -export default { - estimateAmount, - estimateRoute, - swap, -}; diff --git a/libs/oeth/swap/src/actions/swapCurve/curveRoutes.ts b/libs/oeth/swap/src/actions/swapCurve/curveRoutes.ts new file mode 100644 index 000000000..7e7d50952 --- /dev/null +++ b/libs/oeth/swap/src/actions/swapCurve/curveRoutes.ts @@ -0,0 +1,223 @@ +import { contracts, tokens } from '@origin/shared/contracts'; +import { ETH_ADDRESS_CURVE } from '@origin/shared/utils'; + +/* +- Mainnet Curve registry contract: https://etherscan.io/address/0x99a58482BD75cbab83b27EC03CA68fF489b5788f#code +- Vyper implementation for multiple amount exchanges + +``` + def get_exchange_multiple_amount + + @notice Get the current number the final output tokens received in an exchange + @dev Routing and swap params must be determined off-chain. This + functionality is designed for gas efficiency over ease-of-use. + @param _route Array of [initial token, pool, token, pool, token, ...] + The array is iterated until a pool address of 0x00, then the last + given token is transferred to `_receiver` + @param _swap_params Multidimensional array of [i, j, swap type] where i and j are the correct + values for the n'th pool in `_route`. The swap type should be + 1 for a stableswap `exchange`, + 2 for stableswap `exchange_underlying`, + 3 for a cryptoswap `exchange`, + 4 for a cryptoswap `exchange_underlying`, + 5 for factory metapools with lending base pool `exchange_underlying`, + 6 for factory crypto-meta pools underlying exchange (`exchange` method in zap), + 7-11 for wrapped coin (underlying for lending pool) -> LP token "exchange" (actually `add_liquidity`), + 12-14 for LP token -> wrapped coin (underlying for lending or fake pool) "exchange" (actually `remove_liquidity_one_coin`) + 15 for WETH -> ETH "exchange" (actually deposit/withdraw) + @param _amount The amount of `_route[0]` token to be sent. + @param _pools Array of pools for swaps via zap contracts. This parameter is only needed for + Polygon meta-factories underlying swaps. + @return Expected amount of the final output token +``` +*/ + +export const curveRoutes = { + // stETH -> OETH Mint + stETH: { + OETH: { + routes: [ + tokens.mainnet.stETH, + '0x21E27a5E5513D6e65C4f830167390997aA84843a', + ETH_ADDRESS_CURVE, + contracts.mainnet.curveOethPool.address, + tokens.mainnet.OETH.address, + '0x0000000000000000000000000000000000000000', + '0x0000000000000000000000000000000000000000', + '0x0000000000000000000000000000000000000000', + '0x0000000000000000000000000000000000000000', + ], + swapParams: [ + // 1 for a stableswap `exchange`, + [1n, 0n, 1n], + // 1 for a stableswap `exchange`, + [0n, 1n, 1n], + [0n, 0n, 0n], + [0n, 0n, 0n], + ], + }, + }, + // WETH -> OETH Mint + WETH: { + OETH: { + routes: [ + tokens.mainnet.WETH.address, + tokens.mainnet.WETH.address, + ETH_ADDRESS_CURVE, + contracts.mainnet.curveOethPool.address, + tokens.mainnet.OETH.address, + '0x0000000000000000000000000000000000000000', + '0x0000000000000000000000000000000000000000', + '0x0000000000000000000000000000000000000000', + '0x0000000000000000000000000000000000000000', + ], + swapParams: [ + // 15 for WETH -> ETH "exchange" (actually deposit/withdraw) + [0n, 0n, 15n], + // 1 for a stableswap `exchange`, + [0n, 1n, 1n], + [0n, 0n, 0n], + [0n, 0n, 0n], + ], + }, + }, + // rETH -> OETH Mint + rETH: { + OETH: { + routes: [ + tokens.mainnet.rETH.address, + '0x0f3159811670c117c372428D4E69AC32325e4D0F', + ETH_ADDRESS_CURVE, + contracts.mainnet.curveOethPool.address, + tokens.mainnet.OETH.address, + '0x0000000000000000000000000000000000000000', + '0x0000000000000000000000000000000000000000', + '0x0000000000000000000000000000000000000000', + '0x0000000000000000000000000000000000000000', + ], + swapParams: [ + // 3 for a cryptoswap `exchange`, + [1n, 0n, 3n], + // 1 for a stableswap `exchange`, + [0n, 1n, 1n], + [0n, 0n, 0n], + [0n, 0n, 0n], + ], + }, + }, + // frxETH -> OETH Mint + frxETH: { + OETH: { + routes: [ + tokens.mainnet.frxETH.address, + '0xa1F8A6807c402E4A15ef4EBa36528A3FED24E577', + ETH_ADDRESS_CURVE, + contracts.mainnet.curveOethPool.address, + tokens.mainnet.OETH.address, + '0x0000000000000000000000000000000000000000', + '0x0000000000000000000000000000000000000000', + '0x0000000000000000000000000000000000000000', + '0x0000000000000000000000000000000000000000', + ], + swapParams: [ + // 1 for a stableswap `exchange`, + [1n, 0n, 1n], + // 1 for a stableswap `exchange`, + [0n, 1n, 1n], + [0n, 0n, 0n], + [0n, 0n, 0n], + ], + }, + }, + // OETH Redeem + OETH: { + // OETH -> frxETH + frxETH: { + routes: [ + tokens.mainnet.OETH.address, + contracts.mainnet.curveOethPool.address, + ETH_ADDRESS_CURVE, + '0xa1F8A6807c402E4A15ef4EBa36528A3FED24E577', + tokens.mainnet.frxETH.address, + '0x0000000000000000000000000000000000000000', + '0x0000000000000000000000000000000000000000', + '0x0000000000000000000000000000000000000000', + '0x0000000000000000000000000000000000000000', + ], + swapParams: [ + // 1 for a stableswap `exchange`, + [1n, 0n, 1n], + // 1 for a stableswap `exchange`, + [0n, 1n, 1n], + [0n, 0n, 0n], + [0n, 0n, 0n], + ], + }, + // OETH -> WETH + WETH: { + routes: [ + tokens.mainnet.OETH.address, + contracts.mainnet.curveOethPool.address, + ETH_ADDRESS_CURVE, + tokens.mainnet.WETH.address, + tokens.mainnet.WETH.address, + '0x0000000000000000000000000000000000000000', + '0x0000000000000000000000000000000000000000', + '0x0000000000000000000000000000000000000000', + '0x0000000000000000000000000000000000000000', + ], + swapParams: [ + // 1 for a stableswap `exchange`, + [1n, 0n, 1n], + // 15 for WETH -> ETH "exchange" (actually deposit/withdraw) + [0n, 0n, 15n], + [0n, 0n, 0n], + [0n, 0n, 0n], + ], + }, + // OETH -> rETH + rETH: { + routes: [ + tokens.mainnet.OETH.address, + contracts.mainnet.curveOethPool.address, + ETH_ADDRESS_CURVE, + '0x0f3159811670c117c372428D4E69AC32325e4D0F', + tokens.mainnet.rETH.address, + '0x0000000000000000000000000000000000000000', + '0x0000000000000000000000000000000000000000', + '0x0000000000000000000000000000000000000000', + '0x0000000000000000000000000000000000000000', + ], + swapParams: [ + // 1 for a stableswap `exchange`, + [1n, 0n, 1n], + // 3 for a cryptoswap `exchange`, + [0n, 1n, 3n], + [0n, 0n, 0n], + [0n, 0n, 0n], + ], + }, + // OETH -> stETH + stETH: { + routes: [ + tokens.mainnet.OETH.address, + contracts.mainnet.curveOethPool.address, + ETH_ADDRESS_CURVE, + '0x21E27a5E5513D6e65C4f830167390997aA84843a', + tokens.mainnet.stETH.address, + '0x0000000000000000000000000000000000000000', + '0x0000000000000000000000000000000000000000', + '0x0000000000000000000000000000000000000000', + '0x0000000000000000000000000000000000000000', + ], + swapParams: [ + // 1 for a stableswap `exchange`, + [1n, 0n, 1n], + // 1 for a stableswap `exchange`, + [0n, 1n, 1n], + [0n, 0n, 0n], + [0n, 0n, 0n], + ], + }, + }, +} as const; diff --git a/libs/oeth/swap/src/actions/swapCurve/index.ts b/libs/oeth/swap/src/actions/swapCurve/index.ts new file mode 100644 index 000000000..5e4904b91 --- /dev/null +++ b/libs/oeth/swap/src/actions/swapCurve/index.ts @@ -0,0 +1,279 @@ +import { contracts } from '@origin/shared/contracts'; +import { ETH_ADDRESS_CURVE, isNilOrEmpty } from '@origin/shared/utils'; +import { + getAccount, + getPublicClient, + prepareWriteContract, + readContract, + waitForTransaction, + writeContract, +} from '@wagmi/core'; +import { formatUnits, isAddressEqual, parseUnits } from 'viem'; + +import { curveRoutes } from './curveRoutes'; + +import type { + EstimateAmount, + EstimateGas, + EstimateRoute, + Swap, +} from '../../types'; + +const estimateAmount: EstimateAmount = async ({ + tokenIn, + tokenOut, + amountIn, + curve, +}) => { + if (amountIn === 0n || isNilOrEmpty(curve?.CurveRegistryExchange)) { + return 0n; + } + + // ETH swap + if (isNilOrEmpty(tokenIn.address) || isNilOrEmpty(tokenOut.address)) { + const amountOut = await readContract({ + address: curve.CurveRegistryExchange.address, + abi: curve.CurveRegistryExchange.abi, + functionName: 'get_exchange_amount', + args: [ + contracts.mainnet.curveOethPool.address, + tokenIn.address ?? ETH_ADDRESS_CURVE, + tokenOut.address ?? ETH_ADDRESS_CURVE, + amountIn, + ], + }); + + return amountOut as unknown as bigint; + } + + const curveConfig = curveRoutes[tokenIn.symbol]?.[tokenOut?.symbol]; + + if (isNilOrEmpty(curveConfig)) { + // TODO return or throw + console.error('No curve route found, verify exchange mapping'); + } + + console.log(curveConfig); + + const amountOut = await readContract({ + address: curve.CurveRegistryExchange.address, + abi: curve.CurveRegistryExchange.abi, + functionName: 'get_exchange_multiple_amount', + args: [curveConfig.routes, curveConfig.params, amountIn], + }); + + return amountOut as unknown as bigint; +}; + +const estimateGas: EstimateGas = async ({ + tokenIn, + tokenOut, + amountIn, + curve, + amountOut, + slippage, +}) => { + let gasEstimate = 0n; + + if (amountIn === 0n) { + return gasEstimate; + } + + const publicClient = getPublicClient(); + const { address } = getAccount(); + + const minAmountOut = parseUnits( + ( + +formatUnits(amountOut, tokenOut.decimals) - + +formatUnits(amountOut, tokenOut.decimals) * slippage + ).toString(), + tokenOut.decimals, + ); + + // ETH swap + if (isNilOrEmpty(tokenIn.address) || isNilOrEmpty(tokenOut.address)) { + try { + gasEstimate = await publicClient.estimateContractGas({ + address: contracts.mainnet.curveOethPool.address, + abi: contracts.mainnet.curveOethPool.abi, + functionName: 'exchange', + args: [ + BigInt( + curve.OethPoolUnderlyings.findIndex((t) => + isAddressEqual(t, tokenIn.address ?? ETH_ADDRESS_CURVE), + ), + ), + BigInt( + curve.OethPoolUnderlyings.findIndex((t) => + isAddressEqual(t, tokenOut.address ?? ETH_ADDRESS_CURVE), + ), + ), + amountIn, + minAmountOut, + ], + ...(isNilOrEmpty(tokenOut.address) && { value: amountIn }), + account: address ?? ETH_ADDRESS_CURVE, + }); + + return gasEstimate; + } catch (e) { + console.error(`swap curve OETHPool gas estimate error!\n${e.message}`); + } + } + + try { + const curveConfig = curveRoutes[tokenIn.symbol]?.[tokenOut?.symbol]; + + if (isNilOrEmpty(curveConfig)) { + // TODO return or throw + console.error('No curve route found, verify exchange mapping'); + } + + gasEstimate = await publicClient.estimateContractGas({ + address: curve.CurveRegistryExchange.address, + abi: curve.CurveRegistryExchange.abi, + functionName: 'exchange_multiple', + args: [ + curveConfig.routes, + curveConfig.swapParams, + amountIn, + minAmountOut, + ], + account: address ?? ETH_ADDRESS_CURVE, + }); + } catch (e) { + console.error( + `swap curve exchange multiple gas estimate error!\n${e.message}`, + ); + } + + return gasEstimate; +}; + +const estimateRoute: EstimateRoute = async ({ + tokenIn, + tokenOut, + amountIn, + route, + slippage, + curve, +}) => { + if (amountIn === 0n) { + return { ...route, estimatedAmount: 0n, gas: 0n, rate: 0 }; + } + + const estimatedAmount = await estimateAmount({ + tokenIn, + tokenOut, + amountIn, + curve, + }); + const gas = await estimateGas({ + tokenIn, + tokenOut, + amountIn, + amountOut: estimatedAmount, + slippage, + curve, + }); + + return { + ...route, + estimatedAmount, + gas, + rate: + +formatUnits(amountIn, tokenIn.decimals) / + +formatUnits(estimatedAmount, tokenOut.decimals), + }; +}; + +const swap: Swap = async ({ + tokenIn, + tokenOut, + amountIn, + amountOut, + slippage, + curve, +}) => { + if (amountIn === 0n) { + return; + } + + const minAmountOut = parseUnits( + ( + +formatUnits(amountOut, tokenOut.decimals) - + +formatUnits(amountOut, tokenOut.decimals) * slippage + ).toString(), + tokenOut.decimals, + ); + + // ETH swap + if (isNilOrEmpty(tokenIn.address) || isNilOrEmpty(tokenOut.address)) { + try { + const { request } = await prepareWriteContract({ + address: contracts.mainnet.curveOethPool.address, + abi: contracts.mainnet.curveOethPool.abi, + functionName: 'exchange', + args: [ + BigInt( + curve.OethPoolUnderlyings.findIndex((t) => + isAddressEqual(t, tokenIn.address ?? ETH_ADDRESS_CURVE), + ), + ), + BigInt( + curve.OethPoolUnderlyings.findIndex((t) => + isAddressEqual(t, tokenOut.address ?? ETH_ADDRESS_CURVE), + ), + ), + amountIn, + minAmountOut, + ], + ...(isNilOrEmpty(tokenOut.address) && { value: amountIn }), + }); + const { hash } = await writeContract(request); + await waitForTransaction({ hash }); + + // TODO trigger notification + console.log('swap curve OETHPool done!'); + return; + } catch (e) { + // TODO trigger notification + console.error(`swap curve OETHPool error!\n${e.message}`); + return; + } + } + + try { + const curveConfig = curveRoutes[tokenIn.symbol]?.[tokenOut?.symbol]; + + if (isNilOrEmpty(curveConfig)) { + // TODO return or throw + console.error('No curve route found, verify exchange mapping'); + } + + const { request } = await prepareWriteContract({ + address: curve.CurveRegistryExchange.address, + abi: curve.CurveRegistryExchange.abi, + functionName: 'exchange_multiple', + args: [ + curveConfig.routes, + curveConfig.swapParams, + amountIn, + minAmountOut, + ], + }); + const { hash } = await writeContract(request); + await waitForTransaction({ hash }); + + // TODO trigger notification + console.log('swap curve exchange multiple done!'); + } catch (e) { + console.error(`swap curve exchange multiple error!\n${e.message}`); + } +}; + +export default { + estimateAmount, + estimateRoute, + swap, +}; diff --git a/libs/oeth/swap/src/actions/swapZapperEth.ts b/libs/oeth/swap/src/actions/swapZapperEth.ts index a3983c1c4..ebe690591 100644 --- a/libs/oeth/swap/src/actions/swapZapperEth.ts +++ b/libs/oeth/swap/src/actions/swapZapperEth.ts @@ -16,21 +16,11 @@ import type { Swap, } from '../types'; -const estimateAmount: EstimateAmount = async ( - _tokenIn, - _tokenOut, - amountIn, -) => { +const estimateAmount: EstimateAmount = async ({ amountIn }) => { return amountIn; }; -const estimateGas: EstimateGas = async ( - _tokenIn, - _tokenOut, - amountIn, - _slippage, - _amountOut, -) => { +const estimateGas: EstimateGas = async ({ amountIn }) => { let gasEstimate = 200000n; const { address } = getAccount(); @@ -54,20 +44,20 @@ const estimateGas: EstimateGas = async ( return gasEstimate; }; -const estimateRoute: EstimateRoute = async ( +const estimateRoute: EstimateRoute = async ({ tokenIn, tokenOut, amountIn, route, slippage, -) => { +}) => { if (amountIn === 0n) { return { ...route, estimatedAmount: 0n, gas: 0n, rate: 0 }; } const [estimatedAmount, gas] = await Promise.all([ - estimateAmount(tokenIn, tokenOut, amountIn), - estimateGas(tokenIn, tokenOut, amountIn, slippage), + estimateAmount({ tokenIn, tokenOut, amountIn }), + estimateGas({ tokenIn, tokenOut, amountIn, slippage }), ]); return { @@ -80,14 +70,7 @@ const estimateRoute: EstimateRoute = async ( }; }; -const swap: Swap = async ( - _tokenIn, - _tokenOut, - amountIn, - _route, - _slippage, - _amountOut, -) => { +const swap: Swap = async ({ amountIn }) => { const { address } = getAccount(); if (amountIn === 0n || isNilOrEmpty(address)) { diff --git a/libs/oeth/swap/src/actions/swapZapperSfrxeth.ts b/libs/oeth/swap/src/actions/swapZapperSfrxeth.ts index 4c869bf1d..cacb39c2e 100644 --- a/libs/oeth/swap/src/actions/swapZapperSfrxeth.ts +++ b/libs/oeth/swap/src/actions/swapZapperSfrxeth.ts @@ -18,7 +18,7 @@ import type { Swap, } from '../types'; -const estimateAmount: EstimateAmount = async (_tokenIn, tokenOut, amountIn) => { +const estimateAmount: EstimateAmount = async ({ tokenOut, amountIn }) => { if (amountIn === 0n) { return 0n; } @@ -49,30 +49,24 @@ const estimateAmount: EstimateAmount = async (_tokenIn, tokenOut, amountIn) => { ); }; -const estimateGas: EstimateGas = async ( - _tokenIn, - _tokenOut, - amountIn, - _slippage, - _amountOut, -) => { +const estimateGas: EstimateGas = async () => { return 90000n; }; -const estimateRoute: EstimateRoute = async ( +const estimateRoute: EstimateRoute = async ({ tokenIn, tokenOut, amountIn, route, slippage, -) => { +}) => { if (amountIn === 0n) { return { ...route, estimatedAmount: 0n, gas: 0n, rate: 0 }; } const [estimatedAmount, gas] = await Promise.all([ - estimateAmount(tokenIn, tokenOut, amountIn), - estimateGas(tokenIn, tokenOut, amountIn, slippage), + estimateAmount({ tokenIn, tokenOut, amountIn }), + estimateGas({ tokenIn, tokenOut, amountIn, slippage }), ]); return { @@ -85,14 +79,13 @@ const estimateRoute: EstimateRoute = async ( }; }; -const swap: Swap = async ( +const swap: Swap = async ({ tokenIn, tokenOut, amountIn, - _route, slippage, amountOut, -) => { +}) => { const { address } = getAccount(); if (amountIn === 0n || isNilOrEmpty(address)) { diff --git a/libs/oeth/swap/src/actions/unwrapWOETH.ts b/libs/oeth/swap/src/actions/unwrapWOETH.ts index 4db8d470c..891712380 100644 --- a/libs/oeth/swap/src/actions/unwrapWOETH.ts +++ b/libs/oeth/swap/src/actions/unwrapWOETH.ts @@ -17,11 +17,7 @@ import type { Swap, } from '../types'; -const estimateAmount: EstimateAmount = async ( - _tokenIn, - _tokenOut, - amountIn, -) => { +const estimateAmount: EstimateAmount = async ({ amountIn }) => { if (amountIn === 0n) { return 0n; } @@ -36,12 +32,7 @@ const estimateAmount: EstimateAmount = async ( return data; }; -const estimateGas: EstimateGas = async ( - _tokenIn, - _tokenOut, - amountIn, - _slippage, -) => { +const estimateGas: EstimateGas = async ({ amountIn }) => { let gasEstimate = 0n; const publicClient = getPublicClient(); @@ -79,20 +70,20 @@ const estimateGas: EstimateGas = async ( return gasEstimate; }; -const estimateRoute: EstimateRoute = async ( +const estimateRoute: EstimateRoute = async ({ tokenIn, tokenOut, amountIn, route, slippage, -) => { +}) => { if (amountIn === 0n) { return { ...route, estimatedAmount: 0n, gas: 0n, rate: 0 }; } const [estimatedAmount, gas] = await Promise.all([ - estimateAmount(tokenIn, tokenOut, amountIn), - estimateGas(tokenIn, tokenOut, amountIn, slippage), + estimateAmount({ tokenIn, tokenOut, amountIn }), + estimateGas({ tokenIn, tokenOut, amountIn, slippage }), ]); return { @@ -105,7 +96,7 @@ const estimateRoute: EstimateRoute = async ( }; }; -const swap: Swap = async (_tokenIn, _tokenOut, amountIn, _route) => { +const swap: Swap = async ({ amountIn }) => { const { address } = getAccount(); if (amountIn === 0n || isNilOrEmpty(address)) { diff --git a/libs/oeth/swap/src/actions/wrapOETH.ts b/libs/oeth/swap/src/actions/wrapOETH.ts index 0c9b17537..a965bc429 100644 --- a/libs/oeth/swap/src/actions/wrapOETH.ts +++ b/libs/oeth/swap/src/actions/wrapOETH.ts @@ -17,11 +17,7 @@ import type { Swap, } from '../types'; -const estimateAmount: EstimateAmount = async ( - _tokenIn, - _tokenOut, - amountIn, -) => { +const estimateAmount: EstimateAmount = async ({ amountIn }) => { if (amountIn === 0n) { return 0n; } @@ -36,12 +32,7 @@ const estimateAmount: EstimateAmount = async ( return data; }; -const estimateGas: EstimateGas = async ( - _tokenIn, - _tokenOut, - amountIn, - _slippage, -) => { +const estimateGas: EstimateGas = async ({ amountIn }) => { let gasEstimate = 0n; const publicClient = getPublicClient(); @@ -79,20 +70,20 @@ const estimateGas: EstimateGas = async ( return gasEstimate; }; -const estimateRoute: EstimateRoute = async ( +const estimateRoute: EstimateRoute = async ({ tokenIn, tokenOut, amountIn, route, slippage, -) => { +}) => { if (amountIn === 0n) { return { ...route, estimatedAmount: 0n, gas: 0n, rate: 0 }; } const [estimatedAmount, gas] = await Promise.all([ - estimateAmount(tokenIn, tokenOut, amountIn), - estimateGas(tokenIn, tokenOut, amountIn, slippage), + estimateAmount({ tokenIn, tokenOut, amountIn }), + estimateGas({ tokenIn, tokenOut, amountIn, slippage }), ]); return { @@ -105,7 +96,7 @@ const estimateRoute: EstimateRoute = async ( }; }; -const swap: Swap = async (_tokenIn, _tokenOut, amountIn, _route) => { +const swap: Swap = async ({ amountIn }) => { const { address } = getAccount(); if (amountIn === 0n || isNilOrEmpty(address)) { diff --git a/libs/oeth/swap/src/hooks.ts b/libs/oeth/swap/src/hooks.ts index e5e2dccba..e12f6dfc7 100644 --- a/libs/oeth/swap/src/hooks.ts +++ b/libs/oeth/swap/src/hooks.ts @@ -1,5 +1,6 @@ import { useCallback, useMemo } from 'react'; +import { useCurve } from '@origin/shared/providers'; import { isNilOrEmpty } from '@origin/shared/utils'; import { produce } from 'immer'; @@ -19,10 +20,9 @@ export const useHandleAmountInChange = () => { setSwapState( produce((state) => { state.amountIn = amount; - state.amountOut = 0n; - state.isAmountOutLoading = true; - state.isPriceOutLoading = true; - state.isSwapRoutesLoading = true; + state.isAmountOutLoading = amount !== 0n; + state.isPriceOutLoading = amount !== 0n; + state.isSwapRoutesLoading = amount !== 0n; }), ); }, @@ -148,19 +148,29 @@ export const useHandleSwap = () => { const [ { amountIn, amountOut, selectedSwapRoute, slippage, tokenIn, tokenOut }, ] = useSwapState(); + const curve = useCurve(); return useCallback(async () => { if (isNilOrEmpty(selectedSwapRoute)) { return; } - await swapActions[selectedSwapRoute.action].swap( + await swapActions[selectedSwapRoute.action].swap({ tokenIn, tokenOut, amountIn, - selectedSwapRoute, + estimatedRoute: selectedSwapRoute, slippage, amountOut, - ); - }, [amountIn, amountOut, selectedSwapRoute, slippage, tokenIn, tokenOut]); + curve, + }); + }, [ + amountIn, + amountOut, + curve, + selectedSwapRoute, + slippage, + tokenIn, + tokenOut, + ]); }; diff --git a/libs/oeth/swap/src/state.ts b/libs/oeth/swap/src/state.ts index d28e86c10..9308efba4 100644 --- a/libs/oeth/swap/src/state.ts +++ b/libs/oeth/swap/src/state.ts @@ -2,6 +2,7 @@ import { useState } from 'react'; import { queryClient } from '@origin/oeth/shared'; import { tokens } from '@origin/shared/contracts'; +import { useCurve } from '@origin/shared/providers'; import { useDebouncedEffect } from '@react-hookz/web'; import { produce } from 'immer'; import { createContainer } from 'react-tracked'; @@ -26,10 +27,21 @@ export const { Provider: SwapProvider, useTracked: useSwapState } = selectedSwapRoute: null, isSwapRoutesLoading: false, }); + const { CurveRegistryExchange, OethPoolUnderlyings } = useCurve(); useDebouncedEffect( async () => { if (state.amountIn === 0n) { + setState( + produce((draft) => { + draft.swapRoutes = []; + draft.selectedSwapRoute = null; + draft.amountOut = 0n; + draft.isAmountOutLoading = false; + draft.isPriceOutLoading = false; + draft.isSwapRoutesLoading = false; + }), + ); return; } @@ -47,13 +59,18 @@ export const { Provider: SwapProvider, useTracked: useSwapState } = queryFn: async ({ queryKey: [, tokenIn, tokenOut, action, , slippage], }) => - swapActions[action].estimateRoute( + swapActions[action].estimateRoute({ tokenIn, tokenOut, - state.amountIn, + amountIn: state.amountIn, + amountOut: state.amountOut, route, slippage, - ), + curve: { + CurveRegistryExchange, + OethPoolUnderlyings, + }, + }), }), ), ); @@ -78,7 +95,7 @@ export const { Provider: SwapProvider, useTracked: useSwapState } = ); }, [state.amountIn], - 800, + state.amountIn === 0n ? 0 : 800, ); return [state, setState]; diff --git a/libs/oeth/swap/src/types.ts b/libs/oeth/swap/src/types.ts index 0a69f7d43..699a21b27 100644 --- a/libs/oeth/swap/src/types.ts +++ b/libs/oeth/swap/src/types.ts @@ -1,4 +1,5 @@ -import type { Token } from '@origin/shared/contracts'; +import type { Contract, Token } from '@origin/shared/contracts'; +import type { HexAddress } from '@origin/shared/utils'; export type TokenSource = 'tokenIn' | 'tokenOut'; @@ -11,35 +12,55 @@ export type SwapAction = | 'wrap-oeth' | 'unwrap-woeth'; +type Args = { + tokenIn: Token; + tokenOut: Token; + amountIn: bigint; + amountOut?: bigint; + slippage: number; + route: SwapRoute; + estimatedRoute: EstimatedSwapRoute; + curve?: { + CurveRegistryExchange: Contract; + OethPoolUnderlyings: HexAddress[]; + }; +}; + export type EstimateAmount = ( - tokenIn: Token, - tokenOut: Token, - amountIn: bigint, + args: Pick, ) => Promise; export type EstimateGas = ( - tokenIn: Token, - tokenOut: Token, - amountIn: bigint, - slippage: number, - amountOut?: bigint, + args: Pick< + Args, + 'tokenIn' | 'tokenOut' | 'amountIn' | 'amountOut' | 'slippage' | 'curve' + >, ) => Promise; export type EstimateRoute = ( - tokenIn: Token, - tokenOut: Token, - amountIn: bigint, - route: SwapRoute, - slippage: number, + args: Pick< + Args, + | 'tokenIn' + | 'tokenOut' + | 'amountIn' + | 'amountOut' + | 'slippage' + | 'route' + | 'curve' + >, ) => Promise; export type Swap = ( - tokenIn: Token, - tokenOut: Token, - amountIn: bigint, - route: EstimatedSwapRoute, - slippage: number, - amountOut?: bigint, + args: Pick< + Args, + | 'tokenIn' + | 'tokenOut' + | 'amountIn' + | 'amountOut' + | 'slippage' + | 'estimatedRoute' + | 'curve' + >, ) => Promise; export type SwapApi = { diff --git a/libs/shared/contracts/abi-json/CurveAddressProvider.json b/libs/shared/contracts/abi-json/CurveAddressProvider.json new file mode 100644 index 000000000..f0ad12e9f --- /dev/null +++ b/libs/shared/contracts/abi-json/CurveAddressProvider.json @@ -0,0 +1,296 @@ +[ + { + "name": "NewAddressIdentifier", + "inputs": [ + { + "type": "uint256", + "name": "id", + "indexed": true + }, + { + "type": "address", + "name": "addr", + "indexed": false + }, + { + "type": "string", + "name": "description", + "indexed": false + } + ], + "anonymous": false, + "type": "event" + }, + { + "name": "AddressModified", + "inputs": [ + { + "type": "uint256", + "name": "id", + "indexed": true + }, + { + "type": "address", + "name": "new_address", + "indexed": false + }, + { + "type": "uint256", + "name": "version", + "indexed": false + } + ], + "anonymous": false, + "type": "event" + }, + { + "name": "CommitNewAdmin", + "inputs": [ + { + "type": "uint256", + "name": "deadline", + "indexed": true + }, + { + "type": "address", + "name": "admin", + "indexed": true + } + ], + "anonymous": false, + "type": "event" + }, + { + "name": "NewAdmin", + "inputs": [ + { + "type": "address", + "name": "admin", + "indexed": true + } + ], + "anonymous": false, + "type": "event" + }, + { + "outputs": [], + "inputs": [ + { + "type": "address", + "name": "_admin" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "name": "get_registry", + "outputs": [ + { + "type": "address", + "name": "" + } + ], + "inputs": [], + "stateMutability": "view", + "type": "function" + }, + { + "name": "max_id", + "outputs": [ + { + "type": "uint256", + "name": "" + } + ], + "inputs": [], + "stateMutability": "view", + "type": "function" + }, + { + "name": "get_address", + "outputs": [ + { + "type": "address", + "name": "" + } + ], + "inputs": [ + { + "type": "uint256", + "name": "_id" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "name": "add_new_id", + "outputs": [ + { + "type": "uint256", + "name": "" + } + ], + "inputs": [ + { + "type": "address", + "name": "_address" + }, + { + "type": "string", + "name": "_description" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "name": "set_address", + "outputs": [ + { + "type": "bool", + "name": "" + } + ], + "inputs": [ + { + "type": "uint256", + "name": "_id" + }, + { + "type": "address", + "name": "_address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "name": "unset_address", + "outputs": [ + { + "type": "bool", + "name": "" + } + ], + "inputs": [ + { + "type": "uint256", + "name": "_id" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "name": "commit_transfer_ownership", + "outputs": [ + { + "type": "bool", + "name": "" + } + ], + "inputs": [ + { + "type": "address", + "name": "_new_admin" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "name": "apply_transfer_ownership", + "outputs": [ + { + "type": "bool", + "name": "" + } + ], + "inputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "name": "revert_transfer_ownership", + "outputs": [ + { + "type": "bool", + "name": "" + } + ], + "inputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "name": "admin", + "outputs": [ + { + "type": "address", + "name": "" + } + ], + "inputs": [], + "stateMutability": "view", + "type": "function" + }, + { + "name": "transfer_ownership_deadline", + "outputs": [ + { + "type": "uint256", + "name": "" + } + ], + "inputs": [], + "stateMutability": "view", + "type": "function" + }, + { + "name": "future_admin", + "outputs": [ + { + "type": "address", + "name": "" + } + ], + "inputs": [], + "stateMutability": "view", + "type": "function" + }, + { + "name": "get_id_info", + "outputs": [ + { + "type": "address", + "name": "addr" + }, + { + "type": "bool", + "name": "is_active" + }, + { + "type": "uint256", + "name": "version" + }, + { + "type": "uint256", + "name": "last_modified" + }, + { + "type": "string", + "name": "description" + } + ], + "inputs": [ + { + "type": "uint256", + "name": "arg0" + } + ], + "stateMutability": "view", + "type": "function" + } +] diff --git a/libs/shared/contracts/abi-json/CurveFactory.json b/libs/shared/contracts/abi-json/CurveFactory.json new file mode 100644 index 000000000..0e937d334 --- /dev/null +++ b/libs/shared/contracts/abi-json/CurveFactory.json @@ -0,0 +1,508 @@ +[ + { + "name": "BasePoolAdded", + "inputs": [{ "name": "base_pool", "type": "address", "indexed": false }], + "anonymous": false, + "type": "event" + }, + { + "name": "PlainPoolDeployed", + "inputs": [ + { "name": "coins", "type": "address[4]", "indexed": false }, + { "name": "A", "type": "uint256", "indexed": false }, + { "name": "fee", "type": "uint256", "indexed": false }, + { "name": "deployer", "type": "address", "indexed": false } + ], + "anonymous": false, + "type": "event" + }, + { + "name": "MetaPoolDeployed", + "inputs": [ + { "name": "coin", "type": "address", "indexed": false }, + { "name": "base_pool", "type": "address", "indexed": false }, + { "name": "A", "type": "uint256", "indexed": false }, + { "name": "fee", "type": "uint256", "indexed": false }, + { "name": "deployer", "type": "address", "indexed": false } + ], + "anonymous": false, + "type": "event" + }, + { + "name": "LiquidityGaugeDeployed", + "inputs": [ + { "name": "pool", "type": "address", "indexed": false }, + { "name": "gauge", "type": "address", "indexed": false } + ], + "anonymous": false, + "type": "event" + }, + { + "stateMutability": "nonpayable", + "type": "constructor", + "inputs": [{ "name": "_fee_receiver", "type": "address" }], + "outputs": [] + }, + { + "stateMutability": "view", + "type": "function", + "name": "metapool_implementations", + "inputs": [{ "name": "_base_pool", "type": "address" }], + "outputs": [{ "name": "", "type": "address[10]" }], + "gas": 21716 + }, + { + "stateMutability": "view", + "type": "function", + "name": "find_pool_for_coins", + "inputs": [ + { "name": "_from", "type": "address" }, + { "name": "_to", "type": "address" } + ], + "outputs": [{ "name": "", "type": "address" }] + }, + { + "stateMutability": "view", + "type": "function", + "name": "find_pool_for_coins", + "inputs": [ + { "name": "_from", "type": "address" }, + { "name": "_to", "type": "address" }, + { "name": "i", "type": "uint256" } + ], + "outputs": [{ "name": "", "type": "address" }] + }, + { + "stateMutability": "view", + "type": "function", + "name": "get_base_pool", + "inputs": [{ "name": "_pool", "type": "address" }], + "outputs": [{ "name": "", "type": "address" }], + "gas": 2663 + }, + { + "stateMutability": "view", + "type": "function", + "name": "get_n_coins", + "inputs": [{ "name": "_pool", "type": "address" }], + "outputs": [{ "name": "", "type": "uint256" }], + "gas": 2699 + }, + { + "stateMutability": "view", + "type": "function", + "name": "get_meta_n_coins", + "inputs": [{ "name": "_pool", "type": "address" }], + "outputs": [ + { "name": "", "type": "uint256" }, + { "name": "", "type": "uint256" } + ], + "gas": 5201 + }, + { + "stateMutability": "view", + "type": "function", + "name": "get_coins", + "inputs": [{ "name": "_pool", "type": "address" }], + "outputs": [{ "name": "", "type": "address[4]" }], + "gas": 9164 + }, + { + "stateMutability": "view", + "type": "function", + "name": "get_underlying_coins", + "inputs": [{ "name": "_pool", "type": "address" }], + "outputs": [{ "name": "", "type": "address[8]" }], + "gas": 21345 + }, + { + "stateMutability": "view", + "type": "function", + "name": "get_decimals", + "inputs": [{ "name": "_pool", "type": "address" }], + "outputs": [{ "name": "", "type": "uint256[4]" }], + "gas": 20185 + }, + { + "stateMutability": "view", + "type": "function", + "name": "get_underlying_decimals", + "inputs": [{ "name": "_pool", "type": "address" }], + "outputs": [{ "name": "", "type": "uint256[8]" }], + "gas": 19730 + }, + { + "stateMutability": "view", + "type": "function", + "name": "get_metapool_rates", + "inputs": [{ "name": "_pool", "type": "address" }], + "outputs": [{ "name": "", "type": "uint256[2]" }], + "gas": 5281 + }, + { + "stateMutability": "view", + "type": "function", + "name": "get_balances", + "inputs": [{ "name": "_pool", "type": "address" }], + "outputs": [{ "name": "", "type": "uint256[4]" }], + "gas": 20435 + }, + { + "stateMutability": "view", + "type": "function", + "name": "get_underlying_balances", + "inputs": [{ "name": "_pool", "type": "address" }], + "outputs": [{ "name": "", "type": "uint256[8]" }], + "gas": 39733 + }, + { + "stateMutability": "view", + "type": "function", + "name": "get_A", + "inputs": [{ "name": "_pool", "type": "address" }], + "outputs": [{ "name": "", "type": "uint256" }], + "gas": 3135 + }, + { + "stateMutability": "view", + "type": "function", + "name": "get_fees", + "inputs": [{ "name": "_pool", "type": "address" }], + "outputs": [ + { "name": "", "type": "uint256" }, + { "name": "", "type": "uint256" } + ], + "gas": 5821 + }, + { + "stateMutability": "view", + "type": "function", + "name": "get_admin_balances", + "inputs": [{ "name": "_pool", "type": "address" }], + "outputs": [{ "name": "", "type": "uint256[4]" }], + "gas": 13535 + }, + { + "stateMutability": "view", + "type": "function", + "name": "get_coin_indices", + "inputs": [ + { "name": "_pool", "type": "address" }, + { "name": "_from", "type": "address" }, + { "name": "_to", "type": "address" } + ], + "outputs": [ + { "name": "", "type": "int128" }, + { "name": "", "type": "int128" }, + { "name": "", "type": "bool" } + ], + "gas": 33407 + }, + { + "stateMutability": "view", + "type": "function", + "name": "get_gauge", + "inputs": [{ "name": "_pool", "type": "address" }], + "outputs": [{ "name": "", "type": "address" }], + "gas": 3089 + }, + { + "stateMutability": "view", + "type": "function", + "name": "get_implementation_address", + "inputs": [{ "name": "_pool", "type": "address" }], + "outputs": [{ "name": "", "type": "address" }], + "gas": 3119 + }, + { + "stateMutability": "view", + "type": "function", + "name": "is_meta", + "inputs": [{ "name": "_pool", "type": "address" }], + "outputs": [{ "name": "", "type": "bool" }], + "gas": 3152 + }, + { + "stateMutability": "view", + "type": "function", + "name": "get_pool_asset_type", + "inputs": [{ "name": "_pool", "type": "address" }], + "outputs": [{ "name": "", "type": "uint256" }], + "gas": 5450 + }, + { + "stateMutability": "view", + "type": "function", + "name": "get_fee_receiver", + "inputs": [{ "name": "_pool", "type": "address" }], + "outputs": [{ "name": "", "type": "address" }], + "gas": 5480 + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "deploy_plain_pool", + "inputs": [ + { "name": "_name", "type": "string" }, + { "name": "_symbol", "type": "string" }, + { "name": "_coins", "type": "address[4]" }, + { "name": "_A", "type": "uint256" }, + { "name": "_fee", "type": "uint256" } + ], + "outputs": [{ "name": "", "type": "address" }] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "deploy_plain_pool", + "inputs": [ + { "name": "_name", "type": "string" }, + { "name": "_symbol", "type": "string" }, + { "name": "_coins", "type": "address[4]" }, + { "name": "_A", "type": "uint256" }, + { "name": "_fee", "type": "uint256" }, + { "name": "_asset_type", "type": "uint256" } + ], + "outputs": [{ "name": "", "type": "address" }] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "deploy_plain_pool", + "inputs": [ + { "name": "_name", "type": "string" }, + { "name": "_symbol", "type": "string" }, + { "name": "_coins", "type": "address[4]" }, + { "name": "_A", "type": "uint256" }, + { "name": "_fee", "type": "uint256" }, + { "name": "_asset_type", "type": "uint256" }, + { "name": "_implementation_idx", "type": "uint256" } + ], + "outputs": [{ "name": "", "type": "address" }] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "deploy_metapool", + "inputs": [ + { "name": "_base_pool", "type": "address" }, + { "name": "_name", "type": "string" }, + { "name": "_symbol", "type": "string" }, + { "name": "_coin", "type": "address" }, + { "name": "_A", "type": "uint256" }, + { "name": "_fee", "type": "uint256" } + ], + "outputs": [{ "name": "", "type": "address" }] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "deploy_metapool", + "inputs": [ + { "name": "_base_pool", "type": "address" }, + { "name": "_name", "type": "string" }, + { "name": "_symbol", "type": "string" }, + { "name": "_coin", "type": "address" }, + { "name": "_A", "type": "uint256" }, + { "name": "_fee", "type": "uint256" }, + { "name": "_implementation_idx", "type": "uint256" } + ], + "outputs": [{ "name": "", "type": "address" }] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "deploy_gauge", + "inputs": [{ "name": "_pool", "type": "address" }], + "outputs": [{ "name": "", "type": "address" }], + "gas": 93079 + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "add_base_pool", + "inputs": [ + { "name": "_base_pool", "type": "address" }, + { "name": "_fee_receiver", "type": "address" }, + { "name": "_asset_type", "type": "uint256" }, + { "name": "_implementations", "type": "address[10]" } + ], + "outputs": [], + "gas": 1206132 + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "set_metapool_implementations", + "inputs": [ + { "name": "_base_pool", "type": "address" }, + { "name": "_implementations", "type": "address[10]" } + ], + "outputs": [], + "gas": 382072 + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "set_plain_implementations", + "inputs": [ + { "name": "_n_coins", "type": "uint256" }, + { "name": "_implementations", "type": "address[10]" } + ], + "outputs": [], + "gas": 379687 + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "set_gauge_implementation", + "inputs": [{ "name": "_gauge_implementation", "type": "address" }], + "outputs": [], + "gas": 38355 + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "batch_set_pool_asset_type", + "inputs": [ + { "name": "_pools", "type": "address[32]" }, + { "name": "_asset_types", "type": "uint256[32]" } + ], + "outputs": [], + "gas": 1139545 + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "commit_transfer_ownership", + "inputs": [{ "name": "_addr", "type": "address" }], + "outputs": [], + "gas": 38415 + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "accept_transfer_ownership", + "inputs": [], + "outputs": [], + "gas": 58366 + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "set_manager", + "inputs": [{ "name": "_manager", "type": "address" }], + "outputs": [], + "gas": 40996 + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "set_fee_receiver", + "inputs": [ + { "name": "_base_pool", "type": "address" }, + { "name": "_fee_receiver", "type": "address" } + ], + "outputs": [], + "gas": 38770 + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "convert_metapool_fees", + "inputs": [], + "outputs": [{ "name": "", "type": "bool" }], + "gas": 12880 + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "add_existing_metapools", + "inputs": [{ "name": "_pools", "type": "address[10]" }], + "outputs": [{ "name": "", "type": "bool" }], + "gas": 8610792 + }, + { + "stateMutability": "view", + "type": "function", + "name": "admin", + "inputs": [], + "outputs": [{ "name": "", "type": "address" }], + "gas": 3438 + }, + { + "stateMutability": "view", + "type": "function", + "name": "future_admin", + "inputs": [], + "outputs": [{ "name": "", "type": "address" }], + "gas": 3468 + }, + { + "stateMutability": "view", + "type": "function", + "name": "manager", + "inputs": [], + "outputs": [{ "name": "", "type": "address" }], + "gas": 3498 + }, + { + "stateMutability": "view", + "type": "function", + "name": "pool_list", + "inputs": [{ "name": "arg0", "type": "uint256" }], + "outputs": [{ "name": "", "type": "address" }], + "gas": 3573 + }, + { + "stateMutability": "view", + "type": "function", + "name": "pool_count", + "inputs": [], + "outputs": [{ "name": "", "type": "uint256" }], + "gas": 3558 + }, + { + "stateMutability": "view", + "type": "function", + "name": "base_pool_list", + "inputs": [{ "name": "arg0", "type": "uint256" }], + "outputs": [{ "name": "", "type": "address" }], + "gas": 3633 + }, + { + "stateMutability": "view", + "type": "function", + "name": "base_pool_count", + "inputs": [], + "outputs": [{ "name": "", "type": "uint256" }], + "gas": 3618 + }, + { + "stateMutability": "view", + "type": "function", + "name": "base_pool_assets", + "inputs": [{ "name": "arg0", "type": "address" }], + "outputs": [{ "name": "", "type": "bool" }], + "gas": 3863 + }, + { + "stateMutability": "view", + "type": "function", + "name": "plain_implementations", + "inputs": [ + { "name": "arg0", "type": "uint256" }, + { "name": "arg1", "type": "uint256" } + ], + "outputs": [{ "name": "", "type": "address" }], + "gas": 3838 + }, + { + "stateMutability": "view", + "type": "function", + "name": "gauge_implementation", + "inputs": [], + "outputs": [{ "name": "", "type": "address" }], + "gas": 3708 + } +] diff --git a/libs/shared/contracts/abi-json/CurveRegistryExchange.json b/libs/shared/contracts/abi-json/CurveRegistryExchange.json new file mode 100644 index 000000000..b5803ba03 --- /dev/null +++ b/libs/shared/contracts/abi-json/CurveRegistryExchange.json @@ -0,0 +1,300 @@ +[ + { + "name": "TokenExchange", + "inputs": [ + { "name": "buyer", "type": "address", "indexed": true }, + { "name": "receiver", "type": "address", "indexed": true }, + { "name": "pool", "type": "address", "indexed": true }, + { "name": "token_sold", "type": "address", "indexed": false }, + { "name": "token_bought", "type": "address", "indexed": false }, + { "name": "amount_sold", "type": "uint256", "indexed": false }, + { "name": "amount_bought", "type": "uint256", "indexed": false } + ], + "anonymous": false, + "type": "event" + }, + { + "name": "ExchangeMultiple", + "inputs": [ + { "name": "buyer", "type": "address", "indexed": true }, + { "name": "receiver", "type": "address", "indexed": true }, + { "name": "route", "type": "address[9]", "indexed": false }, + { "name": "swap_params", "type": "uint256[3][4]", "indexed": false }, + { "name": "pools", "type": "address[4]", "indexed": false }, + { "name": "amount_sold", "type": "uint256", "indexed": false }, + { "name": "amount_bought", "type": "uint256", "indexed": false } + ], + "anonymous": false, + "type": "event" + }, + { + "stateMutability": "nonpayable", + "type": "constructor", + "inputs": [ + { "name": "_address_provider", "type": "address" }, + { "name": "_calculator", "type": "address" }, + { "name": "_weth", "type": "address" } + ], + "outputs": [] + }, + { "stateMutability": "payable", "type": "fallback" }, + { + "stateMutability": "payable", + "type": "function", + "name": "exchange_with_best_rate", + "inputs": [ + { "name": "_from", "type": "address" }, + { "name": "_to", "type": "address" }, + { "name": "_amount", "type": "uint256" }, + { "name": "_expected", "type": "uint256" } + ], + "outputs": [{ "name": "", "type": "uint256" }] + }, + { + "stateMutability": "payable", + "type": "function", + "name": "exchange_with_best_rate", + "inputs": [ + { "name": "_from", "type": "address" }, + { "name": "_to", "type": "address" }, + { "name": "_amount", "type": "uint256" }, + { "name": "_expected", "type": "uint256" }, + { "name": "_receiver", "type": "address" } + ], + "outputs": [{ "name": "", "type": "uint256" }] + }, + { + "stateMutability": "payable", + "type": "function", + "name": "exchange", + "inputs": [ + { "name": "_pool", "type": "address" }, + { "name": "_from", "type": "address" }, + { "name": "_to", "type": "address" }, + { "name": "_amount", "type": "uint256" }, + { "name": "_expected", "type": "uint256" } + ], + "outputs": [{ "name": "", "type": "uint256" }] + }, + { + "stateMutability": "payable", + "type": "function", + "name": "exchange", + "inputs": [ + { "name": "_pool", "type": "address" }, + { "name": "_from", "type": "address" }, + { "name": "_to", "type": "address" }, + { "name": "_amount", "type": "uint256" }, + { "name": "_expected", "type": "uint256" }, + { "name": "_receiver", "type": "address" } + ], + "outputs": [{ "name": "", "type": "uint256" }] + }, + { + "stateMutability": "payable", + "type": "function", + "name": "exchange_multiple", + "inputs": [ + { "name": "_route", "type": "address[9]" }, + { "name": "_swap_params", "type": "uint256[3][4]" }, + { "name": "_amount", "type": "uint256" }, + { "name": "_expected", "type": "uint256" } + ], + "outputs": [{ "name": "", "type": "uint256" }] + }, + { + "stateMutability": "payable", + "type": "function", + "name": "exchange_multiple", + "inputs": [ + { "name": "_route", "type": "address[9]" }, + { "name": "_swap_params", "type": "uint256[3][4]" }, + { "name": "_amount", "type": "uint256" }, + { "name": "_expected", "type": "uint256" }, + { "name": "_pools", "type": "address[4]" } + ], + "outputs": [{ "name": "", "type": "uint256" }] + }, + { + "stateMutability": "payable", + "type": "function", + "name": "exchange_multiple", + "inputs": [ + { "name": "_route", "type": "address[9]" }, + { "name": "_swap_params", "type": "uint256[3][4]" }, + { "name": "_amount", "type": "uint256" }, + { "name": "_expected", "type": "uint256" }, + { "name": "_pools", "type": "address[4]" }, + { "name": "_receiver", "type": "address" } + ], + "outputs": [{ "name": "", "type": "uint256" }] + }, + { + "stateMutability": "view", + "type": "function", + "name": "get_best_rate", + "inputs": [ + { "name": "_from", "type": "address" }, + { "name": "_to", "type": "address" }, + { "name": "_amount", "type": "uint256" } + ], + "outputs": [ + { "name": "", "type": "address" }, + { "name": "", "type": "uint256" } + ] + }, + { + "stateMutability": "view", + "type": "function", + "name": "get_best_rate", + "inputs": [ + { "name": "_from", "type": "address" }, + { "name": "_to", "type": "address" }, + { "name": "_amount", "type": "uint256" }, + { "name": "_exclude_pools", "type": "address[8]" } + ], + "outputs": [ + { "name": "", "type": "address" }, + { "name": "", "type": "uint256" } + ] + }, + { + "stateMutability": "view", + "type": "function", + "name": "get_exchange_amount", + "inputs": [ + { "name": "_pool", "type": "address" }, + { "name": "_from", "type": "address" }, + { "name": "_to", "type": "address" }, + { "name": "_amount", "type": "uint256" } + ], + "outputs": [{ "name": "", "type": "uint256" }] + }, + { + "stateMutability": "view", + "type": "function", + "name": "get_input_amount", + "inputs": [ + { "name": "_pool", "type": "address" }, + { "name": "_from", "type": "address" }, + { "name": "_to", "type": "address" }, + { "name": "_amount", "type": "uint256" } + ], + "outputs": [{ "name": "", "type": "uint256" }] + }, + { + "stateMutability": "view", + "type": "function", + "name": "get_exchange_amounts", + "inputs": [ + { "name": "_pool", "type": "address" }, + { "name": "_from", "type": "address" }, + { "name": "_to", "type": "address" }, + { "name": "_amounts", "type": "uint256[100]" } + ], + "outputs": [{ "name": "", "type": "uint256[100]" }] + }, + { + "stateMutability": "view", + "type": "function", + "name": "get_exchange_multiple_amount", + "inputs": [ + { "name": "_route", "type": "address[9]" }, + { "name": "_swap_params", "type": "uint256[3][4]" }, + { "name": "_amount", "type": "uint256" } + ], + "outputs": [{ "name": "", "type": "uint256" }] + }, + { + "stateMutability": "view", + "type": "function", + "name": "get_exchange_multiple_amount", + "inputs": [ + { "name": "_route", "type": "address[9]" }, + { "name": "_swap_params", "type": "uint256[3][4]" }, + { "name": "_amount", "type": "uint256" }, + { "name": "_pools", "type": "address[4]" } + ], + "outputs": [{ "name": "", "type": "uint256" }] + }, + { + "stateMutability": "view", + "type": "function", + "name": "get_calculator", + "inputs": [{ "name": "_pool", "type": "address" }], + "outputs": [{ "name": "", "type": "address" }] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "update_registry_address", + "inputs": [], + "outputs": [{ "name": "", "type": "bool" }] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "set_calculator", + "inputs": [ + { "name": "_pool", "type": "address" }, + { "name": "_calculator", "type": "address" } + ], + "outputs": [{ "name": "", "type": "bool" }] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "set_default_calculator", + "inputs": [{ "name": "_calculator", "type": "address" }], + "outputs": [{ "name": "", "type": "bool" }] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "claim_balance", + "inputs": [{ "name": "_token", "type": "address" }], + "outputs": [{ "name": "", "type": "bool" }] + }, + { + "stateMutability": "nonpayable", + "type": "function", + "name": "set_killed", + "inputs": [{ "name": "_is_killed", "type": "bool" }], + "outputs": [{ "name": "", "type": "bool" }] + }, + { + "stateMutability": "view", + "type": "function", + "name": "registry", + "inputs": [], + "outputs": [{ "name": "", "type": "address" }] + }, + { + "stateMutability": "view", + "type": "function", + "name": "factory_registry", + "inputs": [], + "outputs": [{ "name": "", "type": "address" }] + }, + { + "stateMutability": "view", + "type": "function", + "name": "crypto_registry", + "inputs": [], + "outputs": [{ "name": "", "type": "address" }] + }, + { + "stateMutability": "view", + "type": "function", + "name": "default_calculator", + "inputs": [], + "outputs": [{ "name": "", "type": "address" }] + }, + { + "stateMutability": "view", + "type": "function", + "name": "is_killed", + "inputs": [], + "outputs": [{ "name": "", "type": "bool" }] + } +] \ No newline at end of file diff --git a/libs/shared/contracts/src/abis/CurveAddressProvider.ts b/libs/shared/contracts/src/abis/CurveAddressProvider.ts new file mode 100644 index 000000000..d98239ecc --- /dev/null +++ b/libs/shared/contracts/src/abis/CurveAddressProvider.ts @@ -0,0 +1,147 @@ +// DO NOT EDIT - GENERATED +export const CurveAddressProviderABI = [ + { + name: 'NewAddressIdentifier', + inputs: [ + { type: 'uint256', name: 'id', indexed: true }, + { type: 'address', name: 'addr', indexed: false }, + { type: 'string', name: 'description', indexed: false }, + ], + anonymous: false, + type: 'event', + }, + { + name: 'AddressModified', + inputs: [ + { type: 'uint256', name: 'id', indexed: true }, + { type: 'address', name: 'new_address', indexed: false }, + { type: 'uint256', name: 'version', indexed: false }, + ], + anonymous: false, + type: 'event', + }, + { + name: 'CommitNewAdmin', + inputs: [ + { type: 'uint256', name: 'deadline', indexed: true }, + { type: 'address', name: 'admin', indexed: true }, + ], + anonymous: false, + type: 'event', + }, + { + name: 'NewAdmin', + inputs: [{ type: 'address', name: 'admin', indexed: true }], + anonymous: false, + type: 'event', + }, + { + outputs: [], + inputs: [{ type: 'address', name: '_admin' }], + stateMutability: 'nonpayable', + type: 'constructor', + }, + { + name: 'get_registry', + outputs: [{ type: 'address', name: '' }], + inputs: [], + stateMutability: 'view', + type: 'function', + }, + { + name: 'max_id', + outputs: [{ type: 'uint256', name: '' }], + inputs: [], + stateMutability: 'view', + type: 'function', + }, + { + name: 'get_address', + outputs: [{ type: 'address', name: '' }], + inputs: [{ type: 'uint256', name: '_id' }], + stateMutability: 'view', + type: 'function', + }, + { + name: 'add_new_id', + outputs: [{ type: 'uint256', name: '' }], + inputs: [ + { type: 'address', name: '_address' }, + { type: 'string', name: '_description' }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, + { + name: 'set_address', + outputs: [{ type: 'bool', name: '' }], + inputs: [ + { type: 'uint256', name: '_id' }, + { type: 'address', name: '_address' }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, + { + name: 'unset_address', + outputs: [{ type: 'bool', name: '' }], + inputs: [{ type: 'uint256', name: '_id' }], + stateMutability: 'nonpayable', + type: 'function', + }, + { + name: 'commit_transfer_ownership', + outputs: [{ type: 'bool', name: '' }], + inputs: [{ type: 'address', name: '_new_admin' }], + stateMutability: 'nonpayable', + type: 'function', + }, + { + name: 'apply_transfer_ownership', + outputs: [{ type: 'bool', name: '' }], + inputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + name: 'revert_transfer_ownership', + outputs: [{ type: 'bool', name: '' }], + inputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + name: 'admin', + outputs: [{ type: 'address', name: '' }], + inputs: [], + stateMutability: 'view', + type: 'function', + }, + { + name: 'transfer_ownership_deadline', + outputs: [{ type: 'uint256', name: '' }], + inputs: [], + stateMutability: 'view', + type: 'function', + }, + { + name: 'future_admin', + outputs: [{ type: 'address', name: '' }], + inputs: [], + stateMutability: 'view', + type: 'function', + }, + { + name: 'get_id_info', + outputs: [ + { type: 'address', name: 'addr' }, + { type: 'bool', name: 'is_active' }, + { type: 'uint256', name: 'version' }, + { type: 'uint256', name: 'last_modified' }, + { type: 'string', name: 'description' }, + ], + inputs: [{ type: 'uint256', name: 'arg0' }], + stateMutability: 'view', + type: 'function', + }, +] as const; diff --git a/libs/shared/contracts/src/abis/CurveFactory.ts b/libs/shared/contracts/src/abis/CurveFactory.ts new file mode 100644 index 000000000..afc1ba8aa --- /dev/null +++ b/libs/shared/contracts/src/abis/CurveFactory.ts @@ -0,0 +1,509 @@ +// DO NOT EDIT - GENERATED +export const CurveFactoryABI = [ + { + name: 'BasePoolAdded', + inputs: [{ name: 'base_pool', type: 'address', indexed: false }], + anonymous: false, + type: 'event', + }, + { + name: 'PlainPoolDeployed', + inputs: [ + { name: 'coins', type: 'address[4]', indexed: false }, + { name: 'A', type: 'uint256', indexed: false }, + { name: 'fee', type: 'uint256', indexed: false }, + { name: 'deployer', type: 'address', indexed: false }, + ], + anonymous: false, + type: 'event', + }, + { + name: 'MetaPoolDeployed', + inputs: [ + { name: 'coin', type: 'address', indexed: false }, + { name: 'base_pool', type: 'address', indexed: false }, + { name: 'A', type: 'uint256', indexed: false }, + { name: 'fee', type: 'uint256', indexed: false }, + { name: 'deployer', type: 'address', indexed: false }, + ], + anonymous: false, + type: 'event', + }, + { + name: 'LiquidityGaugeDeployed', + inputs: [ + { name: 'pool', type: 'address', indexed: false }, + { name: 'gauge', type: 'address', indexed: false }, + ], + anonymous: false, + type: 'event', + }, + { + stateMutability: 'nonpayable', + type: 'constructor', + inputs: [{ name: '_fee_receiver', type: 'address' }], + outputs: [], + }, + { + stateMutability: 'view', + type: 'function', + name: 'metapool_implementations', + inputs: [{ name: '_base_pool', type: 'address' }], + outputs: [{ name: '', type: 'address[10]' }], + gas: 21716, + }, + { + stateMutability: 'view', + type: 'function', + name: 'find_pool_for_coins', + inputs: [ + { name: '_from', type: 'address' }, + { name: '_to', type: 'address' }, + ], + outputs: [{ name: '', type: 'address' }], + }, + { + stateMutability: 'view', + type: 'function', + name: 'find_pool_for_coins', + inputs: [ + { name: '_from', type: 'address' }, + { name: '_to', type: 'address' }, + { name: 'i', type: 'uint256' }, + ], + outputs: [{ name: '', type: 'address' }], + }, + { + stateMutability: 'view', + type: 'function', + name: 'get_base_pool', + inputs: [{ name: '_pool', type: 'address' }], + outputs: [{ name: '', type: 'address' }], + gas: 2663, + }, + { + stateMutability: 'view', + type: 'function', + name: 'get_n_coins', + inputs: [{ name: '_pool', type: 'address' }], + outputs: [{ name: '', type: 'uint256' }], + gas: 2699, + }, + { + stateMutability: 'view', + type: 'function', + name: 'get_meta_n_coins', + inputs: [{ name: '_pool', type: 'address' }], + outputs: [ + { name: '', type: 'uint256' }, + { name: '', type: 'uint256' }, + ], + gas: 5201, + }, + { + stateMutability: 'view', + type: 'function', + name: 'get_coins', + inputs: [{ name: '_pool', type: 'address' }], + outputs: [{ name: '', type: 'address[4]' }], + gas: 9164, + }, + { + stateMutability: 'view', + type: 'function', + name: 'get_underlying_coins', + inputs: [{ name: '_pool', type: 'address' }], + outputs: [{ name: '', type: 'address[8]' }], + gas: 21345, + }, + { + stateMutability: 'view', + type: 'function', + name: 'get_decimals', + inputs: [{ name: '_pool', type: 'address' }], + outputs: [{ name: '', type: 'uint256[4]' }], + gas: 20185, + }, + { + stateMutability: 'view', + type: 'function', + name: 'get_underlying_decimals', + inputs: [{ name: '_pool', type: 'address' }], + outputs: [{ name: '', type: 'uint256[8]' }], + gas: 19730, + }, + { + stateMutability: 'view', + type: 'function', + name: 'get_metapool_rates', + inputs: [{ name: '_pool', type: 'address' }], + outputs: [{ name: '', type: 'uint256[2]' }], + gas: 5281, + }, + { + stateMutability: 'view', + type: 'function', + name: 'get_balances', + inputs: [{ name: '_pool', type: 'address' }], + outputs: [{ name: '', type: 'uint256[4]' }], + gas: 20435, + }, + { + stateMutability: 'view', + type: 'function', + name: 'get_underlying_balances', + inputs: [{ name: '_pool', type: 'address' }], + outputs: [{ name: '', type: 'uint256[8]' }], + gas: 39733, + }, + { + stateMutability: 'view', + type: 'function', + name: 'get_A', + inputs: [{ name: '_pool', type: 'address' }], + outputs: [{ name: '', type: 'uint256' }], + gas: 3135, + }, + { + stateMutability: 'view', + type: 'function', + name: 'get_fees', + inputs: [{ name: '_pool', type: 'address' }], + outputs: [ + { name: '', type: 'uint256' }, + { name: '', type: 'uint256' }, + ], + gas: 5821, + }, + { + stateMutability: 'view', + type: 'function', + name: 'get_admin_balances', + inputs: [{ name: '_pool', type: 'address' }], + outputs: [{ name: '', type: 'uint256[4]' }], + gas: 13535, + }, + { + stateMutability: 'view', + type: 'function', + name: 'get_coin_indices', + inputs: [ + { name: '_pool', type: 'address' }, + { name: '_from', type: 'address' }, + { name: '_to', type: 'address' }, + ], + outputs: [ + { name: '', type: 'int128' }, + { name: '', type: 'int128' }, + { name: '', type: 'bool' }, + ], + gas: 33407, + }, + { + stateMutability: 'view', + type: 'function', + name: 'get_gauge', + inputs: [{ name: '_pool', type: 'address' }], + outputs: [{ name: '', type: 'address' }], + gas: 3089, + }, + { + stateMutability: 'view', + type: 'function', + name: 'get_implementation_address', + inputs: [{ name: '_pool', type: 'address' }], + outputs: [{ name: '', type: 'address' }], + gas: 3119, + }, + { + stateMutability: 'view', + type: 'function', + name: 'is_meta', + inputs: [{ name: '_pool', type: 'address' }], + outputs: [{ name: '', type: 'bool' }], + gas: 3152, + }, + { + stateMutability: 'view', + type: 'function', + name: 'get_pool_asset_type', + inputs: [{ name: '_pool', type: 'address' }], + outputs: [{ name: '', type: 'uint256' }], + gas: 5450, + }, + { + stateMutability: 'view', + type: 'function', + name: 'get_fee_receiver', + inputs: [{ name: '_pool', type: 'address' }], + outputs: [{ name: '', type: 'address' }], + gas: 5480, + }, + { + stateMutability: 'nonpayable', + type: 'function', + name: 'deploy_plain_pool', + inputs: [ + { name: '_name', type: 'string' }, + { name: '_symbol', type: 'string' }, + { name: '_coins', type: 'address[4]' }, + { name: '_A', type: 'uint256' }, + { name: '_fee', type: 'uint256' }, + ], + outputs: [{ name: '', type: 'address' }], + }, + { + stateMutability: 'nonpayable', + type: 'function', + name: 'deploy_plain_pool', + inputs: [ + { name: '_name', type: 'string' }, + { name: '_symbol', type: 'string' }, + { name: '_coins', type: 'address[4]' }, + { name: '_A', type: 'uint256' }, + { name: '_fee', type: 'uint256' }, + { name: '_asset_type', type: 'uint256' }, + ], + outputs: [{ name: '', type: 'address' }], + }, + { + stateMutability: 'nonpayable', + type: 'function', + name: 'deploy_plain_pool', + inputs: [ + { name: '_name', type: 'string' }, + { name: '_symbol', type: 'string' }, + { name: '_coins', type: 'address[4]' }, + { name: '_A', type: 'uint256' }, + { name: '_fee', type: 'uint256' }, + { name: '_asset_type', type: 'uint256' }, + { name: '_implementation_idx', type: 'uint256' }, + ], + outputs: [{ name: '', type: 'address' }], + }, + { + stateMutability: 'nonpayable', + type: 'function', + name: 'deploy_metapool', + inputs: [ + { name: '_base_pool', type: 'address' }, + { name: '_name', type: 'string' }, + { name: '_symbol', type: 'string' }, + { name: '_coin', type: 'address' }, + { name: '_A', type: 'uint256' }, + { name: '_fee', type: 'uint256' }, + ], + outputs: [{ name: '', type: 'address' }], + }, + { + stateMutability: 'nonpayable', + type: 'function', + name: 'deploy_metapool', + inputs: [ + { name: '_base_pool', type: 'address' }, + { name: '_name', type: 'string' }, + { name: '_symbol', type: 'string' }, + { name: '_coin', type: 'address' }, + { name: '_A', type: 'uint256' }, + { name: '_fee', type: 'uint256' }, + { name: '_implementation_idx', type: 'uint256' }, + ], + outputs: [{ name: '', type: 'address' }], + }, + { + stateMutability: 'nonpayable', + type: 'function', + name: 'deploy_gauge', + inputs: [{ name: '_pool', type: 'address' }], + outputs: [{ name: '', type: 'address' }], + gas: 93079, + }, + { + stateMutability: 'nonpayable', + type: 'function', + name: 'add_base_pool', + inputs: [ + { name: '_base_pool', type: 'address' }, + { name: '_fee_receiver', type: 'address' }, + { name: '_asset_type', type: 'uint256' }, + { name: '_implementations', type: 'address[10]' }, + ], + outputs: [], + gas: 1206132, + }, + { + stateMutability: 'nonpayable', + type: 'function', + name: 'set_metapool_implementations', + inputs: [ + { name: '_base_pool', type: 'address' }, + { name: '_implementations', type: 'address[10]' }, + ], + outputs: [], + gas: 382072, + }, + { + stateMutability: 'nonpayable', + type: 'function', + name: 'set_plain_implementations', + inputs: [ + { name: '_n_coins', type: 'uint256' }, + { name: '_implementations', type: 'address[10]' }, + ], + outputs: [], + gas: 379687, + }, + { + stateMutability: 'nonpayable', + type: 'function', + name: 'set_gauge_implementation', + inputs: [{ name: '_gauge_implementation', type: 'address' }], + outputs: [], + gas: 38355, + }, + { + stateMutability: 'nonpayable', + type: 'function', + name: 'batch_set_pool_asset_type', + inputs: [ + { name: '_pools', type: 'address[32]' }, + { name: '_asset_types', type: 'uint256[32]' }, + ], + outputs: [], + gas: 1139545, + }, + { + stateMutability: 'nonpayable', + type: 'function', + name: 'commit_transfer_ownership', + inputs: [{ name: '_addr', type: 'address' }], + outputs: [], + gas: 38415, + }, + { + stateMutability: 'nonpayable', + type: 'function', + name: 'accept_transfer_ownership', + inputs: [], + outputs: [], + gas: 58366, + }, + { + stateMutability: 'nonpayable', + type: 'function', + name: 'set_manager', + inputs: [{ name: '_manager', type: 'address' }], + outputs: [], + gas: 40996, + }, + { + stateMutability: 'nonpayable', + type: 'function', + name: 'set_fee_receiver', + inputs: [ + { name: '_base_pool', type: 'address' }, + { name: '_fee_receiver', type: 'address' }, + ], + outputs: [], + gas: 38770, + }, + { + stateMutability: 'nonpayable', + type: 'function', + name: 'convert_metapool_fees', + inputs: [], + outputs: [{ name: '', type: 'bool' }], + gas: 12880, + }, + { + stateMutability: 'nonpayable', + type: 'function', + name: 'add_existing_metapools', + inputs: [{ name: '_pools', type: 'address[10]' }], + outputs: [{ name: '', type: 'bool' }], + gas: 8610792, + }, + { + stateMutability: 'view', + type: 'function', + name: 'admin', + inputs: [], + outputs: [{ name: '', type: 'address' }], + gas: 3438, + }, + { + stateMutability: 'view', + type: 'function', + name: 'future_admin', + inputs: [], + outputs: [{ name: '', type: 'address' }], + gas: 3468, + }, + { + stateMutability: 'view', + type: 'function', + name: 'manager', + inputs: [], + outputs: [{ name: '', type: 'address' }], + gas: 3498, + }, + { + stateMutability: 'view', + type: 'function', + name: 'pool_list', + inputs: [{ name: 'arg0', type: 'uint256' }], + outputs: [{ name: '', type: 'address' }], + gas: 3573, + }, + { + stateMutability: 'view', + type: 'function', + name: 'pool_count', + inputs: [], + outputs: [{ name: '', type: 'uint256' }], + gas: 3558, + }, + { + stateMutability: 'view', + type: 'function', + name: 'base_pool_list', + inputs: [{ name: 'arg0', type: 'uint256' }], + outputs: [{ name: '', type: 'address' }], + gas: 3633, + }, + { + stateMutability: 'view', + type: 'function', + name: 'base_pool_count', + inputs: [], + outputs: [{ name: '', type: 'uint256' }], + gas: 3618, + }, + { + stateMutability: 'view', + type: 'function', + name: 'base_pool_assets', + inputs: [{ name: 'arg0', type: 'address' }], + outputs: [{ name: '', type: 'bool' }], + gas: 3863, + }, + { + stateMutability: 'view', + type: 'function', + name: 'plain_implementations', + inputs: [ + { name: 'arg0', type: 'uint256' }, + { name: 'arg1', type: 'uint256' }, + ], + outputs: [{ name: '', type: 'address' }], + gas: 3838, + }, + { + stateMutability: 'view', + type: 'function', + name: 'gauge_implementation', + inputs: [], + outputs: [{ name: '', type: 'address' }], + gas: 3708, + }, +] as const; diff --git a/libs/shared/contracts/src/abis/CurveRegistryExchange.ts b/libs/shared/contracts/src/abis/CurveRegistryExchange.ts new file mode 100644 index 000000000..5e3f78eed --- /dev/null +++ b/libs/shared/contracts/src/abis/CurveRegistryExchange.ts @@ -0,0 +1,301 @@ +// DO NOT EDIT - GENERATED +export const CurveRegistryExchangeABI = [ + { + name: 'TokenExchange', + inputs: [ + { name: 'buyer', type: 'address', indexed: true }, + { name: 'receiver', type: 'address', indexed: true }, + { name: 'pool', type: 'address', indexed: true }, + { name: 'token_sold', type: 'address', indexed: false }, + { name: 'token_bought', type: 'address', indexed: false }, + { name: 'amount_sold', type: 'uint256', indexed: false }, + { name: 'amount_bought', type: 'uint256', indexed: false }, + ], + anonymous: false, + type: 'event', + }, + { + name: 'ExchangeMultiple', + inputs: [ + { name: 'buyer', type: 'address', indexed: true }, + { name: 'receiver', type: 'address', indexed: true }, + { name: 'route', type: 'address[9]', indexed: false }, + { name: 'swap_params', type: 'uint256[3][4]', indexed: false }, + { name: 'pools', type: 'address[4]', indexed: false }, + { name: 'amount_sold', type: 'uint256', indexed: false }, + { name: 'amount_bought', type: 'uint256', indexed: false }, + ], + anonymous: false, + type: 'event', + }, + { + stateMutability: 'nonpayable', + type: 'constructor', + inputs: [ + { name: '_address_provider', type: 'address' }, + { name: '_calculator', type: 'address' }, + { name: '_weth', type: 'address' }, + ], + outputs: [], + }, + { stateMutability: 'payable', type: 'fallback' }, + { + stateMutability: 'payable', + type: 'function', + name: 'exchange_with_best_rate', + inputs: [ + { name: '_from', type: 'address' }, + { name: '_to', type: 'address' }, + { name: '_amount', type: 'uint256' }, + { name: '_expected', type: 'uint256' }, + ], + outputs: [{ name: '', type: 'uint256' }], + }, + { + stateMutability: 'payable', + type: 'function', + name: 'exchange_with_best_rate', + inputs: [ + { name: '_from', type: 'address' }, + { name: '_to', type: 'address' }, + { name: '_amount', type: 'uint256' }, + { name: '_expected', type: 'uint256' }, + { name: '_receiver', type: 'address' }, + ], + outputs: [{ name: '', type: 'uint256' }], + }, + { + stateMutability: 'payable', + type: 'function', + name: 'exchange', + inputs: [ + { name: '_pool', type: 'address' }, + { name: '_from', type: 'address' }, + { name: '_to', type: 'address' }, + { name: '_amount', type: 'uint256' }, + { name: '_expected', type: 'uint256' }, + ], + outputs: [{ name: '', type: 'uint256' }], + }, + { + stateMutability: 'payable', + type: 'function', + name: 'exchange', + inputs: [ + { name: '_pool', type: 'address' }, + { name: '_from', type: 'address' }, + { name: '_to', type: 'address' }, + { name: '_amount', type: 'uint256' }, + { name: '_expected', type: 'uint256' }, + { name: '_receiver', type: 'address' }, + ], + outputs: [{ name: '', type: 'uint256' }], + }, + { + stateMutability: 'payable', + type: 'function', + name: 'exchange_multiple', + inputs: [ + { name: '_route', type: 'address[9]' }, + { name: '_swap_params', type: 'uint256[3][4]' }, + { name: '_amount', type: 'uint256' }, + { name: '_expected', type: 'uint256' }, + ], + outputs: [{ name: '', type: 'uint256' }], + }, + { + stateMutability: 'payable', + type: 'function', + name: 'exchange_multiple', + inputs: [ + { name: '_route', type: 'address[9]' }, + { name: '_swap_params', type: 'uint256[3][4]' }, + { name: '_amount', type: 'uint256' }, + { name: '_expected', type: 'uint256' }, + { name: '_pools', type: 'address[4]' }, + ], + outputs: [{ name: '', type: 'uint256' }], + }, + { + stateMutability: 'payable', + type: 'function', + name: 'exchange_multiple', + inputs: [ + { name: '_route', type: 'address[9]' }, + { name: '_swap_params', type: 'uint256[3][4]' }, + { name: '_amount', type: 'uint256' }, + { name: '_expected', type: 'uint256' }, + { name: '_pools', type: 'address[4]' }, + { name: '_receiver', type: 'address' }, + ], + outputs: [{ name: '', type: 'uint256' }], + }, + { + stateMutability: 'view', + type: 'function', + name: 'get_best_rate', + inputs: [ + { name: '_from', type: 'address' }, + { name: '_to', type: 'address' }, + { name: '_amount', type: 'uint256' }, + ], + outputs: [ + { name: '', type: 'address' }, + { name: '', type: 'uint256' }, + ], + }, + { + stateMutability: 'view', + type: 'function', + name: 'get_best_rate', + inputs: [ + { name: '_from', type: 'address' }, + { name: '_to', type: 'address' }, + { name: '_amount', type: 'uint256' }, + { name: '_exclude_pools', type: 'address[8]' }, + ], + outputs: [ + { name: '', type: 'address' }, + { name: '', type: 'uint256' }, + ], + }, + { + stateMutability: 'view', + type: 'function', + name: 'get_exchange_amount', + inputs: [ + { name: '_pool', type: 'address' }, + { name: '_from', type: 'address' }, + { name: '_to', type: 'address' }, + { name: '_amount', type: 'uint256' }, + ], + outputs: [{ name: '', type: 'uint256' }], + }, + { + stateMutability: 'view', + type: 'function', + name: 'get_input_amount', + inputs: [ + { name: '_pool', type: 'address' }, + { name: '_from', type: 'address' }, + { name: '_to', type: 'address' }, + { name: '_amount', type: 'uint256' }, + ], + outputs: [{ name: '', type: 'uint256' }], + }, + { + stateMutability: 'view', + type: 'function', + name: 'get_exchange_amounts', + inputs: [ + { name: '_pool', type: 'address' }, + { name: '_from', type: 'address' }, + { name: '_to', type: 'address' }, + { name: '_amounts', type: 'uint256[100]' }, + ], + outputs: [{ name: '', type: 'uint256[100]' }], + }, + { + stateMutability: 'view', + type: 'function', + name: 'get_exchange_multiple_amount', + inputs: [ + { name: '_route', type: 'address[9]' }, + { name: '_swap_params', type: 'uint256[3][4]' }, + { name: '_amount', type: 'uint256' }, + ], + outputs: [{ name: '', type: 'uint256' }], + }, + { + stateMutability: 'view', + type: 'function', + name: 'get_exchange_multiple_amount', + inputs: [ + { name: '_route', type: 'address[9]' }, + { name: '_swap_params', type: 'uint256[3][4]' }, + { name: '_amount', type: 'uint256' }, + { name: '_pools', type: 'address[4]' }, + ], + outputs: [{ name: '', type: 'uint256' }], + }, + { + stateMutability: 'view', + type: 'function', + name: 'get_calculator', + inputs: [{ name: '_pool', type: 'address' }], + outputs: [{ name: '', type: 'address' }], + }, + { + stateMutability: 'nonpayable', + type: 'function', + name: 'update_registry_address', + inputs: [], + outputs: [{ name: '', type: 'bool' }], + }, + { + stateMutability: 'nonpayable', + type: 'function', + name: 'set_calculator', + inputs: [ + { name: '_pool', type: 'address' }, + { name: '_calculator', type: 'address' }, + ], + outputs: [{ name: '', type: 'bool' }], + }, + { + stateMutability: 'nonpayable', + type: 'function', + name: 'set_default_calculator', + inputs: [{ name: '_calculator', type: 'address' }], + outputs: [{ name: '', type: 'bool' }], + }, + { + stateMutability: 'nonpayable', + type: 'function', + name: 'claim_balance', + inputs: [{ name: '_token', type: 'address' }], + outputs: [{ name: '', type: 'bool' }], + }, + { + stateMutability: 'nonpayable', + type: 'function', + name: 'set_killed', + inputs: [{ name: '_is_killed', type: 'bool' }], + outputs: [{ name: '', type: 'bool' }], + }, + { + stateMutability: 'view', + type: 'function', + name: 'registry', + inputs: [], + outputs: [{ name: '', type: 'address' }], + }, + { + stateMutability: 'view', + type: 'function', + name: 'factory_registry', + inputs: [], + outputs: [{ name: '', type: 'address' }], + }, + { + stateMutability: 'view', + type: 'function', + name: 'crypto_registry', + inputs: [], + outputs: [{ name: '', type: 'address' }], + }, + { + stateMutability: 'view', + type: 'function', + name: 'default_calculator', + inputs: [], + outputs: [{ name: '', type: 'address' }], + }, + { + stateMutability: 'view', + type: 'function', + name: 'is_killed', + inputs: [], + outputs: [{ name: '', type: 'bool' }], + }, +] as const; diff --git a/libs/shared/contracts/src/contracts.ts b/libs/shared/contracts/src/contracts.ts index cce26ba44..e5badc638 100644 --- a/libs/shared/contracts/src/contracts.ts +++ b/libs/shared/contracts/src/contracts.ts @@ -1,5 +1,6 @@ import { mainnet } from 'wagmi/chains'; +import { CurveAddressProviderABI } from './abis/CurveAddressProvider'; import { CurvePoolABI } from './abis/CurvePool'; import { OETHABI } from './abis/OETH'; import { OETHVaultCoreABI } from './abis/OETHVaultCore'; @@ -10,11 +11,17 @@ import { WOETHABI } from './abis/WOETH'; export const contracts = { mainnet: { curveOethPool: { - address: '0x94b17476a93b3262d87b9a326965d1e91f9c13e7', + address: '0x94B17476A93b3262d87B9a326965D1E91f9c13E7', chainId: mainnet.id, abi: CurvePoolABI, name: 'curveOethPool', }, + CurveAddressProvider: { + address: '0x0000000022d53366457f9d5e68ec105046fc4383', + chainId: mainnet.id, + abi: CurveAddressProviderABI, + name: 'CurveAddressProvider', + }, OETH: { address: '0x856c4Efb76C1D1AE02e20CEB03A2A6a08b0b8dC3', chainId: mainnet.id, diff --git a/libs/shared/contracts/src/tokens.ts b/libs/shared/contracts/src/tokens.ts index 6142129b8..2a7bdfb6a 100644 --- a/libs/shared/contracts/src/tokens.ts +++ b/libs/shared/contracts/src/tokens.ts @@ -15,7 +15,7 @@ export const tokens = { symbol: 'ETH', }, WETH: { - address: '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2', + address: '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2', chainId: mainnet.id, abi: erc20ABI, name: 'Wrapped Ether', @@ -146,7 +146,7 @@ export const tokens = { }, // Frax frxETH: { - address: '0x5e8422345238f34275888049021821e8e08caa1f', + address: '0x5E8422345238F34275888049021821E8E08CAa1f', chainId: mainnet.id, abi: erc20ABI, name: 'Frax Ether', diff --git a/libs/shared/contracts/tsconfig.lib.json b/libs/shared/contracts/tsconfig.lib.json index c96232320..919d40d8f 100644 --- a/libs/shared/contracts/tsconfig.lib.json +++ b/libs/shared/contracts/tsconfig.lib.json @@ -9,5 +9,5 @@ "../../../node_modules/@nx/react/typings/image.d.ts" ], "exclude": ["jest.config.ts", "src/**/*.spec.ts", "src/**/*.test.ts", "src/**/*.spec.tsx", "src/**/*.test.tsx", "src/**/*.spec.js", "src/**/*.test.js", "src/**/*.spec.jsx", "src/**/*.test.jsx"], - "include": ["src/**/*.js", "src/**/*.jsx", "src/**/*.ts", "src/**/*.tsx"] + "include": ["src/**/*.js", "src/**/*.jsx", "src/**/*.ts", "src/**/*.tsx", "../providers/src/curve/abis/CurveRegistryExchange.ts", "../providers/src/curve/abis/CurveFactory.ts"] } diff --git a/libs/shared/providers/src/curve/abis/CurveFactory.ts b/libs/shared/providers/src/curve/abis/CurveFactory.ts new file mode 100644 index 000000000..afc1ba8aa --- /dev/null +++ b/libs/shared/providers/src/curve/abis/CurveFactory.ts @@ -0,0 +1,509 @@ +// DO NOT EDIT - GENERATED +export const CurveFactoryABI = [ + { + name: 'BasePoolAdded', + inputs: [{ name: 'base_pool', type: 'address', indexed: false }], + anonymous: false, + type: 'event', + }, + { + name: 'PlainPoolDeployed', + inputs: [ + { name: 'coins', type: 'address[4]', indexed: false }, + { name: 'A', type: 'uint256', indexed: false }, + { name: 'fee', type: 'uint256', indexed: false }, + { name: 'deployer', type: 'address', indexed: false }, + ], + anonymous: false, + type: 'event', + }, + { + name: 'MetaPoolDeployed', + inputs: [ + { name: 'coin', type: 'address', indexed: false }, + { name: 'base_pool', type: 'address', indexed: false }, + { name: 'A', type: 'uint256', indexed: false }, + { name: 'fee', type: 'uint256', indexed: false }, + { name: 'deployer', type: 'address', indexed: false }, + ], + anonymous: false, + type: 'event', + }, + { + name: 'LiquidityGaugeDeployed', + inputs: [ + { name: 'pool', type: 'address', indexed: false }, + { name: 'gauge', type: 'address', indexed: false }, + ], + anonymous: false, + type: 'event', + }, + { + stateMutability: 'nonpayable', + type: 'constructor', + inputs: [{ name: '_fee_receiver', type: 'address' }], + outputs: [], + }, + { + stateMutability: 'view', + type: 'function', + name: 'metapool_implementations', + inputs: [{ name: '_base_pool', type: 'address' }], + outputs: [{ name: '', type: 'address[10]' }], + gas: 21716, + }, + { + stateMutability: 'view', + type: 'function', + name: 'find_pool_for_coins', + inputs: [ + { name: '_from', type: 'address' }, + { name: '_to', type: 'address' }, + ], + outputs: [{ name: '', type: 'address' }], + }, + { + stateMutability: 'view', + type: 'function', + name: 'find_pool_for_coins', + inputs: [ + { name: '_from', type: 'address' }, + { name: '_to', type: 'address' }, + { name: 'i', type: 'uint256' }, + ], + outputs: [{ name: '', type: 'address' }], + }, + { + stateMutability: 'view', + type: 'function', + name: 'get_base_pool', + inputs: [{ name: '_pool', type: 'address' }], + outputs: [{ name: '', type: 'address' }], + gas: 2663, + }, + { + stateMutability: 'view', + type: 'function', + name: 'get_n_coins', + inputs: [{ name: '_pool', type: 'address' }], + outputs: [{ name: '', type: 'uint256' }], + gas: 2699, + }, + { + stateMutability: 'view', + type: 'function', + name: 'get_meta_n_coins', + inputs: [{ name: '_pool', type: 'address' }], + outputs: [ + { name: '', type: 'uint256' }, + { name: '', type: 'uint256' }, + ], + gas: 5201, + }, + { + stateMutability: 'view', + type: 'function', + name: 'get_coins', + inputs: [{ name: '_pool', type: 'address' }], + outputs: [{ name: '', type: 'address[4]' }], + gas: 9164, + }, + { + stateMutability: 'view', + type: 'function', + name: 'get_underlying_coins', + inputs: [{ name: '_pool', type: 'address' }], + outputs: [{ name: '', type: 'address[8]' }], + gas: 21345, + }, + { + stateMutability: 'view', + type: 'function', + name: 'get_decimals', + inputs: [{ name: '_pool', type: 'address' }], + outputs: [{ name: '', type: 'uint256[4]' }], + gas: 20185, + }, + { + stateMutability: 'view', + type: 'function', + name: 'get_underlying_decimals', + inputs: [{ name: '_pool', type: 'address' }], + outputs: [{ name: '', type: 'uint256[8]' }], + gas: 19730, + }, + { + stateMutability: 'view', + type: 'function', + name: 'get_metapool_rates', + inputs: [{ name: '_pool', type: 'address' }], + outputs: [{ name: '', type: 'uint256[2]' }], + gas: 5281, + }, + { + stateMutability: 'view', + type: 'function', + name: 'get_balances', + inputs: [{ name: '_pool', type: 'address' }], + outputs: [{ name: '', type: 'uint256[4]' }], + gas: 20435, + }, + { + stateMutability: 'view', + type: 'function', + name: 'get_underlying_balances', + inputs: [{ name: '_pool', type: 'address' }], + outputs: [{ name: '', type: 'uint256[8]' }], + gas: 39733, + }, + { + stateMutability: 'view', + type: 'function', + name: 'get_A', + inputs: [{ name: '_pool', type: 'address' }], + outputs: [{ name: '', type: 'uint256' }], + gas: 3135, + }, + { + stateMutability: 'view', + type: 'function', + name: 'get_fees', + inputs: [{ name: '_pool', type: 'address' }], + outputs: [ + { name: '', type: 'uint256' }, + { name: '', type: 'uint256' }, + ], + gas: 5821, + }, + { + stateMutability: 'view', + type: 'function', + name: 'get_admin_balances', + inputs: [{ name: '_pool', type: 'address' }], + outputs: [{ name: '', type: 'uint256[4]' }], + gas: 13535, + }, + { + stateMutability: 'view', + type: 'function', + name: 'get_coin_indices', + inputs: [ + { name: '_pool', type: 'address' }, + { name: '_from', type: 'address' }, + { name: '_to', type: 'address' }, + ], + outputs: [ + { name: '', type: 'int128' }, + { name: '', type: 'int128' }, + { name: '', type: 'bool' }, + ], + gas: 33407, + }, + { + stateMutability: 'view', + type: 'function', + name: 'get_gauge', + inputs: [{ name: '_pool', type: 'address' }], + outputs: [{ name: '', type: 'address' }], + gas: 3089, + }, + { + stateMutability: 'view', + type: 'function', + name: 'get_implementation_address', + inputs: [{ name: '_pool', type: 'address' }], + outputs: [{ name: '', type: 'address' }], + gas: 3119, + }, + { + stateMutability: 'view', + type: 'function', + name: 'is_meta', + inputs: [{ name: '_pool', type: 'address' }], + outputs: [{ name: '', type: 'bool' }], + gas: 3152, + }, + { + stateMutability: 'view', + type: 'function', + name: 'get_pool_asset_type', + inputs: [{ name: '_pool', type: 'address' }], + outputs: [{ name: '', type: 'uint256' }], + gas: 5450, + }, + { + stateMutability: 'view', + type: 'function', + name: 'get_fee_receiver', + inputs: [{ name: '_pool', type: 'address' }], + outputs: [{ name: '', type: 'address' }], + gas: 5480, + }, + { + stateMutability: 'nonpayable', + type: 'function', + name: 'deploy_plain_pool', + inputs: [ + { name: '_name', type: 'string' }, + { name: '_symbol', type: 'string' }, + { name: '_coins', type: 'address[4]' }, + { name: '_A', type: 'uint256' }, + { name: '_fee', type: 'uint256' }, + ], + outputs: [{ name: '', type: 'address' }], + }, + { + stateMutability: 'nonpayable', + type: 'function', + name: 'deploy_plain_pool', + inputs: [ + { name: '_name', type: 'string' }, + { name: '_symbol', type: 'string' }, + { name: '_coins', type: 'address[4]' }, + { name: '_A', type: 'uint256' }, + { name: '_fee', type: 'uint256' }, + { name: '_asset_type', type: 'uint256' }, + ], + outputs: [{ name: '', type: 'address' }], + }, + { + stateMutability: 'nonpayable', + type: 'function', + name: 'deploy_plain_pool', + inputs: [ + { name: '_name', type: 'string' }, + { name: '_symbol', type: 'string' }, + { name: '_coins', type: 'address[4]' }, + { name: '_A', type: 'uint256' }, + { name: '_fee', type: 'uint256' }, + { name: '_asset_type', type: 'uint256' }, + { name: '_implementation_idx', type: 'uint256' }, + ], + outputs: [{ name: '', type: 'address' }], + }, + { + stateMutability: 'nonpayable', + type: 'function', + name: 'deploy_metapool', + inputs: [ + { name: '_base_pool', type: 'address' }, + { name: '_name', type: 'string' }, + { name: '_symbol', type: 'string' }, + { name: '_coin', type: 'address' }, + { name: '_A', type: 'uint256' }, + { name: '_fee', type: 'uint256' }, + ], + outputs: [{ name: '', type: 'address' }], + }, + { + stateMutability: 'nonpayable', + type: 'function', + name: 'deploy_metapool', + inputs: [ + { name: '_base_pool', type: 'address' }, + { name: '_name', type: 'string' }, + { name: '_symbol', type: 'string' }, + { name: '_coin', type: 'address' }, + { name: '_A', type: 'uint256' }, + { name: '_fee', type: 'uint256' }, + { name: '_implementation_idx', type: 'uint256' }, + ], + outputs: [{ name: '', type: 'address' }], + }, + { + stateMutability: 'nonpayable', + type: 'function', + name: 'deploy_gauge', + inputs: [{ name: '_pool', type: 'address' }], + outputs: [{ name: '', type: 'address' }], + gas: 93079, + }, + { + stateMutability: 'nonpayable', + type: 'function', + name: 'add_base_pool', + inputs: [ + { name: '_base_pool', type: 'address' }, + { name: '_fee_receiver', type: 'address' }, + { name: '_asset_type', type: 'uint256' }, + { name: '_implementations', type: 'address[10]' }, + ], + outputs: [], + gas: 1206132, + }, + { + stateMutability: 'nonpayable', + type: 'function', + name: 'set_metapool_implementations', + inputs: [ + { name: '_base_pool', type: 'address' }, + { name: '_implementations', type: 'address[10]' }, + ], + outputs: [], + gas: 382072, + }, + { + stateMutability: 'nonpayable', + type: 'function', + name: 'set_plain_implementations', + inputs: [ + { name: '_n_coins', type: 'uint256' }, + { name: '_implementations', type: 'address[10]' }, + ], + outputs: [], + gas: 379687, + }, + { + stateMutability: 'nonpayable', + type: 'function', + name: 'set_gauge_implementation', + inputs: [{ name: '_gauge_implementation', type: 'address' }], + outputs: [], + gas: 38355, + }, + { + stateMutability: 'nonpayable', + type: 'function', + name: 'batch_set_pool_asset_type', + inputs: [ + { name: '_pools', type: 'address[32]' }, + { name: '_asset_types', type: 'uint256[32]' }, + ], + outputs: [], + gas: 1139545, + }, + { + stateMutability: 'nonpayable', + type: 'function', + name: 'commit_transfer_ownership', + inputs: [{ name: '_addr', type: 'address' }], + outputs: [], + gas: 38415, + }, + { + stateMutability: 'nonpayable', + type: 'function', + name: 'accept_transfer_ownership', + inputs: [], + outputs: [], + gas: 58366, + }, + { + stateMutability: 'nonpayable', + type: 'function', + name: 'set_manager', + inputs: [{ name: '_manager', type: 'address' }], + outputs: [], + gas: 40996, + }, + { + stateMutability: 'nonpayable', + type: 'function', + name: 'set_fee_receiver', + inputs: [ + { name: '_base_pool', type: 'address' }, + { name: '_fee_receiver', type: 'address' }, + ], + outputs: [], + gas: 38770, + }, + { + stateMutability: 'nonpayable', + type: 'function', + name: 'convert_metapool_fees', + inputs: [], + outputs: [{ name: '', type: 'bool' }], + gas: 12880, + }, + { + stateMutability: 'nonpayable', + type: 'function', + name: 'add_existing_metapools', + inputs: [{ name: '_pools', type: 'address[10]' }], + outputs: [{ name: '', type: 'bool' }], + gas: 8610792, + }, + { + stateMutability: 'view', + type: 'function', + name: 'admin', + inputs: [], + outputs: [{ name: '', type: 'address' }], + gas: 3438, + }, + { + stateMutability: 'view', + type: 'function', + name: 'future_admin', + inputs: [], + outputs: [{ name: '', type: 'address' }], + gas: 3468, + }, + { + stateMutability: 'view', + type: 'function', + name: 'manager', + inputs: [], + outputs: [{ name: '', type: 'address' }], + gas: 3498, + }, + { + stateMutability: 'view', + type: 'function', + name: 'pool_list', + inputs: [{ name: 'arg0', type: 'uint256' }], + outputs: [{ name: '', type: 'address' }], + gas: 3573, + }, + { + stateMutability: 'view', + type: 'function', + name: 'pool_count', + inputs: [], + outputs: [{ name: '', type: 'uint256' }], + gas: 3558, + }, + { + stateMutability: 'view', + type: 'function', + name: 'base_pool_list', + inputs: [{ name: 'arg0', type: 'uint256' }], + outputs: [{ name: '', type: 'address' }], + gas: 3633, + }, + { + stateMutability: 'view', + type: 'function', + name: 'base_pool_count', + inputs: [], + outputs: [{ name: '', type: 'uint256' }], + gas: 3618, + }, + { + stateMutability: 'view', + type: 'function', + name: 'base_pool_assets', + inputs: [{ name: 'arg0', type: 'address' }], + outputs: [{ name: '', type: 'bool' }], + gas: 3863, + }, + { + stateMutability: 'view', + type: 'function', + name: 'plain_implementations', + inputs: [ + { name: 'arg0', type: 'uint256' }, + { name: 'arg1', type: 'uint256' }, + ], + outputs: [{ name: '', type: 'address' }], + gas: 3838, + }, + { + stateMutability: 'view', + type: 'function', + name: 'gauge_implementation', + inputs: [], + outputs: [{ name: '', type: 'address' }], + gas: 3708, + }, +] as const; diff --git a/libs/shared/providers/src/curve/abis/CurveRegistryExchange.ts b/libs/shared/providers/src/curve/abis/CurveRegistryExchange.ts new file mode 100644 index 000000000..5e3f78eed --- /dev/null +++ b/libs/shared/providers/src/curve/abis/CurveRegistryExchange.ts @@ -0,0 +1,301 @@ +// DO NOT EDIT - GENERATED +export const CurveRegistryExchangeABI = [ + { + name: 'TokenExchange', + inputs: [ + { name: 'buyer', type: 'address', indexed: true }, + { name: 'receiver', type: 'address', indexed: true }, + { name: 'pool', type: 'address', indexed: true }, + { name: 'token_sold', type: 'address', indexed: false }, + { name: 'token_bought', type: 'address', indexed: false }, + { name: 'amount_sold', type: 'uint256', indexed: false }, + { name: 'amount_bought', type: 'uint256', indexed: false }, + ], + anonymous: false, + type: 'event', + }, + { + name: 'ExchangeMultiple', + inputs: [ + { name: 'buyer', type: 'address', indexed: true }, + { name: 'receiver', type: 'address', indexed: true }, + { name: 'route', type: 'address[9]', indexed: false }, + { name: 'swap_params', type: 'uint256[3][4]', indexed: false }, + { name: 'pools', type: 'address[4]', indexed: false }, + { name: 'amount_sold', type: 'uint256', indexed: false }, + { name: 'amount_bought', type: 'uint256', indexed: false }, + ], + anonymous: false, + type: 'event', + }, + { + stateMutability: 'nonpayable', + type: 'constructor', + inputs: [ + { name: '_address_provider', type: 'address' }, + { name: '_calculator', type: 'address' }, + { name: '_weth', type: 'address' }, + ], + outputs: [], + }, + { stateMutability: 'payable', type: 'fallback' }, + { + stateMutability: 'payable', + type: 'function', + name: 'exchange_with_best_rate', + inputs: [ + { name: '_from', type: 'address' }, + { name: '_to', type: 'address' }, + { name: '_amount', type: 'uint256' }, + { name: '_expected', type: 'uint256' }, + ], + outputs: [{ name: '', type: 'uint256' }], + }, + { + stateMutability: 'payable', + type: 'function', + name: 'exchange_with_best_rate', + inputs: [ + { name: '_from', type: 'address' }, + { name: '_to', type: 'address' }, + { name: '_amount', type: 'uint256' }, + { name: '_expected', type: 'uint256' }, + { name: '_receiver', type: 'address' }, + ], + outputs: [{ name: '', type: 'uint256' }], + }, + { + stateMutability: 'payable', + type: 'function', + name: 'exchange', + inputs: [ + { name: '_pool', type: 'address' }, + { name: '_from', type: 'address' }, + { name: '_to', type: 'address' }, + { name: '_amount', type: 'uint256' }, + { name: '_expected', type: 'uint256' }, + ], + outputs: [{ name: '', type: 'uint256' }], + }, + { + stateMutability: 'payable', + type: 'function', + name: 'exchange', + inputs: [ + { name: '_pool', type: 'address' }, + { name: '_from', type: 'address' }, + { name: '_to', type: 'address' }, + { name: '_amount', type: 'uint256' }, + { name: '_expected', type: 'uint256' }, + { name: '_receiver', type: 'address' }, + ], + outputs: [{ name: '', type: 'uint256' }], + }, + { + stateMutability: 'payable', + type: 'function', + name: 'exchange_multiple', + inputs: [ + { name: '_route', type: 'address[9]' }, + { name: '_swap_params', type: 'uint256[3][4]' }, + { name: '_amount', type: 'uint256' }, + { name: '_expected', type: 'uint256' }, + ], + outputs: [{ name: '', type: 'uint256' }], + }, + { + stateMutability: 'payable', + type: 'function', + name: 'exchange_multiple', + inputs: [ + { name: '_route', type: 'address[9]' }, + { name: '_swap_params', type: 'uint256[3][4]' }, + { name: '_amount', type: 'uint256' }, + { name: '_expected', type: 'uint256' }, + { name: '_pools', type: 'address[4]' }, + ], + outputs: [{ name: '', type: 'uint256' }], + }, + { + stateMutability: 'payable', + type: 'function', + name: 'exchange_multiple', + inputs: [ + { name: '_route', type: 'address[9]' }, + { name: '_swap_params', type: 'uint256[3][4]' }, + { name: '_amount', type: 'uint256' }, + { name: '_expected', type: 'uint256' }, + { name: '_pools', type: 'address[4]' }, + { name: '_receiver', type: 'address' }, + ], + outputs: [{ name: '', type: 'uint256' }], + }, + { + stateMutability: 'view', + type: 'function', + name: 'get_best_rate', + inputs: [ + { name: '_from', type: 'address' }, + { name: '_to', type: 'address' }, + { name: '_amount', type: 'uint256' }, + ], + outputs: [ + { name: '', type: 'address' }, + { name: '', type: 'uint256' }, + ], + }, + { + stateMutability: 'view', + type: 'function', + name: 'get_best_rate', + inputs: [ + { name: '_from', type: 'address' }, + { name: '_to', type: 'address' }, + { name: '_amount', type: 'uint256' }, + { name: '_exclude_pools', type: 'address[8]' }, + ], + outputs: [ + { name: '', type: 'address' }, + { name: '', type: 'uint256' }, + ], + }, + { + stateMutability: 'view', + type: 'function', + name: 'get_exchange_amount', + inputs: [ + { name: '_pool', type: 'address' }, + { name: '_from', type: 'address' }, + { name: '_to', type: 'address' }, + { name: '_amount', type: 'uint256' }, + ], + outputs: [{ name: '', type: 'uint256' }], + }, + { + stateMutability: 'view', + type: 'function', + name: 'get_input_amount', + inputs: [ + { name: '_pool', type: 'address' }, + { name: '_from', type: 'address' }, + { name: '_to', type: 'address' }, + { name: '_amount', type: 'uint256' }, + ], + outputs: [{ name: '', type: 'uint256' }], + }, + { + stateMutability: 'view', + type: 'function', + name: 'get_exchange_amounts', + inputs: [ + { name: '_pool', type: 'address' }, + { name: '_from', type: 'address' }, + { name: '_to', type: 'address' }, + { name: '_amounts', type: 'uint256[100]' }, + ], + outputs: [{ name: '', type: 'uint256[100]' }], + }, + { + stateMutability: 'view', + type: 'function', + name: 'get_exchange_multiple_amount', + inputs: [ + { name: '_route', type: 'address[9]' }, + { name: '_swap_params', type: 'uint256[3][4]' }, + { name: '_amount', type: 'uint256' }, + ], + outputs: [{ name: '', type: 'uint256' }], + }, + { + stateMutability: 'view', + type: 'function', + name: 'get_exchange_multiple_amount', + inputs: [ + { name: '_route', type: 'address[9]' }, + { name: '_swap_params', type: 'uint256[3][4]' }, + { name: '_amount', type: 'uint256' }, + { name: '_pools', type: 'address[4]' }, + ], + outputs: [{ name: '', type: 'uint256' }], + }, + { + stateMutability: 'view', + type: 'function', + name: 'get_calculator', + inputs: [{ name: '_pool', type: 'address' }], + outputs: [{ name: '', type: 'address' }], + }, + { + stateMutability: 'nonpayable', + type: 'function', + name: 'update_registry_address', + inputs: [], + outputs: [{ name: '', type: 'bool' }], + }, + { + stateMutability: 'nonpayable', + type: 'function', + name: 'set_calculator', + inputs: [ + { name: '_pool', type: 'address' }, + { name: '_calculator', type: 'address' }, + ], + outputs: [{ name: '', type: 'bool' }], + }, + { + stateMutability: 'nonpayable', + type: 'function', + name: 'set_default_calculator', + inputs: [{ name: '_calculator', type: 'address' }], + outputs: [{ name: '', type: 'bool' }], + }, + { + stateMutability: 'nonpayable', + type: 'function', + name: 'claim_balance', + inputs: [{ name: '_token', type: 'address' }], + outputs: [{ name: '', type: 'bool' }], + }, + { + stateMutability: 'nonpayable', + type: 'function', + name: 'set_killed', + inputs: [{ name: '_is_killed', type: 'bool' }], + outputs: [{ name: '', type: 'bool' }], + }, + { + stateMutability: 'view', + type: 'function', + name: 'registry', + inputs: [], + outputs: [{ name: '', type: 'address' }], + }, + { + stateMutability: 'view', + type: 'function', + name: 'factory_registry', + inputs: [], + outputs: [{ name: '', type: 'address' }], + }, + { + stateMutability: 'view', + type: 'function', + name: 'crypto_registry', + inputs: [], + outputs: [{ name: '', type: 'address' }], + }, + { + stateMutability: 'view', + type: 'function', + name: 'default_calculator', + inputs: [], + outputs: [{ name: '', type: 'address' }], + }, + { + stateMutability: 'view', + type: 'function', + name: 'is_killed', + inputs: [], + outputs: [{ name: '', type: 'bool' }], + }, +] as const; diff --git a/libs/shared/providers/src/curve/state.ts b/libs/shared/providers/src/curve/state.ts index e557c0da8..41af1e44e 100644 --- a/libs/shared/providers/src/curve/state.ts +++ b/libs/shared/providers/src/curve/state.ts @@ -1,98 +1,80 @@ -/* eslint-disable @typescript-eslint/no-explicit-any */ import { useEffect, useState } from 'react'; -import curve from '@curvefi/api'; +import { contracts } from '@origin/shared/contracts'; import { isNilOrEmpty } from '@origin/shared/utils'; +import { readContract } from '@wagmi/core'; +import { produce } from 'immer'; import { createContainer } from 'react-tracked'; -import { mainnet, useAccount, useNetwork } from 'wagmi'; +import { mainnet, useContractReads } from 'wagmi'; -import { useEthersProvider, useEthersSigner } from '../wagmi'; +import { CurveFactoryABI } from './abis/CurveFactory'; +import { CurveRegistryExchangeABI } from './abis/CurveRegistryExchange'; -export type CurveProviderProps = { - alchemyApiKey: string; - customRpcUrl?: string; -}; +import type { HexAddress } from '@origin/shared/utils'; + +import type { CurveState } from './types'; export const { Provider: CurveProvider, useTrackedState: useCurve } = - createContainer(({ alchemyApiKey, customRpcUrl }: CurveProviderProps) => { - const [state, setState] = useState(null); - const { isConnected } = useAccount(); - const { chain } = useNetwork(); - const provider = useEthersProvider(); - const signer = useEthersSigner(); + createContainer(() => { + const [state, setState] = useState({ + CurveRegistryExchange: null, + OethPoolUnderlyings: [], + }); - useEffect(() => { - const initPools = async () => { - await Promise.allSettled([ - curve.factory.fetchPools(), - curve.crvUSDFactory.fetchPools(), - curve.EYWAFactory.fetchPools(), - curve.cryptoFactory.fetchPools(), - curve.tricryptoFactory.fetchPools(), - ]); - }; + const { data } = useContractReads({ + contracts: [ + { + address: contracts.mainnet.CurveAddressProvider.address, + abi: contracts.mainnet.CurveAddressProvider.abi, + functionName: 'get_address', + args: [2n], + }, + { + address: contracts.mainnet.CurveAddressProvider.address, + abi: contracts.mainnet.CurveAddressProvider.abi, + functionName: 'get_address', + args: [3n], + }, + ], + }); - const initPublic = async () => { - if (isNilOrEmpty(customRpcUrl)) { - await curve.init( - 'Alchemy', - { - externalProvider: provider as any, - apiKey: alchemyApiKey, - }, - { chainId: chain?.id ?? mainnet.id }, - ); - } else { - await curve.init( - 'JsonRpc', - { - externalProvider: provider as any, - url: customRpcUrl, - }, - { - chainId: chain?.id ?? mainnet.id, - }, - ); - } + useEffect(() => { + if (!isNilOrEmpty(data?.[0]?.result)) { + setState( + produce((draft) => { + draft.CurveRegistryExchange = { + address: data[0].result, + chainId: mainnet.id, + abi: CurveRegistryExchangeABI, + name: 'CurveRegistryExchange', + } as const; + }), + ); + console.log('Curve registry exchange initialized', data); + } + }, [data]); - await initPools(); - setState(curve); - console.log('CURVE-JS public provider initialized'); - }; + useEffect(() => { + const getUnderlyings = async () => { + const res = await readContract({ + address: data[1].result, + abi: CurveFactoryABI, + functionName: 'get_coins', + args: [contracts.mainnet.curveOethPool.address], + }); - const initWallet = async () => { - if (isNilOrEmpty(customRpcUrl)) { - await curve.init( - 'Alchemy', - { - externalProvider: signer as any, - apiKey: alchemyApiKey, - }, - { chainId: chain?.id ?? mainnet.id }, - ); - } else { - await curve.init( - 'JsonRpc', - { - externalProvider: signer as any, - url: customRpcUrl, - }, - { - chainId: chain?.id ?? mainnet.id, - }, - ); - } - await initPools(); - setState(curve); - console.log('CURVE-JS WALLET PROVIDER INITIALIZED'); + setState( + produce((draft) => { + draft.OethPoolUnderlyings = res as unknown as HexAddress[]; + }), + ); + console.log('Curve OETH Pool initialized', res); }; - if (isConnected) { - initWallet(); - } else { - initPublic(); + if (!isNilOrEmpty(data?.[1]?.result)) { + getUnderlyings(); } - }, [alchemyApiKey, chain?.id, customRpcUrl, isConnected, provider, signer]); + }, [data]); return [state, setState]; }); diff --git a/libs/shared/providers/src/curve/types.ts b/libs/shared/providers/src/curve/types.ts new file mode 100644 index 000000000..560ec0221 --- /dev/null +++ b/libs/shared/providers/src/curve/types.ts @@ -0,0 +1,7 @@ +import type { Contract } from '@origin/shared/contracts'; +import type { HexAddress } from '@origin/shared/utils'; + +export type CurveState = { + CurveRegistryExchange: Contract | null; + OethPoolUnderlyings: HexAddress[]; +}; diff --git a/libs/shared/providers/src/wagmi/hooks.ts b/libs/shared/providers/src/wagmi/hooks.ts deleted file mode 100644 index edb7bb975..000000000 --- a/libs/shared/providers/src/wagmi/hooks.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { useMemo } from 'react'; - -import { usePublicClient, useWalletClient } from 'wagmi'; - -import { publicClientToProvider, walletClientToSigner } from './utils'; - -export const useEthersProvider = ({ chainId }: { chainId?: number } = {}) => { - const publicClient = usePublicClient({ chainId }); - - return useMemo(() => publicClientToProvider(publicClient), [publicClient]); -}; - -export const useEthersSigner = ({ chainId }: { chainId?: number } = {}) => { - const { data: walletClient } = useWalletClient({ chainId }); - - return useMemo( - () => (walletClient ? walletClientToSigner(walletClient) : undefined), - [walletClient], - ); -}; diff --git a/libs/shared/providers/src/wagmi/index.ts b/libs/shared/providers/src/wagmi/index.ts index c55977d1b..07635cbbc 100644 --- a/libs/shared/providers/src/wagmi/index.ts +++ b/libs/shared/providers/src/wagmi/index.ts @@ -1,3 +1 @@ export * from './components'; -export * from './hooks'; -export * from './utils'; diff --git a/libs/shared/providers/src/wagmi/utils.ts b/libs/shared/providers/src/wagmi/utils.ts deleted file mode 100644 index 09c43af37..000000000 --- a/libs/shared/providers/src/wagmi/utils.ts +++ /dev/null @@ -1,60 +0,0 @@ -// Adapted from https://wagmi.sh/core/ethers-adapters -import { getPublicClient, getWalletClient } from '@wagmi/core'; -import { - BrowserProvider, - FallbackProvider, - JsonRpcProvider, - JsonRpcSigner, -} from 'ethers'; - -import type { PublicClient } from '@wagmi/core'; -import type { HttpTransport } from 'viem'; -import type { WalletClient } from 'wagmi'; - -export function publicClientToProvider(publicClient: PublicClient) { - const { chain, transport } = publicClient; - const network = { - chainId: chain.id, - name: chain.name, - ensAddress: chain.contracts?.ensRegistry?.address, - }; - if (transport.type === 'fallback') { - const providers = (transport.transports as ReturnType[]).map( - ({ value }) => new JsonRpcProvider(value?.url, network), - ); - if (providers.length === 1) return providers[0]; - - return new FallbackProvider(providers); - } - - return new JsonRpcProvider(transport.url, network); -} - -/** Action to convert a viem Public Client to an ethers.js Provider. */ -export function getEthersProvider({ chainId }: { chainId?: number } = {}) { - const publicClient = getPublicClient({ chainId }); - - return publicClientToProvider(publicClient); -} - -export function walletClientToSigner(walletClient: WalletClient) { - const { account, chain, transport } = walletClient; - const network = { - chainId: chain.id, - name: chain.name, - ensAddress: chain.contracts?.ensRegistry?.address, - }; - // eslint-disable-next-line @typescript-eslint/no-explicit-any - const provider = new BrowserProvider(transport as any, network); - const signer = new JsonRpcSigner(provider, account.address); - - return signer; -} - -/** Action to convert a viem Wallet Client to an ethers.js Signer. */ -export async function getEthersSigner({ chainId }: { chainId?: number } = {}) { - const walletClient = await getWalletClient({ chainId }); - if (!walletClient) return undefined; - - return walletClientToSigner(walletClient); -} diff --git a/libs/shared/utils/src/addresses.ts b/libs/shared/utils/src/addresses.ts index bcc70c5c3..eb6cc99f2 100644 --- a/libs/shared/utils/src/addresses.ts +++ b/libs/shared/utils/src/addresses.ts @@ -1,2 +1,3 @@ export const ZERO_ADDRESS = '0x0000000000000000000000000000000000000000'; export const DEAD_ADDRESS = '0x000000000000000000000000000000000000dEaD'; +export const ETH_ADDRESS_CURVE = '0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE'; diff --git a/package.json b/package.json index e9e17c4f2..8e37b5fb9 100644 --- a/package.json +++ b/package.json @@ -20,7 +20,6 @@ "@tanstack/react-table": "^8.9.3", "@wagmi/core": "^1.4.1", "axios": "^1.4.0", - "ethers": "^6.7.1", "graphql": "^16.8.0", "immer": "^10.0.2", "ramda": "^0.29.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index f7d1f9510..ccc1471a1 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -35,9 +35,6 @@ dependencies: axios: specifier: ^1.4.0 version: 1.4.0 - ethers: - specifier: ^6.7.1 - version: 6.7.1 graphql: specifier: ^16.8.0 version: 16.8.0