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

Predicted estimates/deltas are significantly off for swaps between pairs with different decimals #1

Closed
drewdrewthis opened this issue Nov 27, 2021 · 2 comments

Comments

@drewdrewthis
Copy link

drewdrewthis commented Nov 27, 2021

Not sure the best way to show this, but these are my results below. As you can see, all of the estimates are correct except for one, which turns out to be the only one with a different decimal value for one of the pairs. These pool values are pulled via the subgraph, parsed, estimated, and then queried, so I understand that there might simply be a diff created by a swap in a new block, but I get it consistently ... it seems like a large diff, especially since it compounds when trying to calculate the deltas for a batch with multiple swaps.

    SDK deltas [
      '2.097419317298821807645e+21',
      '118553',
      '253143290065472600',
      '148630155501753702',
      '93275464391108282418',
      '375461148782927411125',
      '289663185636574',
      '54105534600875717950',
      '2.812897167024091257484e+21',
      '4.7335838481961226020905e+22'
    ] 

Actual deltas (from queryBatchSwap; the second number is the delta under analysis):

[
      [ '1804086870540397545', '-2097419317298821807645' ],
      [ '756', '-118553' ],
      [ '2430121', '-253143213776194404' ], <<< THIS ONE IS OFF
      [ '1427933661696875', '-148630155501753702' ],
      [ '1175047681676218395', '-93275464391108282418' ],
      [ '261694720835645986321160', '-375461148782927411125' ],
      [ '1368690034825606436', '-289663185636574' ],
      [ '13146688249344598', '-54105534600875717950' ],
      [ '14550850511996682359694360', '-2812897167024091257484' ],
      [ '50673306620315115997', '-47335838481961226020905' ]
]

The pair/swap that is off is this:

  {
    "address": "0x0297e37f1873d2dab4487aa67cd56b58e2f27875",
    "id": "0x0297e37f1873d2dab4487aa67cd56b58e2f27875000200000000000000000003",
    "swapFee": "0.0004",
    "tokens": [
      {
        "address": "0x2260fac5e5542a773aa44fbcfedf7c193bc2c599",
        "balance": "0.08100405",
        "decimals": 8,
        "symbol": "WBTC",
        "weight": "0.5"
      },
      {
        "address": "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2",
        "balance": "1.097292090085436554",
        "decimals": 18,
        "symbol": "WETH",
        "weight": "0.5"
      }
    ]
  },
Here is a snippet where the deltas are being calculated:
import * as SDK from '@georgeroman/balancer-v2-pools';
   
...

export const getSDKestimatesForPools = (pools: Balancer.Pool[]) => pools
 .map((pool) => {
   const { tokens } = pool;
   const [srcToken, destToken] = tokens;

   const maxIn = calcMaxOutForToken(srcToken)
     .div(10 ** srcToken.decimals)
     .toString();

   try {
     const wPool = new SDK.WeightedPool({
       ...pool,
       tokens: tokens.map((token) => ({
         ...token,
         weight:  token.weight.toString(),
         balance: token.balance.toString(),
       })),
       bptTotalSupply:    '0', // We're not using this for the moment
       swapFeePercentage: pool.swapFee.toString(),
       query:             true,
     });

     return Big(wPool.swapGivenIn(srcToken.symbol, destToken.symbol, maxIn))
       .mul(10 ** destToken.decimals).toString();  

With the Pool type def:

     export namespace Balancer {
 export type PoolToken = {
   id: number;
   poolId: Pool;
   symbol: string;
   name: string;
   decimals: number;
   address: string;
   priceRate: number;
   balance: number;
   invested: number;
   weight: number;
 }

 // https://github.com/balancer-labs/balancer-subgraph-v2/blob/master/schema.graphql#L12
 export type Pool = {
   id: string;
   address: string;
   poolType: string;
   strategyType: string;
   symbol: string;
   name: string;
   swapEnabled: boolean;
   swapFee: Big;
   totalSwapFee: Big;
   tokens: PoolToken[];
 }

 export type PoolId = {
   id: number
 }

Here is the raw pool data:

[{"address":"0x01abc00e86c7e258823b9a055fd62ca6cf61a163","id":"0x01abc00e86c7e258823b9a055fd62ca6cf61a16300010000000000000000003b","swapFee":"0.0015","tokens":[{"address":"0x0bc529c00c6401aef6d220be8c6ea1667f6ad93e","balance":"6.013622901801325153","decimals":18,"symbol":"YFI","weight":"0.125"},{"address":"0x1f9840a85d5af5bf1d1762f925bdaddc4201f984","balance":"9099.319892491319984239","decimals":18,"symbol":"UNI","weight":"0.125"},{"address":"0x6b3595068778dd592e39a122f4f5a5cf09c90fe2","balance":"24840.656829305797359151","decimals":18,"symbol":"SUSHI","weight":"0.125"},{"address":"0x7fc66500c84a76ad7e9c93437bfc5ac33e2ddae9","balance":"742.810889219707179281","decimals":18,"symbol":"AAVE","weight":"0.125"},{"address":"0x9f8f72aa9304c8b593d555f12ef6589cc3a579a2","balance":"56.755479852960235545","decimals":18,"symbol":"","weight":"0.125"},{"address":"0xba100000625a3754423978a60c9317c58a424e3d","balance":"8744.874649841242923741","decimals":18,"symbol":"BAL","weight":"0.125"},{"address":"0xc00e94cb662c3520282e6f5717214004a7f26888","balance":"669.335977004737319178","decimals":18,"symbol":"COMP","weight":"0.125"},{"address":"0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2","balance":"42.81467757825287324","decimals":18,"symbol":"WETH","weight":"0.125"}]},{"address":"0x021c343c6180f03ce9e48fae3ff432309b9af199","id":"0x021c343c6180f03ce9e48fae3ff432309b9af19900020000000000000000000b","swapFee":"0.005","tokens":[{"address":"0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2","balance":"0.000000000000002521","decimals":18,"symbol":"WETH","weight":"0.2"},{"address":"0xd291e7a03283640fdc51b121ac401383a46cc623","balance":"0.000000000001876469","decimals":18,"symbol":"RGT","weight":"0.8"}]},{"address":"0x0297e37f1873d2dab4487aa67cd56b58e2f27875","id":"0x0297e37f1873d2dab4487aa67cd56b58e2f27875000200000000000000000003","swapFee":"0.0004","tokens":[{"address":"0x2260fac5e5542a773aa44fbcfedf7c193bc2c599","balance":"0.08100405","decimals":8,"symbol":"WBTC","weight":"0.5"},{"address":"0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2","balance":"1.097292090085436554","decimals":18,"symbol":"WETH","weight":"0.5"}]},{"address":"0x03cd191f589d12b0582a99808cf19851e468e6b5","id":"0x03cd191f589d12b0582a99808cf19851e468e6b500020000000000000000002b","swapFee":"0.005","tokens":[{"address":"0x9f8f72aa9304c8b593d555f12ef6589cc3a579a2","balance":"0.004759778872322919","decimals":18,"symbol":"","weight":"0.5"},{"address":"0xba100000625a3754423978a60c9317c58a424e3d","balance":"0.646553624519376179","decimals":18,"symbol":"BAL","weight":"0.5"}]},{"address":"0x062f38735aac32320db5e2dbbeb07968351d7c72","id":"0x062f38735aac32320db5e2dbbeb07968351d7c720002000000000000000000ac","swapFee":"0.003","tokens":[{"address":"0x06325440d014e39736583c165c2963ba99faf14e","balance":"3.916825605587394651","decimals":18,"symbol":"steCRV","weight":"0.500000000000000001"},{"address":"0xeb1a6c6ea0cd20847150c27b5985fa198b2f90bd","balance":"405.129240356044205643","decimals":18,"symbol":"eYyvcrvSTETH-15APR22","weight":"0.499999999999999999"}]},{"address":"0x072f14b85add63488ddad88f855fda4a99d6ac9b","id":"0x072f14b85add63488ddad88f855fda4a99d6ac9b000200000000000000000027","swapFee":"0.0029","tokens":[{"address":"0xc011a73ee8576fb46f5e1c5751ca3b9fe0af2a6f","balance":"872315.736118819954403869","decimals":18,"symbol":"SNX","weight":"0.5"},{"address":"0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2","balance":"1630.638325204361987215","decimals":18,"symbol":"WETH","weight":"0.5"}]},{"address":"0x09804caea2400035b18e2173fdd10ec8b670ca09","id":"0x09804caea2400035b18e2173fdd10ec8b670ca09000100000000000000000038","swapFee":"0.0015","tokens":[{"address":"0x04fa0d235c4abf4bcf4787af4cf447de572ef828","balance":"4.562300116085354789","decimals":18,"symbol":"UMA","weight":"0.125"},{"address":"0x0bc529c00c6401aef6d220be8c6ea1667f6ad93e","balance":"0.001256657629424214","decimals":18,"symbol":"YFI","weight":"0.125"},{"address":"0x1f9840a85d5af5bf1d1762f925bdaddc4201f984","balance":"2.107829214730689206","decimals":18,"symbol":"UNI","weight":"0.125"},{"address":"0x514910771af9ca656af840dff83e8264ecf986ca","balance":"1.949409240792221736","decimals":18,"symbol":"LINK","weight":"0.125"},{"address":"0x7fc66500c84a76ad7e9c93437bfc5ac33e2ddae9","balance":"0.154339756888995831","decimals":18,"symbol":"AAVE","weight":"0.125"},{"address":"0x9f8f72aa9304c8b593d555f12ef6589cc3a579a2","balance":"0.017270757086778536","decimals":18,"symbol":"","weight":"0.125"},{"address":"0xc011a73ee8576fb46f5e1c5751ca3b9fe0af2a6f","balance":"5.31316273465435187","decimals":18,"symbol":"SNX","weight":"0.125"},{"address":"0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2","balance":"0.018972472132080956","decimals":18,"symbol":"WETH","weight":"0.125"}]},{"address":"0x0a9e96988e21c9a03b8dc011826a00259e02c46e","id":"0x0a9e96988e21c9a03b8dc011826a00259e02c46e000200000000000000000055","swapFee":"0.003","tokens":[{"address":"0x6b175474e89094c44da98b954eedeac495271d0f","balance":"0.043822294164481996","decimals":18,"symbol":"DAI","weight":"0.500000000000000001"},{"address":"0xe7f4294033d0fde6eecb94bef7da22fde68a61ec","balance":"235","decimals":18,"symbol":"eYyvDAI-27JUN21","weight":"0.499999999999999999"}]},{"address":"0x0b09dea16768f0799065c475be02919503cb2a35","id":"0x0b09dea16768f0799065c475be02919503cb2a3500020000000000000000001a","swapFee":"0.0012","tokens":[{"address":"0x6b175474e89094c44da98b954eedeac495271d0f","balance":"48502835.039988941198981203","decimals":18,"symbol":"DAI","weight":"0.4"},{"address":"0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2","balance":"17546.393302094325054807","decimals":18,"symbol":"WETH","weight":"0.6"}]},{"address":"0x1050f901a307e7e71471ca3d12dfcea01d0a0a1c","id":"0x1050f901a307e7e71471ca3d12dfcea01d0a0a1c00020000000000000000004c","swapFee":"0.0015","tokens":[{"address":"0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2","balance":"168.911022067717053326","decimals":18,"symbol":"WETH","weight":"0.2"},{"address":"0xf629cbd94d3791c9250152bd8dfbdf380e2a3b9c","balance":"746561.063835352040083549","decimals":18,"symbol":"ENJ","weight":"0.8"}]}]
@georgeroman
Copy link
Owner

georgeroman commented Nov 28, 2021

The SDK was subtracting/adding the swap fees on the scaled amountIn/amountOut values. However, the contracts handle fees on the unscaled values (eg. https://github.com/balancer-labs/balancer-v2-monorepo/blob/8066660d3035faabf96179e71f8c7b69a5936d3d/pkg/pool-utils/contracts/BaseMinimalSwapInfoPool.sol#L40, https://github.com/balancer-labs/balancer-v2-monorepo/blob/8066660d3035faabf96179e71f8c7b69a5936d3d/pkg/pool-utils/contracts/BaseMinimalSwapInfoPool.sol#L69). I added a fix in this commit 6cbbe41. As you can see, I removed the fee handling from the math functions since that can give erroneous results in case the unscaled amount is different from the scaled amount (this happens when a token has less than 18 decimals). Let me know if this solves it for you.

@drewdrewthis
Copy link
Author

@georgeroman Yeah! The fix works. Great job, thanks

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

No branches or pull requests

2 participants