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

Safe + whitelisting #48

Merged
merged 47 commits into from
Nov 24, 2022
Merged
Show file tree
Hide file tree
Changes from 14 commits
Commits
Show all changes
47 commits
Select commit Hold shift + click to select a range
1d6fa15
Draft of safe
porkbrain Oct 26, 2022
a301f1e
Merge branch 'beekeeping/removing-white-spaces' into feature/safe
porkbrain Oct 26, 2022
374d729
Merge branch 'main' into feature/safe
porkbrain Oct 26, 2022
290a854
Draft of a heterogenous whitelist
porkbrain Oct 26, 2022
b19d277
Exposing more logic in Safe
porkbrain Oct 26, 2022
db39e3d
Renaming entities to authorities
porkbrain Oct 26, 2022
cf68477
Adding whitelisting errs
porkbrain Oct 26, 2022
c5cb53c
Consistent code styles
porkbrain Oct 26, 2022
278fcf7
Draft of using logical owner and collection in conjunction with white…
porkbrain Oct 26, 2022
f13154b
Fixing a bug where for delisting we only rotate version but not counter
porkbrain Oct 26, 2022
321672e
Removing the store ability
porkbrain Oct 26, 2022
b31e963
Merge remote-tracking branch 'origin/main' into feature/safe
kaizu-xyz Oct 27, 2022
bf13395
Adapted code to new NFT fields
kaizu-xyz Oct 27, 2022
050912b
New Embedded NFTs Flow
kaizu-xyz Oct 27, 2022
8474527
Implementing Safe with ObjectBag
porkbrain Oct 31, 2022
b466939
Merge branch 'main' into feature/safe
porkbrain Oct 31, 2022
a20f330
Renaming rc to ref
porkbrain Oct 31, 2022
7da7133
Using witness for whitelisting which enables us to get rid of colleti…
porkbrain Oct 31, 2022
3c96939
Adding some docs about the 3 witness types
porkbrain Oct 31, 2022
81cd2f5
Renaming generic, using store with Whitelist and creating a struct in…
porkbrain Oct 31, 2022
68d403f
Asserting that tx sender is a collection creator before adding collec…
porkbrain Oct 31, 2022
6ea12b6
Using TypeName instead of String because types can always be referenced
porkbrain Nov 1, 2022
4d13a16
More granular control over what NFTs can be deposited
porkbrain Nov 1, 2022
58ccc98
Deduplicating logic for transfers
porkbrain Nov 1, 2022
0fa8fb1
Adding docs to transfer methods in Nft wrapper module
porkbrain Nov 1, 2022
3d61588
Being consistent with variable naming: target -> recipient
porkbrain Nov 1, 2022
0baa543
Adding docs and renaming some fields
porkbrain Nov 1, 2022
d1f0270
New flow for embedded NFTs
kaizu-xyz Nov 1, 2022
9c693d3
New NFT release flow
kaizu-xyz Nov 1, 2022
6b362fa
Documentation comments
kaizu-xyz Nov 2, 2022
d4b229b
Moving transfer whitelist to trading directory
porkbrain Nov 2, 2022
e0ed26b
Removing NFT ID as input because it's already included in the transfe…
porkbrain Nov 2, 2022
8e32fd9
Merging main into self
porkbrain Nov 3, 2022
f60e001
Merge remote-tracking branch 'origin/main' into feature/safe
kaizu-xyz Nov 4, 2022
50fa532
doc comments
kaizu-xyz Nov 4, 2022
9245e50
Merge remote-tracking branch 'origin/main' into nft-release-flow
kaizu-xyz Nov 4, 2022
b1e9b95
Adapt gutenberg
kaizu-xyz Nov 4, 2022
aabe973
Merge remote-tracking branch 'origin/nft-release-flow' into feature/safe
kaizu-xyz Nov 4, 2022
6ea7402
fix mint functions
kaizu-xyz Nov 4, 2022
6a4d283
Merge branch 'main' into feature/safe
porkbrain Nov 9, 2022
22cd61f
Sorting imports
porkbrain Nov 9, 2022
bdd6126
Merge branch 'main' into feature/safe
porkbrain Nov 14, 2022
d064f95
Co-authored-by: Jakub Łabor <Suficio@users.noreply.github.com>
porkbrain Nov 21, 2022
477b0b9
Fixing merge conflicts
porkbrain Nov 21, 2022
a898a27
Fixing wrong merge to main
porkbrain Nov 21, 2022
1909eda
Simplifying Whitelist by removing a generic
porkbrain Nov 21, 2022
7aa4c99
Merge remote-tracking branch 'origin/develop' into feature/safe
kaizu-xyz Nov 23, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 2 additions & 4 deletions sources/examples/suimarines.move
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ module nft_protocol::suimarines {
);
}

public entry fun mint_nft(
public entry fun mint_nft_data(
name: vector<u8>,
description: vector<u8>,
url: vector<u8>,
Expand All @@ -54,15 +54,13 @@ module nft_protocol::suimarines {
launchpad: &mut Slingshot<SUIMARINES, FixedPriceMarket>,
ctx: &mut TxContext,
) {
unique_nft::mint_regulated_nft(
unique_nft::mint_regulated_nft_data(
name,
description,
url,
attribute_keys,
attribute_values,
mint_authority,
sale_index,
launchpad,
ctx,
);
}
Expand Down
16 changes: 14 additions & 2 deletions sources/launchpad/market/fixed_price.move
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,7 @@ module nft_protocol::fixed_price {
let launchpad_id = slingshot::id(slingshot);

let receiver = slingshot::receiver(slingshot);
let collection_id = slingshot::collection_id(slingshot);
let sale = slingshot::sale_mut(slingshot, tier_index);

// Infer that sales is NOT whitelisted
Expand All @@ -179,7 +180,12 @@ module nft_protocol::fixed_price {
ctx
);

let certificate = sale::issue_nft_certificate(sale, launchpad_id, ctx);
let certificate = sale::issue_nft_certificate(
sale,
launchpad_id,
collection_id,
ctx
);

transfer::transfer(
certificate,
Expand All @@ -206,6 +212,7 @@ module nft_protocol::fixed_price {
let launchpad_id = slingshot::id(slingshot);

let receiver = slingshot::receiver(slingshot);
let collection_id = slingshot::collection_id(slingshot);
let sale = slingshot::sale_mut(slingshot, tier_index);

// Infer that sales is whitelisted
Expand Down Expand Up @@ -234,7 +241,12 @@ module nft_protocol::fixed_price {

whitelist::burn_whitelist_token(whitelist_token);

let certificate = sale::issue_nft_certificate(sale, launchpad_id, ctx);
let certificate = sale::issue_nft_certificate(
sale,
launchpad_id,
collection_id,
ctx
);

transfer::transfer(
certificate,
Expand Down
12 changes: 11 additions & 1 deletion sources/launchpad/sale.move
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ module nft_protocol::sale {
struct NftCertificate has key, store {
id: UID,
launchpad_id: ID,
collection_id: ID,
nft_id: ID,
}

Expand Down Expand Up @@ -91,13 +92,15 @@ module nft_protocol::sale {
public fun issue_nft_certificate<T, M>(
sale: &mut Sale<T, M>,
launchpad_id: ID,
collection_id: ID,
ctx: &mut TxContext,
): NftCertificate {
let nft_id = pop_nft(sale);

let certificate = NftCertificate {
id: object::new(ctx),
launchpad_id: launchpad_id,
launchpad_id,
collection_id,
nft_id: nft_id,
};

Expand All @@ -110,6 +113,7 @@ module nft_protocol::sale {
let NftCertificate {
id,
launchpad_id: _,
collection_id: _,
nft_id: _,
} = certificate;

Expand Down Expand Up @@ -176,4 +180,10 @@ module nft_protocol::sale {
): bool {
sale.whitelisted
}

public fun collection_id(
certificate: &NftCertificate,
): ID {
certificate.collection_id
}
}
36 changes: 29 additions & 7 deletions sources/launchpad/slingshot.move
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ module nft_protocol::slingshot {
use sui::object::{Self, ID , UID};
use sui::tx_context::{Self, TxContext};

use nft_protocol::nft::{Self, Nft};
use nft_protocol::nft;
use nft_protocol::err;
use nft_protocol::sale::{Self, Sale, NftCertificate};

Expand Down Expand Up @@ -126,20 +126,33 @@ module nft_protocol::slingshot {
/// of the NFT. Since the slingshot is a shared object anyone can mention it
/// in the function signature and therefore be able to mention its child
/// objects as well, the NFTs owned by it.
public entry fun claim_nft_embedded<T, M: store, D: store>(
public entry fun claim_nft_embedded<T, M: store, D: key + store>(
slingshot: &Slingshot<T, M>,
nft: Nft<T, D>,
// TODO: nft_data is a shared object, we should confirm that we can
// add it directly as a parameter since this transfers ownership to the
// function's scope
nft_data: D,
certificate: NftCertificate,
recipient: address,
ctx: &mut TxContext,
) {
assert!(
nft::id(&nft) == sale::nft_id(&certificate),
object::id(&nft_data) == sale::nft_id(&certificate),
err::certificate_does_not_correspond_to_nft_given()
);

assert!(is_embedded(slingshot), err::nft_not_embedded());

let nft = nft::mint_nft_loose<T, D>(
object::id(&nft_data),
recipient,
sale::collection_id(&certificate),
ctx,
);

sale::burn_certificate(certificate);

assert!(is_embedded(slingshot), err::nft_not_embedded());
nft::join_nft_data(&mut nft, nft_data);

transfer::transfer(
nft,
Expand Down Expand Up @@ -168,18 +181,20 @@ module nft_protocol::slingshot {
err::certificate_does_not_correspond_to_nft_given()
);

sale::burn_certificate(certificate);

assert!(!is_embedded(slingshot), err::nft_not_loose());

// We are currently not increasing the current supply of the NFT
// being minted (both collectibles and cNFT implementation have a concept
// of supply).
let nft = nft::mint_nft_loose<T, D>(
object::id(nft_data),
recipient,
sale::collection_id(&certificate),
ctx,
);

sale::burn_certificate(certificate);

transfer::transfer(
nft,
recipient,
Expand Down Expand Up @@ -228,6 +243,13 @@ module nft_protocol::slingshot {
object::uid_as_inner(&slingshot.id)
}

/// Get the Slingshot's `collection_id`
public fun collection_id<T, M>(
slingshot: &Slingshot<T, M>,
): ID {
slingshot.collection_id
}

/// Get the Slingshot's `live`
public fun live<T, M>(
slingshot: &Slingshot<T, M>,
Expand Down
74 changes: 72 additions & 2 deletions sources/nft/nft.move
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,17 @@ module nft_protocol::nft {

use sui::event;
use sui::object::{Self, UID, ID};
use sui::tx_context::{TxContext};
use sui::tx_context::{Self, TxContext};
use sui::transfer;

use nft_protocol::err;
use nft_protocol::transfer_whitelist::{Self, Whitelist};

// NFT object with an option to hold `D`ata object
struct Nft<phantom T, D: store> has key, store {
struct Nft<phantom T, D: store> has key {
id: UID,
logical_owner: address,
collection: ID,
data_id: ID,
data: Option<D>,
}
Expand All @@ -50,6 +54,8 @@ module nft_protocol::nft {
/// Create a loose `Nft` and returns it.
public fun mint_nft_loose<T, D: store>(
data_id: ID,
logical_owner: address,
collection: ID,
ctx: &mut TxContext,
): Nft<T, D> {
let nft_id = object::new(ctx);
Expand All @@ -63,6 +69,8 @@ module nft_protocol::nft {

Nft {
id: nft_id,
logical_owner,
collection,
data_id: data_id,
data: option::none(),
}
Expand All @@ -71,6 +79,8 @@ module nft_protocol::nft {
/// Create a embeded `Nft` and returns it.
public fun mint_nft_embedded<T, D: store>(
data_id: ID,
logical_owner: address,
collection: ID,
data: D,
ctx: &mut TxContext,
): Nft<T, D> {
Expand All @@ -85,6 +95,8 @@ module nft_protocol::nft {

Nft {
id: nft_id,
logical_owner,
collection,
data_id: data_id,
data: option::some(data),
}
Expand Down Expand Up @@ -121,6 +133,8 @@ module nft_protocol::nft {

let Nft {
id,
logical_owner: _,
collection: _,
data_id: _,
data,
} = nft;
Expand All @@ -144,6 +158,8 @@ module nft_protocol::nft {

let Nft {
id,
logical_owner: _,
collection: _,
data_id: _,
data,
} = nft;
Expand All @@ -159,6 +175,60 @@ module nft_protocol::nft {
option::is_none(&nft.data)
}

// === Transfer Functions ===

public fun transfer<T, D: store, W>(
nft: Nft<T, D>,
target: address,
authority: &UID,
whitelist: &Whitelist<W>,
) {
let is_ok = transfer_whitelist::can_be_transferred(
&nft.collection,
object::uid_as_inner(authority),
whitelist,
);
assert!(is_ok, err::authority_not_whitelisted());

transfer::transfer(nft, target);
}

public fun transfer_to_owner<T, D: store>(nft: Nft<T, D>) {
let logical_owner = nft.logical_owner;
transfer::transfer(nft, logical_owner);
}

public fun transfer_to_object<T, D: store, Target, W>(
nft: Nft<T, D>,
target: &mut Target,
authority: &UID,
whitelist: &Whitelist<W>,
) {
let is_ok = transfer_whitelist::can_be_transferred(
&nft.collection,
object::uid_as_inner(authority),
whitelist,
);
assert!(is_ok, err::authority_not_whitelisted());

// TODO: move to given target
abort(0);
}

public fun priviledged_transfer_to_object<T, D: store, Target>(
nft: Nft<T, D>,
target: &mut Target,
ctx: &mut TxContext,
) {
assert!(
nft.logical_owner == tx_context::sender(ctx),
err::not_nft_owner(),
);

// TODO: move to given target
abort(0);
}

// === Getter Functions ===

public fun id<T, D: store>(
Expand Down
12 changes: 9 additions & 3 deletions sources/nft/nfts/c_nft.move
Original file line number Diff line number Diff line change
Expand Up @@ -300,6 +300,8 @@ module nft_protocol::c_nft {

let nft = nft::mint_nft_loose<T, Data>(
nft_data_id(nft_data),
recipient,
nft_data.collection_id,
ctx,
);

Expand Down Expand Up @@ -360,6 +362,8 @@ module nft_protocol::c_nft {

let nft = nft::mint_nft_loose<T, Data>(
object::uid_to_inner(&combo_data.id),
recipient,
combo_data.collection_id,
ctx,
);

Expand Down Expand Up @@ -389,15 +393,15 @@ module nft_protocol::c_nft {
/// objects when we merge them, therefore we maintain consistency.
public entry fun split_c_nft<T, MetaColl: store, C: store + copy>(
nft: Nft<T, Composable<C>>,
c_nft_data: &mut Composable<C>,
combo_data: &mut Composable<C>,
nfts_data: vector<Composable<C>>,
ctx: &mut TxContext,
) {
// Assert that nft pointer corresponds to c_nft_data
// If so, then burn pointer and mint pointer for each nfts_data
assert!(nft::data_id(&nft) == id(c_nft_data), err::nft_data_mismatch());
assert!(nft::data_id(&nft) == id(combo_data), err::nft_data_mismatch());

supply::decrement_supply(&mut c_nft_data.supply, 1);
supply::decrement_supply(&mut combo_data.supply, 1);
nft::burn_loose_nft(nft);

let len = vector::length(&nfts_data);
Expand All @@ -407,6 +411,8 @@ module nft_protocol::c_nft {

let nft = nft::mint_nft_loose<T, Composable<C>>(
id(&data),
tx_context::sender(ctx),
combo_data.collection_id,
ctx,
);

Expand Down
2 changes: 2 additions & 0 deletions sources/nft/nfts/collectible.move
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,8 @@ module nft_protocol::collectible {

let nft = nft::mint_nft_loose<T, Collectible>(
nft_data_id(nft_data),
recipient,
nft_data.collection_id,
ctx,
);

Expand Down
Loading