diff --git a/contracts/liquidity_layer_v1/Move.toml b/contracts/liquidity_layer_v1/Move.toml index c5e34ea0..44d01f97 100644 --- a/contracts/liquidity_layer_v1/Move.toml +++ b/contracts/liquidity_layer_v1/Move.toml @@ -32,5 +32,8 @@ local = "./../kiosk" [dependencies.Utils] local = "./../utils" +[dependencies.LiquidityLayer] +local = "./../liquidity_layer" + [addresses] liquidity_layer_v1 = "0x4e0629fa51a62b0c1d7c7b9fc89237ec5b6f630d7798ad3f06d820afb93a995a" diff --git a/contracts/liquidity_layer_v1/sources/trading/orderbook.move b/contracts/liquidity_layer_v1/sources/trading/orderbook.move index aae85efd..5b45d15b 100644 --- a/contracts/liquidity_layer_v1/sources/trading/orderbook.move +++ b/contracts/liquidity_layer_v1/sources/trading/orderbook.move @@ -50,9 +50,8 @@ module liquidity_layer_v1::orderbook { use liquidity_layer_v1::trading; use liquidity_layer_v1::liquidity_layer::LIQUIDITY_LAYER; - // TODO: Add back migration endpoints - // use liquidity_layer::orderbook::{Self as orderbook_v2, Orderbook as OrderbookV2}; - // use liquidity_layer::trading as trading_v2; + use liquidity_layer::orderbook::{Self as orderbook_v2, Orderbook as OrderbookV2}; + use liquidity_layer::trading as trading_v2; // Track the current version of the module const VERSION: u64 = 3; @@ -1907,145 +1906,140 @@ module liquidity_layer_v1::orderbook { df::add(&mut book.id, IsDeprecatedDfKey {}, true); } - // TODO: Add back migration endpoints - // public fun start_migration_to_v2( - // witness: DelegatedWitness, - // book_v1: &mut Orderbook, - // book_v2: &OrderbookV2, - // ) { - // set_protection(witness, book_v1, custom_protection(true, true, true)); - // df::add(&mut book_v1.id, UnderMigrationToDfKey {}, object::id(book_v2)); - // } - - // TODO: Add back migration endpoints - // public fun migrate_bid( - // witness: DelegatedWitness, - // book_v1: &mut Orderbook, - // book_v2: &mut OrderbookV2, - // ctx: &mut TxContext - // ) { - // assert_orderbook_v2(book_v1, book_v2); - - // let (buyer, bid_offer, buyer_kiosk_id, bid_commission_v1) = migrate_bid_( - // witness, book_v1 - // ); - - // let bid_commission_v2 = option::none(); - - // if (option::is_some(&bid_commission_v1)) { - // let (commission, bid_beneficiary) = trading::destroy_bid_commission( - // option::extract(&mut bid_commission_v1) - // ); - - // option::fill(&mut bid_commission_v2, trading_v2::new_bid_commission(bid_beneficiary, commission)); - // }; - - // option::destroy_none(bid_commission_v1); - // let price = balance::value(&bid_offer); - - // let wallet = coin::from_balance(bid_offer, ctx); - - // orderbook_v2::migrate_bid_v1( - // book_v2, - // buyer_kiosk_id, - // price, - // bid_commission_v2, - // &mut wallet, - // buyer, - // &book_v1.id, - // ); - - // coin::destroy_zero(wallet); - // } - - // TODO: Add back migration endpoints - // fun migrate_bid_( - // _witness: DelegatedWitness, - // book: &mut Orderbook, - // ): (address, Balance, ID, Option>) { - // let price = crit_bit::min_key(&book.bids); - // let price_level = crit_bit::borrow_mut(&mut book.bids, price); - // let bid = vector::pop_back(price_level); - - // if (vector::length(price_level) == 0) { - // vector::destroy_empty(crit_bit::pop(&mut book.bids, price)); - // }; - - // let Bid { - // owner: buyer, - // offer: bid_offer, - // kiosk: buyer_kiosk_id, - // commission: bid_commission, - // } = bid; - - // (buyer, bid_offer, buyer_kiosk_id, bid_commission) - // } - - // TODO: Add back migration endpoints - // public fun migrate_ask( - // witness: DelegatedWitness, - // seller_kiosk: &mut Kiosk, - // book_v1: &mut Orderbook, - // book_v2: &mut OrderbookV2, - // ) { - // assert_orderbook_v2(book_v1, book_v2); - - // let (price, seller, nft_id, kiosk_id, ask_commission_v1) = migrate_ask_( - // witness, seller_kiosk, book_v1, - // ); - - // assert!(object::id(seller_kiosk) == kiosk_id, EKioskIdMismatch); - - // let ask_commission_v2 = option::none(); - - // if (option::is_some(&ask_commission_v1)) { - // let (commission, bid_beneficiary) = trading::destroy_ask_commission( - // option::extract(&mut ask_commission_v1) - // ); - - // option::fill(&mut ask_commission_v2, trading_v2::new_ask_commission(bid_beneficiary, commission)); - // }; - - // option::destroy_none(ask_commission_v1); - - // orderbook_v2::migrate_ask_v1( - // book_v2, - // seller_kiosk, - // price, - // ask_commission_v2, - // nft_id, - // seller, - // &book_v1.id - // ); - // } - - // TODO: Add back migration endpoints - // fun migrate_ask_( - // _witness: DelegatedWitness, - // kiosk: &mut Kiosk, - // book: &mut Orderbook, - // ): (u64, address, ID, ID, Option) { - // let price = crit_bit::max_key(&book.asks); - - // let price_level = crit_bit::borrow_mut(&mut book.asks, price); - // let ask = vector::pop_back(price_level); - - // if (vector::length(price_level) == 0) { - // vector::destroy_empty(crit_bit::pop(&mut book.asks, price)); - // }; - - // ob_kiosk::assert_has_nft(kiosk, ask.nft_id); - - // let Ask { - // price, - // owner: seller, - // nft_id, - // kiosk_id, - // commission: ask_commission, - // } = ask; - - // (price, seller, nft_id, kiosk_id, ask_commission) - // } + public fun start_migration_to_v2( + witness: DelegatedWitness, + book_v1: &mut Orderbook, + book_v2: &OrderbookV2, + ) { + set_protection(witness, book_v1, custom_protection(true, true, true)); + df::add(&mut book_v1.id, UnderMigrationToDfKey {}, object::id(book_v2)); + } + + public fun migrate_bid( + witness: DelegatedWitness, + book_v1: &mut Orderbook, + book_v2: &mut OrderbookV2, + ctx: &mut TxContext + ) { + assert_orderbook_v2(book_v1, book_v2); + + let (buyer, bid_offer, buyer_kiosk_id, bid_commission_v1) = migrate_bid_( + witness, book_v1 + ); + + let bid_commission_v2 = option::none(); + + if (option::is_some(&bid_commission_v1)) { + let (commission, bid_beneficiary) = trading::destroy_bid_commission( + option::extract(&mut bid_commission_v1) + ); + + option::fill(&mut bid_commission_v2, trading_v2::new_bid_commission(bid_beneficiary, commission)); + }; + + option::destroy_none(bid_commission_v1); + let price = balance::value(&bid_offer); + + let wallet = coin::from_balance(bid_offer, ctx); + + orderbook_v2::migrate_bid_v1( + book_v2, + buyer_kiosk_id, + price, + bid_commission_v2, + &mut wallet, + buyer, + &book_v1.id, + ); + + coin::destroy_zero(wallet); + } + + fun migrate_bid_( + _witness: DelegatedWitness, + book: &mut Orderbook, + ): (address, Balance, ID, Option>) { + let price = crit_bit::min_key(&book.bids); + let price_level = crit_bit::borrow_mut(&mut book.bids, price); + let bid = vector::pop_back(price_level); + + if (vector::length(price_level) == 0) { + vector::destroy_empty(crit_bit::pop(&mut book.bids, price)); + }; + + let Bid { + owner: buyer, + offer: bid_offer, + kiosk: buyer_kiosk_id, + commission: bid_commission, + } = bid; + + (buyer, bid_offer, buyer_kiosk_id, bid_commission) + } + + public fun migrate_ask( + witness: DelegatedWitness, + seller_kiosk: &mut Kiosk, + book_v1: &mut Orderbook, + book_v2: &mut OrderbookV2, + ) { + assert_orderbook_v2(book_v1, book_v2); + + let (price, seller, nft_id, kiosk_id, ask_commission_v1) = migrate_ask_( + witness, seller_kiosk, book_v1, + ); + + assert!(object::id(seller_kiosk) == kiosk_id, EKioskIdMismatch); + + let ask_commission_v2 = option::none(); + + if (option::is_some(&ask_commission_v1)) { + let (commission, bid_beneficiary) = trading::destroy_ask_commission( + option::extract(&mut ask_commission_v1) + ); + + option::fill(&mut ask_commission_v2, trading_v2::new_ask_commission(bid_beneficiary, commission)); + }; + + option::destroy_none(ask_commission_v1); + + orderbook_v2::migrate_ask_v1( + book_v2, + seller_kiosk, + price, + ask_commission_v2, + nft_id, + seller, + &book_v1.id + ); + } + + fun migrate_ask_( + _witness: DelegatedWitness, + kiosk: &mut Kiosk, + book: &mut Orderbook, + ): (u64, address, ID, ID, Option) { + let price = crit_bit::max_key(&book.asks); + + let price_level = crit_bit::borrow_mut(&mut book.asks, price); + let ask = vector::pop_back(price_level); + + if (vector::length(price_level) == 0) { + vector::destroy_empty(crit_bit::pop(&mut book.asks, price)); + }; + + ob_kiosk::assert_has_nft(kiosk, ask.nft_id); + + let Ask { + price, + owner: seller, + nft_id, + kiosk_id, + commission: ask_commission, + } = ask; + + (price, seller, nft_id, kiosk_id, ask_commission) + } fun assert_under_migration(self: &Orderbook) { assert!(df::exists_(&self.id, UnderMigrationToDfKey {}), ENotUnderMigration); @@ -2055,11 +2049,10 @@ module liquidity_layer_v1::orderbook { assert!(!df::exists_(&self.id, UnderMigrationToDfKey {}), EUnderMigration); } - // TODO: Add back migration endpoints - // fun assert_orderbook_v2(book_v1: &Orderbook, book_v2: &OrderbookV2) { - // let book_v2_id = df::borrow(&book_v1.id, UnderMigrationToDfKey {}); - // assert!(object::id(book_v2) == *book_v2_id, EIncorrectOrderbookV2); - // } + fun assert_orderbook_v2(book_v1: &Orderbook, book_v2: &OrderbookV2) { + let book_v2_id = df::borrow(&book_v1.id, UnderMigrationToDfKey {}); + assert!(object::id(book_v2) == *book_v2_id, EIncorrectOrderbookV2); + } // === Upgradeability === diff --git a/contracts/tests/tests/liquidity_layer_v1/orderbook/migration.move b/contracts/tests/tests/liquidity_layer_v1/orderbook/migration.move index 4881cfb3..fd30c395 100644 --- a/contracts/tests/tests/liquidity_layer_v1/orderbook/migration.move +++ b/contracts/tests/tests/liquidity_layer_v1/orderbook/migration.move @@ -1,301 +1,300 @@ -// TODO: Add back migration endpoints -// #[test_only] -// module ob_tests::orderbook_migration { -// use std::vector; - -// use sui::coin; -// use sui::object; -// use sui::transfer; -// use sui::sui::SUI; -// use sui::kiosk::Kiosk; -// use sui::test_scenario::{Self, ctx}; -// use sui::transfer_policy::{TransferPolicy}; - -// use ob_permissions::witness; -// use critbit::critbit_u64::{Self as critbit}; -// use ob_kiosk::ob_kiosk::{Self}; -// use ob_tests::test_utils::{Self, Foo, seller, buyer, creator}; -// use originmate::crit_bit_u64::{Self as crit_bit}; -// use liquidity_layer::orderbook::{Self as orderbook_v2, Orderbook as OrderbookV2}; -// use liquidity_layer_v1::orderbook::{Self as orderbook_v1, Orderbook as OrderbookV1}; - -// const OFFER_SUI: u64 = 100; - -// #[test] -// fun test_migrate_asks() { -// let scenario = test_scenario::begin(creator()); - -// // 1. Create Collection, TransferPolicy and Orderbook -// let (collection, mint_cap) = test_utils::init_collection_foo(ctx(&mut scenario)); -// let publisher = test_utils::get_publisher(ctx(&mut scenario)); -// let (tx_policy, policy_cap) = test_utils::init_transfer_policy(&publisher, ctx(&mut scenario)); - -// let dw = witness::test_dw(); -// test_utils::create_orderbook_v1(dw, &tx_policy, &mut scenario); - -// transfer::public_share_object(collection); -// transfer::public_share_object(tx_policy); - -// let quantity = 100; -// let i = quantity; -// let price = 1; -// let depth = 10; -// let j = 0; - -// // 4. Create seller kiosks, NFTs and asks order -// test_scenario::next_tx(&mut scenario, seller()); -// let book_v1 = test_scenario::take_shared>(&mut scenario); - -// let kiosks = vector::empty(); +#[test_only] +module ob_tests::orderbook_migration { + use std::vector; + + use sui::coin; + use sui::object; + use sui::transfer; + use sui::sui::SUI; + use sui::kiosk::Kiosk; + use sui::test_scenario::{Self, ctx}; + use sui::transfer_policy::{TransferPolicy}; + + use ob_permissions::witness; + use critbit::critbit_u64::{Self as critbit}; + use ob_kiosk::ob_kiosk::{Self}; + use ob_tests::test_utils::{Self, Foo, seller, buyer, creator}; + use originmate::crit_bit_u64::{Self as crit_bit}; + use liquidity_layer::orderbook::{Self as orderbook_v2, Orderbook as OrderbookV2}; + use liquidity_layer_v1::orderbook::{Self as orderbook_v1, Orderbook as OrderbookV1}; + + const OFFER_SUI: u64 = 100; + + #[test] + fun test_migrate_asks() { + let scenario = test_scenario::begin(creator()); + + // 1. Create Collection, TransferPolicy and Orderbook + let (collection, mint_cap) = test_utils::init_collection_foo(ctx(&mut scenario)); + let publisher = test_utils::get_publisher(ctx(&mut scenario)); + let (tx_policy, policy_cap) = test_utils::init_transfer_policy(&publisher, ctx(&mut scenario)); + + let dw = witness::test_dw(); + test_utils::create_orderbook_v1(dw, &tx_policy, &mut scenario); + + transfer::public_share_object(collection); + transfer::public_share_object(tx_policy); + + let quantity = 100; + let i = quantity; + let price = 1; + let depth = 10; + let j = 0; + + // 4. Create seller kiosks, NFTs and asks order + test_scenario::next_tx(&mut scenario, seller()); + let book_v1 = test_scenario::take_shared>(&mut scenario); -// let price_levels = 1; -// while (i > 0) { -// test_scenario::next_tx(&mut scenario, seller()); + let kiosks = vector::empty(); -// // create kiosk -// let (seller_kiosk, _) = ob_kiosk::new(ctx(&mut scenario)); + let price_levels = 1; + while (i > 0) { + test_scenario::next_tx(&mut scenario, seller()); -// // Create and deposit NFT -// let nft = test_utils::get_foo_nft(ctx(&mut scenario)); -// let nft_id = object::id(&nft); -// ob_kiosk::deposit(&mut seller_kiosk, nft, ctx(&mut scenario)); + // create kiosk + let (seller_kiosk, _) = ob_kiosk::new(ctx(&mut scenario)); -// orderbook_v1::create_ask( -// &mut book_v1, -// &mut seller_kiosk, -// price, -// nft_id, -// ctx(&mut scenario), -// ); - -// j = j + 1; - -// // Assersions -// // 1. NFT is exclusively listed in the Seller Kiosk -// ob_kiosk::assert_exclusively_listed(&mut seller_kiosk, nft_id); - -// vector::push_back(&mut kiosks, seller_kiosk); - -// // Assert price level -// assert!(crit_bit::length(orderbook_v1::borrow_asks(&book_v1)) == price_levels, 0); - -// // 2. New price level gets added -// if (j == depth) { -// price_levels = price_levels + 1; -// price = price + 1; -// j = 0; -// }; - -// i = i - 1; -// }; + // Create and deposit NFT + let nft = test_utils::get_foo_nft(ctx(&mut scenario)); + let nft_id = object::id(&nft); + ob_kiosk::deposit(&mut seller_kiosk, nft, ctx(&mut scenario)); -// test_scenario::next_tx(&mut scenario, creator()); - -// let i = quantity; -// let j = 0; -// let price_levels = depth; -// let price_levels_new = 1; - -// let dw = witness::from_witness(test_utils::witness()); -// let tx_policy = test_scenario::take_shared>(&mut scenario); - -// let book_v2 = orderbook_v2::new_unprotected( -// dw, -// &mut tx_policy, -// false, -// ctx(&mut scenario), -// ); - -// orderbook_v1::start_migration_to_v2(dw, &mut book_v1, &book_v2); -// orderbook_v2::start_migration_from_v1(dw, &mut book_v2, object::id(&book_v1)); - -// transfer::public_share_object(book_v2); -// test_scenario::next_tx(&mut scenario, creator()); -// let book_v2 = test_scenario::take_shared>(&mut scenario); - -// // 6. Migrate asks -// while (i > 0) { -// test_scenario::next_tx(&mut scenario, seller()); + orderbook_v1::create_ask( + &mut book_v1, + &mut seller_kiosk, + price, + nft_id, + ctx(&mut scenario), + ); + + j = j + 1; + + // Assersions + // 1. NFT is exclusively listed in the Seller Kiosk + ob_kiosk::assert_exclusively_listed(&mut seller_kiosk, nft_id); + + vector::push_back(&mut kiosks, seller_kiosk); + + // Assert price level + assert!(crit_bit::length(orderbook_v1::borrow_asks(&book_v1)) == price_levels, 0); + + // 2. New price level gets added + if (j == depth) { + price_levels = price_levels + 1; + price = price + 1; + j = 0; + }; -// let seller_kiosk = vector::pop_back(&mut kiosks); + i = i - 1; + }; -// orderbook_v1::migrate_ask( -// dw, -// &mut seller_kiosk, -// &mut book_v1, -// &mut book_v2, -// ); - -// // Note: for simplicity in the test we transfer the object, but -// // in practice this object should be shared -// transfer::public_transfer(seller_kiosk, seller()); + test_scenario::next_tx(&mut scenario, creator()); + + let i = quantity; + let j = 0; + let price_levels = depth; + let price_levels_new = 1; + + let dw = witness::from_witness(test_utils::witness()); + let tx_policy = test_scenario::take_shared>(&mut scenario); + + let book_v2 = orderbook_v2::new_unprotected( + dw, + &mut tx_policy, + false, + ctx(&mut scenario), + ); + + orderbook_v1::start_migration_to_v2(dw, &mut book_v1, &book_v2); + orderbook_v2::start_migration_from_v1(dw, &mut book_v2, object::id(&book_v1)); + + transfer::public_share_object(book_v2); + test_scenario::next_tx(&mut scenario, creator()); + let book_v2 = test_scenario::take_shared>(&mut scenario); + + // 6. Migrate asks + while (i > 0) { + test_scenario::next_tx(&mut scenario, seller()); -// j = j + 1; + let seller_kiosk = vector::pop_back(&mut kiosks); -// assert!(critbit::size(orderbook_v2::borrow_asks(&book_v2)) == price_levels_new, 0); + orderbook_v1::migrate_ask( + dw, + &mut seller_kiosk, + &mut book_v1, + &mut book_v2, + ); + + // Note: for simplicity in the test we transfer the object, but + // in practice this object should be shared + transfer::public_transfer(seller_kiosk, seller()); -// // 2. New price level gets added -// if (j == depth) { -// price_levels_new = price_levels_new + 1; -// price_levels = price_levels - 1; -// j = 0; -// }; + j = j + 1; -// assert!(crit_bit::length(orderbook_v1::borrow_asks(&book_v1)) == price_levels, 0); - -// i = i - 1; -// }; + assert!(critbit::size(orderbook_v2::borrow_asks(&book_v2)) == price_levels_new, 0); -// vector::destroy_empty(kiosks); + // 2. New price level gets added + if (j == depth) { + price_levels_new = price_levels_new + 1; + price_levels = price_levels - 1; + j = 0; + }; -// // Assert that orderbook is empty -// assert!(crit_bit::is_empty(orderbook_v1::borrow_bids(&book_v1)), 0); -// assert!(crit_bit::is_empty(orderbook_v1::borrow_asks(&book_v1)), 0); + assert!(crit_bit::length(orderbook_v1::borrow_asks(&book_v1)) == price_levels, 0); + + i = i - 1; + }; -// assert!(critbit::size(orderbook_v2::borrow_bids(&book_v2)) == 0, 0); -// assert!(critbit::size(orderbook_v2::borrow_asks(&book_v2)) == 10, 0); + vector::destroy_empty(kiosks); -// orderbook_v2::finish_migration_from_v1(dw, &mut book_v2); -// orderbook_v1::finish_migration_to_v2(dw, &mut book_v1); - -// transfer::public_transfer(publisher, creator()); -// transfer::public_transfer(mint_cap, creator()); -// transfer::public_transfer(policy_cap, creator()); -// test_scenario::return_shared(tx_policy); -// test_scenario::return_shared(book_v1); -// test_scenario::return_shared(book_v2); -// test_scenario::end(scenario); -// } + // Assert that orderbook is empty + assert!(crit_bit::is_empty(orderbook_v1::borrow_bids(&book_v1)), 0); + assert!(crit_bit::is_empty(orderbook_v1::borrow_asks(&book_v1)), 0); -// #[test] -// fun test_migrate_bids() { -// let scenario = test_scenario::begin(creator()); - -// // 1. Create Collection, TransferPolicy and Orderbook -// let (collection, mint_cap) = test_utils::init_collection_foo(ctx(&mut scenario)); -// let publisher = test_utils::get_publisher(ctx(&mut scenario)); -// let (tx_policy, policy_cap) = test_utils::init_transfer_policy(&publisher, ctx(&mut scenario)); + assert!(critbit::size(orderbook_v2::borrow_bids(&book_v2)) == 0, 0); + assert!(critbit::size(orderbook_v2::borrow_asks(&book_v2)) == 10, 0); -// let dw = witness::test_dw(); -// test_utils::create_orderbook_v1(dw, &tx_policy, &mut scenario); + orderbook_v2::finish_migration_from_v1(dw, &mut book_v2); + orderbook_v1::finish_migration_to_v2(dw, &mut book_v1); + + transfer::public_transfer(publisher, creator()); + transfer::public_transfer(mint_cap, creator()); + transfer::public_transfer(policy_cap, creator()); + test_scenario::return_shared(tx_policy); + test_scenario::return_shared(book_v1); + test_scenario::return_shared(book_v2); + test_scenario::end(scenario); + } -// transfer::public_share_object(collection); -// transfer::public_share_object(tx_policy); + #[test] + fun test_migrate_bids() { + let scenario = test_scenario::begin(creator()); + + // 1. Create Collection, TransferPolicy and Orderbook + let (collection, mint_cap) = test_utils::init_collection_foo(ctx(&mut scenario)); + let publisher = test_utils::get_publisher(ctx(&mut scenario)); + let (tx_policy, policy_cap) = test_utils::init_transfer_policy(&publisher, ctx(&mut scenario)); -// // 3. Create Buyer Kiosk -// test_scenario::next_tx(&mut scenario, buyer()); -// let (buyer_kiosk, _) = ob_kiosk::new(ctx(&mut scenario)); + let dw = witness::test_dw(); + test_utils::create_orderbook_v1(dw, &tx_policy, &mut scenario); -// transfer::public_share_object(buyer_kiosk); + transfer::public_share_object(collection); + transfer::public_share_object(tx_policy); -// let quantity = 100; -// let i = quantity; -// let price = 1; -// let depth = 10; -// let j = 0; - -// // 4. Create bid orders -// test_scenario::next_tx(&mut scenario, seller()); -// let buyer_kiosk = test_scenario::take_shared(&mut scenario); -// let book_v1 = test_scenario::take_shared>(&mut scenario); -// let wallet = coin::mint_for_testing(1_000_000, ctx(&mut scenario)); - -// let price_levels = 1; -// while (i > 0) { -// test_scenario::next_tx(&mut scenario, buyer()); - -// orderbook_v1::create_bid( -// &mut book_v1, -// &mut buyer_kiosk, -// price, -// &mut wallet, -// ctx(&mut scenario), -// ); - -// j = j + 1; - -// // Assert price level -// assert!(crit_bit::length(orderbook_v1::borrow_bids(&book_v1)) == price_levels, 0); - -// // 2. New price level gets added -// if (j == depth) { -// price_levels = price_levels + 1; -// price = price + 1; -// j = 0; -// }; - -// i = i - 1; -// }; - -// test_scenario::next_tx(&mut scenario, creator()); - -// let i = quantity; -// let j = 0; -// let price_levels = depth; -// let price_levels_new = 1; - -// let dw = witness::from_witness(test_utils::witness()); -// let tx_policy = test_scenario::take_shared>(&mut scenario); - -// let book_v2 = orderbook_v2::new_unprotected( -// dw, -// &mut tx_policy, -// false, -// ctx(&mut scenario), -// ); - -// orderbook_v1::start_migration_to_v2(dw, &mut book_v1, &book_v2); -// orderbook_v2::start_migration_from_v1(dw, &mut book_v2, object::id(&book_v1)); - -// transfer::public_share_object(book_v2); -// test_scenario::next_tx(&mut scenario, creator()); -// let book_v2 = test_scenario::take_shared>(&mut scenario); - -// // 6. Migrate asks -// while (i > 0) { -// test_scenario::next_tx(&mut scenario, seller()); - -// orderbook_v1::migrate_bid( -// dw, -// &mut book_v1, -// &mut book_v2, -// ctx(&mut scenario), -// ); - -// j = j + 1; - -// assert!(critbit::size(orderbook_v2::borrow_bids(&book_v2)) == price_levels_new, 0); - -// // 2. New price level gets added -// if (j == depth) { -// price_levels_new = price_levels_new + 1; -// price_levels = price_levels - 1; -// j = 0; -// }; - -// assert!(crit_bit::length(orderbook_v1::borrow_bids(&book_v1)) == price_levels, 0); - -// i = i - 1; -// }; - -// // Assert that orderbook is empty -// assert!(crit_bit::is_empty(orderbook_v1::borrow_asks(&book_v1)), 0); -// assert!(crit_bit::is_empty(orderbook_v1::borrow_bids(&book_v1)), 0); - -// assert!(critbit::size(orderbook_v2::borrow_asks(&book_v2)) == 0, 0); -// assert!(critbit::size(orderbook_v2::borrow_bids(&book_v2)) == 10, 0); - -// orderbook_v2::finish_migration_from_v1(dw, &mut book_v2); -// orderbook_v1::finish_migration_to_v2(dw, &mut book_v1); - -// transfer::public_transfer(publisher, creator()); -// transfer::public_transfer(mint_cap, creator()); -// transfer::public_transfer(policy_cap, creator()); -// transfer::public_transfer(wallet, buyer()); -// test_scenario::return_shared(tx_policy); -// test_scenario::return_shared(book_v1); -// test_scenario::return_shared(book_v2); -// test_scenario::return_shared(buyer_kiosk); -// test_scenario::end(scenario); -// } -// } + // 3. Create Buyer Kiosk + test_scenario::next_tx(&mut scenario, buyer()); + let (buyer_kiosk, _) = ob_kiosk::new(ctx(&mut scenario)); + + transfer::public_share_object(buyer_kiosk); + + let quantity = 100; + let i = quantity; + let price = 1; + let depth = 10; + let j = 0; + + // 4. Create bid orders + test_scenario::next_tx(&mut scenario, seller()); + let buyer_kiosk = test_scenario::take_shared(&mut scenario); + let book_v1 = test_scenario::take_shared>(&mut scenario); + let wallet = coin::mint_for_testing(1_000_000, ctx(&mut scenario)); + + let price_levels = 1; + while (i > 0) { + test_scenario::next_tx(&mut scenario, buyer()); + + orderbook_v1::create_bid( + &mut book_v1, + &mut buyer_kiosk, + price, + &mut wallet, + ctx(&mut scenario), + ); + + j = j + 1; + + // Assert price level + assert!(crit_bit::length(orderbook_v1::borrow_bids(&book_v1)) == price_levels, 0); + + // 2. New price level gets added + if (j == depth) { + price_levels = price_levels + 1; + price = price + 1; + j = 0; + }; + + i = i - 1; + }; + + test_scenario::next_tx(&mut scenario, creator()); + + let i = quantity; + let j = 0; + let price_levels = depth; + let price_levels_new = 1; + + let dw = witness::from_witness(test_utils::witness()); + let tx_policy = test_scenario::take_shared>(&mut scenario); + + let book_v2 = orderbook_v2::new_unprotected( + dw, + &mut tx_policy, + false, + ctx(&mut scenario), + ); + + orderbook_v1::start_migration_to_v2(dw, &mut book_v1, &book_v2); + orderbook_v2::start_migration_from_v1(dw, &mut book_v2, object::id(&book_v1)); + + transfer::public_share_object(book_v2); + test_scenario::next_tx(&mut scenario, creator()); + let book_v2 = test_scenario::take_shared>(&mut scenario); + + // 6. Migrate asks + while (i > 0) { + test_scenario::next_tx(&mut scenario, seller()); + + orderbook_v1::migrate_bid( + dw, + &mut book_v1, + &mut book_v2, + ctx(&mut scenario), + ); + + j = j + 1; + + assert!(critbit::size(orderbook_v2::borrow_bids(&book_v2)) == price_levels_new, 0); + + // 2. New price level gets added + if (j == depth) { + price_levels_new = price_levels_new + 1; + price_levels = price_levels - 1; + j = 0; + }; + + assert!(crit_bit::length(orderbook_v1::borrow_bids(&book_v1)) == price_levels, 0); + + i = i - 1; + }; + + // Assert that orderbook is empty + assert!(crit_bit::is_empty(orderbook_v1::borrow_asks(&book_v1)), 0); + assert!(crit_bit::is_empty(orderbook_v1::borrow_bids(&book_v1)), 0); + + assert!(critbit::size(orderbook_v2::borrow_asks(&book_v2)) == 0, 0); + assert!(critbit::size(orderbook_v2::borrow_bids(&book_v2)) == 10, 0); + + orderbook_v2::finish_migration_from_v1(dw, &mut book_v2); + orderbook_v1::finish_migration_to_v2(dw, &mut book_v1); + + transfer::public_transfer(publisher, creator()); + transfer::public_transfer(mint_cap, creator()); + transfer::public_transfer(policy_cap, creator()); + transfer::public_transfer(wallet, buyer()); + test_scenario::return_shared(tx_policy); + test_scenario::return_shared(book_v1); + test_scenario::return_shared(book_v2); + test_scenario::return_shared(buyer_kiosk); + test_scenario::end(scenario); + } +}