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