# Feral File v2.0 Exhibition Contract
###### tags: `Feral File` `Smart Contract`
###### Status: Wait for review
###### Reviewer: Sean and Casey Reas
Learn from [previous contract design](/z_qDgKYqQWmN4Ve3zCznUA).
## Repository
- [feralfile-exhibition-smart-contract](https://github.com/bitmark-inc/feralfile-exhibition-smart-contract)
- Commit: `ff80a5d488e21cf2de3a9db980bde83b1f56952d`
- Files:
- contracts
├── Authorizable.sol
├── ECDSASigner.sol
├── FeralfileArtworkV4.sol <- main contract
├── FeralfileSaleData.sol
├── FeralfileVault.sol
├── IFeralfileSaleData.sol
├── IFeralfileVault.sol
└── UpdateableOperatorFilterer.sol
## Design Requirements
1. Token Exhibition + Sale (only pay function, no auction)
2. Pre-mint tokens to contract address
3. Only support ETH (native token)
4. Start, pause and resume the sale
5. Close the sale options:
- Burn all remaining tokens
- Tranfer all remaining tokens to artists
6. Can buy to another address
7. Can pay to buy a list of tokens (to support set)
8. Collectors submit purchasing transaction (pay in native token)
- Collectors request valid purchase intent (sale info) from server
9. Target purchasing token is assigned by the FF server
- An expiration will set to each sale info
- The expiration time is 3 minutes starting from the time an intent is created
10. `OperatorFilter` is required
11. Credit card payment collector will get a price which is added up with the gas price in `fast` manner for the sale transaction
- Unused gas fee will be return to the user
- Refund the unused gas fee if a tx is minted very fast
- Refund by deducting the spent gas if a tx is timeout
12. Design the token id to ensure the uniquness by server
13. Not implement the EIP2981
## Feral File Sale Flow with Smart Contract
{%hackmd yGIcakyPSNqxhObASKfmag %}
## Signature Validation
Follow the [Ethereum Signing](/PKa3Xsh7QOykUeAvA5BOGQ?view#Ethereum-Signing) to sign and validate signatures.
## ECDSASigner Contract
**ECDSASigner** is a contract for validating signatures from the set signer.
### Functions
1. `setSigner` - assign the signer's address
2. `isValidSignature` - validate if a signature is signed by signer.
## FeralFileVault Contract
**FeralFileVault** is a vault contract to facilitate the `buyArtworks` if the transaction comes from an address which is not allow to send ETH (for example, ITX) directly to the exhibition contract.
This contract maintains an ETH balance for delegating payments from sales. It uses the same signature validating mechanism to ensure payment requests come from the authorized signer.
### Functions
- `payForSale` - validate the sale data and send ETH to the caller
- `withdrawFund` - withdraw remaining funds
## IFeralfileSaleData
IFeralfileSaleData is a contract for defined `SaleData` object. This would be inherited by both `FeralfileExhibitionV4` and `FeralfileVault`. This defined required data for executing the `buyArtworks`.
### Structure
```solidity
struct SaleData {
uint256 price; // in wei
uint256 cost; // in wei
uint256 expiryTime;
address destination;
uint256[] tokenIds;
RevenueShare[][] revenueShares; // address and royalty bps (500 means 5%)
bool payByVaultContract; // get eth from vault contract, used by credit card pay that proxy by ITX
}
```
## Exhibition Contract
**FeralfileExhibitionV4** is the main contract of Feral File's exhibition.
### Simple sale flow
```mermaid
flowchart LR
A[Deploy Contract] --> X[Mint Artworks] --> B[Start Sale]
B --> C[Close Sale And Transfer]
B --> D[Close Sale And Burn]
```
### Variables
#### Attributes
- `burnable` - indicate if tokens in the contract is allowed to burn for collectors
- `bridgeable` - indicate if tokens in this contract is allowed to swap to another blockchain is the future. (it is just a feature attribute for now)
#### Sale Status
- `mintable` - the mint status. It will be disabled forever when the sale starts.
- `_selling` - the sale status.
### Functions
#### Sale
1. `mintArtworks`
Feral File will mint tokens in advance so that collectors can preview and see which artworks they are interested to collect.
2. `startSale` - stop the minting process and start the sale for the exhibition
3. `buyArtworks` - buy artworks by a sale data signed from Feral File
4. `stopSaleAndTransfer` - stop the sale and transfer all remaining tokens to specific addresses by series. The sale can not resume again once stopped.
5. `stopSaleAndBurn` - stop the sale and burn all remaining tokens. The sale can not resume again once stopped.
##### buyArtworks
`buyArtworks` is a key function of the exhibition contract. It follows the [sale data](/GooHL48zTgymKNAqn7t1Lw#Structure) from Feral File to execute the following:
- take funds from transaction sender or FeralfileVault
- dispatch sale tokens to addresses
- dispatch revenue streams and fees to corresponded addresses
#### Operation
1. `withdrawFunds` - withdraw funds in the contract if there are any not totally spent.
2. `pauseSale` - temporarily pause the sale
3. `resumeSale` - resume the sale
### Events
```solidity
/// @notice Event emitted when new Artwork has been minted
event NewArtwork( address indexed owner, uint256 indexed seriesId, uint256 indexed tokenId );
/// @notice Event emitted when Artwork has been burned
event BurnArtwork(uint256 indexed tokenId);
/// @notice Event emitted when Artwork has been sold
event BuyArtwork(address indexed buyer, uint256 indexed tokenId);
```
## Feral File Server Side Integration
- Use [ITX](https://github.com/INFURA/demo-eth-tx/tree/master/infura-transactions) as the ethereum transaction broadcasting solution
- ITX is about to stops it services. We need to find another alternative
- [Minting Flow](/R61MQj0ETX-PVKJK2aJw3w)
- [Purchase / Sale Flow](/0SX3n-5-Scme79l0gZ0n2g)
- [Third party marketplaces metadata](/Y5aWIYLcReyxT1V5XfmBXg)
## Notes
- Collaboration at the contract level requires a single address. (Could be a contract address or multisig.) We will put collaborators into the metadata as per marketplace spec.