# Burn to Earn Tested OnChain Solidity code

```
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
import "@openzeppelin/contracts/access/Ownable.sol";

contract MyRefundableNFT is ERC721, Ownable {
    uint256 public tokenCounter;
    uint256 public refundPeriod; // in seconds (days will be converted to seconds)
    uint256 public refundPercentage; // e.g., 90 means 90% refund
    mapping(uint256 => uint256) public mintTimestamps; // stores the mint timestamp for each NFT
    mapping(uint256 => uint256) public mintPrices; // stores the mint price for each NFT

    constructor(uint256 _refundPeriodInDays, uint256 _refundPercentage) ERC721("MyRefundableNFT", "MNFT") {
        tokenCounter = 0;
        refundPeriod = _refundPeriodInDays * 1 days; // converting days to seconds
        refundPercentage = _refundPercentage;
    }

    // Function to mint new NFTs and hold funds for the refund period
    function mintNFT(address recipient) public payable onlyOwner returns (uint256) {
        require(refundPercentage >= 0 && refundPercentage <= 100, "Invalid refund percentage");

        uint256 newTokenId = tokenCounter;
        tokenCounter++;

        _safeMint(recipient, newTokenId);

        // Store the minting price and timestamp
        mintTimestamps[newTokenId] = block.timestamp;
        mintPrices[newTokenId] = msg.value;

        return newTokenId;
    }

    // Function to burn the NFT and refund the buyer if within refund period
    function burnNFT(uint256 tokenId) public {
        require(ownerOf(tokenId) == msg.sender, "Only the owner can burn this NFT");
        require(block.timestamp <= mintTimestamps[tokenId] + refundPeriod, "Refund period has expired");

        // Calculate refund amount
        uint256 refundAmount = (mintPrices[tokenId] * refundPercentage) / 100;

        // Burn the NFT
        _burn(tokenId);

        // Transfer the refund to the user
        payable(msg.sender).transfer(refundAmount);

        // Clean up data for the burned token
        delete mintTimestamps[tokenId];
        delete mintPrices[tokenId];
    }

    // Fallback function to receive funds
    receive() external payable {}

    // Function to withdraw contract funds by the owner (developer)
    function withdrawFunds() public onlyOwner {
        payable(owner()).transfer(address(this).balance);
    }
}

```

Got it! We will take an ERC-721 smart contract and modify it to include the following features:

1. **Developer inputs a duration in days (e.g., 3 days)**: Funds from minting will be held for this period.
2. **Developer inputs a refund percentage (e.g., 90%)**: A percentage of the mint price will be refunded if the buyer burns the NFT within the specified days.
3. **NFT Burn Functionality**: Buyers can burn their NFTs within the set time frame to receive the refund.

Here’s the Solidity smart contract code that incorporates these features:

```solidity
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
import "@openzeppelin/contracts/access/Ownable.sol";

contract MyRefundableNFT is ERC721, Ownable {
    uint256 public tokenCounter;
    uint256 public refundPeriod; // in seconds (days will be converted to seconds)
    uint256 public refundPercentage; // e.g., 90 means 90% refund
    mapping(uint256 => uint256) public mintTimestamps; // stores the mint timestamp for each NFT
    mapping(uint256 => uint256) public mintPrices; // stores the mint price for each NFT

    constructor(uint256 _refundPeriodInDays, uint256 _refundPercentage) ERC721("MyRefundableNFT", "MNFT") {
        tokenCounter = 0;
        refundPeriod = _refundPeriodInDays * 1 days; // converting days to seconds
        refundPercentage = _refundPercentage;
    }

    // Function to mint new NFTs and hold funds for the refund period
    function mintNFT(address recipient) public payable onlyOwner returns (uint256) {
        require(refundPercentage >= 0 && refundPercentage <= 100, "Invalid refund percentage");

        uint256 newTokenId = tokenCounter;
        tokenCounter++;

        _safeMint(recipient, newTokenId);

        // Store the minting price and timestamp
        mintTimestamps[newTokenId] = block.timestamp;
        mintPrices[newTokenId] = msg.value;

        return newTokenId;
    }

    // Function to burn the NFT and refund the buyer if within refund period
    function burnNFT(uint256 tokenId) public {
        require(ownerOf(tokenId) == msg.sender, "Only the owner can burn this NFT");
        require(block.timestamp <= mintTimestamps[tokenId] + refundPeriod, "Refund period has expired");

        // Calculate refund amount
        uint256 refundAmount = (mintPrices[tokenId] * refundPercentage) / 100;

        // Burn the NFT
        _burn(tokenId);

        // Transfer the refund to the user
        payable(msg.sender).transfer(refundAmount);

        // Clean up data for the burned token
        delete mintTimestamps[tokenId];
        delete mintPrices[tokenId];
    }

    // Fallback function to receive funds
    receive() external payable {}

    // Function to withdraw contract funds by the owner (developer)
    function withdrawFunds() public onlyOwner {
        payable(owner()).transfer(address(this).balance);
    }
}
```

#### Key Features :

1. **Refund Period**: The developer inputs a number of days when deploying the contract, and this is converted into seconds for Solidity to track time accurately. For example, 3 days would be `3 * 24 * 60 * 60` seconds.
2. **Refund Percentage**: The developer also specifies the refund percentage when deploying the contract. This ensures that when an NFT is burned, the buyer can receive a refund based on the mint price and this percentage.
3. **Minting Process**:
   * When an NFT is minted, the mint price (the `msg.value` sent in the mint transaction) and the mint timestamp are stored for each token ID.
   * The funds from the mint transaction stay in the contract until withdrawn by the owner after the refund period has passed.
4. **Burning NFTs**:
   * The buyer can burn the NFT within the specified refund period.
   * If the NFT is burned within that period, the buyer gets refunded based on the percentage set by the developer.
5. **Funds Withdrawal**:
   * After the refund period expires, the contract owner (developer) can withdraw the remaining funds.

#### Example:

* The developer deploys the contract with a 3-day refund period and a 90% refund rate.
* A buyer mints an NFT by paying, e.g., 1 ETH. This amount is held in the contract.
* The buyer can burn the NFT within 3 days and receive 90% of the mint price (i.e., 0.9 ETH).
* After the 3 days, if the NFT is not burned, the developer can withdraw the remaining funds.

This contract gives the buyers a safe option to get their money back if they are not satisfied with the NFT within the given time, and developers can build trust by offering this refund mechanism.


---

# 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://sols-organization.gitbook.io/burn-to-earn-nft-launchpad/burn-to-earn-tested-onchain-solidity-code.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.
