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

Optimize TrueFi pool join and exit #28

Open
dmaretskyi opened this issue Sep 27, 2021 · 3 comments
Open

Optimize TrueFi pool join and exit #28

dmaretskyi opened this issue Sep 27, 2021 · 3 comments

Comments

@dmaretskyi
Copy link

Today joining or exiting a pool spends around 700-800 thousand gas which cost $100-$200 in fees. This makes it unfeasible to use the pool with smaller sums.

Both join and exit transactions spend almost 90% gas calculating the pool value. Optimisation ideas are centered around reusing the same calculation for multiple transactions.

Gas profiling of the current smart-contracts

liquidExit

https://dashboard.tenderly.co/tx/mainnet/0xc448a21d588c350fccfb09ed599c6d36850503ea85ac51c280f01e4555b9b760/gas-usage

getPoolValue = 615274 gas (90%)
total = 682976 gas

join

https://dashboard.tenderly.co/tx/mainnet/0x689a04afc74d6a8a703b0864a108ccc5c1e9221f2aa98314039ce28a99744786/gas-usage

getPoolValue = 675414 gas (88%)
total = 764492 gas

Option 1: Users queue their deposits and bot processes them in-batch

In this proposal users would call a contract method that would lock their tokens but would not mint any LP tokens right away. Their deposit would be enqueued along with others.

After enough users have enqueued their tokens a bot (probably owned by TrustToken) would call the pool smart-contract to process a batch of enqueued deposits. In this case the pool value would be calculated once and then used to mint LP tokens for each user in the batch.

In this case the most gas would be spent by the bot. The total gas usage would be reduced, but the protocol fees would need to be adjusted accordingly.

Advantages

  • Overall reduction in total gas spent.
  • The frequency of the batch deposit/withdrawal calls can be adjusted to the current amount of users in queue.

Disadvantages

  • User's funds might stay locked for a period of time without being utilized.
  • Users are susceptible to future value fluctuations and do not know the amount of LPs they would receive at the time of deposit.

TODO

  • Develop financial incentives and make the protocol open for anyone to execute batch transactions (maybe some sort of gas fee refund from the user to batch transaction sender).

Option 2: Lock the pool value for deposits and withdrawals for a time period

In this case a bot would periodically calculate the pool value and lock the LP token price for a certain period. In that period all of the deposits and withdrawals would be calculated using the locked price.

Analogous to option 1, the bot would be spending the majority of gas.

Advantages

  • Deposits/withdrawals are settled instantly.

Disadvantages

  • The bot would have to keep updating the pool value on chain regardless of the amount of users depositing/withdrawing which might become financially unfeasible.
  • This method is susceptible to sandwich attacks where attacker would deposit into the pool before the LP price is updated and then withdraw immediately after.
@vanruch
Copy link
Contributor

vanruch commented Sep 28, 2021

Hi @marik-d, thanks for the suggestions.

I don't think #1 is suitable for us because there's not enough traction to batch transactions. Last USDC pool join was performed 4 days ago for example. This would really mean that we will have a bot which will be executing metatransactions (which might be not that bad of idea)

I like #2 though, after second thought it looks like it's not that important for pool to have latest pool value. This might cause some problems when pool is almost empty but this can probably be neglected. But we still need to carefully check if this will not provide any threads other than arbitrage opportunity (we can introduce a cooldown to prevent this).

@yuchenlintt
Copy link
Contributor

Thanks @marik-d for these proposals! I think these are both feasible technical optimizations, and I also have a preference for #2.

However, before we add epicycles on epicycles, I'd first like to investigate why calculating pool value costs 700-800k gas, and determine whether it really needs to spend that much. Where is our critical loop?

  1. calculating the Curve strategy value is expensive
  2. (FTL) iteration through all loans, where every loan accrues value linearly per-block
  3. (LoC) ditto with FTL but for buckets
  4. we're calling several outside contracts (Curve, TrueLender2 FTLs, FTLA FTLs, LoCs, SAFU deficits), which would inherently be expensive even if each call were a simple lookup

If we can find a solution that cuts off non-essential code, I would prefer that to building more on top of what we have. For instance for LoCs, perhaps we can accept that the LoC value doesn't accrue per-block. It would only increase when someone manually calls poke().

@yuchenlintt
Copy link
Contributor

Another perspective on the pool value update bot in option 2: sandwich profits could be our incentive for lenders to call the public update function. That is, sandwich lenders are welcome to join + update + liquidExit and collect a proportional share of instant profits. As long as liquidExit has a high enough utilization-dependent penalty, a sandwich lender can't drain too much profit from the pool.

We could adjust the penalty calculation to vary the optimal frequency for a sandwich lender to call update:

  • low penalty => high update frequency since other sandwich lender bots would frontrun
  • high penalty => low update frequency since it's not worth the gas to call update this frequently

Our own bot would be funded from sandwich lending to the protocol when it's gas-profitable.

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

4 participants
@vanruch @dmaretskyi @yuchenlintt and others