Skip to content
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 optional account to swap query #398

Open
johngrantuk opened this issue Aug 23, 2024 · 4 comments · May be fixed by #404
Open

Add optional account to swap query #398

johngrantuk opened this issue Aug 23, 2024 · 4 comments · May be fixed by #404
Assignees

Comments

@johngrantuk
Copy link
Member

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:

  • Add optional account param to query
  • Where await routerContract.simulate.query... is called add account in params beside blockNumber
    There might be a better way to do this.
@MattPereira
Copy link
Member

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

private async querySingleSwap(
client: PublicClient,
block?: bigint,
account?: Address,
): Promise<ExactInQueryOutput | ExactOutQueryOutput> {
const routerContract = getContract({
address: BALANCER_ROUTER[this.chainId],
abi: balancerRouterAbi,
client,
});
if ('exactAmountIn' in this.swaps) {
console.log('account', account);
const { result } =
await routerContract.simulate.querySwapSingleTokenExactIn(
[
this.swaps.pool,
this.swaps.tokenIn,
this.swaps.tokenOut,
this.swaps.exactAmountIn,
DEFAULT_USERDATA,
],
{
blockNumber: block,
account, // error happens if account is defined

> 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
Copy link
Member

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

const { result } =
await routerContract.simulate.querySwapSingleTokenExactIn(
[
this.swaps.pool,
this.swaps.tokenIn,
this.swaps.tokenOut,
this.swaps.exactAmountIn,
DEFAULT_USERDATA,
],
{
blockNumber: block,
account, // error happens if account is defined
},
);

@johngrantuk
Copy link
Member Author

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
Copy link
Member Author

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants