Popsicle JIT Engine Update!

Popsicle.Finance (WAGMI)
6 min readOct 20, 2022

Dear Isvikingers, it has been a while since our last update! Our developers have been heads down building the framework for our JIT engine. We are approaching the release and would like to use this new Medium article to explain what JIT is and how the engine works!

tl:dr: The JIT engine will improve Fragola profitability, by reducing the Slippage of rebalances and therefore the IL that our current strategies are experiencing.

Intro to JIT

JIT, or Just In Time Liquidity, is a method of LPing that consists of deploying huge amounts of capital into a very tight price range on UniV3. The JIT liquidity provider deepens the liquidity in that particular trading range and is compensated as they earn the majority of fees for a particular trade. For very large trades, these fees can be substantial.

This liquidity comes from different protocols that allow flash loans, such as AAVE or Euler. The constraint on flash loans is only one: the tokens borrowed need to be given back in the same block on which they are borrowed, without the need of depositing collateral.

In the past few months a lot of research has happened on this, and we have realised that it can be very useful to use in tandem with Fragola, our UniV3 optimiser. Let’s understand why.

The Role of JIT in Fragola

Before understanding why JIT is pivotal in Fragola development, we highly recommend you to first have a read at what Fragola is and how it works here.

Over the past few months, we have realised that when rebalancing the ranges in which Fragola operates, we are often swapping a large portion of LP, which leads to a high amount of slippage that negatively impacts the profitability of the Fragola strategy.

This is where JIT comes into play.

By using our brand new JIT engine, we will be able to deepen the liquidity that we use to rebalance, decreasing slippage and increasing the profitability of our strategies. How does the JIT engine work?

The JIT Engine

The engine is constituted of different contracts that interact between each other, and source large amounts of liquidity from different places.

The JIT process involves 4 parties and each party is comprised of one or more contracts: the Borrower, the Liquidity Provider, the Fragola main contract, and the Normaliser.

The most important part of our JIT engine is the Normaliser Contract. This contract is responsible for computing the inputs and outputs of the process while taking into account the on-chain liquidity, sources of flash loans, etc.

To better explain this multistep process, here’s an example:

Step 1) The first part is the request signal, which starts the JIT process. A request comes from the main Fragola contract with information (which tokens are being traded, who is borrowing, the quantity of tokens needed, and the swap data) on the rebalance that is about to happen.

Step 2) Once this information is received from the Borrower contract, each token is borrowed through a flash loan from different protocols and sent to the Liquidity Provider contract (LP contract).

Step 3) The LP contract computes the exact ticks in which liquidity is required, and provides liquidity.

Step 4) The Fragola Main contract is executing according to the price slippage in the strategy (i.e how much we are happy to take on in slippage to rebalance the pool). Remember that this amount is constrained by the total slippage we are specifying, in order to avoid any possible malfunctions that might create a loss in the strategy.

Right now, the JIT liquidity is deployed and ready to be used by the Fragola Rebalance!

Step 5) Fragola Main contract activates the rebalance, pulls liquidity from the old range and deploys liquidity in the new range. In this step, the slippage encountered is much lower than usual, because of the deep liquidity we are deploying using JIT. This is where the big innovation comes in.

The swap has happened now and the Fragola pool has been rebalanced. Now it is time to repay the flash loan. Here is where the Normaliser comes into play.

Step 6) Now that our swap has happened, the Liquidity Provider contract pulls the liquidity from the pool, and can now swap it back in the amounts originally borrowed in order to repay the flash loan.

Step 7) Once liquidity is pulled, the Liquidity Provider contracts signals to the Normaliser the quantity, types of tokens and amounts that have been pulled from the pool. The Swapper uses this data to “normalise” the tokens received. In order to fully understand this, let’s imagine that we are trying to flash loan the ICE/WETH pool. We therefore borrow 100 ICE tokens, and 5 WETH. After the liquidity is pulled from the pool though, we might have 120 ICE and 4 WETH. Here comes into play the normaliser that computes the sale of this 20 ICE for one more WETH.

Step 8) The normaliser processes this data, and executes the swap through protocols such as 1inch and 0xProtocol, in order to always get the most profitable swapping path. Slippage constraints are applied also on this step. The Normaliser works on principles of contradictio in contrarium i.e proof by contradiction.

Step 9) The swapper sends the tokens back to the borrower contract that pays back the flash loan and makes this all transaction possible.

Step 10) Whatever profit is made from this whole series of steps, it is sent back to Bentobox and will be treated as protocol revenue!

Note though that the rewards destination can be changed, and we can for example choose to send the profits back to the UniV3 LP position (basically achieving close to zero-cost rebalanaces). More information on this will come in a future article so stay tuned!

And there we have it! We have managed to optimise a rebalance call on Fragola through the use of the JIT engine, and we have made a profit from it!

Remember that all of these steps happen in one single transaction, and if one of these steps fails, the whole transaction fails.

The possibility of loss of funds is reduced to the minimum thanks to the different safeguards we have on slippage tolerance on all of these contracts, and Fragola rebalances will happen so much more smoothly!

The ground-breaking thing is that we can completely exclude any interaction with the fragola contracts, and still have a working JIT engine that could be used to provide liquidity for major trades on Unisvap V3! The Normaliser contract is composable, upgradable and can be adapted to different tasks!

Being completely written in Solidity, it will also allow users to build on top of it in the future, if they wish to do so!

Spotlight on the Normaliser

As mentioned before, the most innovative and time consuming part of this whole development was engineering the Normaliser Contract as a composable tool that can be used not only in JIT, but as a general engine to get liquidity for all kinds of interactions (Liquidations for example).

We are gonna give more information on the Normaliser in the future, but see the Normaliser as the “computer” that checks when liquidity is needed, where it can be sourced, how much it will cost, the amounts and the profits.

Timelines and Development Status

As you can see, this is a very complex system that can be used in many different scenarios, which is why it has taken us so many months to develop and test. We are now happy to announce that development has been completed, and we are in the process of testing to correctly configure all the different parameters involved.

We are now approaching the final rounds of this testing, which will be a test in prod round directly on our Fragola Pools! As soon as we have the data on this testing, we will share it right away with the community to show you how the profitability has increased, basically revamping Fragola utility!

More information on the normaliser and JIT are coming soon, so stay tuned Isvikingers!

Follow us on twitter or join our Discord!

--

--