Skip to content

Commit

Permalink
Merge pull request #19 from uniswapfoundation/feat/swap-and-add-liqui…
Browse files Browse the repository at this point in the history
…dity

Update swap-and-add-liquidity example to match new sdk version
  • Loading branch information
Florian-S-A-W authored Dec 15, 2023
2 parents d51ceb5 + ae87785 commit c123fc9
Show file tree
Hide file tree
Showing 9 changed files with 10,472 additions and 240 deletions.
6 changes: 3 additions & 3 deletions v3-sdk/swap-and-add-liquidity/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@
"@types/node": "^16.7.13",
"@types/react": "^18.0.0",
"@types/react-dom": "^18.0.0",
"@uniswap/sdk-core": "^3.1.0",
"@uniswap/smart-order-router": "^3.3.0",
"@uniswap/v3-sdk": "^3.9.0",
"@uniswap/sdk-core": "npm:@koraykoska/uniswap-sdk-core@^6.0.9",
"@uniswap/v3-sdk": "npm:@florian-s-a-w/[email protected]",
"@uniswap/smart-order-router": "npm:@florian-s-a-w/uniswap-smart-order-router@^3.18.8",
"ethers": "^5.7.2",
"react": "^18.2.0",
"react-dom": "^18.2.0",
Expand Down
56 changes: 27 additions & 29 deletions v3-sdk/swap-and-add-liquidity/src/example/Example.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,8 @@ import './Example.css'
import { Environment, CurrentConfig } from '../config'
import { getCurrencyBalance } from '../libs/wallet'
import {
getPositionIds,
getPositionInfo,
getPositions,
mintPosition,
PositionInfo,
swapAndAddLiquidity,
} from '../libs/liquidity'
import {
Expand All @@ -15,6 +13,7 @@ import {
TransactionState,
getWalletAddress,
} from '../libs/providers'
import { Position } from '@uniswap/v3-sdk'

const useOnBlockUpdated = (callback: (blockNumber: number) => void) => {
useEffect(() => {
Expand All @@ -28,8 +27,7 @@ const useOnBlockUpdated = (callback: (blockNumber: number) => void) => {
const Example = () => {
const [token0Balance, setToken0Balance] = useState<string>()
const [token1Balance, setToken1Balance] = useState<string>()
const [positionIds, setPositionIds] = useState<number[]>([])
const [positionsInfo, setPositionsInfo] = useState<PositionInfo[]>([])
const [positions, setPositions] = useState<Position[]>([])
const [txState, setTxState] = useState<TransactionState>(TransactionState.New)
const [blockNumber, setBlockNumber] = useState<number>(0)

Expand All @@ -55,10 +53,8 @@ const Example = () => {
await getCurrencyBalance(provider, address, CurrentConfig.tokens.token1)
)

// Set Position Info
const ids = await getPositionIds()
setPositionIds(ids)
setPositionsInfo(await Promise.all(ids.map(getPositionInfo)))
// Set Positions
setPositions(await getPositions())
}, [])

// Event Handlers
Expand All @@ -74,26 +70,28 @@ const Example = () => {
setTxState(await mintPosition())
}, [])

const onSwapAndAddLiquidity = useCallback(async (position: number) => {
setTxState(TransactionState.Sending)
setTxState(await swapAndAddLiquidity(position))
}, [])
const onSwapAndAddLiquidity = useCallback(
async (positionId: bigint | undefined) => {
if (positionId === undefined) {
throw new Error('Positions not fetched correctly!')
}
setTxState(TransactionState.Sending)
setTxState(await swapAndAddLiquidity(positionId))
},
[]
)

// Formatted Data

const positionInfoStrings: string[] = useMemo(() => {
if (positionIds.length !== positionsInfo.length) {
return []
}

return positionIds
.map((id, index) => [id, positionsInfo[index]])
.map((info) => {
const id = info[0]
const posInfo = info[1] as PositionInfo
return `${id}: ${posInfo.liquidity.toString()} liquidity, owed ${posInfo.tokensOwed0.toString()} and ${posInfo.tokensOwed1.toString()}`
})
}, [positionIds, positionsInfo])
const positionStrings: string[] = useMemo(() => {
return positions.map((pos) => {
return `${
pos.positionId ? pos.positionId : 'No id'
}: ${pos.liquidity.toString()} liquidity, owed ${
pos.tokensOwed0 ? pos.tokensOwed0.toString() : '0'
} and ${pos.tokensOwed1 ? pos.tokensOwed1.toString() : '0'}`
})
}, [positions])

return (
<div className="App">
Expand All @@ -117,7 +115,7 @@ const Example = () => {
<h3>{`${CurrentConfig.tokens.token1.symbol} Balance: ${token1Balance}`}</h3>
<div>
Positions:{' '}
{positionInfoStrings.map((s, i) => (
{positionStrings.map((s, i) => (
<p key={i}>{s}</p>
))}
</div>
Expand All @@ -137,13 +135,13 @@ const Example = () => {
if (!token0Balance || !token1Balance) {
return
}
onSwapAndAddLiquidity(positionIds[positionIds.length - 1])
onSwapAndAddLiquidity(positions[positions.length - 1].positionId)
}}
disabled={
txState === TransactionState.Sending ||
getProvider() === null ||
CurrentConfig.rpc.mainnet === '' ||
positionIds.length === 0
positions.length === 0
}>
<p>Swap and Add Liquidity</p>
</button>
Expand Down
21 changes: 4 additions & 17 deletions v3-sdk/swap-and-add-liquidity/src/libs/constants.ts
Original file line number Diff line number Diff line change
@@ -1,28 +1,24 @@
// This file stores web3 related constants such as addresses, token definitions, ETH currency references and ABI's

import { SupportedChainId, Token } from '@uniswap/sdk-core'
import { ChainId, Token } from '@uniswap/sdk-core'

// Addresses

export const POOL_FACTORY_CONTRACT_ADDRESS =
'0x1F98431c8aD98523631AE4a59f267346ea31F984'
export const NONFUNGIBLE_POSITION_MANAGER_CONTRACT_ADDRESS =
'0xC36442b4a4522E871399CD717aBDD847Ab11FE88'
export const V3_SWAP_ROUTER_ADDRESS =
'0x68b3465833fb72A70ecDF485E0e4C7bD8665Fc45'

// Currencies and Tokens

export const USDC_TOKEN = new Token(
SupportedChainId.MAINNET,
ChainId.MAINNET,
'0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48',
6,
'USDC',
'USD//C'
)

export const DAI_TOKEN = new Token(
SupportedChainId.MAINNET,
ChainId.MAINNET,
'0x6B175474E89094C44Da98b954EedeAC495271d0F',
18,
'DAI',
Expand All @@ -33,7 +29,7 @@ export const DAI_TOKEN = new Token(

export const MAX_FEE_PER_GAS = '100000000000'
export const MAX_PRIORITY_FEE_PER_GAS = '100000000000'
export const TOKEN_AMOUNT_TO_APPROVE_FOR_TRANSFER = 1000000000000
export const TOKEN_AMOUNT_TO_APPROVE_FOR_TRANSFER = 1000000000000n

// ABI's

Expand All @@ -50,12 +46,3 @@ export const ERC20_ABI = [
// Events
'event Transfer(address indexed from, address indexed to, uint amount)',
]

export const NONFUNGIBLE_POSITION_MANAGER_ABI = [
// Read-Only Functions
'function balanceOf(address _owner) view returns (uint256)',
'function tokenOfOwnerByIndex(address _owner, uint256 _index) view returns (uint256)',
'function tokenURI(uint256 tokenId) view returns (string memory)',

'function positions(uint256 tokenId) external view returns (uint96 nonce, address operator, address token0, address token1, uint24 fee, int24 tickLower, int24 tickUpper, uint128 liquidity, uint256 feeGrowthInside0LastX128, uint256 feeGrowthInside1LastX128, uint128 tokensOwed0, uint128 tokensOwed1)',
]
17 changes: 4 additions & 13 deletions v3-sdk/swap-and-add-liquidity/src/libs/conversion.ts
Original file line number Diff line number Diff line change
@@ -1,22 +1,13 @@
import JSBI from 'jsbi'

export function fromReadableAmount(amount: number, decimals: number): JSBI {
export function fromReadableAmount(amount: number, decimals: number): bigint {
const extraDigits = Math.pow(10, countDecimals(amount))
const adjustedAmount = amount * extraDigits
return JSBI.divide(
JSBI.multiply(
JSBI.BigInt(adjustedAmount),
JSBI.exponentiate(JSBI.BigInt(10), JSBI.BigInt(decimals))
),
JSBI.BigInt(extraDigits)
return (
(BigInt(adjustedAmount) * 10n ** BigInt(decimals)) / BigInt(extraDigits)
)
}

export function toReadableAmount(rawAmount: number, decimals: number): string {
return JSBI.divide(
JSBI.BigInt(rawAmount),
JSBI.exponentiate(JSBI.BigInt(10), JSBI.BigInt(decimals))
).toString()
return (rawAmount / 10 ** decimals).toString()
}

function countDecimals(x: number) {
Expand Down
Loading

0 comments on commit c123fc9

Please sign in to comment.