Giter VIP home page Giter VIP logo

cfmms-rs's People

Contributors

0xkitsune avatar 0xosiris avatar da-bao-jian avatar kadenzipfel avatar kutugu avatar mouseless-eth avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

cfmms-rs's Issues

Fix: Update logic to sync UniswapV3 pool from swap log

Right now, the current logic is getting the amount_0 and amount_1 from log_data[1]. This is incorrect as the amount_0 should be retrieved from log_data[0]. All logic used to sync pools from logs should be checked and updated. Additionally, logic decoding logs should ensure that indexed arguments are handled correctly and not assumed to be in log data.

Snippet for reference

Update price calculations to use BigFloat for now

Currently calculate_price casts reserve_0 and reserve_1 to f64. Change this to BigFloat for now.

In the future, we should add a function that returns the price as a Fixed point number and only uses U256 for the price calculation.

Incorporate Protocol fee within Uniswap v3 swap simulation.

For Uniswap V3 Swap simulation, the protocol needs to be incorporated.

     // if the protocol fee is on, calculate how much is owed, decrement feeAmount, and increment protocolFee
            if (cache.feeProtocol > 0) {
                uint256 delta = step.feeAmount / cache.feeProtocol;
                step.feeAmount -= delta;
                state.protocolFee += uint128(delta);
            }

Liquidity Provisioning Utilities for Liquidity Providors + JIT Exploitation

I think adding liquidity provision helpers on the pools could be very appealing to liquidity providers monitoring and moving around large amounts of liquidity across CFMMs. This would allow liquidity providers to seamlessly automate their liquidity provision, and analytically optimize the profitability of their positions.

For Starters:

Mint Liquidity

function mint(
        address recipient,
        int24 tickLower,
        int24 tickUpper,
        uint128 amount,
        bytes calldata data
    ) external returns (uint256 amount0, uint256 amount1);

Collect Fees

function collect(
        address recipient,
        int24 tickLower,
        int24 tickUpper,
        uint128 amount0Requested,
        uint128 amount1Requested
    ) external returns (uint128 amount0, uint128 amount1);

Remove Liquidity from a position

function burn(
        int24 tickLower,
        int24 tickUpper,
        uint128 amount
    ) external returns (uint256 amount0, uint256 amount1);

Ranged Liquidity or Time Weighted Average price

function observe(uint32[] calldata secondsAgos)
        external
        view
        returns (int56[] memory tickCumulatives, uint160[] memory secondsPerLiquidityCumulativeX128s);

Seconds per Liquidity & Seconds inside a tick range

function snapshotCumulativesInside(int24 tickLower, int24 tickUpper)
        external
        view
        returns (
            int56 tickCumulativeInside,
            uint160 secondsPerLiquidityInsideX128,
            uint32 secondsInside
        );

The above function would also be helpful for calculating optimal JIT positions and amounts.

Fix: update type for Dex fee when constructing a checkpoint.

Right now, when constructing a checkpoint, we are saving the Dex fee as a String, but it needs to be a number. This can be fixed very simply but just switching the existing code:

  dex_map.insert(
    String::from("fee"),
    format!("{:?}", uniswap_v2_dex.fee).into(),
);

to this:

  dex_map.insert(
    String::from("fee"),
     uniswap_v2_dex.fee.into(),
);

Link to the line of code

Integrate Batched Calls in v3 Swap simulation

simulate_swap and simulate_swap_mut both require two external calls to the node to retrieve the Tick.Info and the word corresponding to tickBitmap[currentTick] during simulation. Two separate calls are made each time an initialized tick in crossed.

This can be optimized by batching the two calls into a single call to the node as both calls can happen in parallel. I think this will be most easily accomplished by abstracting the calls to the node outside of uniswap_v3_math into cfmms-rs.

CFFM book

Opening this issue to start brainstorming around what the CFFM book might look like. I think the book should look something like the Foundry book, walking through the different mods in the lib and how to use them.

`BigFloat` panics

Remove num-bigfloat crate from all price calculations because of unexpected panic in division.

Panic Example:

use num_bigfloat::BigFloat;

fn main() {
    let x = BigFloat::from(1);
    let y = BigFloat::from(2);
    let z = x / y;
    println!("{z:?}");
}

Addresses #7

This affects the calculate_price functions in uniswap_v2.rs & uniswap_v3.rs

Implement Multicall where applicable to speed up operations.

Some functions that call the node (ex. Syncing, getting pool data, etc) can use a multicall to complete much faster. We should implement this where applicable. There should be an option to use the function with and without multicall, probably by passing in a optional Chain Enum (ex. Chain::Ethereum, Chain::Polygon, etc). If the value is None, it wont use the multicall. The mulicall address should be a constant value for each chain.

Feature: Implement swap functions for each pool variant.

Implement swap functions for UniswapV2Pool and UniswapV3Pool that takes in swap arguments, a wallet and a provider. These functions should create a transaction, sign and send it to the network, returning a Result with the Ok variant containing the pending transaction hash.

Additionally, there should be a some_swap_function_calldata() function for each swap function that generates the calldata for the transaction, but doesn't actually sign and send the transaction to the network.

Implement batch requests

Addresses #51

  • Update v2 get pool data
  • Update v3 get pool data
  • Update v3 sync pool
  • Update v2 new from address
  • Update v3 new from address
  • Add batch sync contract for v3 sync

Contract creation code storage out of gas

On sync UniswapV2, when solidity batcher contract tries to batch pool 0xc0ca776fe52ec92b1d5603caadf148dbd8c22a80, one of the tokens doesn't have decimals() method. Because of that, raw call of contract deployer results with Error: (code: -32000, message: contract creation code storage out of gas, data: None).
I tries:

  • modify foundry.toml config with gas_limit = u64::MAX and extended memory_limit
  • experiments with max size of batch if it included tokens like that (processed unsuccess call for decimals()). Maximum - 18 normal pools and 1 pool with token which doesn't have a decimals method. Also, its fine to call contract with a single [pool_address] where pool_address will be 0xc0ca776fe52ec92b1d5603caadf148dbd8c22a80. If we have [pool_address, usdc_weth_pool_address] there is also out of gas error.

In Remix it seems fine to deploy, but there is kinda other simulation.

Remove magic numbers

A contant value should be used anywhere there is a U256 value that never changes.

For example:

      //Set sqrt_price_limit_x_96 to the max or min sqrt price in the pool depending on zero_for_one
        let sqrt_price_limit_x_96 = if zero_for_one {
            U256::from("4295128739") + 1
        } else {
            U256::from("0xFFFD8963EFD1FC6A506488495D951D5263988D26") - 1
        };

All of these values should be changed to match this format:

pub const MIN_SQRT_RATIO: U256 = U256([285968860985, 0, 0, 0]);
pub const MAX_SQRT_RATIO: U256 = U256([
    9809463991923573570,
    227557619515130776,
    5049738529920590081,
    1,
]);

Use `Middlewear` instead of `Arc<Provider<P>>`

Update the functions to take middleware instead of a provider. This allows for greater flexibility like using the NonceManagerMiddleware, FlashbotsMiddleware or some custom Middlewear.

Feature: Get all pools with a specific token.

Implement a function within the dex mod that gets all of the pools containing a target token address.

pub fn get_all_pools_containing_token(target_token: H160, dexes: Vec<Dex>, provider: Arc<Provider<P>>, ) -> Result<Vec<Pool>, CFFMError<P>>{
    for dex in dexes{
        //Get all pools starting from the dex creation block,
        //Filter out pools that do not have the target token
       //For all pools containing the target token, sync the pools 

    }

    // --snip--
}

abigen

Hey Guys

Great work on cfmm-rs and uniswapv3_math-rs!!

Just had a question... I noticed in uniswap_v3.rs you are defining the swap event signature and writing code to decode swap logs, can't you instead just generate this code using abigen with ethers-rs?

Something like:

let event = UniswapV3PoolEvents::decode_log(&RawLog {
    topics: log.topics,
    data: log.data.to_vec(),
});

Thanks
Q

Question: Slight difference in simulated swap out amounts

Hey.

Thanks for the amazing effort on this library!
When doing some comparisons to Swap events outputted for an arbitrary pair (for this example I am using 500 fee tier WETH/USDC on Optimism), I notice a very small margin of error from the output of the simulation vs what the swap log shows.

The negative amount 0 representing the output of the swap from logs.
'Amount out from internal swap' representing the result of the simulated swap.

I thought it could be due to a difference in pool state after the swap log, as the batch tick data call would hit the chain AFTER the swap log. However, I switched to a completely pool 'state' which is initialised with tick data in either direction and altered the simulation to use that data, there is still a small error. See DIFF. Is this due to just precision difference between EVM and Rust?

Am able to get 0 DIFF when the output is USDC sometimes...

2023-06-06T08:19:50.046Z INFO  [verdant] Found a swap event 0x68df429f0050417cac5ebb407bbe2adcbe6aab990d9d7f65d8bc2a93f08695fe. Running sims.
2023-06-06T08:19:50.046Z INFO  [cfmms::pool::uniswap_v3] SQRT PRICE FROM LOG 3374780273765172741931233
2023-06-06T08:19:50.046Z INFO  [cfmms::pool::uniswap_v3] AMOUNT 0 "-1472873957491611"
2023-06-06T08:19:50.046Z INFO  [cfmms::pool::uniswap_v3] AMOUNT 1 "2673712"
2023-06-06T08:19:50.047Z INFO  [cfmms::pool::uniswap_v3] Current tick -201286 false
2023-06-06T08:19:50.048Z INFO  [cfmms::pool::uniswap_v3] AMOUNT OUT FROM INTERNAL SWAP "1472873826317980"
2023-06-06T08:19:50.049Z INFO  [cfmms::pool::uniswap_v3] DIFF "0.00000008905964446774203"```

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.