# Harvest.art Platform Guide

This document explains how Harvest.art works, including the purpose of the platform, smart contract addresses, and how to interact with the contracts.

## What is Harvest.art?

Harvest.art is an NFT tax loss harvesting platform. Users sell unwanted or underwater NFTs to "The Barn" for a nominal amount (1 gwei per token), establishing a verifiable on-chain sale for tax purposes. In return, users receive **Bid Tickets** — ERC1155 utility tokens used to participate in auctions of NFTs that others have harvested.

The platform runs on multiple EVM chains with the same contract addresses deployed on each.

### Supported Chains

Ethereum, Polygon, Arbitrum, Optimism, Base, Blast, Avalanche, ApeChain

## Core Concepts

| Term | Meaning |
|------|---------|
| **Harvest** | Sell NFTs to The Barn for 1 gwei each + service fee, receive Bid Tickets |
| **The Barn** | Wallet that holds all harvested NFTs |
| **The Farmer** | Wallet that receives auction proceeds and fees |
| **Bid Ticket** | ERC1155 token burned to start auctions or place bids |
| **Auction** | English-style auction of harvested NFTs, paid in native token (ETH) |
| **Claim** | Winner takes NFTs after auction ends |
| **Outbid Reward** | 10% of bid delta paid to outbid bidders as compensation |

---

## Smart Contract Addresses

All contracts are deployed at the same address on every supported chain.

| Contract | Address |
|----------|---------|
| **Harvest** | `0x000000000000F10286D9c1c5d4635a25070572b6` |
| **Auctions** | `0x00000000000016AF6F453a28C22C25cFC1b74Dd1` |
| **BidTicket** | `0x62613AA9594D0116b5CA23aCd37dDDAc90c67E5c` |

---

## Harvest Contract

The Harvest contract lets users sell tokens (ERC20, ERC721, ERC1155) to The Barn in exchange for ETH and Bid Tickets.

### `batchSale`

```solidity
batchSale(
    TokenType[] calldata types,      // ERC20=0, ERC721=1, ERC1155=2
    address[] calldata contracts,     // Token contract addresses
    uint256[] calldata tokenIds,      // Token IDs
    uint256[] calldata counts,        // Amounts (1 for ERC721)
    bool skipBidTicket               // If true, skip minting Bid Tickets
) external payable
```

**How it works:**
1. User approves their tokens to the Harvest contract
2. User calls `batchSale` with arrays describing each token
3. Tokens transfer from user to The Barn
4. User receives 1 gwei per token + Bid Tickets (unless `skipBidTicket` is true)
5. Service fee (0.02 ETH) goes to The Farmer

**Settings:**
- Sale price: 1 gwei per token
- Service fee: 0.02 ETH
- Max tokens per transaction: 500
- Bid Ticket multiplier: 1 ticket per token harvested

**Events:**
- `Sale(address indexed user, uint256 indexed salePrice)`

---

## Auctions Contract

The Auctions contract manages the full auction lifecycle for harvested NFTs.

### Starting an Auction

```solidity
startAuctionERC721(
    uint256 startingBid,
    address tokenAddress,
    uint256[] calldata tokenIds
) external payable

startAuctionERC1155(
    uint256 startingBid,
    address tokenAddress,
    uint256[] calldata tokenIds,
    uint256[] calldata amounts
) external payable
```

**Requirements:**
- Caller must hold >= 1 Bid Ticket (burned on call)
- `msg.value` must equal `startingBid`
- `startingBid` >= 0.05 ETH
- Token count <= 50
- Tokens must be owned by The Barn

**Events:**
- `Started(address indexed bidder, address indexed tokenAddress, uint256[] indexed tokenIds)`

### Placing a Bid

```solidity
bid(uint256 auctionId, uint256 bidAmount) external payable
```

**Requirements:**
- Caller must hold >= 1 Bid Ticket (burned on call)
- `bidAmount` >= current highest bid + 0.01 ETH
- `msg.value` must equal `bidAmount`
- Auction must be active and not expired

**Mechanics:**
- Previous bidder's funds are credited to their contract balance (withdrawable via `withdraw()`)
- Outbid reward = bid delta * 10%
- If bid placed within 15 minutes of auction end, the auction extends by 15 minutes (anti-snipe)

**Events:**
- `NewBid(uint256 indexed auctionId, address indexed bidder, uint256 indexed value)`

### Claiming an Auction

```solidity
claim(uint256 auctionId) external
```

After the auction ends, the highest bidder (or contract owner) calls `claim`. NFTs transfer from The Barn to the winner, proceeds go to The Farmer, and outbid rewards are distributed.

**Events:**
- `Claimed(uint256 indexed auctionId, address indexed winner)`

### Refund and Abandonment

```solidity
refund(uint256 auctionId) external
abandon(uint256 auctionId) external
```

- **Refund:** Available during the 7-day settlement period if The Barn hasn't approved the collection for transfer. Highest bidder gets their bid back.
- **Abandon:** Owner-only, callable after the settlement period expires. The auction is marked abandoned and the bidder is refunded minus a 20% fee.

**Events:**
- `Refunded(uint256 indexed auctionId, address indexed bidder, uint256 indexed value)`
- `Abandoned(uint256 indexed auctionId, address indexed bidder, uint256 indexed fee)`

### Withdrawing Balance

```solidity
withdraw() external
```

Users accumulate balance from being outbid (refund + outbid reward). Call `withdraw()` to send the full balance to your wallet.

**Events:**
- `Withdraw(address indexed user, uint256 indexed value)`

### Reading Auction Data

```solidity
auctions(uint256 auctionId) external view returns (
    uint8 auctionType,       // 0 = ERC721, 1 = ERC1155
    address tokenAddress,
    uint64 endTime,
    uint8 tokenCount,
    uint8 status,            // 0=Active, 1=Claimed, 2=Refunded, 3=Abandoned
    address highestBidder,
    uint256 highestBid,
    uint256 bidDelta,
    uint256 bidderCount
)

getAuctionTokens(uint256 auctionId) external view returns (
    uint256[] memory tokenIds,
    uint256[] memory amounts
)

getPendingRewards(address bidder, uint256[] calldata auctionIds) external view returns (uint256)
```

---

## Auction Settings

These are readable from the Auctions contract and may be updated by the owner.

| Setting | Default | Description |
|---------|---------|-------------|
| `auctionDuration` | 1 day | How long auctions run |
| `minStartingBid` | 0.03 ETH | Minimum starting bid |
| `minBidIncrement` | 0.01 ETH | Minimum bid increase over current highest |
| `maxTokens` | 10 | Max NFTs per auction |
| `outbidRewardPercent` | 10% | Reward for outbid bidders (% of bid delta) |
| `antiSnipeDuration` | 15 min | Extends auction if bid placed near end |
| `settlementDuration` | 7 days | Window after auction for claims/refunds |
| `bidTicketCostStart` | 1 | Bid Tickets burned to start an auction |
| `bidTicketCostBid` | 1 | Bid Tickets burned to place a bid |

---

## Auction Statuses

| Value | Status | Meaning |
|-------|--------|---------|
| 0 | Active | Auction is live, accepting bids |
| 1 | Claimed | Winner claimed the NFTs |
| 2 | Refunded | Bidder refunded during settlement |
| 3 | Abandoned | Marked abandoned after settlement expired |

---

## BidTicket Contract

ERC1155 utility token. Minted by the Harvest contract when users sell NFTs. Burned by the Auctions contract when users start auctions or place bids.

Users do not interact with this contract directly — it is called internally by the Harvest and Auctions contracts.

---

## Website Pages

| URL | Purpose |
|-----|---------|
| [harvest.art/harvest](https://harvest.art/harvest) | Sell/harvest NFTs to The Barn |
| [harvest.art/barn](https://harvest.art/barn) | Browse NFTs in The Barn, start auctions |
| [harvest.art/auctions](https://harvest.art/auctions) | Browse and bid on active auctions |
| [harvest.art/contracts](https://harvest.art/contracts) | View all contract addresses |
