diff --git a/dapp-oeth/abis/CurveRegistryExchange.json b/dapp-oeth/abis/CurveRegistryExchange.json
index 53ac79560a..b7ce9a4c66 100644
--- a/dapp-oeth/abis/CurveRegistryExchange.json
+++ b/dapp-oeth/abis/CurveRegistryExchange.json
@@ -6,41 +6,27 @@
{
"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
- }
+ { "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"
@@ -49,180 +35,116 @@
"stateMutability": "nonpayable",
"type": "constructor",
"inputs": [
- {
- "name": "_address_provider",
- "type": "address"
- },
- {
- "name": "_calculator",
- "type": "address"
- }
+ { "name": "_address_provider", "type": "address" },
+ { "name": "_calculator", "type": "address" },
+ { "name": "_weth", "type": "address" }
],
"outputs": []
},
+ { "stateMutability": "payable", "type": "fallback" },
{
"stateMutability": "payable",
- "type": "fallback"
+ "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": "_from", "type": "address" },
+ { "name": "_to", "type": "address" },
+ { "name": "_amount", "type": "uint256" },
+ { "name": "_expected", "type": "uint256" },
+ { "name": "_receiver", "type": "address" }
],
- "outputs": [
- {
- "name": "",
- "type": "uint256"
- }
- ]
+ "outputs": [{ "name": "", "type": "uint256" }]
},
{
"stateMutability": "payable",
"type": "function",
- "name": "exchange_with_best_rate",
+ "name": "exchange",
"inputs": [
- {
- "name": "_from",
- "type": "address"
- },
- {
- "name": "_to",
- "type": "address"
- },
- {
- "name": "_amount",
- "type": "uint256"
- },
- {
- "name": "_expected",
- "type": "uint256"
- },
- {
- "name": "_receiver",
- "type": "address"
- }
+ { "name": "_pool", "type": "address" },
+ { "name": "_from", "type": "address" },
+ { "name": "_to", "type": "address" },
+ { "name": "_amount", "type": "uint256" },
+ { "name": "_expected", "type": "uint256" }
],
- "outputs": [
- {
- "name": "",
- "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": "_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"
- }
- ]
+ "outputs": [{ "name": "", "type": "uint256" }]
},
{
"stateMutability": "payable",
"type": "function",
- "name": "exchange",
+ "name": "exchange_multiple",
"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"
- }
+ { "name": "_route", "type": "address[9]" },
+ { "name": "_swap_params", "type": "uint256[3][4]" },
+ { "name": "_amount", "type": "uint256" },
+ { "name": "_expected", "type": "uint256" }
],
- "outputs": [
- {
- "name": "",
- "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"
- }
+ { "name": "_from", "type": "address" },
+ { "name": "_to", "type": "address" },
+ { "name": "_amount", "type": "uint256" }
],
"outputs": [
- {
- "name": "",
- "type": "address"
- },
- {
- "name": "",
- "type": "uint256"
- }
+ { "name": "", "type": "address" },
+ { "name": "", "type": "uint256" }
]
},
{
@@ -230,32 +152,14 @@
"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]"
- }
+ { "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"
- }
+ { "name": "", "type": "address" },
+ { "name": "", "type": "uint256" }
]
},
{
@@ -263,238 +167,141 @@
"type": "function",
"name": "get_exchange_amount",
"inputs": [
- {
- "name": "_pool",
- "type": "address"
- },
- {
- "name": "_from",
- "type": "address"
- },
- {
- "name": "_to",
- "type": "address"
- },
- {
- "name": "_amount",
- "type": "uint256"
- }
+ { "name": "_pool", "type": "address" },
+ { "name": "_from", "type": "address" },
+ { "name": "_to", "type": "address" },
+ { "name": "_amount", "type": "uint256" }
],
- "outputs": [
- {
- "name": "",
- "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"
- }
+ { "name": "_pool", "type": "address" },
+ { "name": "_from", "type": "address" },
+ { "name": "_to", "type": "address" },
+ { "name": "_amount", "type": "uint256" }
],
- "outputs": [
- {
- "name": "",
- "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]"
- }
+ { "name": "_pool", "type": "address" },
+ { "name": "_from", "type": "address" },
+ { "name": "_to", "type": "address" },
+ { "name": "_amounts", "type": "uint256[100]" }
],
- "outputs": [
- {
- "name": "",
- "type": "uint256[100]"
- }
- ]
+ "outputs": [{ "name": "", "type": "uint256[100]" }]
},
{
"stateMutability": "view",
"type": "function",
- "name": "get_calculator",
+ "name": "get_exchange_multiple_amount",
"inputs": [
- {
- "name": "_pool",
- "type": "address"
- }
+ { "name": "_route", "type": "address[9]" },
+ { "name": "_swap_params", "type": "uint256[3][4]" },
+ { "name": "_amount", "type": "uint256" }
],
- "outputs": [
- {
- "name": "",
- "type": "address"
- }
- ]
+ "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"
- }
- ]
+ "outputs": [{ "name": "", "type": "bool" }]
},
{
"stateMutability": "nonpayable",
"type": "function",
"name": "set_calculator",
"inputs": [
- {
- "name": "_pool",
- "type": "address"
- },
- {
- "name": "_calculator",
- "type": "address"
- }
+ { "name": "_pool", "type": "address" },
+ { "name": "_calculator", "type": "address" }
],
- "outputs": [
- {
- "name": "",
- "type": "bool"
- }
- ]
+ "outputs": [{ "name": "", "type": "bool" }]
},
{
"stateMutability": "nonpayable",
"type": "function",
"name": "set_default_calculator",
- "inputs": [
- {
- "name": "_calculator",
- "type": "address"
- }
- ],
- "outputs": [
- {
- "name": "",
- "type": "bool"
- }
- ]
+ "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"
- }
- ]
+ "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"
- }
- ]
+ "inputs": [{ "name": "_is_killed", "type": "bool" }],
+ "outputs": [{ "name": "", "type": "bool" }]
},
{
"stateMutability": "view",
"type": "function",
"name": "registry",
"inputs": [],
- "outputs": [
- {
- "name": "",
- "type": "address"
- }
- ]
+ "outputs": [{ "name": "", "type": "address" }]
},
{
"stateMutability": "view",
"type": "function",
"name": "factory_registry",
"inputs": [],
- "outputs": [
- {
- "name": "",
- "type": "address"
- }
- ]
+ "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"
- }
- ]
+ "outputs": [{ "name": "", "type": "address" }]
},
{
"stateMutability": "view",
"type": "function",
"name": "is_killed",
"inputs": [],
- "outputs": [
- {
- "name": "",
- "type": "bool"
- }
- ]
+ "outputs": [{ "name": "", "type": "bool" }]
}
],
"linkReferences": {},
"deployedLinkReferences": {}
-}
\ No newline at end of file
+}
diff --git a/dapp-oeth/next.config.js b/dapp-oeth/next.config.js
index 43f4b08352..7d5b47affb 100644
--- a/dapp-oeth/next.config.js
+++ b/dapp-oeth/next.config.js
@@ -59,7 +59,7 @@ const config = {
if (!isServer) {
config.resolve.alias['@sentry/node'] = '@sentry/browser'
- }
+ }
return config
},
@@ -71,22 +71,22 @@ const config = {
{
source: '/swap',
destination: '/',
- permanent: true
+ permanent: true,
},
{
source: '/dapp',
destination: '/',
- permanent: true
+ permanent: true,
},
{
source: '/mint',
destination: '/',
- permanent: true
+ permanent: true,
},
{
source: '/stake',
destination: '/earn',
- permanent: true
+ permanent: true,
},
]
},
@@ -112,7 +112,7 @@ const config = {
},
{
key: 'Content-Security-Policy',
- value: "frame-ancestors https://*.ledger.com",
+ value: 'frame-ancestors https://*.ledger.com',
},
],
},
diff --git a/dapp-oeth/pages/_app.js b/dapp-oeth/pages/_app.js
index 36ece05e2f..753707716d 100644
--- a/dapp-oeth/pages/_app.js
+++ b/dapp-oeth/pages/_app.js
@@ -43,11 +43,11 @@ function App({ Component, pageProps, err }) {
).split('?')[0]
useEffect(() => {
- router.events.on("routeChangeComplete", pageview);
+ router.events.on('routeChangeComplete', pageview)
return () => {
- router.events.off("routeChangeComplete", pageview);
- };
- }, [router.events]);
+ router.events.off('routeChangeComplete', pageview)
+ }
+ }, [router.events])
useEffect(() => {
// Update account info when connection already established
diff --git a/dapp-oeth/src/components/GetOUSD.js b/dapp-oeth/src/components/GetOUSD.js
index f8db112422..eb98f9ba7b 100644
--- a/dapp-oeth/src/components/GetOUSD.js
+++ b/dapp-oeth/src/components/GetOUSD.js
@@ -59,7 +59,7 @@ const GetOUSD = ({
style={style}
onClick={() => {
if (process.browser) {
- event({'event': 'connect_click'})
+ event({ event: 'connect_click' })
if (ledgerLive) {
activate(ledgerLiveConnector, undefined, true)
} else {
diff --git a/dapp-oeth/src/components/IPFSDappLink.js b/dapp-oeth/src/components/IPFSDappLink.js
index 2456f0b0ad..e0f31084f7 100644
--- a/dapp-oeth/src/components/IPFSDappLink.js
+++ b/dapp-oeth/src/components/IPFSDappLink.js
@@ -5,13 +5,11 @@ export default function IPFSDappLink({ css }) {
const [displayIpfsLink, setDisplayIpfsLink] = useState(false)
useEffect(() => {
- setDisplayIpfsLink(
- process.env.DEPLOY_MODE !== 'ipfs'
- )
+ setDisplayIpfsLink(process.env.DEPLOY_MODE !== 'ipfs')
}, [])
if (!displayIpfsLink) {
- return null;
+ return null
}
return (
diff --git a/dapp-oeth/src/components/Nav.js b/dapp-oeth/src/components/Nav.js
index af41394c37..50a485395c 100644
--- a/dapp-oeth/src/components/Nav.js
+++ b/dapp-oeth/src/components/Nav.js
@@ -152,7 +152,7 @@ const TransactionActivityDropdown = () => {
animationHash.current = setTimeout(() => {
setTxHashesToAnimate([])
animationHash.current = null
- }, 8000)
+ }, 13000)
}
const sortedTx = [...transactions]
diff --git a/dapp-oeth/src/components/WalletSelectContent.js b/dapp-oeth/src/components/WalletSelectContent.js
index f00a5401e1..b59a9dbef5 100644
--- a/dapp-oeth/src/components/WalletSelectContent.js
+++ b/dapp-oeth/src/components/WalletSelectContent.js
@@ -39,8 +39,8 @@ const WalletSelectContent = ({ isMobile }) => {
if (active) {
closeWalletSelectModal()
event({
- 'event': 'connect',
- 'connect_address': account?.slice(2)
+ event: 'connect',
+ connect_address: account?.slice(2),
})
}
}, [active])
@@ -70,8 +70,8 @@ const WalletSelectContent = ({ isMobile }) => {
const onConnect = async (name) => {
event({
- 'event': 'connect_modal_click',
- 'connect_modal_wallet': name.toLowerCase()
+ event: 'connect_modal_click',
+ connect_modal_wallet: name.toLowerCase(),
})
setError(null)
diff --git a/dapp-oeth/src/components/buySell/ApproveSwap.js b/dapp-oeth/src/components/buySell/ApproveSwap.js
index 3ec8aa9e7f..db134b2012 100644
--- a/dapp-oeth/src/components/buySell/ApproveSwap.js
+++ b/dapp-oeth/src/components/buySell/ApproveSwap.js
@@ -12,7 +12,7 @@ import { walletLogin } from 'utils/account'
import { event } from '../../../lib/gtm'
const ApproveSwap = ({
- stableCoinToApprove,
+ coinToApprove,
needsApproval,
selectedSwap,
inputAmount,
@@ -36,12 +36,10 @@ const ApproveSwap = ({
const [isApproving, setIsApproving] = useState({})
const web3react = useWeb3React()
const { library, account, activate, active } = web3react
- const coinApproved = stableCoinToApprove === 'eth' || stage === 'done'
+ const coinApproved = coinToApprove === 'eth' || stage === 'done'
const isWrapped =
- selectedSwap &&
- selectedSwap.name === 'woeth' &&
- stableCoinToApprove === 'oeth'
+ selectedSwap && selectedSwap.name === 'woeth' && coinToApprove === 'oeth'
const approvalNeeded =
(selectedSwap &&
@@ -59,15 +57,8 @@ const ApproveSwap = ({
const {
vault,
- uniV3SwapRouter,
- uniV2Router,
- sushiRouter,
- curveOUSDMetaPool,
curveOETHPool,
- usdt,
- dai,
- usdc,
- ousd,
+ curveRegistryExchange,
weth,
reth,
steth,
@@ -78,6 +69,8 @@ const ApproveSwap = ({
zapper,
} = useStoreState(ContractStore, (s) => s.contracts || {})
+ const curveRegistryCoins = ['steth', 'weth', 'reth', 'frxeth']
+
const routeConfig = {
vault: {
contract: vault,
@@ -93,39 +86,25 @@ const ApproveSwap = ({
done: 'Zap + Vault',
},
},
- // uniswap: {
- // contract: uniV3SwapRouter,
- // name: {
- // approving: 'Uniswap',
- // done: 'Uniswap',
- // },
- // },
curve: {
- contract: curveOETHPool,
+ contract:
+ // Use router address for LSDs, and if OETH is going to LSD via curve
+ curveRegistryCoins.includes(coinToApprove) ||
+ (coinToApprove === 'oeth' &&
+ curveRegistryCoins.includes(selectedSwap?.coinToSwap) &&
+ selectedSwap.name === 'curve')
+ ? curveRegistryExchange
+ : curveOETHPool,
name: {
approving: 'Curve',
done: 'Curve',
},
},
- // uniswapV2: {
- // contract: uniV2Router,
- // name: {
- // approving: 'Uniswap',
- // done: 'Uniswap',
- // },
- // },
- // sushiswap: {
- // contract: sushiRouter,
- // name: {
- // approving: 'Sushi Swap',
- // done: 'Sushi Swap',
- // },
- // },
woeth: {
contract: woeth,
name: {
- approving: 'wOETH',
- done: 'wOETH',
+ approving: 'wOETH contract',
+ done: 'wOETH contract',
},
},
}
@@ -134,26 +113,26 @@ const ApproveSwap = ({
if (selectedSwap) {
if (
isApproving.contract === selectedSwap.name &&
- isApproving.coin === stableCoinToApprove
+ isApproving.coin === coinToApprove
) {
setStage('waiting-network')
return
}
}
setStage('approve')
- }, [selectedSwap])
+ }, [JSON.stringify(selectedSwap), JSON.stringify(isApproving)])
useEffect(() => {
const coinToContract = { weth, reth, steth, sfrxeth, oeth, frxeth, woeth }
- if (Object.keys(coinToContract).includes(stableCoinToApprove)) {
- setContract(coinToContract[stableCoinToApprove])
+ if (Object.keys(coinToContract).includes(coinToApprove)) {
+ setContract(coinToContract[coinToApprove])
}
- }, [stableCoinToApprove, reth, weth, steth, oeth, frxeth, woeth])
+ }, [coinToApprove, reth, weth, steth, oeth, frxeth, woeth])
const ApprovalMessage = ({
stage,
selectedSwap,
- stableCoinToApprove,
+ coinToApprove,
isMobile,
}) => {
if (stage === 'waiting-user') {
@@ -182,7 +161,7 @@ const ApproveSwap = ({
const route = `${
routeConfig[selectedSwap.name].name.approving
- } to use your ${stableCoinToApprove.toUpperCase()}`
+ } to use your ${coinToApprove.toUpperCase()}`
const routeMobile = `${routeConfig[selectedSwap.name].name.approving}`
return (
@@ -199,16 +178,14 @@ const ApproveSwap = ({
const SwapMessage = ({
balanceError,
- stableCoinToApprove,
+ coinToApprove,
swapsLoaded,
selectedSwap,
swappingGloballyDisabled,
active,
}) => {
const coin =
- stableCoinToApprove === 'woeth'
- ? 'wOETH'
- : stableCoinToApprove.toUpperCase()
+ coinToApprove === 'woeth' ? 'wOETH' : coinToApprove.toUpperCase()
const noSwapRouteAvailable = swapsLoaded && !selectedSwap
if (swappingGloballyDisabled) {
return process.env.NEXT_PUBLIC_DISABLE_SWAP_BUTTON_MESSAGE
@@ -223,7 +200,7 @@ const ApproveSwap = ({
return fbt('Insufficient liquidity', 'Insufficient liquidity')
} else if (isWrapped) {
return fbt('Wrap', 'Wrap')
- } else if (stableCoinToApprove === 'woeth') {
+ } else if (coinToApprove === 'woeth') {
return fbt('Unwrap', 'Unwrap')
} else {
return fbt('Swap', 'Swap')
@@ -235,7 +212,7 @@ const ApproveSwap = ({
event({
event: 'approve_started',
approval_type: isWrapped ? 'wrap' : 'swap',
- approval_token: stableCoinToApprove,
+ approval_token: coinToApprove,
})
setStage('waiting-user')
try {
@@ -248,18 +225,18 @@ const ApproveSwap = ({
storeTransaction(
result,
isWrapped ? 'approveWrap' : 'approve',
- stableCoinToApprove
+ coinToApprove
)
setStage('waiting-network')
setIsApproving({
contract: needsApproval,
- coin: stableCoinToApprove,
+ coin: coinToApprove,
})
await rpcProvider.waitForTransaction(result.hash)
event({
event: 'approve_complete',
approval_type: isWrapped ? 'wrap' : 'swap',
- approval_token: stableCoinToApprove,
+ approval_token: coinToApprove,
approval_address: '',
approval_tx: '',
})
@@ -270,11 +247,11 @@ const ApproveSwap = ({
console.error('Exception happened: ', e)
setStage('approve')
if (e.code !== 4001) {
- await storeTransactionError('approve', stableCoinToApprove)
+ await storeTransactionError('approve', coinToApprove)
event({
event: 'approve_failed',
approval_type: isWrapped ? 'wrap' : 'swap',
- approval_token: stableCoinToApprove,
+ approval_token: coinToApprove,
approval_address: '',
approval_tx: '',
})
@@ -282,7 +259,7 @@ const ApproveSwap = ({
event({
event: 'approve_rejected',
approval_type: isWrapped ? 'wrap' : 'swap',
- approval_token: stableCoinToApprove,
+ approval_token: coinToApprove,
})
}
}
@@ -341,7 +318,7 @@ const ApproveSwap = ({
)}
@@ -370,7 +347,7 @@ const ApproveSwap = ({
>
{
const coinsToRender =
- coin === 'mix' ? ['weth', 'reth', 'steth', 'frxeth'] : coin.split(',')
+ coin === 'mix' ? ['weth', 'retFh', 'steth', 'frxeth'] : coin.split(',')
const size = 24
return (
<>
diff --git a/dapp-oeth/src/components/wrap/WrapHomepage.js b/dapp-oeth/src/components/wrap/WrapHomepage.js
index a66df43ea4..e93f5aa253 100644
--- a/dapp-oeth/src/components/wrap/WrapHomepage.js
+++ b/dapp-oeth/src/components/wrap/WrapHomepage.js
@@ -309,7 +309,7 @@ const WrapHomepage = ({
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
+```
+*/
+
+const curveRoutes = {
+ // stETH -> OETH Mint
+ '0xae7ab96520DE3A18E5e111B5EaAb095312D7fE84': {
+ '0x856c4Efb76C1D1AE02e20CEB03A2A6a08b0b8dC3': {
+ routes: [
+ '0xae7ab96520DE3A18E5e111B5EaAb095312D7fE84',
+ '0x21E27a5E5513D6e65C4f830167390997aA84843a',
+ '0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE',
+ '0x94B17476A93b3262d87B9a326965D1E91f9c13E7',
+ '0x856c4Efb76C1D1AE02e20CEB03A2A6a08b0b8dC3',
+ '0x0000000000000000000000000000000000000000',
+ '0x0000000000000000000000000000000000000000',
+ '0x0000000000000000000000000000000000000000',
+ '0x0000000000000000000000000000000000000000',
+ ],
+ swapParams: [
+ // 1 for a stableswap `exchange`,
+ [BigNumber.from(1), BigNumber.from(0), BigNumber.from(1)],
+ // 1 for a stableswap `exchange`,
+ [BigNumber.from(0), BigNumber.from(1), BigNumber.from(1)],
+ [BigNumber.from(0), BigNumber.from(0), BigNumber.from(0)],
+ [BigNumber.from(0), BigNumber.from(0), BigNumber.from(0)],
+ ],
+ },
+ },
+ // WETH -> OETH Mint
+ '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2': {
+ '0x856c4Efb76C1D1AE02e20CEB03A2A6a08b0b8dC3': {
+ routes: [
+ '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2',
+ '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2',
+ '0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE',
+ '0x94B17476A93b3262d87B9a326965D1E91f9c13E7',
+ '0x856c4Efb76C1D1AE02e20CEB03A2A6a08b0b8dC3',
+ '0x0000000000000000000000000000000000000000',
+ '0x0000000000000000000000000000000000000000',
+ '0x0000000000000000000000000000000000000000',
+ '0x0000000000000000000000000000000000000000',
+ ],
+ swapParams: [
+ // 15 for WETH -> ETH "exchange" (actually deposit/withdraw)
+ [BigNumber.from(0), BigNumber.from(0), BigNumber.from(15)],
+ // 1 for a stableswap `exchange`,
+ [BigNumber.from(0), BigNumber.from(1), BigNumber.from(1)],
+ [BigNumber.from(0), BigNumber.from(0), BigNumber.from(0)],
+ [BigNumber.from(0), BigNumber.from(0), BigNumber.from(0)],
+ ],
+ },
+ },
+ // rETH -> OETH Mint
+ '0xae78736Cd615f374D3085123A210448E74Fc6393': {
+ '0x856c4Efb76C1D1AE02e20CEB03A2A6a08b0b8dC3': {
+ routes: [
+ '0xae78736Cd615f374D3085123A210448E74Fc6393',
+ '0x0f3159811670c117c372428D4E69AC32325e4D0F',
+ '0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE',
+ '0x94B17476A93b3262d87B9a326965D1E91f9c13E7',
+ '0x856c4Efb76C1D1AE02e20CEB03A2A6a08b0b8dC3',
+ '0x0000000000000000000000000000000000000000',
+ '0x0000000000000000000000000000000000000000',
+ '0x0000000000000000000000000000000000000000',
+ '0x0000000000000000000000000000000000000000',
+ ],
+ swapParams: [
+ // 3 for a cryptoswap `exchange`,
+ [BigNumber.from(1), BigNumber.from(0), BigNumber.from(3)],
+ // 1 for a stableswap `exchange`,
+ [BigNumber.from(0), BigNumber.from(1), BigNumber.from(1)],
+ [BigNumber.from(0), BigNumber.from(0), BigNumber.from(0)],
+ [BigNumber.from(0), BigNumber.from(0), BigNumber.from(0)],
+ ],
+ },
+ },
+ // frxETH -> OETH Mint
+ '0x5e8422345238f34275888049021821e8e08caa1f': {
+ '0x856c4Efb76C1D1AE02e20CEB03A2A6a08b0b8dC3': {
+ routes: [
+ '0x5E8422345238F34275888049021821E8E08CAa1f',
+ '0xa1F8A6807c402E4A15ef4EBa36528A3FED24E577',
+ '0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE',
+ '0x94B17476A93b3262d87B9a326965D1E91f9c13E7',
+ '0x856c4Efb76C1D1AE02e20CEB03A2A6a08b0b8dC3',
+ '0x0000000000000000000000000000000000000000',
+ '0x0000000000000000000000000000000000000000',
+ '0x0000000000000000000000000000000000000000',
+ '0x0000000000000000000000000000000000000000',
+ ],
+ swapParams: [
+ // 1 for a stableswap `exchange`,
+ [BigNumber.from(1), BigNumber.from(0), BigNumber.from(1)],
+ // 1 for a stableswap `exchange`,
+ [BigNumber.from(0), BigNumber.from(1), BigNumber.from(1)],
+ [BigNumber.from(0), BigNumber.from(0), BigNumber.from(0)],
+ [BigNumber.from(0), BigNumber.from(0), BigNumber.from(0)],
+ ],
+ },
+ },
+ // OETH Redeem
+ '0x856c4Efb76C1D1AE02e20CEB03A2A6a08b0b8dC3': {
+ // OETH -> frxETH
+ '0x5e8422345238f34275888049021821e8e08caa1f': {
+ routes: [
+ '0x856c4Efb76C1D1AE02e20CEB03A2A6a08b0b8dC3',
+ '0x94B17476A93b3262d87B9a326965D1E91f9c13E7',
+ '0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE',
+ '0xa1F8A6807c402E4A15ef4EBa36528A3FED24E577',
+ '0x5E8422345238F34275888049021821E8E08CAa1f',
+ '0x0000000000000000000000000000000000000000',
+ '0x0000000000000000000000000000000000000000',
+ '0x0000000000000000000000000000000000000000',
+ '0x0000000000000000000000000000000000000000',
+ ],
+ swapParams: [
+ // 1 for a stableswap `exchange`,
+ [BigNumber.from(1), BigNumber.from(0), BigNumber.from(1)],
+ // 1 for a stableswap `exchange`,
+ [BigNumber.from(0), BigNumber.from(1), BigNumber.from(1)],
+ [BigNumber.from(0), BigNumber.from(0), BigNumber.from(0)],
+ [BigNumber.from(0), BigNumber.from(0), BigNumber.from(0)],
+ ],
+ },
+ // OETH -> WETH
+ '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2': {
+ routes: [
+ '0x856c4Efb76C1D1AE02e20CEB03A2A6a08b0b8dC3',
+ '0x94B17476A93b3262d87B9a326965D1E91f9c13E7',
+ '0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE',
+ '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2',
+ '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2',
+ '0x0000000000000000000000000000000000000000',
+ '0x0000000000000000000000000000000000000000',
+ '0x0000000000000000000000000000000000000000',
+ '0x0000000000000000000000000000000000000000',
+ ],
+ swapParams: [
+ // 1 for a stableswap `exchange`,
+ [BigNumber.from(1), BigNumber.from(0), BigNumber.from(1)],
+ // 15 for WETH -> ETH "exchange" (actually deposit/withdraw)
+ [BigNumber.from(0), BigNumber.from(0), BigNumber.from(15)],
+ [BigNumber.from(0), BigNumber.from(0), BigNumber.from(0)],
+ [BigNumber.from(0), BigNumber.from(0), BigNumber.from(0)],
+ ],
+ },
+ // OETH -> rETH
+ '0xae78736Cd615f374D3085123A210448E74Fc6393': {
+ routes: [
+ '0x856c4Efb76C1D1AE02e20CEB03A2A6a08b0b8dC3',
+ '0x94B17476A93b3262d87B9a326965D1E91f9c13E7',
+ '0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE',
+ '0x0f3159811670c117c372428D4E69AC32325e4D0F',
+ '0xae78736Cd615f374D3085123A210448E74Fc6393',
+ '0x0000000000000000000000000000000000000000',
+ '0x0000000000000000000000000000000000000000',
+ '0x0000000000000000000000000000000000000000',
+ '0x0000000000000000000000000000000000000000',
+ ],
+ swapParams: [
+ // 1 for a stableswap `exchange`,
+ [BigNumber.from(1), BigNumber.from(0), BigNumber.from(1)],
+ // 3 for a cryptoswap `exchange`,
+ [BigNumber.from(0), BigNumber.from(1), BigNumber.from(3)],
+ [BigNumber.from(0), BigNumber.from(0), BigNumber.from(0)],
+ [BigNumber.from(0), BigNumber.from(0), BigNumber.from(0)],
+ ],
+ },
+ // OETH -> stETH
+ '0xae7ab96520DE3A18E5e111B5EaAb095312D7fE84': {
+ routes: [
+ '0x856c4Efb76C1D1AE02e20CEB03A2A6a08b0b8dC3',
+ '0x94B17476A93b3262d87B9a326965D1E91f9c13E7',
+ '0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE',
+ '0x21E27a5E5513D6e65C4f830167390997aA84843a',
+ '0xae7ab96520DE3A18E5e111B5EaAb095312D7fE84',
+ '0x0000000000000000000000000000000000000000',
+ '0x0000000000000000000000000000000000000000',
+ '0x0000000000000000000000000000000000000000',
+ '0x0000000000000000000000000000000000000000',
+ ],
+ swapParams: [
+ // 1 for a stableswap `exchange`,
+ [BigNumber.from(1), BigNumber.from(0), BigNumber.from(1)],
+ // 1 for a stableswap `exchange`,
+ [BigNumber.from(0), BigNumber.from(1), BigNumber.from(1)],
+ [BigNumber.from(0), BigNumber.from(0), BigNumber.from(0)],
+ [BigNumber.from(0), BigNumber.from(0), BigNumber.from(0)],
+ ],
+ },
+ },
+}
+
+module.exports = curveRoutes
diff --git a/dapp-oeth/src/hooks/useCurrencySwapper.js b/dapp-oeth/src/hooks/useCurrencySwapper.js
index 8700fd4fd4..5b95b41825 100644
--- a/dapp-oeth/src/hooks/useCurrencySwapper.js
+++ b/dapp-oeth/src/hooks/useCurrencySwapper.js
@@ -1,7 +1,6 @@
import React, { useEffect, useState } from 'react'
import { ethers, BigNumber } from 'ethers'
import { useStoreState } from 'pullstate'
-
import ContractStore from 'stores/ContractStore'
import AccountStore from 'stores/AccountStore'
import {
@@ -15,8 +14,8 @@ import {
NullAddress,
} from 'utils/constants'
import { useWeb3React } from '@web3-react/core'
-import { find } from 'lodash'
import addresses from 'constants/contractAddresses'
+import curveRoutes from 'constants/curveRoutes'
import { calculateSwapAmounts } from 'utils/math'
@@ -124,11 +123,28 @@ const useCurrencySwapper = ({
)
}
+ const curveRegistryCoins = ['steth', 'weth', 'reth', 'frxeth']
+
+ let allowanceCheckKey = nameMaps[selectedSwap.name]
+
+ if (selectedSwap.name === 'curve') {
+ allowanceCheckKey =
+ (swapMode === 'mint' &&
+ selectedCoin === 'oeth' &&
+ curveRegistryCoins.includes(coinNeedingApproval)) ||
+ (swapMode === 'redeem' &&
+ coinNeedingApproval === 'oeth' &&
+ curveRegistryCoins.includes(selectedCoin))
+ ? 'curve_registry'
+ : 'curve'
+ }
+
+ const allowance = parseFloat(
+ allowances[coinNeedingApproval][allowanceCheckKey]
+ )
+
setNeedsApproval(
- Object.keys(allowances).length > 0 &&
- parseFloat(
- allowances[coinNeedingApproval][nameMaps[selectedSwap.name]]
- ) < amount
+ Object.keys(allowances).length > 0 && allowance < amount
? selectedSwap.name
: false
)
@@ -338,45 +354,76 @@ const useCurrencySwapper = ({
}
const _swapCurve = async (swapAmount, minSwapAmount, isGasEstimate) => {
- const nullAddress = NullAddress?.toLowerCase()
- const fromAddress = coinContract?.address?.toLowerCase() || nullAddress
- const toAddress =
- coinToReceiveContract?.address?.toLowerCase() || nullAddress
-
- const swapParams = [
- curveUnderlyingCoins.indexOf(fromAddress),
- curveUnderlyingCoins.indexOf(toAddress),
- swapAmount,
- minSwapAmount,
- ]
+ // Handle stETH, rETH, WETH, frxETH
+ if (coinContract?.address && coinToReceiveContract?.address) {
+ const { routes, swapParams } =
+ curveRoutes[coinContract?.address]?.[coinToReceiveContract?.address]
- const overrides =
- fromAddress === nullAddress
- ? {
- value: swapAmount,
- }
- : {}
+ if (!routes) {
+ throw new Error('No curve route found for contract address pair')
+ }
- const estimatedGasLimit = await curveOETHPool.estimateGas.exchange(
- ...swapParams,
- {
+ const estimatedGasLimit = await curveRegistryExchange.estimateGas[
+ 'exchange_multiple(address[9],uint256[3][4],uint256,uint256)'
+ ](routes, swapParams, swapAmount, minSwapAmount, {
from: account,
- ...overrides,
- }
- )
+ })
- const gasLimit = increaseGasLimitByBuffer(
- estimatedGasLimit,
- curveGasLimitBuffer
- )
+ const gasLimit = increaseGasLimitByBuffer(
+ estimatedGasLimit,
+ curveGasLimitBuffer
+ )
- if (isGasEstimate) {
- return gasLimit
+ if (isGasEstimate) {
+ return gasLimit
+ } else {
+ return await connSigner(curveRegistryExchange)[
+ 'exchange_multiple(address[9],uint256[3][4],uint256,uint256)'
+ ](routes, swapParams, swapAmount, minSwapAmount, {
+ gasLimit,
+ })
+ }
} else {
- return await connSigner(curveOETHPool).exchange(...swapParams, {
- gasLimit,
- ...overrides,
- })
+ const nullAddress = NullAddress?.toLowerCase()
+ const fromAddress = coinContract?.address?.toLowerCase() || nullAddress
+ const toAddress =
+ coinToReceiveContract?.address?.toLowerCase() || nullAddress
+
+ const swapParams = [
+ curveUnderlyingCoins.indexOf(fromAddress),
+ curveUnderlyingCoins.indexOf(toAddress),
+ swapAmount,
+ minSwapAmount,
+ ]
+
+ const overrides =
+ fromAddress === nullAddress
+ ? {
+ value: swapAmount,
+ }
+ : {}
+
+ const estimatedGasLimit = await curveOETHPool.estimateGas.exchange(
+ ...swapParams,
+ {
+ from: account,
+ ...overrides,
+ }
+ )
+
+ const gasLimit = increaseGasLimitByBuffer(
+ estimatedGasLimit,
+ curveGasLimitBuffer
+ )
+
+ if (isGasEstimate) {
+ return gasLimit
+ } else {
+ return await connSigner(curveOETHPool).exchange(...swapParams, {
+ gasLimit,
+ ...overrides,
+ })
+ }
}
}
@@ -399,16 +446,33 @@ const useCurrencySwapper = ({
}
const quoteCurve = async (swapAmount) => {
- return curveRegistryExchange.get_exchange_amount(
- addresses.mainnet.CurveOETHPool,
- // For Eth support
- coinContract?.address || NullAddress,
- coinToReceiveContract?.address || NullAddress,
- swapAmount,
- {
- gasLimit: 1000000,
+ // Not a ETH/OETH swap
+ if (coinContract?.address && coinToReceiveContract?.address) {
+ const { routes, swapParams } =
+ curveRoutes[coinContract?.address]?.[coinToReceiveContract?.address]
+
+ if (!routes) {
+ throw new Error('No curve route found for contract address pair')
}
- )
+
+ return curveRegistryExchange[
+ 'get_exchange_multiple_amount(address[9],uint256[3][4],uint256)'
+ ](routes, swapParams, swapAmount, {
+ gasLimit: 1000000,
+ })
+ } else {
+ // ETH
+ return curveRegistryExchange['get_exchange_amount'](
+ addresses.mainnet.CurveOETHPool,
+ // For Eth support
+ coinContract?.address || NullAddress,
+ coinToReceiveContract?.address || NullAddress,
+ swapAmount,
+ {
+ gasLimit: 1000000,
+ }
+ )
+ }
}
const _swapUniswap = async (swapAmount, minSwapAmount, isGasEstimate) => {
diff --git a/dapp-oeth/src/hooks/useSwapEstimator.js b/dapp-oeth/src/hooks/useSwapEstimator.js
index f10b44bb9b..dee14b15dc 100644
--- a/dapp-oeth/src/hooks/useSwapEstimator.js
+++ b/dapp-oeth/src/hooks/useSwapEstimator.js
@@ -79,17 +79,10 @@ const useSwapEstimator = ({
const account = useStoreState(AccountStore, (s) => s.account)
const [estimationCallback, setEstimationCallback] = useState(null)
+
const {
mintVaultGasEstimate,
- swapUniswapGasEstimate,
swapCurveGasEstimate,
- swapUniswapV2GasEstimate,
- swapUniswapV2,
- swapCurve,
- quoteUniswap,
- quoteUniswapV2,
- quoteSushiSwap,
- swapSushiswapGasEstimate,
quoteCurve,
redeemVaultGasEstimate,
} = useCurrencySwapper({
@@ -208,9 +201,6 @@ const useSwapEstimator = ({
? estimateMintSuitabilityVault()
: estimateRedeemSuitabilityVault(),
estimateSwapSuitabilityZapper(),
- // estimateSwapSuitabilityUniswapV3(),
- // estimateSwapSuitabilityUniswapV2(),
- // estimateSwapSuitabilitySushiSwap(),
estimateSwapSuitabilityCurve(),
fetchEthPrice(),
])
@@ -408,10 +398,11 @@ const useSwapEstimator = ({
*/
const estimateSwapSuitabilityCurve = async () => {
const isRedeem = swapMode === 'redeem'
+ const curveRegistryCoins = ['steth', 'reth', 'weth', 'frxeth']
if (
(isRedeem && selectedCoin === 'mix') ||
- !['eth', 'oeth'].includes(selectedCoin)
+ !['eth', 'oeth', ...curveRegistryCoins].includes(selectedCoin)
) {
return {
canDoSwap: false,
@@ -453,15 +444,28 @@ const useSwapEstimator = ({
}
}
- const approveAllowanceNeeded = allowancesLoaded
- ? parseFloat(allowances[coinToSwap].curve) < parseFloat(inputAmountRaw)
- : true
-
/* Check if Curve router has allowance to spend coin. If not we can not run gas estimation and need
* to guess the gas usage.
*
* We don't check if positive amount is large enough: since we always approve max_int allowance.
*/
+
+ const allowanceCheckKey =
+ (swapMode === 'mint' &&
+ selectedCoin === 'oeth' &&
+ curveRegistryCoins.includes(coinToSwap)) ||
+ (swapMode === 'redeem' &&
+ coinToSwap === 'oeth' &&
+ curveRegistryCoins.includes(selectedCoin))
+ ? 'curve_registry'
+ : 'curve'
+
+ // ETH / OETH mint flow
+ const approveAllowanceNeeded = allowancesLoaded
+ ? parseFloat(allowances[coinToSwap]?.[allowanceCheckKey]) <
+ parseFloat(inputAmountRaw)
+ : true
+
const hasEnoughBalance = userHasEnoughStablecoin(
coinToSwap,
parseFloat(inputAmountRaw)
@@ -472,6 +476,7 @@ const useSwapEstimator = ({
const approveGasUsage = approveAllowanceNeeded
? gasLimitForApprovingCoin(coinToSwap)
: 0
+
return {
canDoSwap: true,
/* This estimate is from the few ones observed on the mainnet:
@@ -479,7 +484,6 @@ const useSwapEstimator = ({
* https://etherscan.io/tx/0xbf033ffbaf01b808953ca1904d3b0110b50337d60d89c96cd06f3f9a6972d3ca
* https://etherscan.io/tx/0x77d98d0307b53e81f50b39132e038a1c6ef87a599a381675ce44038515a04738
* https://etherscan.io/tx/0xbce1a2f1e76d4b4f900b3952f34f5f53f8be4a65ccff348661d19b9a3827aa04
- *
*/
gasUsed: swapGasUsage + approveGasUsage,
swapGasUsage,
@@ -522,274 +526,6 @@ const useSwapEstimator = ({
}
}
- const estimateSwapSuitabilityUniswapV2 = async () => {
- return _estimateSwapSuitabilityUniswapV2Variant(false)
- }
-
- const estimateSwapSuitabilitySushiSwap = async () => {
- return _estimateSwapSuitabilityUniswapV2Variant(true)
- }
-
- // Gives information on suitability of uniswapV2 / SushiSwap for this swap
- const _estimateSwapSuitabilityUniswapV2Variant = async (
- isSushiSwap = false
- ) => {
- const isRedeem = swapMode === 'redeem'
- if (isRedeem && selectedCoin === 'mix') {
- return {
- canDoSwap: false,
- error: 'unsupported',
- }
- }
-
- try {
- const priceQuoteValues = isSushiSwap
- ? await quoteSushiSwap(swapAmount)
- : await quoteUniswapV2(swapAmount)
- const priceQuoteBn = priceQuoteValues[priceQuoteValues.length - 1]
-
- // 18 because ousd has 18 decimals
- const amountReceived = ethers.utils.formatUnits(
- priceQuoteBn,
- isRedeem ? coinToReceiveDecimals : 18
- )
-
- if (
- ethers.utils.formatUnits(swapAmount, decimals) / amountReceived >
- max_price
- ) {
- return {
- canDoSwap: false,
- error: 'price_too_high',
- }
- }
-
- /* Check if Uniswap router has allowance to spend coin. If not we can not run gas estimation and need
- * to guess the gas usage.
- *
- * We don't check if positive amount is large enough: since we always approve max_int allowance.
- */
- const requiredAllowance = allowancesLoaded
- ? allowances[coinToSwap][
- isSushiSwap ? 'sushiRouter' : 'uniswapV2Router'
- ]
- : 0
-
- if (requiredAllowance === undefined) {
- throw new Error('Can not find correct allowance for coin')
- }
-
- const approveAllowanceNeeded = parseFloat(requiredAllowance) === 0
-
- const hasEnoughBalance = userHasEnoughStablecoin(
- coinToSwap,
- parseFloat(inputAmountRaw)
- )
-
- if (approveAllowanceNeeded || !hasEnoughBalance) {
- const swapGasUsage = selectedCoin === 'usdt' ? 175000 : 230000
- const approveGasUsage = approveAllowanceNeeded
- ? gasLimitForApprovingCoin(coinToSwap)
- : 0
- return {
- canDoSwap: true,
- /* Some example Uniswap transactions. When 2 swaps are done:
- * - https://etherscan.io/tx/0x436ef157435c93241257fb0b347db7cc1b2c4f73d749c7e5c1181393f3d0aa26
- * - https://etherscan.io/tx/0x504799fecb64a0452f5635245ca313aa5612132dc6fe66c441b61fd98a0e0766
- * - https://etherscan.io/tx/0x2e3429fb9f04819a55f85cfdbbaf78dfbb049bff85be84a324650d77ff98dfc3
- *
- * And Uniswap when 1 swap:
- * - https://etherscan.io/tx/0x6ceca6c6c2a829928bbf9cf97a018b431def8e475577fcc7cc97ed6bd35f9f7b
- * - https://etherscan.io/tx/0x02c1fffb94b06d54e0c6d47da460cb6e5e736e43f928b7e9b2dcd964b1390188
- * - https://etherscan.io/tx/0xe5a35025ec3fe71ece49a4311319bdc16302b7cc16b3e7a95f0d8e45baa922c7
- *
- * Some example Sushiswap transactions. When 2 swaps are done:
- * - https://etherscan.io/tx/0x8e66d8d682b8028fd44c916d4318fee7e69704e9f8e386dd7debbfe3157375c5
- * - https://etherscan.io/tx/0xbb837c5f001a0d71c75db49ddc22bd75b7800e426252ef1f1135e8e543769bea
- * - https://etherscan.io/tx/0xe00ab2125b55fd398b00e361e2fd22f6fc9225e609fb2bb2b712586523c89824
- * - https://etherscan.io/tx/0x5c26312ac2bab17aa8895592faa8dc8607f15912de953546136391ee2e955e92
- *
- * And Sushiswap when 1 swap:
- * - https://etherscan.io/tx/0xa8a0c5d2433bcb6ddbfdfb1db7c55c674714690e353f305e4f3c72878ab6a3a7
- * - https://etherscan.io/tx/0x8d2a273d0451ab48c554f8a97d333f7f62b40804946cbd546dc57e2c009514f0
- *
- * Both contracts have very similar gas usage (since they share a lot of the code base)
- */
- gasUsed: swapGasUsage + approveGasUsage,
- swapGasUsage,
- approveGasUsage,
- approveAllowanceNeeded,
- inputAmount: parseFloat(inputAmountRaw),
- amountReceived,
- hasEnoughBalance,
- }
- }
-
- const {
- swapAmount: swapAmountQuoted,
- minSwapAmount: minSwapAmountQuoted,
- } = calculateSwapAmounts(
- amountReceived,
- coinToReceiveDecimals,
- priceToleranceValue
- )
-
- let gasEstimate
-
- if (isSushiSwap) {
- gasEstimate = await swapSushiswapGasEstimate(
- swapAmount,
- minSwapAmountQuoted
- )
- } else {
- gasEstimate = await swapUniswapV2GasEstimate(
- swapAmount,
- minSwapAmountQuoted
- )
- }
-
- return {
- canDoSwap: true,
- gasUsed: gasEstimate,
- inputAmount: parseFloat(inputAmountRaw),
- amountReceived,
- }
- } catch (e) {
- console.error(
- `Unexpected error estimating ${
- isSushiSwap ? 'sushiSwap' : 'uniswap v2'
- } swap suitability: ${e?.message}`
- )
-
- if (
- (e.data &&
- e.data.message &&
- e.data.message.includes('INSUFFICIENT_OUTPUT_AMOUNT')) ||
- e.message.includes('INSUFFICIENT_OUTPUT_AMOUNT')
- ) {
- return {
- canDoSwap: false,
- error: 'price_too_high',
- }
- }
-
- return {
- canDoSwap: false,
- error: 'unexpected_error',
- }
- }
- }
-
- /* Gives information on suitability of uniswap for this swap
- */
- const estimateSwapSuitabilityUniswapV3 = async () => {
- const isRedeem = swapMode === 'redeem'
- if (isRedeem && selectedCoin === 'mix') {
- return {
- canDoSwap: false,
- error: 'unsupported',
- }
- }
-
- try {
- const priceQuote = await quoteUniswap(swapAmount)
- const priceQuoteBn = BigNumber.from(priceQuote)
- // 18 because ousd has 18 decimals
- const amountReceived = ethers.utils.formatUnits(
- priceQuoteBn,
- isRedeem ? coinToReceiveDecimals : 18
- )
-
- if (
- ethers.utils.formatUnits(swapAmount, decimals) / amountReceived >
- max_price
- ) {
- return {
- canDoSwap: false,
- error: 'price_too_high',
- }
- }
-
- /* Check if Uniswap router has allowance to spend coin. If not we can not run gas estimation and need
- * to guess the gas usage.
- *
- * We don't check if positive amount is large enough: since we always approve max_int allowance.
- */
-
- if (
- !allowancesLoaded ||
- parseFloat(allowances[coinToSwap].uniswapV3Router) === 0 ||
- !userHasEnoughStablecoin(coinToSwap, parseFloat(inputAmountRaw))
- ) {
- const approveAllowanceNeeded = allowancesLoaded
- ? parseFloat(allowances[coinToSwap].uniswapV3Router) === 0
- : true
- const approveGasUsage = approveAllowanceNeeded
- ? gasLimitForApprovingCoin(coinToSwap)
- : 0
- const swapGasUsage = 165000
- return {
- canDoSwap: true,
- /* This estimate is over the maximum one appearing on mainnet: https://etherscan.io/tx/0x6b1163b012570819e2951fa95a8287ce16be96b8bf18baefb6e738d448188ed5
- * Swap gas costs are usually between 142k - 162k
- *
- * Other transactions here: https://etherscan.io/tokentxns?a=0x129360c964e2e13910d603043f6287e5e9383374&p=6
- */
- // TODO: if usdc / dai are selected it will cost more gas
- gasUsed: swapGasUsage + approveGasUsage,
- approveAllowanceNeeded,
- swapGasUsage,
- approveGasUsage,
- inputAmount: parseFloat(inputAmountRaw),
- amountReceived,
- }
- }
-
- const {
- swapAmount: swapAmountQuoted,
- minSwapAmount: minSwapAmountQuoted,
- } = calculateSwapAmounts(
- amountReceived,
- coinToReceiveDecimals,
- priceToleranceValue
- )
-
- const gasEstimate = await swapUniswapGasEstimate(
- swapAmount,
- minSwapAmountQuoted
- )
-
- return {
- canDoSwap: true,
- gasUsed: gasEstimate,
- inputAmount: parseFloat(inputAmountRaw),
- amountReceived,
- }
- } catch (e) {
- console.error(
- `Unexpected error estimating uniswap v3 swap suitability: ${e.message}`
- )
-
- // local node and mainnet return errors in different formats, this handles both cases
- if (
- (e.data &&
- e.data.message &&
- e.data.message.includes('Too little received')) ||
- e.message.includes('Too little received')
- ) {
- return {
- canDoSwap: false,
- error: 'price_too_high',
- }
- }
-
- return {
- canDoSwap: false,
- error: 'unexpected_error',
- }
- }
- }
-
/* Gives information on suitability of vault mint
*/
const estimateMintSuitabilityVault = async () => {
@@ -1116,7 +852,6 @@ const useSwapEstimator = ({
estimateSwapSuitabilityZapper,
estimateMintSuitabilityVault,
estimateRedeemSuitabilityVault,
- estimateSwapSuitabilityUniswapV3,
estimateSwapSuitabilityCurve,
}
}
diff --git a/dapp-oeth/src/services/allowances.service.js b/dapp-oeth/src/services/allowances.service.js
index 7b3c9da032..a51cfdba62 100644
--- a/dapp-oeth/src/services/allowances.service.js
+++ b/dapp-oeth/src/services/allowances.service.js
@@ -14,6 +14,7 @@ export default class AllowancesService {
oeth,
woeth,
curveOETHPool,
+ curveRegistryExchange,
} = contracts
const [
@@ -40,13 +41,45 @@ export default class AllowancesService {
])
let oethAllowanceCurvePool
+ let oethRegistryAllowanceCurvePool
+ let stethAllowanceCurvePool
+ let wethAllowanceCurvePool
+ let rethAllowanceCurvePool
+ let frxethAllowanceCurvePool
if (curveOETHPool) {
- ;[oethAllowanceCurvePool] = await Promise.all([
+ ;[
+ oethAllowanceCurvePool,
+ oethRegistryAllowanceCurvePool,
+ stethAllowanceCurvePool,
+ wethAllowanceCurvePool,
+ rethAllowanceCurvePool,
+ frxethAllowanceCurvePool,
+ ] = await Promise.all([
displayCurrency(
await oeth.allowance(account, curveOETHPool.address),
oeth
),
+ displayCurrency(
+ await oeth.allowance(account, curveRegistryExchange.address),
+ oeth
+ ),
+ displayCurrency(
+ await steth.allowance(account, curveRegistryExchange.address),
+ steth
+ ),
+ displayCurrency(
+ await weth.allowance(account, curveRegistryExchange.address),
+ weth
+ ),
+ displayCurrency(
+ await reth.allowance(account, curveRegistryExchange.address),
+ reth
+ ),
+ displayCurrency(
+ await frxeth.allowance(account, curveRegistryExchange.address),
+ frxeth
+ ),
])
}
@@ -59,16 +92,20 @@ export default class AllowancesService {
oeth: {
vault: oethAllowanceVault,
curve: oethAllowanceCurvePool,
+ curve_registry: oethRegistryAllowanceCurvePool,
woeth: woethAllowance,
},
weth: {
vault: wethAllowanceVault,
+ curve: wethAllowanceCurvePool,
},
reth: {
vault: rethAllowanceVault,
+ curve: rethAllowanceCurvePool,
},
frxeth: {
vault: frxethAllowanceVault,
+ curve: frxethAllowanceCurvePool,
},
sfrxeth: {
vault: sfrxethAllowanceVault,
@@ -76,6 +113,7 @@ export default class AllowancesService {
},
steth: {
vault: stethAllowanceVault,
+ curve: stethAllowanceCurvePool,
},
}
}
diff --git a/dapp-oeth/src/utils/connectors.js b/dapp-oeth/src/utils/connectors.js
index 713a9121ee..1efd8bfffb 100644
--- a/dapp-oeth/src/utils/connectors.js
+++ b/dapp-oeth/src/utils/connectors.js
@@ -71,7 +71,7 @@ export const defiWalletConnector = process.browser
: {}
export const ledgerLiveConnector = new LedgerHQFrameConnector({
- targetOrigin: "https://dapp-browser.apps.ledger.com",
+ targetOrigin: 'https://dapp-browser.apps.ledger.com',
timeoutMilliseconds: 10000,
})
diff --git a/dapp-oeth/src/utils/contracts.js b/dapp-oeth/src/utils/contracts.js
index e8610b31be..6c363aca4c 100644
--- a/dapp-oeth/src/utils/contracts.js
+++ b/dapp-oeth/src/utils/contracts.js
@@ -17,6 +17,7 @@ import ognAbi from 'constants/mainnetAbi/ogn.json'
import ogvAbi from 'constants/mainnetAbi/ogv.json'
import veogvAbi from 'constants/mainnetAbi/veogv.json'
import sfrxethAbi from 'constants/mainnetAbi/sfrxeth.json'
+import registryExchangeJson from '../../abis/CurveRegistryExchange.json'
const curveFactoryMiniAbi = [
{
@@ -570,6 +571,11 @@ const setupCurve = async (curveAddressProvider, getContract, chainId) => {
const registryExchangeAddress = await curveAddressProvider.get_address(2)
const registryExchangeJson = require('../../abis/CurveRegistryExchange.json')
+ const curveRegistryExchange = getContract(
+ registryExchangeAddress,
+ registryExchangeJson.abi
+ )
+
const factoryAddress = await curveAddressProvider.get_address(3)
const factory = getContract(factoryAddress, curveFactoryMiniAbi)
@@ -582,11 +588,7 @@ const setupCurve = async (curveAddressProvider, getContract, chainId) => {
curvePoolMiniAbi
)
- return [
- getContract(registryExchangeAddress, registryExchangeJson.abi),
- curveOETHPool,
- curveUnderlyingCoins,
- ]
+ return [curveRegistryExchange, curveOETHPool, curveUnderlyingCoins]
}
// calls to be executed only once after setup
diff --git a/dapp-oeth/src/utils/hooks.js b/dapp-oeth/src/utils/hooks.js
index 86a4afb76b..5827c57d41 100644
--- a/dapp-oeth/src/utils/hooks.js
+++ b/dapp-oeth/src/utils/hooks.js
@@ -63,7 +63,7 @@ export function useEagerConnect() {
setTriedLedgerLive(true)
return
}
-
+
AccountStore.update((s) => {
s.connectorName = 'Ledger'
})
diff --git a/dapp-oeth/src/utils/web3.js b/dapp-oeth/src/utils/web3.js
index 767f0c9105..318c686d67 100644
--- a/dapp-oeth/src/utils/web3.js
+++ b/dapp-oeth/src/utils/web3.js
@@ -8,8 +8,8 @@ export function isCorrectNetwork(chainId) {
return chainId === 1
} else {
return (
- chainId ===
- (parseInt(process.env.NEXT_PUBLIC_ETHEREUM_RPC_CHAIN_ID)) || 1337
+ chainId === parseInt(process.env.NEXT_PUBLIC_ETHEREUM_RPC_CHAIN_ID) ||
+ 1337
)
}
}
diff --git a/package.json b/package.json
index a259c2e4e1..9baadec94d 100644
--- a/package.json
+++ b/package.json
@@ -13,6 +13,6 @@
"react-use": "^17.4.0"
},
"engines": {
- "node": ">=16"
+ "node": "16"
}
}