|
4 | 4 | * Run command:
|
5 | 5 | * yarn example ./examples/pools/exit/recovery-exit.ts
|
6 | 6 | */
|
| 7 | +import { FORK_NODES } from '@/test/lib/utils'; |
7 | 8 | import {
|
8 | 9 | BalancerSDK,
|
9 |
| - insert, |
| 10 | + removeItem, |
10 | 11 | Network,
|
11 | 12 | truncateAddresses,
|
12 | 13 | } from '@balancer-labs/sdk';
|
13 | 14 | import { parseEther } from '@ethersproject/units';
|
14 | 15 | import { getTokenBalance, reset, setTokenBalance } from 'examples/helpers';
|
15 | 16 |
|
16 |
| -async function recoveryExit() { |
| 17 | +async function recoveryExitLive() { |
| 18 | + const network = Network.MAINNET; |
| 19 | + const rpcUrl = FORK_NODES[network]; |
| 20 | + const poolId = |
| 21 | + '0x20b156776114e8a801e9767d90c6ccccc8adf398000000000000000000000499'; |
| 22 | + const userAddress = '0x0000000000000000000000000000000000000000'; |
| 23 | + const bptAmount = String(parseEther('1')); |
| 24 | + const slippage = '1'; // 1 bps = 0.1% |
| 25 | + |
| 26 | + const balancer = new BalancerSDK({ |
| 27 | + network, |
| 28 | + rpcUrl, |
| 29 | + }); |
| 30 | + const { poolsOnChain, pools } = balancer.data; |
| 31 | + |
| 32 | + // Use SDK to find pool info |
| 33 | + let pool = await pools.find(poolId); |
| 34 | + if (!pool) throw 'POOL_DOESNT_EXIST'; |
| 35 | + |
| 36 | + // Refresh pool data from chain before building and sending tx |
| 37 | + pool = await poolsOnChain.refresh(pool); |
| 38 | + |
| 39 | + // Build transaction |
| 40 | + const { expectedAmountsOut, minAmountsOut } = |
| 41 | + balancer.pools.buildRecoveryExit({ |
| 42 | + pool, |
| 43 | + bptAmount, |
| 44 | + userAddress, |
| 45 | + slippage, |
| 46 | + }); |
| 47 | + |
| 48 | + console.log(expectedAmountsOut.toString()); |
| 49 | + console.log(minAmountsOut.toString()); |
| 50 | +} |
| 51 | + |
| 52 | +async function recoveryExitFork() { |
| 53 | + const poolId = |
| 54 | + '0x20b156776114e8a801e9767d90c6ccccc8adf398000000000000000000000499'; |
| 55 | + const blockNo = 17700000; |
| 56 | + |
17 | 57 | const balancer = new BalancerSDK({
|
18 | 58 | network: Network.MAINNET,
|
19 | 59 | rpcUrl: 'http://127.0.0.1:8545', // Using local fork for simulation
|
20 | 60 | });
|
| 61 | + const { poolsOnChain, pools } = balancer.data; |
21 | 62 |
|
22 | 63 | // Setup exit parameters
|
23 | 64 | const signer = balancer.provider.getSigner();
|
24 |
| - const address = await signer.getAddress(); |
25 |
| - |
26 |
| - const poolId = |
27 |
| - // '0x50cf90b954958480b8df7958a9e965752f62712400000000000000000000046f'; // bb-e-usd |
28 |
| - // '0xd4e7c1f3da1144c9e2cfd1b015eda7652b4a439900000000000000000000046a'; // bb-e-usdc |
29 |
| - // '0xa13a9247ea42d743238089903570127dda72fe4400000000000000000000035d'; // bb-a-usd |
30 |
| - '0xa718042e5622099e5f0ace4e7122058ab39e1bbe000200000000000000000475'; // 50temple_50bb-e-usd |
| 65 | + const userAddress = await signer.getAddress(); |
31 | 66 |
|
32 |
| - const bptIn = String(parseEther('1')); |
| 67 | + const bptAmount = String(parseEther('1')); |
33 | 68 | const slippage = '200'; // 200 bps = 2%
|
34 | 69 |
|
35 | 70 | // Use SDK to find pool info
|
36 |
| - const pool = await balancer.pools.find(poolId); |
| 71 | + let pool = await pools.find(poolId); |
37 | 72 | if (!pool) throw 'POOL_DOESNT_EXIST';
|
38 | 73 |
|
39 | 74 | // Prepare local fork for simulation
|
40 |
| - await reset(balancer.provider, 17700000); |
41 |
| - await setTokenBalance(balancer.provider, address, pool.address, bptIn, 0); |
| 75 | + await reset(balancer.provider, blockNo); |
| 76 | + await setTokenBalance( |
| 77 | + balancer.provider, |
| 78 | + userAddress, |
| 79 | + pool.address, |
| 80 | + bptAmount, |
| 81 | + 0 |
| 82 | + ); |
| 83 | + |
| 84 | + // Refresh pool data from chain before building and sending tx |
| 85 | + pool = await poolsOnChain.refresh(pool); |
42 | 86 |
|
43 | 87 | // Build transaction
|
44 | 88 | const { to, data, expectedAmountsOut, minAmountsOut } =
|
45 |
| - pool.buildRecoveryExit(address, bptIn, slippage); |
| 89 | + balancer.pools.buildRecoveryExit({ |
| 90 | + pool, |
| 91 | + bptAmount, |
| 92 | + userAddress, |
| 93 | + slippage, |
| 94 | + }); |
46 | 95 |
|
47 | 96 | // Send transaction
|
48 | 97 | await signer.sendTransaction({ to, data });
|
49 | 98 |
|
| 99 | + // Refresh pool data from chain before building and sending tx |
| 100 | + pool = await poolsOnChain.refresh(pool); |
| 101 | + |
| 102 | + const bptIndex = pool.tokensList.indexOf(pool.address); |
| 103 | + const tokensWithoutBpt = |
| 104 | + bptIndex === -1 ? pool.tokensList : removeItem(pool.tokensList, bptIndex); |
50 | 105 | // Check balances after transaction to confirm success
|
51 |
| - const balances = await Promise.all( |
52 |
| - pool.tokensList.map((token) => |
53 |
| - getTokenBalance(token, address, balancer.provider) |
54 |
| - ) |
55 |
| - ); |
| 106 | + const balances = await Promise.all([ |
| 107 | + ...tokensWithoutBpt.map((token) => |
| 108 | + getTokenBalance(token, userAddress, balancer.provider) |
| 109 | + ), |
| 110 | + getTokenBalance(pool.address, userAddress, balancer.provider), |
| 111 | + ]); |
56 | 112 |
|
57 | 113 | console.table({
|
58 |
| - tokensOut: truncateAddresses(pool.tokensList), |
59 |
| - minAmountsOut: insert(minAmountsOut, pool.bptIndex, bptIn), |
60 |
| - expectedAmountsOut: insert(expectedAmountsOut, pool.bptIndex, bptIn), |
61 |
| - amountsOut: balances.map((b) => b.toString()), |
| 114 | + tokensOut: truncateAddresses(tokensWithoutBpt), |
| 115 | + minAmountsOut: minAmountsOut, |
| 116 | + expectedAmountsOut: expectedAmountsOut, |
| 117 | + amountsOut: removeItem(balances, balances.length - 1).map((b) => |
| 118 | + b.toString() |
| 119 | + ), |
62 | 120 | });
|
| 121 | + console.log(`BPT Balance: `, balances[balances.length - 1].toString()); |
63 | 122 | }
|
64 | 123 |
|
65 |
| -recoveryExit(); |
| 124 | +// recoveryExitFork(); |
| 125 | +recoveryExitLive(); |
0 commit comments