Retirement certificates

Retirement certificates

The RetirementCertificates contract lets users mint NFTs that act as proof of retirement. These NFTs display how many TCO2 tokens a user has retired, along with retirement details such as the beneficiary of the retirement and a message. This contract extends ERC721 and is upgradeable.

Note that minting NFTs directly via the RetirementCertificates contract is only supported for Verra retirements. For Puro retirements, users can only request a retirement that will then need to be processed by Toucan offchain in the Puro registry, before finalizing onchain by minting the certificate to the retirer.

If you are interested in building on top of Puro retirements, we recommend using fractional retirements as that model can accommodate sub-tonnage retirement use cases.

mintCertificate

Mints a new RetirementCertificates NFT based on existing Retired events. The function can either be called by a valid TCO2 contract (in its retireAndMintCertificate() function), or by a user who owns Retired events.

Note: This information is publicly written to the blockchain in plaintext.

function mintCertificate(
  address retiringEntity,
  string calldata retiringEntityString,
  address beneficiary,
  string calldata beneficiaryString,
  string calldata retirementMessage,
  uint256[] calldata retirementEventIds
) external;

Params

Name
Type
Description

retiringEntity

address

The entity that has retired TCO2 and is eligible to mint an NFT

retiringEntityString

string

An identifiable string for the retiring entity, e.g. their name

beneficiary

address

The address of the beneficiary to set in the NFT

beneficiaryString

string

An identifiable string for the beneficiary to set in the NFT, e.g. their name

retirementMessage

string

A retirement message to be set in the NFT

retirementEventIds

uint256[]

An array with with event IDs to associate with the NFT

attachRetirementEvents

This function allows you to attach the Retired events to a RetirementCertificates NFT.

For context, if you go back to the TCO2 contract docs you will see that you are able to retire TCO2 without minting a RetirementCertificates, but you do get a retirementEventId.

This allows you to update the amount in an existent RetirementCertificates NFT with new retirements.

function attachRetirementEvents(
  uint256 tokenId,
  uint256[] calldata retirementEventIds
) external;

Params

Name
Type
Description

tokenId

uint256

The ID of the RetirementCertificate NFT to attach events to

retirementEventIds

uint256[]

An array with with event IDs to associate with the NFT

getUserEvents

Fetches all the Retired events that a given user owns.

function getUserEvents(address user)external view returns (uint256[] memory);

Params

Name
Type
Description

user

address

The address of the user for whom to fetch all events.

Return Values

Name
Type
Description

retirementEventIds

uint256[]

The IDs of the events owned by the given user.

updateCertificate

This function allows you to update the retirementMessage, beneficiary, and beneficiaryString of a RetirementCertificates NFT within 24 hours of creation. Empty param values are ignored, and will not overwrite the existing stored values in the NFT.

function updateCertificate(
  uint256 tokenId,
  string calldata retiringEntityString,
  address beneficiary,
  string calldata beneficiaryString,
  string calldata retirementMessage
) external;

Params

Name
Type
Description

tokenId

uint256

The ID of the RetirementCertificates NFT to update

retiringEntityString

string

An identifiable string for the retiring entity, e.g. their name

beneficiary

address

The address of the beneficiary to set in the NFT

beneficiaryString

string

An identifiable string for the beneficiary to set in the NFT, e.g. their name

retirementMessage

string

A retirement message to be set in the NFT

getRetiredAmount

This function returns the amount of TCO2 tokens retired by a user that's associated with a given RetirementCertificates NFT. The function sums up all the retirement amounts from all of event IDs attached to the RetirementCertificate.

function getRetiredAmount(uint256 tokenId) external view returns (uint256);

Params

Name
Type
Description

tokenId

uint256

The ID of the RetirementCertificates NFT to fetch the amount for

Return Values

Name
Type
Description

amount

uint256

The amount of retired TCO2 tokens associated with that tokenId

Fractional retirements

Fractional retirements are currently supported only on Base Sepolia

The Puro registry supports retirements only of tonne denominations, hence we have extended our protocol to support franctionalizing retirement certificate NFTs so we can enable sub-tonnage retirement use cases. There are two new contracts involved in fractionalizing a RetirementCertificates NFT:

  • RetirementCertificateFractionalizer, an ERC1155 contract that fractionalizes certificates and keeps track of fractional balances. These balances represent the right to mint a fractional retirement certificate, they are not an environmental claim

  • RetirementCertificateFractions, an ERC721 contract that is used to mint fractional retirement certificates. Minting such a certificate can only be done by an account that holds or has been approved to use RetirementCertificateFractionalizer balance. In order to mint a fractional certificate, the equivalent amount of RetirementCertificateFractionalizer balance is burnt

How to fractionalize a certificate

On a high level, Alice has to retire a Puro TCO2 on behalf of RetirementCertificateFractionalizer. Alice can then send her RetirementCertificates NFT to the RetirementCertificateFractionalizer. The act of transferring a RetirementCertificates NFT to the fractionalizer plus the fact that the fractionalizer is set as the beneficiary of the certificate allows the fractionalizer to mint an ERC1155 balance to Alice.

Alice can then list her ERC1155 balance on any NFT marketplace from where it can be bought by whomever needs to do a fractional retirement. We invite the community to come up with novel mechanisms to buy and sell RetirementCertificateFractionalizer liquidity.

Concretely:

  1. Request a retirement by using any available TCO2 balance in the My Carbon Assets section and include the following information:

    • Beneficiary wallet address: Set this to the address of the RetirementCertificateFractionalizer (found in the Contracts page – ensure the correct network tab is selected).

    • Beneficiary name or organization name: Set this to the output of RetirementCertificateFractionalizer.beneficiaryString(), formatted as TOUCAN-2.0-RCS-[CHAIN_ID], where [CHAIN_ID] represents the chain ID of the current chain.

  2. Once the retirement is finalized by Toucan, transfer the newly minted RetirementCertificates NFT to the RetirementCertificateFractionalizer contract. The transfer should mint the equivalent amount of ERC1155 balance to your account.

Each RetirementCertificateFractionalizer token id maps to the respective CarbonProjectVintages token id on the same chain.

How to retire fractional balance

You can acquire RetirementCertificateFractionalizer balance on Base Sepolia via OpenSea.

Once you hold RetirementCertificateFractionalizer balance, you can retire it and mint a RetirementCertificateFractions NFT by calling mintFraction on the fractionalizer contract.

RetirementCertificateFractionalizer

FractionRequestData

struct FractionRequestData {
  uint256 amount;
  uint256 projectVintageTokenId;
  address beneficiary;
  string beneficiaryString;
  string retirementMessage;
  string beneficiaryLocation;
  string consumptionCountryCode;
  uint256 consumptionPeriodStart;
  uint256 consumptionPeriodEnd;
  string tokenURI;
  bytes extraData;
}

mintFraction

function mintFraction(struct FractionRequestData params) external returns (uint256 fractionTokenId)

Mint a fraction of a retirement certificate, from the balance of the caller

Parameters

Name
Type
Description

params

struct FractionRequestData

The request data of the fraction to mint

Return Values

Name
Type
Description

fractionTokenId

uint256

The id of the minted fraction NFT, in the fractions contract

mintFractionFrom

function mintFractionFrom(address from, struct FractionRequestData params) public returns (uint256 fractionTokenId)

Mint a fraction of a retirement certificate, from the balance of the listing owner

Parameters

Name
Type
Description

from

address

The owner of the balance to mint the fraction from

params

struct FractionRequestData

The request data of the fraction to mint

Return Values

Name
Type
Description

fractionTokenId

uint256

The id of the minted fraction NFT, in the fractions contract

Last updated