# PID

### Overview

`PID` is the core NFT contract that represents Payment ID ownership as ERC-721 tokens. It handles token registration, transfers, and delegates ownership and resolver management to the PIDRegistry contract. This contract implements the tokenized representation of Payment IDs, allowing them to be transferred, approved, and managed like standard NFTs.

### Key Concepts

| Concept              | Description                                                                           |
| -------------------- | ------------------------------------------------------------------------------------- |
| NFT Representation   | Each Payment ID is represented as a unique ERC-721 token.                             |
| Registry Integration | Maintains synchronization with PIDRegistry when tokens are transferred or registered. |
| Controller Pattern   | Only authorized controller contracts can register new Payment IDs.                    |
| Ownership Management | Extends OpenZeppelin's Ownable2Step for secure contract ownership management.         |

### Data Structures

State Variables

| Name        | Type         | Description                                                        |
| ----------- | ------------ | ------------------------------------------------------------------ |
| registry    | IPIDRegistry | Reference to the PID Registry contract.                            |
| totalAmount | uint256      | Counter for the total number of minted Payment IDs.                |
| controller  | address      | Address of the authorized controller that can register new tokens. |

### Functions

Constructor

```solidity
constructor(address _initialOwner) public
```

| Input Parameter | Type    | Description                            |
| --------------- | ------- | -------------------------------------- |
| \_initialOwner  | address | Address of the initial contract owner. |

Initialization

init

```solidity
function init(address _registry, address _controller) external onlyOwner
```

| Input Parameter | Type    | Description                           |
| --------------- | ------- | ------------------------------------- |
| \_registry      | address | Address of the PID Registry contract. |
| \_controller    | address | Address of the controller contract.   |

| Reverts                   | Description                                            |
| ------------------------- | ------------------------------------------------------ |
| PID\_\_AlreadyInitialized | Thrown when the contract has already been initialized. |
| PID\_\_InvalidRegistry    | Thrown when the registry address is zero.              |
| PID\_\_InvalidController  | Thrown when the controller address is zero.            |

Token Registration

register

```solidity
function register(uint256 id, address owner, address resolver) external onlyController returns (uint256)
```

| Input Parameter | Type    | Description                          |
| --------------- | ------- | ------------------------------------ |
| id              | uint256 | The token ID to register.            |
| owner           | address | The address that will own the token. |
| resolver        | address | The resolver address for the token.  |

| Returns | Description              |
| ------- | ------------------------ |
| uint256 | The registered token ID. |

| Reverts                 | Description                                     |
| ----------------------- | ----------------------------------------------- |
| PID\_\_NameAlreadyTaken | Thrown when the token ID is already registered. |
| PID\_\_OnlyController   | Thrown when caller is not the controller.       |

Token Transfers

transferFrom

```solidity
function transferFrom(address from, address to, uint256 tokenId) public override(ERC721, IERC721)
```

| Input Parameter | Type    | Description                   |
| --------------- | ------- | ----------------------------- |
| from            | address | Current owner of the token.   |
| to              | address | Address to receive the token. |
| tokenId         | uint256 | ID of the token to transfer.  |

| Reverts                   | Description                                        |
| ------------------------- | -------------------------------------------------- |
| PID\_\_NotApprovedOrOwner | Thrown when caller is not token owner or approved. |

safeTransferFrom

```solidity
function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory _data) public override(ERC721, IERC721)
```

| Input Parameter | Type    | Description                               |
| --------------- | ------- | ----------------------------------------- |
| from            | address | Current owner of the token.               |
| to              | address | Address to receive the token.             |
| tokenId         | uint256 | ID of the token to transfer.              |
| \_data          | bytes   | Additional data with no specified format. |

| Reverts                   | Description                                        |
| ------------------------- | -------------------------------------------------- |
| PID\_\_NotApprovedOrOwner | Thrown when caller is not token owner or approved. |

Availability Check

available

```solidity
function available(uint256 id) public view returns (bool)
```

| Input Parameter | Type    | Description                         |
| --------------- | ------- | ----------------------------------- |
| id              | uint256 | Token ID to check availability for. |

| Returns | Description                                             |
| ------- | ------------------------------------------------------- |
| bool    | `true` if the token ID is available, `false` otherwise. |

Internal Functions

\_isApprovedOrOwner

```solidity
function _isApprovedOrOwner(address spender, uint256 tokenId) internal view returns (bool)
```

| Input Parameter | Type    | Description                    |
| --------------- | ------- | ------------------------------ |
| spender         | address | Address to check for approval. |
| tokenId         | uint256 | Token ID to check.             |

| Returns | Description                                                |
| ------- | ---------------------------------------------------------- |
| bool    | `true` if spender is owner or approved, `false` otherwise. |

\_safeMint

```solidity
function _safeMint(address _to, uint256 _tokenId, bytes memory _data) internal virtual override(ERC721)
```

| Input Parameter | Type    | Description                               |
| --------------- | ------- | ----------------------------------------- |
| \_to            | address | Address receiving the token.              |
| \_tokenId       | uint256 | ID of token to mint.                      |
| \_data          | bytes   | Additional data with no specified format. |

### Events

| Event             | Parameters                                     | Description                                     |
| ----------------- | ---------------------------------------------- | ----------------------------------------------- |
| RegistryUpdated   | (address oldRegistry, address newRegistry)     | Emitted when the registry address is updated.   |
| ControllerUpdated | (address oldController, address newController) | Emitted when the controller address is updated. |
| NameRegistered    | (uint256 id, address owner, address resolver)  | Emitted when a new Payment ID is registered.    |

### Errors

| Error                     | Description                                                            |
| ------------------------- | ---------------------------------------------------------------------- |
| PID\_\_AlreadyInitialized | Thrown when attempting to initialize an already initialized contract.  |
| PID\_\_InvalidRegistry    | Thrown when providing a zero address for the registry.                 |
| PID\_\_InvalidController  | Thrown when providing a zero address for the controller.               |
| PID\_\_OnlyController     | Thrown when a non-controller address calls a controller-only function. |
| PID\_\_NameAlreadyTaken   | Thrown when attempting to register an ID that is already taken.        |
| PID\_\_NotApprovedOrOwner | Thrown when an unauthorized address attempts to transfer a token.      |
