# Algorand ARC4 Contracts

### Algorand ARC4 Smart Contract Functions for diSed Marketplace

Here is a technical documentation for the Algorand ARC4 smart contract functions you plan to use in your diSed marketplace:

## VISION - No. of Product Interaction on diSed = No. of onchain activity on Algorand

### List an Asset on Sale

To list an asset for sale on the diSed marketplace, the smart contract should have the following functionality:

1. `make_sell_offer(sell_price)`: This method allows the asset owner to set the sale price for their NFT asset in microAlgos. The contract should ensure that only the asset owner can call this method.
2. `stop_sell_offer()`: This method allows the asset owner to remove the asset from the sale listing. Again, the contract should ensure that only the asset owner can call this method.

### Pay for and Receive the Asset

To facilitate the purchase of an asset, the smart contract should have the following functionality:

1. `buy()`: This method allows a user to purchase the asset that is currently listed for sale. The contract should transfer the NFT asset from the seller to the buyer and the sale price from the buyer to the seller.

### Transfer Sales Profits

To distribute the sales profits to the asset owner, the smart contract should have the following functionality:

1. `transfer_profits()`: This method should allow the asset owner to withdraw the sales proceeds from the contract. The contract should ensure that only the asset owner can call this method.

### Update Asset Price

To allow the asset owner to update the sale price of their asset, the smart contract should have the following functionality:

1. `update_price(new_price)`: This method should allow the asset owner to change the sale price of their asset. The contract should ensure that only the asset owner can call this method.

### Opt-in to Receive and Hold Assets

To enable users to opt-in to receive and hold assets, the smart contract should have the following functionality:

1. `opt_in()`: This method should allow users to opt-in to the contract in order to receive and hold assets. The contract should update its internal state to reflect the user's opt-in status.
2. `opt_out()`: This method should allow users to opt-out of the contract, removing their ability to receive and hold assets. The contract should update its internal state accordingly.

### Buy Asset

To facilitate the purchase of an asset, the smart contract should have the following functionality:

1. `buy_asset(asset_id)`: This method should allow a user who has opted-in to the contract to purchase a specific asset. The contract should transfer the asset from the seller to the buyer and deduct the sale price from the buyer's account.

### Delete Product

To allow asset owners to remove their assets from the marketplace, the smart contract should have the following functionality:

1. `delete_product(asset_id)`: This method should allow the asset owner to permanently remove their asset from the marketplace. The contract should ensure that only the asset owner can call this method.

```python
# Algorand ARC4 Smart Contract for diSed Marketplace

# Importing the Algorand Smart Contract library
from algosdk.future import smartcontract

# Declaring the contract state variables
owner = "your_owner_address"
asset_id = 1234567 # Example asset ID
sell_price = 1000000 # Example sell price in microAlgos

# Mapping to store sell offers
sell_offers = {}

# Mapping to track asset ownership
asset_owners = {}

# Mapping to track asset prices
asset_prices = {}

# Mapping to track asset opt-in status
opt_ins = {}

# Modifier to check if caller is the owner
def only_owner():
    assert tx['sender'] == owner, "Only the owner can call this method."

# Modifier to check if caller is the asset owner
def only_asset_owner(asset_id):
    assert asset_owners[asset_id] == tx['sender'], "Only the asset owner can call this method."

# Modifier to check if caller has opted in
def only_opted_in():
    assert opt_ins[tx['sender']] == True, "Caller must opt-in to the contract."

# Method to list an asset on sale
@export
def make_sell_offer(sell_price):
    only_opted_in()
    sell_offers[asset_id] = sell_price
    asset_prices[asset_id] = sell_price

# Method to stop an asset sale offer
@export
def stop_sell_offer():
    only_asset_owner(asset_id)
    del sell_offers[asset_id]
    del asset_prices[asset_id]

# Method to buy an asset
@export
def buy():
    only_opted_in()
    assert asset_id in sell_offers, "No sell offer for this asset."
    seller = asset_owners[asset_id]
    assert ctx.accounts[seller].balance >= sell_offers[asset_id], "Buyer does not have enough funds."
    payment = sell_offers[asset_id]
    asset.transfer(ctx.sender, payment)
    asset.send(asset_id, ctx.sender)
    del sell_offers[asset_id]

# Method to transfer sales profits
@export
def transfer_profits():
    only_owner()
    assert ctx.balance >= 0, "Insufficient balance."
    payment = ctx.balance
    pay(owner, payment)

# Method to update asset price
@export
def update_price(new_price):
    only_asset_owner(asset_id)
    asset_prices[asset_id] = new_price

# Method to opt-in to the contract
@export
def opt_in():
    opt_ins[ctx.sender] = True

# Method to opt-out of the contract
@export
def opt_out():
    opt_ins[ctx.sender] = False

# Method to buy an asset
@export
def buy_asset(asset_id):
    only_opted_in()
    only_owner()
    assert asset_id in sell_offers, "No sell offer for this asset."
    seller = asset_owners[asset_id]
    assert ctx.accounts[seller].balance >= sell_offers[asset_id], "Buyer does not have enough funds."
    payment = sell_offers[asset_id]
    asset.transfer(ctx.sender, payment)
    asset.send(asset_id, ctx.sender)
    del sell_offers[asset_id]

# Method to delete a product
@export
def delete_product(asset_id):
    only_asset_owner(asset_id)
    del asset_owners[asset_id]
    del asset_prices[asset_id]


```

### This is the boiler plate code for the implementation of required functionalities, also appropriate error handing and security measures need to be added for best practices.

\\
