Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix endpoints updates and Algorand USDT pool availability warnings #80

Merged
merged 7 commits into from
Apr 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/giant-camels-care.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'ptokens-dapp-v2': patch
---

fix endpoint update and algorand pool availability warnings.
10 changes: 10 additions & 0 deletions .snyk
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# Snyk (https://snyk.io) policy file, patches or ignores known vulnerabilities.
version: v1.25.0
# ignores vulnerabilities until expiry date; change duration by modifying expiry date
ignore:
SNYK-JS-WEB3UTILS-6229337:
- '*':
reason: Not currently expoitable - fix planned
expires: 2024-05-04T00:00:00.000Z
created: 2024-04-04T11:30:11.068Z
patch: {}
6,125 changes: 3,494 additions & 2,631 deletions package-lock.json

Large diffs are not rendered by default.

5 changes: 3 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,13 @@
"dependencies": {
"@blockshake/defly-connect": "^1.1.5",
"@changesets/cli": "^2.27.1",
"@curvefi/api": "^2.28.0",
"@curvefi/api": "2.30.0",
"@json-rpc-tools/utils": "^1.7.6",
"@libre-chain/libre-link": "^3.5.0",
"@libre-chain/libre-link-browser-transport": "^3.4.2",
"@msgpack/msgpack": "^2.7.2",
"@p.network/ptokens": "^1.7.1",
"@p.network/react-web3-settings": "^1.2.0",
"@perawallet/connect": "^1.3.1",
"@randlabs/myalgo-connect": "^1.2.0",
"@walletconnect/ethereum-provider": "^2.8.1",
Expand Down Expand Up @@ -62,7 +63,6 @@
"react-step-progress-bar": "^1.0.3",
"react-switch": "^7.0.0",
"react-tooltip": "^4.4.2",
"react-web3-settings": "^1.1.0",
"reactstrap": "^9.1.6",
"redux": "^4.2.1",
"redux-thunk": "^2.4.2",
Expand All @@ -74,6 +74,7 @@
"web3modal": "^1.9.9"
},
"devDependencies": {
"@babel/plugin-proposal-private-property-in-object": "^7.21.11",
"@commitlint/config-conventional": "^17.6.3",
"@testing-library/jest-dom": "^5.16.5",
"@testing-library/react": "^14.0.0",
Expand Down
2 changes: 1 addition & 1 deletion src/components/molecules/version/Version.jsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Web3SettingsButton } from '@p.network/react-web3-settings'
import React from 'react'
import { Web3SettingsButton } from 'react-web3-settings'
import styled from 'styled-components'

const VersionDiv = styled.div`
Expand Down
11 changes: 6 additions & 5 deletions src/components/organisms/header/Header.jsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
import React, { useState, useCallback } from 'react'
import { Web3SettingsButton } from '@p.network/react-web3-settings'
import PropTypes from 'prop-types'
import styled from 'styled-components'
import React, { useState, useCallback } from 'react'
import { Navbar, Nav, NavDropdown, Container, Row, Col } from 'react-bootstrap'
import Walletinfo from '../walletInfoModal/WalletInfoModal'
import styled from 'styled-components'

import { useWallets } from '../../../hooks/use-wallets'
import Icon from '../../atoms/icon/Icon'
import settings from '../../../settings'
import { Web3SettingsButton } from 'react-web3-settings'
import Icon from '../../atoms/icon/Icon'
import Walletinfo from '../walletInfoModal/WalletInfoModal'

const HeaderWrapper = styled.div`
border-bottom: 1px solid rgba(0, 0, 0, 0.1);
Expand Down
2 changes: 1 addition & 1 deletion src/components/organisms/settings/Settings.jsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Web3SettingsProvider } from '@p.network/react-web3-settings'
import React, { useContext } from 'react'
import { Web3SettingsProvider } from 'react-web3-settings'
import { ThemeContext } from 'styled-components'

import settings from '../../../settings'
Expand Down
16 changes: 16 additions & 0 deletions src/components/pages/swap/Swap.jsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import BigNumber from 'bignumber.js'
import _ from 'lodash'
import PropTypes from 'prop-types'
import React, { useCallback, useEffect, useState } from 'react'
import { Row, Col, Container } from 'react-bootstrap'
Expand Down Expand Up @@ -462,6 +463,21 @@ const Swap = ({
)}
</InfoEta>
) : null}
{to && to.swapperAddress && _.isNil(poolAmount) ? (
<WarningEta>
It is currently not possible to check the liquidity pool availability. It is possible the configured
Algorand endpoint is offline, please try with a different one. If the amount exceeds the pool
availability you will likely receive p{to.symbol} rather than native {to.nativeSymbol}. Proceed at
your own risk.
</WarningEta>
) : null}
{from && from.swapperAddress && _.isNil(poolAmount) ? (
<WarningEta>
It is currently not possible to check the liquidity pool availability. It is possible the configured
Algorand endpoint is offline, please try with a different one. If the amount exceeds the pool
availability, the transaction will likely fail.
</WarningEta>
) : null}
{to && to.swapperAddress && poolAmount < 1.2 * toAmount ? (
<WarningEta>
Due to insufficient liquidity it may not be possible to process a swap of this size. Please try with a
Expand Down
79 changes: 77 additions & 2 deletions src/components/pages/swap/__test__/Swap.test.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,18 @@ import { ThemeContext } from 'styled-components'
import { describe, expect, it, vi } from 'vitest'

import { PBTC_ON_ETH_MAINNET, PNT_ON_BSC_MAINNET, PNT_ON_ETH_MAINNET } from '../../../../constants'
import * as UseSwapInfo from '../../../../hooks/use-swap-info'
import swapAssets from '../../../../settings/swap-assets'
import { getDefaultSelection } from '../../../../store/swap/utils/default-selection'
import * as feeUtils from '../../../../utils/fee'
import * as AssetListModal from '../../../organisms/assetListModal/AssetListModal'
import * as SwapInfo from '../../../organisms/swapInfo/SwapInfo'
import Swap from '../Swap'

const Wrapper = ({ asset, originBlockchain, destBlockchain }) => {
const Wrapper = ({ asset, originBlockchain, destBlockchain, algorand_from_assetid, algorand_to_assetid }) => {
const ThemeContextMock = {}
const [button, setButton] = useState({})
const [wallets] = useState({ eth: {}, bsc: {} })
const [wallets] = useState({ eth: {}, bsc: {}, algorand: {} })
const updateSwapButton = useCallback((_text, _disabled = false) => {
setButton({ text: _text, disabled: _disabled })
}, [])
Expand All @@ -26,6 +27,8 @@ const Wrapper = ({ asset, originBlockchain, destBlockchain }) => {
v2selection.asset = asset
v2selection.from = originBlockchain
v2selection.to = destBlockchain
v2selection.algorand_from_assetid = algorand_from_assetid
v2selection.algorand_to_assetid = algorand_to_assetid
}
const [assets] = useState([...swapAssets, ...getDefaultSelection(swapAssets, v2selection)])
return (
Expand Down Expand Up @@ -81,6 +84,78 @@ describe('Swap', async () => {
expect(swapButton).toBeDisabled()
})

it('Should continue and warn USDT swap from Algorand if pool is not reachable', async () => {
vi.spyOn(UseSwapInfo, 'useSwapInfo').mockReturnValue({ eta: '1', poolAmount: undefined })
vi.spyOn(SwapInfo, 'default').mockImplementation(() => <div data-testid="swap-info" />)
vi.spyOn(feeUtils, 'getSwapFees').mockResolvedValue({ basisPoints: 15, networkFee: 1e18, minProtocolFee: 2e18 })
render(<Wrapper asset="usdt" originBlockchain="algorand" destBlockchain="eth" algorand_from_assetid={'312769'} />)
await waitFor(() => expect(screen.getByText(/Enter an amount/)).toBeInTheDocument())
const [swapButton] = screen.getAllByRole('button')
const [fromInput, toInput] = screen.getAllByRole('textbox')
await UserEvent.type(fromInput, '10')
expect(fromInput).toHaveAttribute('value', '10')
expect(toInput).toHaveAttribute('value', '7')
expect(swapButton).toHaveTextContent('Connect Wallet')
expect(screen.getByText(/the transaction will likely fail/)).toBeInTheDocument()
expect(swapButton).toBeEnabled()
})

test.each(['0', '1000'])(
'Should prevent and warn USDT swap from Algorand if pool liquidity is insufficient',
async (poolAmount) => {
vi.spyOn(UseSwapInfo, 'useSwapInfo').mockReturnValue({ eta: '1', poolAmount: poolAmount })
vi.spyOn(SwapInfo, 'default').mockImplementation(() => <div data-testid="swap-info" />)
vi.spyOn(feeUtils, 'getSwapFees').mockResolvedValue({ basisPoints: 15, networkFee: 1e18, minProtocolFee: 2e18 })
render(<Wrapper asset="usdt" originBlockchain="algorand" destBlockchain="eth" algorand_from_assetid={'312769'} />)
await waitFor(() => expect(screen.getByText(/Enter an amount/)).toBeInTheDocument())
const [swapButton] = screen.getAllByRole('button')
const [fromInput, toInput] = screen.getAllByRole('textbox')
await UserEvent.type(fromInput, '10000')
expect(fromInput).toHaveAttribute('value', '10,000')
expect(toInput).toHaveAttribute('value', '9,984')
expect(swapButton).toHaveTextContent('Insufficient liquidity')
expect(screen.getByText(/There is not enough liquidity in the stableswap/)).toBeInTheDocument()
expect(swapButton).toBeDisabled()
}
)

it('Should continue and warn USDT swap to Algorand if pool is not reachable', async () => {
vi.spyOn(UseSwapInfo, 'useSwapInfo').mockReturnValue({ eta: '1', poolAmount: undefined })
vi.spyOn(SwapInfo, 'default').mockImplementation(() => <div data-testid="swap-info" />)
vi.spyOn(feeUtils, 'getSwapFees').mockResolvedValue({ basisPoints: 15, networkFee: 1e18, minProtocolFee: 2e18 })
render(<Wrapper asset="usdt" originBlockchain="eth" destBlockchain="algorand" algorand_to_assetid={'312769'} />)
await waitFor(() => expect(screen.getByText(/Enter an amount/)).toBeInTheDocument())
const [swapButton] = screen.getAllByRole('button')
const [fromInput, toInput] = screen.getAllByRole('textbox')
await UserEvent.type(fromInput, '100')
expect(fromInput).toHaveAttribute('value', '100')
expect(toInput).toHaveAttribute('value', '97')
expect(swapButton).toHaveTextContent('Connect Wallet')
expect(screen.getByText(/you will likely receive pUSDT rather than native USDT/)).toBeInTheDocument()
expect(swapButton).toBeEnabled()
})

test.each(['0', '1000'])(
'Should continue and warn USDT swap to Algorand if pool liquidity is insufficient',
async (poolAmount) => {
vi.spyOn(UseSwapInfo, 'useSwapInfo').mockReturnValue({ eta: '1', poolAmount: poolAmount })
vi.spyOn(SwapInfo, 'default').mockImplementation(() => <div data-testid="swap-info" />)
vi.spyOn(feeUtils, 'getSwapFees').mockResolvedValue({ basisPoints: 15, networkFee: 1e18, minProtocolFee: 2e18 })
render(<Wrapper asset="usdt" originBlockchain="eth" destBlockchain="algorand" algorand_to_assetid={'312769'} />)
await waitFor(() => expect(screen.getByText(/Enter an amount/)).toBeInTheDocument())
const [swapButton] = screen.getAllByRole('button')
const [fromInput, toInput] = screen.getAllByRole('textbox')
await UserEvent.type(fromInput, '10000')
expect(fromInput).toHaveAttribute('value', '10,000')
expect(toInput).toHaveAttribute('value', '9,984')
expect(swapButton).toHaveTextContent('Connect Wallet')
expect(
screen.getByText(/Due to insufficient liquidity it may not be possible to process a swap of this size/)
).toBeInTheDocument()
expect(swapButton).toBeEnabled()
}
)

it('Should continue with balance null', async () => {
vi.spyOn(SwapInfo, 'default').mockImplementation(() => <div data-testid="swap-info" />)
vi.spyOn(feeUtils, 'getSwapFees').mockResolvedValue({ basisPoints: 15, networkFee: 1e18, minProtocolFee: 2e18 })
Expand Down
2 changes: 1 addition & 1 deletion src/store/swap/__tests__/swap.actions.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import * as pegout from '../utils/pegout'
describe('swap', () => {
beforeAll(() => {
vi.mock('@p.network/ptokens-node')
vi.mock('react-web3-settings')
vi.mock('@p.network/react-web3-settings')
})

beforeEach(() => {
Expand Down
2 changes: 1 addition & 1 deletion src/store/wallets/arbitrum/index.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { getWeb3Settings } from 'react-web3-settings'
import { getWeb3Settings } from '@p.network/react-web3-settings'
import WalletLink from 'walletlink'
import Web3 from 'web3'
import Web3Modal from 'web3modal'
Expand Down
2 changes: 1 addition & 1 deletion src/store/wallets/bsc/index.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { getWeb3Settings } from 'react-web3-settings'
import { getWeb3Settings } from '@p.network/react-web3-settings'
import WalletLink from 'walletlink'
import Web3 from 'web3'
import Web3Modal from 'web3modal'
Expand Down
2 changes: 1 addition & 1 deletion src/store/wallets/eos/index.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { getWeb3Settings } from 'react-web3-settings'
import { getWeb3Settings } from '@p.network/react-web3-settings'

import { WALLET_EOS_CONNECTED, WALLET_EOS_DISCONNECTED } from '../../../constants'
import EosConnect from '../../../lib/eosConnect/'
Expand Down
2 changes: 1 addition & 1 deletion src/store/wallets/eth/index.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { getWeb3Settings } from 'react-web3-settings'
import { getWeb3Settings } from '@p.network/react-web3-settings'
import WalletLink from 'walletlink'
import Web3 from 'web3'
import Web3Modal from 'web3modal'
Expand Down
2 changes: 1 addition & 1 deletion src/store/wallets/ftm/index.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { getWeb3Settings } from 'react-web3-settings'
import { getWeb3Settings } from '@p.network/react-web3-settings'
import WalletLink from 'walletlink'
import Web3 from 'web3'
import Web3Modal from 'web3modal'
Expand Down
2 changes: 1 addition & 1 deletion src/store/wallets/gnosis/index.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { getWeb3Settings } from 'react-web3-settings'
import { getWeb3Settings } from '@p.network/react-web3-settings'
import WalletLink from 'walletlink'
import Web3 from 'web3'
import Web3Modal from 'web3modal'
Expand Down
2 changes: 1 addition & 1 deletion src/store/wallets/libre/index.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { getWeb3Settings } from '@p.network/react-web3-settings'
import { toastr } from 'react-redux-toastr'
import { getWeb3Settings } from 'react-web3-settings'

import { WALLET_LIBRE_CONNECTED, WALLET_LIBRE_DISCONNECTED } from '../../../constants'
import EosConnect from '../../../lib/eosConnect/'
Expand Down
2 changes: 1 addition & 1 deletion src/store/wallets/luxochain/index.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { getWeb3Settings } from 'react-web3-settings'
import { getWeb3Settings } from '@p.network/react-web3-settings'
import WalletLink from 'walletlink'
import Web3 from 'web3'
import Web3Modal from 'web3modal'
Expand Down
2 changes: 1 addition & 1 deletion src/store/wallets/polygon/index.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { getWeb3Settings } from 'react-web3-settings'
import { getWeb3Settings } from '@p.network/react-web3-settings'
import WalletLink from 'walletlink'
import Web3 from 'web3'
import Web3Modal from 'web3modal'
Expand Down
2 changes: 1 addition & 1 deletion src/store/wallets/telos/index.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { getWeb3Settings } from '@p.network/react-web3-settings'
import { toastr } from 'react-redux-toastr'
import { getWeb3Settings } from 'react-web3-settings'

import { WALLET_TELOS_CONNECTED, WALLET_TELOS_DISCONNECTED } from '../../../constants'
import EosConnect from '../../../lib/eosConnect/'
Expand Down
2 changes: 1 addition & 1 deletion src/store/wallets/ultra/index.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { getWeb3Settings } from '@p.network/react-web3-settings'
import { toastr } from 'react-redux-toastr'
import { getWeb3Settings } from 'react-web3-settings'

import { WALLET_ULTRA_CONNECTED, WALLET_ULTRA_DISCONNECTED } from '../../../constants'
import EosConnect from '../../../lib/eosConnect/'
Expand Down
2 changes: 1 addition & 1 deletion src/utils/__tests__/ptokens.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ describe('createEthPntAsset', () => {

const expectedFees = {
networkFee: 0,
networkFeeUsd: 15,
networkFeeUsd: 20,
minNodeOperatorFee: 0,
minNodeOperatorFeeUsd: 0,
basisPoints: {
Expand Down
2 changes: 1 addition & 1 deletion src/utils/read-only-providers.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { getWeb3Settings } from '@p.network/react-web3-settings'
import { Algodv2 } from 'algosdk'
import fetch from 'cross-fetch'
import { JsonRpc } from 'eosjs'
import { getWeb3Settings } from 'react-web3-settings'
import Web3 from 'web3'

import settings from '../settings'
Expand Down
Loading