# TCO2 contracts

A separate TCO2 contract is created for each different vintage issuance. Each token contract has the same standard functions, extends ERC20, and is upgradeable.

Find out more about how we name TCO2s in the [Carbon Rosetta Stone](https://toucan-protocol.notion.site/Carbon-Rosetta-Stone-Standard-Attributes-DB-bb0bb434bf6c4661b45155a84d192e22?p=337ff61399244063aee2b4e2e4dca9bb\&pm=s).

Currently, we support TCO2s for two different carbon registries, [Puro](https://puro.earth/) and [Verra](https://verra.org/), each with a varying degree of functionality documented below.

### getAttributes

Function to get corresponding attributes from the carbon project vintage that is represented by this TCO2 contract.

```solidity
function getAttributes() public view virtual returns (ProjectData memory, VintageData memory);
```

The return values are tuples — below you can find the definitions of the `ProjectData` & `VintageData` structs.

```solidity
struct ProjectData {
    string projectId;
    string standard;
    string methodology;
    string region;
    string storageMethod;
    string method;
    string emissionType;
    string category;
    string uri;
    address beneficiary;
}

struct VintageData {
    /// @dev A human-readable string which differentiates this from other vintages in
    /// the same project, and helps build the corresponding TCO2 name and symbol.
    string name; // the vintage year
    uint64 startTime; // UNIX timestamp
    uint64 endTime; // UNIX timestamp
    uint256 projectTokenId;
    uint64 totalVintageQuantity;
    bool isCorsiaCompliant;
    bool isCCPcompliant;
    string coBenefits;
    string correspAdjustment;
    string additionalCertification;
    string uri;
    string registry;
}
```

## Puro

The integration with Puro is achieved through a two-way bridge, where state is synced between the registry and onchain. For more high-level info on the Puro bridge read [here](https://docs.toucan.earth/toucan/carbon-bridge/puro-carbon-bridge).

To ensure a robust sync between the Puro offchain registry and the Toucan onchain contracts, our Puro TCO2 contracts use an escrow contract to hold TCO2s temporarily. The TCO2s are escrowed on every detokenization or retirement request, until the request is completed in the registry, before it can be finalized onchain.

Developers only need to care about creating the request with one of the functions documented below, then it's up to Toucan to finalize the request. In the future, we envision deprecating the admin functionality to process requests offchain and finalize onchain with the use of oracles.

### requestDetokenization

```solidity
function requestDetokenization(uint256[] tokenIds, uint256 amount) external returns (uint256 requestId)
```

Request a detokenization of batch-NFTs. The amount of TCO2 to detokenize will be transferred from the user to an escrow contract. The detokenization request will be processed asynchronously by Toucan so callers should monitor the status of the request by listening to the DetokenizationFinalized and DetokenizationReverted events.

*This function is permissionless and can be called by anyone with enough TCO2 to detokenize*

#### Parameters

| Name       | Type        | Description                                                                                                                                                                                              |
| ---------- | ----------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `tokenIds` | `uint256[]` | Token IDs of one or more batches to detokenize                                                                                                                                                           |
| `amount`   | `uint256`   | The amount of TCO2 to detokenize, must be greater than zero and equal to or smaller than the total amount of the batches (and also greater then the total amount of all the batches except the last one) |

#### Return Values

| Name        | Type      | Description                                  |
| ----------- | --------- | -------------------------------------------- |
| `requestId` | `uint256` | The ID of the request in the escrow contract |

### requestRetirement

```solidity
function requestRetirement(struct CreateRetirementRequestParams params) external returns (uint256 requestId)
```

Request a retirement of TCO2s from batch-NFTs. The amount of TCO2s to retire will be transferred from the user to an escrow contract. The retirement request will be processed asynchronously by Toucan so callers should monitor the status of the request by listening to the RetirementFinalized and RetirementReverted events.

*This function is permissionless and can be called by anyone with enough TCO2 to retire*

#### Parameters

| Name     | Type                                   | Description                                                                                                                                                                                                              |
| -------- | -------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `params` | struct `CreateRetirementRequestParams` | The parameters of the retirement request:                                                                                                                                                                                |
|          |                                        | - **`uint256[] tokenIds`**: One or more batches to retire                                                                                                                                                                |
|          |                                        | - **`uint256 amount`**: The amount of TCO2 to retire; must be greater than zero and equal to or smaller than the total amount of the batches (and also greater than the total amount of all batches except the last one) |
|          |                                        | - **`string retiringEntityString`**: An identifiable string for the retiring entity, e.g., their name                                                                                                                    |
|          |                                        | - **`address beneficiary`**: The address of the beneficiary of the retirement                                                                                                                                            |
|          |                                        | - **`string beneficiaryString`**: An identifiable string for the beneficiary, e.g., their name                                                                                                                           |
|          |                                        | - **`string retirementMessage`**: A message to include in the retirement certificate                                                                                                                                     |
|          |                                        | - **`string beneficiaryLocation`**: The location of the beneficiary of the retirement                                                                                                                                    |
|          |                                        | - **`string consumptionCountryCode`**: The country code of the consumption location                                                                                                                                      |
|          |                                        | - **`uint256 consumptionPeriodStart`**: The start of the consumption period, in seconds since the epoch                                                                                                                  |
|          |                                        | - **`uint256 consumptionPeriodEnd`**: The end of the consumption period, in seconds since the epoch                                                                                                                      |

#### Return Values

| Name        | Type      | Description                                  |
| ----------- | --------- | -------------------------------------------- |
| `requestId` | `uint256` | The ID of the request in the escrow contract |

## Verra

[Note that the Verra bridge does not support bringing new credits onchain anymore](https://docs.toucan.earth/resources/archives/verra-bridge-deprecated). Nevertheless for existing Verra credits, we support direct onchain retirements, which can be executed using any of the functions documented below.

### retire

To retire a given amount of CO2 tons. The credits are permanently removed from circulation — this achieves the offset. This also emits a `Retired` event.

```solidity
function retire(uint256 amount) public virtual returns (uint256 retirementEventId);
```

#### Params

| Name     | Type      | Description                     |
| -------- | --------- | ------------------------------- |
| `amount` | `uint256` | Amount of TCO2 tokens to retire |

#### Return values

| Name                | Type      | Description                                                                                                                                                                     |
| ------------------- | --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `retirementEventId` | `uint256` | The ID of the event emitted upon retirement. Can be used later to mint [`RetirementCertificates`](https://docs.toucan.earth/developers/smart-contracts/retirement-certificates) |

### retireFrom

Achieves similar functionality as `retire()`, but instead of retiring from the caller's address, it does so from the provided address. This allow for pools or third party contracts to retire for the user.

{% hint style="info" %}
This function requires the user to approve the third party from the TCO2 contract.
{% endhint %}

```solidity
function retireFrom(address account, uint256 amount) external virtual returns (uint256 retirementEventId);
```

#### Params

| Name      | Type      | Description                     |
| --------- | --------- | ------------------------------- |
| `account` | `address` | Address from which to retire    |
| `amount`  | `uint256` | Amount of TCO2 tokens to retire |

#### Return values

| Name                | Type      | Description                                                                                     |
| ------------------- | --------- | ----------------------------------------------------------------------------------------------- |
| `retirementEventId` | `uint256` | The ID of the event emitted upon retirement. Can be used later to mint `RetirementCertificates` |

### retireAndMintCertificate

Retires an amount of TCO2 tokensand mints a certificate, passing the `retirementEventId`. The information provided is set in the `RetirementCertificate` NFT.

{% hint style="warning" %}
**Note:** This information is publicly written to the blockchain in plaintext.
{% endhint %}

```solidity
function retireAndMintCertificate(
    string calldata retiringEntityString,
    address beneficiary,
    string calldata beneficiaryString,
    string calldata retirementMessage,
    uint256 amount
) external virtual;
```

#### Params

| Name                   | Type      | Description                                                      |
| ---------------------- | --------- | ---------------------------------------------------------------- |
| `retiringEntityString` | `string`  | An identifiable string for the retiring entity, e.g., their name |
| `beneficiary`          | `address` | The address of the beneficiary of the retirement                 |
| `beneficiaryString`    | `string`  | An identifiable string for the beneficiary, e.g., their name     |
| `retirementMessage`    | `string`  | A message to be included in the retirement certificate           |
| `amount`               | `uint256` | The amount to retire and issue an NFT certificate for            |

### mintCertificateLegacy

This function mints a `RetirementCertificate` NFT based on the legacy retirement functionality. **This function is used only for backwards-compatibility reasons**. (In case you retired before the `RetirementCertificates` NFT was introduced, but still want the NFT.)

{% hint style="info" %}
**Some context:** before the `RetirementCertificates` NFT was introduced, retirements didn't emit the `Retired` event. How much an address/entity had retired was stored solely in a mapping (`mapping(address => uint256) public retiredAmount;`).

* **This is relevant for retirements performed before Block 27360444 on Polygon**
* **All retirements on Celo are compatible with `RetirementCertificates`**
  {% endhint %}

Going forward users should mint NFT either directly in the `RetirementCertificates` contract or using the `retireAndMintCertificate()` function above.

```solidity
function mintCertificateLegacy(
    string calldata retiringEntityString,
    address beneficiary,
    string calldata beneficiaryString,
    string calldata retirementMessage
) external;
```

#### Params

| Name                   | Type      | Description                                                      |
| ---------------------- | --------- | ---------------------------------------------------------------- |
| `retiringEntityString` | `string`  | An identifiable string for the retiring entity, e.g., their name |
| `beneficiary`          | `address` | The address of the beneficiary of the retirement                 |
| `beneficiaryString`    | `string`  | An identifiable string for the beneficiary, e.g., their name     |
| `retirementMessage`    | `string`  | A message to be included in the retirement certificate           |


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.toucan.earth/developers/smart-contracts/tco2.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
