Giter VIP home page Giter VIP logo

openbook-v2's Introduction

OpenBook V2

A central-limit order-book program based on Mango V4 and the previous OpenBook program (which was a fork of Serum).

License

See the LICENSE file.

The majority of this repo is MIT-licensed, but some parts needed for compiling the Solana program are under GPL.

All GPL code is gated behind the enable-gpl feature. If you use the openbook-v2 crate as a dependency with the client or cpi features, you use only MIT parts of it.

The intention is for you to be able to depend on the openbook-v2 crate for building closed-source tools and integrations, including other Solana programs that call into the Openbook program.

But deriving a Solana program with similar functionality to the Openbook program from this codebase would require the changes and improvements to stay publicly available under GPL.

Deployed versions

tag  network program ID
v1.7 mainnet opnb2LAfJYbRMAHHvqjCwQxanZn7ReEHp1k81EohpZb
v1.7 devnet opnb2LAfJYbRMAHHvqjCwQxanZn7ReEHp1k81EohpZb
v1.7 testnet opnb2LAfJYbRMAHHvqjCwQxanZn7ReEHp1k81EohpZb

Building & testing

Pre-requisites

Before you can build the program, you will first need to install the following:

Installing

To install the repo, run:

git clone https://github.com/openbook-dex/openbook-v2.git --recursive

The recursive flag ensures that you receive all of the submodules. If you have already cloned without passing in this flag, you can run:

git submodule init
git submodule update

To ensure that you always have the latest submodules, you can configure your git like so:

git config --global submodule.recurse true

Building

To build, run:

just build

IDL

To generate the progam & typescript IDLs, run:

just idl

Testing

To see whether all of the tests are passing, run:

just test-all

To drill down on a specific test (e.g., test_expired_order), run:

just test test_expired_order

If you want to have tests that automatically re-run when you edit a file, install entr and run:

just test-dev

TS Client

yarn build

TS Testing

export SOL_RPC_URL=https://a.b.c
export KEYPAIR="[1,2,3,4,...]"
yarn ts/client/src/test/market.ts
yarn ts/client/src/test/openOrders.ts

openbook-v2's People

Contributors

0xbridges avatar arrowana avatar binyebarwe avatar brittcyr avatar ckamm avatar dboures avatar farnyser avatar godmodegalactus avatar grooviegermanikus avatar kizmt avatar lou-kamades avatar metaproph3t avatar mschneider avatar ozodimgba avatar riordanp avatar silas-x avatar skrrb avatar tlrjs 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  avatar  avatar  avatar

openbook-v2's Issues

Who is GluonicLedger Ltd?

In the license file, it names an entity called 'GluonicLedger Ltd.' Who is this and what is their relationship to OpenBook?

Compiling switchboard-v2 v0.4.0 Error

When running cargo build-sbf --features enable-gpl, this error is raised when Compiling switchboard-v2 v0.4.0
Error: Function ZN86$LT$switchboard_v2..aggregator..AggregatorAccountData$u20$as$u20$core..fmt..Debug$GT$3fmt17h89cbfb284c6b84ecE Stack offset of 4128 exceeded max offset of 4096 by 32 bytes, please minimize large stack variables

How do I get my market id?

I created a market. The website gave up on the transaction and gave me an error message with the transaction id.

The transaction went through, so my 0.2 SOL are gone, but I never got a market id. Is there any way I can get the market id when all I have is a transaction id?

uncompleted operation

I have created an openbook market ID for my ANBL token and regularly paid the 0.2 SOL fee.
Unfortunately the operation was not completed by openbook even if the fee transaction was completed.
How can I recover my market ID?
Sugnature on solscan: 3dkK6WT8EtJrvM9B6PjuDUUj7q9KUgFugWYEYehUf8m4Ft4mH9itvUPrsrL6NQkHDvaZ1LoJZpps73AAXtdPAt4f
Thanks

SettleFundsExpired is broken, therefore closing markets is broken

Unfortunately it looks like @binyebarwe added the requirement for both the account owner and penalty account to sign the settle funds expired function after @skrrb originally created the function without these signers.

pub struct SettleFundsExpired<'info> {
pub close_market_admin: Signer<'info>,
#[account(mut)]
pub owner: Signer<'info>,
#[account(mut)]
pub penalty_payer: Signer<'info>,

The whole point of expired functions is to allow the close market admin to clean up a market and get it ready to close. First using the prune orders function, then settling those accounts so the market vaults are empty, and finally closing the market.

e.g. here no signature from the owner of the open orders account is needed to prune their orders because the market has expired.

pub struct PruneOrders<'info> {
pub close_market_admin: Signer<'info>,
#[account(
mut,
has_one = market
)]
pub open_orders_account: AccountLoader<'info, OpenOrdersAccount>,

Essentially this means the whole close market admin functionality is broken. Since it's not possible to close the market and retrieve sol rent back unless all the users have settled their own accounts.

Perhaps I'm missing something and it is still possible to settle accounts and close the market?

Edit: In the commit where the payer was added I can see the logic is an improvement, since the original function was assuming the close_market_admin was also the account owner, which is not a good assumption to make. But yeh, get rid of the signing requirement please.

Permissioned markets

What are they?

Permissioned markets stored a market_authority on the market data structure. Permissioned markets required all OpenOrders accounts to be owned by the Proxy program/market authority. This gave authority the ability to

A) Prune the order book (canceling orders and clearing out the book.
B) [never actually implemented on mainnet] Closing a market to reclaim the rent.
C) Require all instructions to proxy through the Proxy program for preprocessing (e.g. authorization checks)

Use cases

Permissioned markets were introduced into Serum V3 for at least 2 main reasons (there may be more, but these were the use cases I've encountered with other contributors).

  1. Ephemeral markets. A PsyFi options program can transparently implement closing DEX markets when an option expires.
  2. Authorized markets. Some markets may require identity tokens or authorization to trade on.

Possible to fetch multiple order accounts by combining memcmp filters?

I currently have some TS code like this:

const passOrders = await openbook.account.openOrdersAccount.all([
        { memcmp: { offset: 8, bytes: owner.toBase58() } },
        { memcmp: { offset: 40, bytes: proposal.account.openbookPassMarket.toBase58() } },
      ]);
      const failOrders = await openbook.account.openOrdersAccount.all([
        { memcmp: { offset: 8, bytes: owner.toBase58() } },
        { memcmp: { offset: 40, bytes: proposal.account.openbookFailMarket.toBase58() } },
      ]);
      ```
      
      but could I possibly do something like this? 
      ```
      const allOrders = await openbook.account.openOrdersAccount.all([
        { memcmp: { offset: 8, bytes: owner.toBase58() } },
        { memcmp: { offset: 40, bytes: proposal.account.openbookPassMarket.toBase58() } },
        { memcmp: { offset: 40, bytes: proposal.account.openbookFailMarket.toBase58() } },
      ]);
      ```

Abstract away details in `placeOrder`

Today, it's a bit cumbersome to specify all of the fields in PlaceOrderArgs and the other fields that placeOrder takes

It would be nice to have a placeOrder interface that looks something like:

public async placeOrder(
      market: PublicKey,
      side: Side,
      priceLots: BN,
      maxBaseLots: BN,
      maxQuoteLots: BN,
      orderType: OrderType,
      expiryTimestamp: BN = new BN(0),
      selfTradeBehavior: SelfTradeBehavior = SelfTradeBehavior.DecrementTake,
      limit: number = 255,
      userTokenAccount?: PublicKey,
      clientOrderId?: BN,
   ): Promise<BN>
  • openOrdersAccount could be set by a call .setOpenOrdersAccount() on the client
  • the MarketAccount could be pulled either from on-chain or from a cache
  • if userTokenAccount isn't provided, default could be associated token account for the user's public key
  • clientId could start at 0 and increment each time, unless explicitly specified, and be returned by the function

that way, you would only need to specify 5 params instead of 15

Using TS client import error

I am having issues building with the latest version of the TS client. (0.2.5)

./node_modules/@openbook-dex/openbook-v2/dist/esm/utils/utils.js
Attempted import error: 'Wallet' is not exported from '@coral-xyz/anchor' (imported as 'Wallet').

Has anyone seen similar issues? I am using nextjs for building. I can't seem to get this to work right now.

Update: I was able to successfully recreate the issue with a brand new nextjs app. I have linked the repo here: https://github.com/LukasDeco/test-web3

DRY out tests

Currently, there is a great deal of code redundancy in the test suite. For example, the below snippet is used in practically every test, and could be factored out to a function:

let context = TestContext::new().await;
    let solana = &context.solana.clone();

    let fee_admin = TestKeypair::new();
    let oracle_admin = TestKeypair::new();
    let owner = context.users[0].key;
    let payer = context.users[1].key;
    let mints = &context.mints[0..=2];

    let owner_token_0 = context.users[0].token_accounts[0];
    let owner_token_1 = context.users[0].token_accounts[1];

    let tokens = Token::create(mints.to_vec(), solana, fee_admin, payer).await;

    //
    // TEST: Create a market
    //

    let market = get_market_address(1);
    let base_vault = solana
        .create_associated_token_account(&market, mints[0].pubkey)
        .await;
    let quote_vault = solana
        .create_associated_token_account(&market, mints[1].pubkey)
        .await;

    let openbook_v2::accounts::CreateMarket {
        market,
        base_vault,
        quote_vault,
        ..
    } = send_tx(
        solana,
        CreateMarketInstruction {
            fee_admin: fee_admin.pubkey(),
            oracle_admin: oracle_admin.pubkey(),
            open_orders_admin: None,
            close_market_admin: None,
            payer,
            market_index: 1,
            quote_lot_size: 10,
            base_lot_size: 100,
            maker_fee: -0.0002,
            taker_fee: 0.0004,
            base_mint: mints[0].pubkey,
            quote_mint: mints[1].pubkey,
            base_vault,
            quote_vault,
            ..CreateMarketInstruction::with_new_book_and_queue(solana, &tokens[1]).await
        },
    )
    .await
    .unwrap();

Add order book pruning

Issue 33 discusses the need for an admin to be able to prune the order book for ephemeral markets. Normally, I would include this in the addressing PR, but order book pruning requires a new instruction (and corresponding tests), and this PR is already a bit plump.

Required changes:

  • new prune_order instruction (batch or 1 order at a time?)
  • new prune_order_admin field stored inside Market, checked against in the aforementioned prune_order instruction
  • corresponding tests

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.