Hic Et Nunc community marketplace smart contract

Development

GUI

Initializing the contract

def __init__(self, manager, metadata, allowed_fa2s, fee):
self.init(
manager=manager,
metadata=metadata,
allowed_fa2s=allowed_fa2s,
swaps=sp.big_map(),
fee=fee,
fee_recipient=manager,
counter=0,
proposed_manager=sp.none,
swaps_paused=False,
collects_paused=False)

Utility methods

Swapping

@sp.entry_point
def swap(self, params):
# Define the input parameter data type
sp.set_type(params, sp.TRecord(
fa2=sp.TAddress,
objkt_id=sp.TNat,
objkt_amount=sp.TNat,
xtz_per_objkt=sp.TMutez,
royalties=sp.TNat,
creator=sp.TAddress).layout(
("fa2", ("objkt_id", ("objkt_amount", ("xtz_per_objkt", ("royalties", "creator")))))))

# Check that swaps are not paused
sp.verify(~self.data.swaps_paused, message="Swaps are paused")

# Check that no tez have been transferred
self.check_no_tez_transfer()

# Check that the token is one of the allowed tokens to trade
sp.verify(self.data.allowed_fa2s.get(params.fa2, default_value=False),
message="This token type cannot be traded")

# Check that at least one edition will be swapped
sp.verify(params.objkt_amount > 0,
message="At least one edition needs to be swapped")

# Check that the royalties are within the expected limits
sp.verify(params.royalties <= 250,
message="The royalties cannot be higher than 25%")

# Transfer all the editions to the marketplace account
self.fa2_transfer(
fa2=params.fa2,
from_=sp.sender,
to_=sp.self_address,
token_id=params.objkt_id,
token_amount=params.objkt_amount)

# Update the swaps bigmap with the new swap information
self.data.swaps[self.data.counter] = sp.record(
issuer=sp.sender,
fa2=params.fa2,
objkt_id=params.objkt_id,
objkt_amount=params.objkt_amount,
xtz_per_objkt=params.xtz_per_objkt,
royalties=params.royalties,
creator=params.creator)

# Increase the swaps counter
self.data.counter += 1

Collecting

@sp.entry_point
def collect(self, swap_id):
# Define the input parameter data type
sp.set_type(swap_id, sp.TNat)

# Check that collects are not paused
sp.verify(~self.data.collects_paused, message="Collects are
paused")

# Check that the swap id is present in the swaps big map
sp.verify(self.data.swaps.contains(swap_id),
message="The provided swap_id doesn't exist")

# Check that the collector is not the creator of the swap
swap = self.data.swaps[swap_id]
sp.verify(sp.sender != swap.issuer,
message="The collector cannot be the swap issuer")

# Check that the provided tez amount is exactly the edition price
sp.verify(sp.amount == swap.xtz_per_objkt,
message="The sent tez amount does not coincide with the
edition price")

# Check that there is at least one edition available to collect
sp.verify(swap.objkt_amount > 0,
message="All editions have already been collected")

# Handle tez tranfers if the edition price is not zero
sp.if swap.xtz_per_objkt != sp.tez(0):
# Send the royalties to the NFT creator
royalties_amount = sp.local(
"royalties_amount", sp.split_tokens(swap.xtz_per_objkt,
swap.royalties, 1000))

sp.if royalties_amount.value > sp.mutez(0):
sp.send(swap.creator, royalties_amount.value)

# Send the management fees
fee_amount = sp.local(
"fee_amount", sp.split_tokens(swap.xtz_per_objkt,
self.data.fee, 1000))

sp.if fee_amount.value > sp.mutez(0):
sp.send(self.data.fee_recipient, fee_amount.value)

# Send what is left to the swap issuer
sp.send(swap.issuer, sp.amount - royalties_amount.value -
fee_amount.value)

# Transfer the token edition to the collector
self.fa2_transfer(
fa2=swap.fa2,
from_=sp.self_address,
to_=sp.sender,
token_id=swap.objkt_id,
token_amount=1)

# Update the number of editions available in the swaps big map
swap.objkt_amount = sp.as_nat(swap.objkt_amount - 1

Canceling

@sp.entry_point
def cancel_swap(self, swap_id):
# Define the input parameter data type
sp.set_type(swap_id, sp.TNat)

# Check that no tez have been transferred
self.check_no_tez_transfer()

# Check that the swap id is present in the swaps big map
sp.verify(self.data.swaps.contains(swap_id),
message="The provided swap_id doesn't exist")

# Check that the swap issuer is cancelling the swap
swap = self.data.swaps[swap_id]
sp.verify(sp.sender == swap.issuer,
message="Only the swap issuer can cancel the swap")

# Check that there is at least one swapped edition
sp.verify(swap.objkt_amount > 0,
message="All editions have been collected")

# Transfer the remaining token editions back to the owner
self.fa2_transfer(
fa2=swap.fa2,
from_=sp.self_address,
to_=sp.sender,
token_id=swap.objkt_id,
token_amount=swap.objkt_amount)

# Delete the swap entry in the swaps big map
del self.data.swaps[swap_id]

Management

Views

Next steps

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store