balancer / b-sdk

MIT License
18 stars 7 forks source link

Add optional account to swap query #398

Open johngrantuk opened 3 weeks ago

johngrantuk commented 3 weeks ago

Currently swap queries don't have an associated account. This means we can't query a swap that includes a hook that relies on specific account data (e.g. veBal balance discount fee). Investigate following as possible solution:

MattPereira commented 1 week ago

Obstacle

The swap query throws error if you add account in params beside blockNumber, but works fine when account is left as undefined. Will investigate further this week https://github.com/balancer/b-sdk/blob/f4ce57f1c9fdae7cd7814ddb2f096fdca5b2dbbe/src/entities/swap/swaps/v3/index.ts#L105-L128

> npx tsx ./examples/lib/executeExample.ts "./examples/swaps/customSwap.ts"

Input token: 0xe8d4e9fc8257b77acb9eb80b5e8176f4f0cbcebc, Amount: 10000000000000000000
Output token: 0xf0bab79d87f51a249afe316a580c1cdfc111be10, Amount: 990000000000000000
account 0x5036388C540994Ed7b74b82F71175a441F85BdA1
/home/matthu/Desktop/Balancer/b-sdk/node_modules/.pnpm/viem@2.12.1_typescript@5.3.3/node_modules/viem/utils/errors/getContractError.ts:72
  return new ContractFunctionExecutionError(cause as BaseError, {
         ^

ContractFunctionExecutionError: The contract function "querySwapSingleTokenExactIn" reverted with the following signature:
0x67f84ab2

Unable to decode signature "0x67f84ab2" as it was not found on the provided ABI.
Make sure you are using the correct ABI and that the error exists on it.
You can look up the decoded signature here: https://openchain.xyz/signatures?query=0x67f84ab2.

Contract Call:
  address:   0xDd10aDF05379D7C0Ee4bC9c72ecc5C01c40E25b8
  function:  querySwapSingleTokenExactIn(address pool, address tokenIn, address tokenOut, uint256 exactAmountIn, bytes userData)
  args:                                 (0x6D9656174205876897A9f526CCDcD3aE725ffEFF, 0xE8d4E9Fc8257B77Acb9eb80B5e8176F4f0cBCeBC, 0xF0Bab79D87F51a249AFe316a580C1cDFC111bE10, 10000000000000000000, 0x)
  sender:    0x5036388C540994Ed7b74b82F71175a441F85BdA1
MattPereira commented 1 week ago

Update

Managed to decode the error using viem and the vaultV3Abi. The error sig is NotStaticCall, which comes from library v3 is using that explains the error as "A state-changing transaction was initiated in a context that only allows static calls"

Not entirely sure why because of assumption that viem's .simulate for contract instances doesn't actually send state changing transaction

https://github.com/balancer/b-sdk/blob/f4ce57f1c9fdae7cd7814ddb2f096fdca5b2dbbe/src/entities/swap/swaps/v3/index.ts#L117-L130

johngrantuk commented 1 week ago

I tried this directly on Tenderly and it doesn't seem possible. I also tried using an address for a swap through a pool without a hook and it also throws. MkFlow confirmed that Any query checks if tx.origin == address(0) This seems like a potential awkward limitation, I'll bring it up during V3 meeting to see what everyones thoughts are.

johngrantuk commented 1 week ago

Juani suggested doing a static call to actual function (with the account address) which will simulate the write and return the result. The biggest issue with this approach is it needs the account to actually have balance, etc but this is potentially ok I think because we wouldn't really be interested otherwise.

@MattPereira could you give this a try? If it works maybe we can switch the method used in query depending if address is passed.