-
Notifications
You must be signed in to change notification settings - Fork 14
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
Add Add/Remove Liquidity Nested #99
Merged
Merged
Changes from all commits
Commits
Show all changes
92 commits
Select commit
Hold shift + click to select a range
3161895
Initial draft with hardcoded values to focus on lower level methods (…
brunoguerios 4e046fd
Grant proper roles to relayer deployed locally
brunoguerios 74268bc
Fix relayer approval signature within multicall
brunoguerios aeaf966
First working version of nested-joins
brunoguerios d2081da
Merge remote-tracking branch 'origin/fix-circular-deps' into nested-join
brunoguerios f0edb4a
Minor refactors
brunoguerios 2902554
Remove unused comment
brunoguerios af4e5c2
Add ComposableStableEncoder
brunoguerios 4780328
Update BALANCER_RELAYER constant to be per chain
brunoguerios 034fa83
Move level from token to pool data
brunoguerios cfda997
Refactor nested pool data structure
brunoguerios 0a7aeaf
Add test case for all tokens join
brunoguerios 1aed248
Add native asset nested join
brunoguerios b64e29a
Refactor methods to improve code readability
brunoguerios 61ae94f
Fix address comparison
brunoguerios 584914b
Add changeset
brunoguerios 4e64197
Minor refactors
brunoguerios 3ab481d
Fix incorrect refactor
brunoguerios 685fa83
Add proportional nested exit
brunoguerios 331aa25
Extract getPeekCalls to external function
brunoguerios 4b402bb
Add single token nested exit
brunoguerios 1170151
Add test for single token nested exit to native asset (commented out)
brunoguerios f437da1
Merge pull request #107 from balancer/nested-exit
brunoguerios cb8a11b
Remove stable encoder
brunoguerios 4dda5a2
Remove outputRef workaround
brunoguerios a178ec8
Update swift-wasps-flash.md
brunoguerios af92b91
Remove unnecessary outputRefKey offset
brunoguerios f5dcf3c
Remove chainId from join/exit buildCall inputs
brunoguerios aa3f628
Rename join/exit calls to callsAttributes
brunoguerios 7c4d8c8
Refactor parseNestedJoinCall and parseNestedExitCalls to encodeCalls
brunoguerios 2a0af4d
Better describe logic to build amountsIn for nested join calls
brunoguerios 739ebb5
Expose isProportional boolean on nestedExit main function
brunoguerios aa68125
Remove non-temp flag from peek calls
brunoguerios 96b2dd4
Remove decimals from amountsIn input
brunoguerios 42ef791
Move specific logic into getProportionalExitCalls and getSingleTokenE…
brunoguerios a3198b7
Extract getExitPath to separate function
brunoguerios 3a19c81
Refactor tests to separate functionality from test setup
brunoguerios 51efe34
Remaining test refactors
brunoguerios 9f02490
Add comments explaining getPeekCall logic
brunoguerios a8fc342
Add input validation
brunoguerios 7b260de
Minor refactor
brunoguerios 1c9b7f3
Merge remote-tracking branch 'origin/join' into nested-join
brunoguerios 43ddadb
Update anvil global setup to enable skipping it
brunoguerios 392a858
Move hasApproved to a separate helper function
brunoguerios 322cf43
Minor refactor on assertResults
brunoguerios 98baead
Extract relayer helpers so they can be reused
brunoguerios ef38be8
Update chainId from number to ChainId
brunoguerios 97fd6f4
Add PoolKind enum
brunoguerios a6ee413
Simplified getQueryCallsAttributes input parameter
brunoguerios 3fc0eae
Refactor getBptAmountIn and getMaxAmountsIn logic
brunoguerios 1f23c28
Refactor outputReference logic
brunoguerios 998c3d0
Refactor input validation
brunoguerios 76073ae
Extract getUserData into separate functions
brunoguerios 2c10248
Update sender/recipient logic for nestedJoin
brunoguerios c306371
Update sender/recipient logic for nestedExit
brunoguerios efc84c1
Refactor getRecipients so the whole logic is in one single place
brunoguerios db96a69
Minor refactor
brunoguerios f04ce9c
Merge remote-tracking branch 'origin/join' into nested-join
brunoguerios 97d7817
Fix small typo on batchRelayerLibraryAbi
brunoguerios d628fb5
Add comment explaining getExitPath logic
brunoguerios c3fd6a7
feat: Add constraint validation with tests.
johngrantuk 1125808
chore: Add validation checks to nested joins/exits.
johngrantuk c5de0ff
fix: Get top level without assuming pool ordering.
johngrantuk 8788ff5
chore: Fix lock.
johngrantuk fc8c2c6
Merge pull request #113 from balancer/constraint-validations
johngrantuk bdd2204
Merge branch 'nested-join' of github.com:balancer/b-sdk into nested-join
brunoguerios 2823ccb
Add API integration for nested joins and exits
brunoguerios 78dba48
Add nestedJoin example
brunoguerios 54e6c84
Merge remote-tracking branch 'origin/join' into nested-join
brunoguerios 9afc5bb
Remove commented out workaround
brunoguerios fb8f4cf
Merge remote-tracking branch 'origin/main' into nested-join
brunoguerios b9b4953
Refactor nested join into add liquidity nested
brunoguerios 639b13f
Refactor nested exit into remove liquidity nested
brunoguerios ec774b2
Merge remote-tracking branch 'origin/main' into nested-join
brunoguerios 3497b56
Hardcode token slots to improve test performance
brunoguerios 39bcd43
Update blockNumber to avoid moving to an archived RPC url
brunoguerios ed0f7ab
Skip nested liquidity integration tests (until relayerV6 is working a…
brunoguerios 2bd8639
Merge remote-tracking branch 'origin/main' into nested-join
brunoguerios 310aa55
Update relayer address to v6
brunoguerios ef5769c
Make biome the default formatter
brunoguerios 29491e4
Fix lint issues
brunoguerios 14624d2
Allow custom blockNumber setup for PriceImpact tests
brunoguerios 3ea99bd
Fix blockNumber to match hardcoded comparison results
brunoguerios eced858
Reverted hardcoded comparison values
brunoguerios fd97739
Merge remote-tracking branch 'origin/main' into nested-join
brunoguerios 6e90721
chore: fix COMPOSABLE_STABLE api breaking change
agualis 042c1ac
Merge pull request #201 from balancer/nested-join-composable-stable
brunoguerios 6a4ce99
Fix add liquidity nested example
brunoguerios ac574bb
Expose nested liquidity types
agualis 2370310
Merge remote-tracking branch 'origin/main' into nested-join
brunoguerios ef5c88d
Update to work with viem v2
brunoguerios 47f952b
Improve pool type mapper safety by checking for unsupported types
brunoguerios File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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,7 @@ | ||
--- | ||
"@balancer/sdk": minor | ||
--- | ||
|
||
- Add AddLiquidityNested | ||
- Add RemoveLiquidityNestedProportional | ||
- Add RemoveLiquidityNestedSingleToken |
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 |
---|---|---|
@@ -1,10 +1,7 @@ | ||
{ | ||
"editor.defaultFormatter": "rome.rome", | ||
"editor.defaultFormatter": "biomejs.biome", | ||
"editor.formatOnSave": true, | ||
"[json]": { | ||
"editor.defaultFormatter": "rome.rome" | ||
}, | ||
"[typescript]": { | ||
"editor.defaultFormatter": "rome.rome" | ||
"editor.defaultFormatter": "biomejs.biome" | ||
} | ||
} |
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,174 @@ | ||
// pnpm example ./examples/addLiquidityNested.ts | ||
import { config } from 'dotenv'; | ||
config(); | ||
|
||
import { | ||
Address, | ||
BALANCER_RELAYER, | ||
BalancerApi, | ||
ChainId, | ||
CHAINS, | ||
AddLiquidityNested, | ||
NestedPoolState, | ||
replaceWrapped, | ||
Slippage, | ||
} from '../src'; | ||
import { | ||
Client, | ||
createTestClient, | ||
http, | ||
parseUnits, | ||
PublicActions, | ||
publicActions, | ||
TestActions, | ||
WalletActions, | ||
walletActions, | ||
} from 'viem'; | ||
import { AddLiquidityNestedInput } from '../src/entities/addLiquidityNested/types'; | ||
import { Relayer } from '../src/entities/relayer'; | ||
import { | ||
forkSetup, | ||
sendTransactionGetBalances, | ||
} from '../test/lib/utils/helper'; | ||
import { ANVIL_NETWORKS, startFork } from '../test/anvil/anvil-global-setup'; | ||
|
||
const balancerApiUrl = 'https://backend-v3-canary.beets-ftm-node.com/graphql'; | ||
const poolId = | ||
'0x08775ccb6674d6bdceb0797c364c2653ed84f3840002000000000000000004f0'; // WETH-3POOL | ||
const chainId = ChainId.MAINNET; | ||
|
||
const addLiquidityNested = async () => { | ||
// User approve vault to spend their tokens and update user balance | ||
const { client, accountAddress, nestedPoolState, rpcUrl } = | ||
await exampleSetup(); | ||
|
||
// setup add liquidity helper | ||
const addLiquidityNested = new AddLiquidityNested(); | ||
|
||
const amountsIn = [ | ||
{ | ||
address: '0x6b175474e89094c44da98b954eedeac495271d0f' as Address, // DAI | ||
rawAmount: parseUnits('1', 18), | ||
}, | ||
]; | ||
|
||
const useNativeAssetAsWrappedAmountIn = false; | ||
|
||
const addLiquidityInput: AddLiquidityNestedInput = { | ||
amountsIn, | ||
chainId, | ||
rpcUrl, | ||
accountAddress, | ||
useNativeAssetAsWrappedAmountIn, | ||
}; | ||
const queryOutput = await addLiquidityNested.query( | ||
addLiquidityInput, | ||
nestedPoolState, | ||
); | ||
|
||
// build add liquidity nested call with expected minBpOut based on slippage | ||
const slippage = Slippage.fromPercentage('1'); // 1% | ||
|
||
const signature = await Relayer.signRelayerApproval( | ||
BALANCER_RELAYER[chainId], | ||
accountAddress, | ||
client, | ||
); | ||
|
||
const { call, to, value } = addLiquidityNested.buildCall({ | ||
...queryOutput, | ||
slippage, | ||
sender: accountAddress, | ||
recipient: accountAddress, | ||
relayerApprovalSignature: signature, | ||
}); | ||
|
||
let tokensIn = queryOutput.amountsIn.map((a) => a.token); | ||
if (useNativeAssetAsWrappedAmountIn) { | ||
tokensIn = replaceWrapped(tokensIn, chainId); | ||
} | ||
|
||
const tokens = [ | ||
...tokensIn.map((t) => t.address), | ||
queryOutput.bptOut.token.address, | ||
]; | ||
|
||
// send add liquidity nested transaction and check balance changes | ||
const { transactionReceipt, balanceDeltas } = | ||
await sendTransactionGetBalances( | ||
tokens, | ||
client, | ||
accountAddress, | ||
to, | ||
call, | ||
value, | ||
); | ||
console.log(`transaction status: ${transactionReceipt.status}`); | ||
console.table({ | ||
tokens, | ||
balanceDeltas, | ||
}); | ||
}; | ||
|
||
const exampleSetup = async (): Promise<{ | ||
client: Client & PublicActions & TestActions & WalletActions; | ||
accountAddress: Address; | ||
nestedPoolState: NestedPoolState; | ||
rpcUrl: string; | ||
}> => { | ||
const { rpcUrl } = await startFork(ANVIL_NETWORKS.MAINNET); | ||
const balancerApi = new BalancerApi(balancerApiUrl, chainId); | ||
const nestedPoolState = | ||
await balancerApi.nestedPools.fetchNestedPoolState(poolId); | ||
|
||
const client: Client & PublicActions & TestActions & WalletActions = | ||
createTestClient({ | ||
mode: 'anvil', | ||
chain: CHAINS[chainId], | ||
transport: http(rpcUrl), | ||
}) | ||
.extend(publicActions) | ||
.extend(walletActions); | ||
|
||
const accountAddress = (await client.getAddresses())[0]; | ||
|
||
const mainTokens = [ | ||
{ | ||
address: '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2' as Address, | ||
balance: parseUnits('1000', 18), | ||
slot: 3, | ||
}, | ||
{ | ||
address: '0x6b175474e89094c44da98b954eedeac495271d0f' as Address, | ||
balance: parseUnits('1000', 18), | ||
slot: 2, | ||
}, | ||
{ | ||
address: '0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48' as Address, | ||
balance: parseUnits('1000', 6), | ||
slot: 9, | ||
}, | ||
{ | ||
address: '0xdac17f958d2ee523a2206206994597c13d831ec7' as Address, | ||
balance: parseUnits('1000', 6), | ||
slot: 2, | ||
}, | ||
]; | ||
|
||
await forkSetup( | ||
client, | ||
accountAddress, | ||
mainTokens.map((t) => t.address), | ||
mainTokens.map((t) => t.slot), | ||
mainTokens.map((t) => t.balance), | ||
); | ||
|
||
return { | ||
client, | ||
accountAddress, | ||
nestedPoolState, | ||
rpcUrl, | ||
}; | ||
}; | ||
|
||
export default addLiquidityNested; |
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
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,28 @@ | ||
export const authorizerAbi = [ | ||
{ | ||
inputs: [ | ||
{ internalType: 'bytes32', name: 'role', type: 'bytes32' }, | ||
{ internalType: 'address', name: 'account', type: 'address' }, | ||
], | ||
name: 'grantRole', | ||
outputs: [], | ||
stateMutability: 'payable', | ||
type: 'function', | ||
}, | ||
{ | ||
inputs: [ | ||
{ internalType: 'bytes32', name: 'role', type: 'bytes32' }, | ||
{ internalType: 'address', name: 'account', type: 'address' }, | ||
], | ||
name: 'hasRole', | ||
outputs: [ | ||
{ | ||
internalType: 'bool', | ||
name: '', | ||
type: 'bool', | ||
}, | ||
], | ||
stateMutability: 'view', | ||
type: 'function', | ||
}, | ||
] as const; |
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,86 @@ | ||
export const balancerRelayerAbi = [ | ||
{ | ||
inputs: [ | ||
{ | ||
internalType: 'contract IVault', | ||
name: 'vault', | ||
type: 'address', | ||
}, | ||
{ | ||
internalType: 'address', | ||
name: 'libraryAddress', | ||
type: 'address', | ||
}, | ||
], | ||
stateMutability: 'nonpayable', | ||
type: 'constructor', | ||
}, | ||
{ | ||
inputs: [], | ||
name: 'getLibrary', | ||
outputs: [ | ||
{ | ||
internalType: 'address', | ||
name: '', | ||
type: 'address', | ||
}, | ||
], | ||
stateMutability: 'view', | ||
type: 'function', | ||
}, | ||
{ | ||
inputs: [], | ||
name: 'getVault', | ||
outputs: [ | ||
{ | ||
internalType: 'contract IVault', | ||
name: '', | ||
type: 'address', | ||
}, | ||
], | ||
stateMutability: 'view', | ||
type: 'function', | ||
}, | ||
{ | ||
inputs: [ | ||
{ | ||
internalType: 'bytes[]', | ||
name: 'data', | ||
type: 'bytes[]', | ||
}, | ||
], | ||
name: 'multicall', | ||
outputs: [ | ||
{ | ||
internalType: 'bytes[]', | ||
name: 'results', | ||
type: 'bytes[]', | ||
}, | ||
], | ||
stateMutability: 'payable', | ||
type: 'function', | ||
}, | ||
{ | ||
inputs: [ | ||
{ | ||
internalType: 'bytes[]', | ||
name: 'data', | ||
type: 'bytes[]', | ||
}, | ||
], | ||
name: 'vaultActionsQueryMulticall', | ||
outputs: [ | ||
{ | ||
internalType: 'bytes[]', | ||
name: 'results', | ||
type: 'bytes[]', | ||
}, | ||
], | ||
stateMutability: 'nonpayable', | ||
type: 'function', | ||
}, | ||
{ | ||
stateMutability: 'payable', | ||
type: 'receive', | ||
}, | ||
] as const; |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is only needed until Relayer V6 is deployed right? Note to remove once we have updated tests.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@brunoguerios do we have an expected date for this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not yet. It's currently being audited and after that it needs to go through governance approval. My guess is that it will be live in ~1 month.