-
Notifications
You must be signed in to change notification settings - Fork 23
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #387 from balancer/fix-proportional-amounts-cow-amm
Fix add liquidity proportional query for cow-amm
- Loading branch information
Showing
6 changed files
with
264 additions
and
7 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
--- | ||
"@balancer/sdk": patch | ||
--- | ||
|
||
Fix add liquidity proportional query for cow-amm |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,141 @@ | ||
/** | ||
* Example showing how to add liquidity to a pool. | ||
* (Runs against a local Anvil fork) | ||
* | ||
* Run with: | ||
* pnpm example ./examples/addLiquidity/addLiquidityCowAmm.ts | ||
*/ | ||
import { Address } from 'viem'; | ||
import { | ||
AddLiquidityInput, | ||
AddLiquidityKind, | ||
AddLiquidity, | ||
BalancerApi, | ||
calculateProportionalAmountsCowAmm, | ||
ChainId, | ||
getPoolStateWithBalancesCowAmm, | ||
Slippage, | ||
} from '../../src'; | ||
import { ANVIL_NETWORKS, startFork } from '../../test/anvil/anvil-global-setup'; | ||
import { makeForkTx } from '../lib/makeForkTx'; | ||
import { getSlot } from 'examples/lib/getSlot'; | ||
|
||
async function runAgainstFork() { | ||
// User defined inputs | ||
const { rpcUrl } = await startFork( | ||
ANVIL_NETWORKS.MAINNET, | ||
undefined, | ||
20520774n, | ||
); | ||
const chainId = ChainId.MAINNET; | ||
const userAccount = '0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045'; | ||
// USDC-WETH CowAmm pool | ||
const pool = { | ||
id: '0xf08d4dea369c456d26a3168ff0024b904f2d8b91', | ||
address: '0xf08d4dea369c456d26a3168ff0024b904f2d8b91' as Address, | ||
}; | ||
|
||
const referenceAmountIn = { | ||
rawAmount: 158708n, | ||
decimals: 6, | ||
address: '0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48' as Address, // USDC | ||
}; | ||
|
||
const slippage = Slippage.fromPercentage('0'); // 1% | ||
|
||
const call = await addLiquidityProportional({ | ||
rpcUrl, | ||
chainId, | ||
referenceAmountIn, | ||
poolId: pool.id, | ||
slippage, | ||
}); | ||
|
||
// Make the tx against the local fork and print the result | ||
await makeForkTx( | ||
call, | ||
{ | ||
rpcUrl, | ||
chainId, | ||
impersonateAccount: userAccount, | ||
forkTokens: call.maxAmountsIn.map((a) => ({ | ||
address: a.token.address, | ||
slot: getSlot(chainId, a.token.address), | ||
rawBalance: a.amount, | ||
})), | ||
}, | ||
[...call.maxAmountsIn.map((a) => a.token.address), pool.address], | ||
call.protocolVersion, | ||
); | ||
} | ||
|
||
const addLiquidityProportional = async ({ | ||
rpcUrl, | ||
chainId, | ||
poolId, | ||
referenceAmountIn, | ||
slippage, | ||
}) => { | ||
// API + on-chain calls are used to fetch relevant pool data | ||
const balancerApi = new BalancerApi('https://api-v3.balancer.fi/', chainId); | ||
const poolState = await balancerApi.pools.fetchPoolState(poolId); | ||
const poolStateWithBalances = await getPoolStateWithBalancesCowAmm( | ||
poolState, | ||
chainId, | ||
rpcUrl, | ||
); | ||
console.log('Pool State with Balances:'); | ||
console.log(poolStateWithBalances); | ||
|
||
const { tokenAmounts, bptAmount } = calculateProportionalAmountsCowAmm( | ||
poolStateWithBalances, | ||
referenceAmountIn, | ||
); | ||
|
||
console.log('Token Amounts:'); | ||
tokenAmounts.map((a) => console.log(a.address, a.rawAmount.toString())); | ||
|
||
// Construct the AddLiquidityInput, in this case an AddLiquidityUnbalanced | ||
const addLiquidityInput: AddLiquidityInput = { | ||
bptOut: bptAmount, | ||
chainId, | ||
rpcUrl, | ||
kind: AddLiquidityKind.Proportional, | ||
}; | ||
|
||
// Simulate addLiquidity to get the amount of BPT out | ||
const addLiquidity = new AddLiquidity(); | ||
const queryOutput = await addLiquidity.query( | ||
addLiquidityInput, | ||
poolStateWithBalances, | ||
); | ||
|
||
console.log('\nAdd Liquidity Query Output:'); | ||
console.log('Tokens In:'); | ||
queryOutput.amountsIn.map((a) => | ||
console.log(a.token.address, a.amount.toString()), | ||
); | ||
console.log(`BPT Out: ${queryOutput.bptOut.amount.toString()}`); | ||
|
||
// Apply slippage to the BPT amount received from the query and construct the call | ||
const call = addLiquidity.buildCall({ | ||
...queryOutput, | ||
slippage, | ||
chainId, | ||
wethIsEth: false, | ||
}); | ||
|
||
console.log('\nWith slippage applied:'); | ||
console.log('Max tokens in:'); | ||
call.maxAmountsIn.forEach((a) => | ||
console.log(a.token.address, a.amount.toString()), | ||
); | ||
console.log(`Min BPT Out: ${call.minBptOut.amount.toString()}`); | ||
|
||
return { | ||
...call, | ||
protocolVersion: queryOutput.protocolVersion, | ||
}; | ||
}; | ||
|
||
export default runAgainstFork; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters