Skip to content

Commit

Permalink
first commit
Browse files Browse the repository at this point in the history
  • Loading branch information
mauricedesaxe committed Feb 24, 2022
0 parents commit c32e84c
Show file tree
Hide file tree
Showing 56 changed files with 45,204 additions and 0 deletions.
3 changes: 3 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
ETHERSCAN_API_KEY=ABC123ABC123ABC123ABC123ABC123ABC1
ROPSTEN_URL=https://eth-ropsten.alchemyapi.io/v2/<YOUR ALCHEMY KEY>
PRIVATE_KEY=0xabc123abc123abc123abc123abc123abc123abc123abc123abc123abc123abc1
4 changes: 4 additions & 0 deletions .eslintignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
node_modules
artifacts
cache
coverage
24 changes: 24 additions & 0 deletions .eslintrc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
module.exports = {
env: {
browser: false,
es2021: true,
mocha: true,
node: true,
},
plugins: ["@typescript-eslint"],
extends: [
"standard",
"plugin:prettier/recommended",
"plugin:node/recommended",
],
parser: "@typescript-eslint/parser",
parserOptions: {
ecmaVersion: 12,
},
rules: {
"node/no-unsupported-features/es-syntax": [
"error",
{ ignores: ["modules"] },
],
},
};
9 changes: 9 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
node_modules
.env
coverage
coverage.json
typechain

#Hardhat files
cache
artifacts
8 changes: 8 additions & 0 deletions .idea/.gitignore

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 9 additions & 0 deletions .idea/OffsetHelper.iml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

48 changes: 48 additions & 0 deletions .idea/codeStyles/Project.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions .idea/codeStyles/codeStyleConfig.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions .idea/inspectionProfiles/Project_Default.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions .idea/misc.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 8 additions & 0 deletions .idea/modules.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions .npmignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
hardhat.config.ts
scripts
test
5 changes: 5 additions & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
node_modules
artifacts
cache
coverage*
gasReporterOutput.json
1 change: 1 addition & 0 deletions .prettierrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{}
7 changes: 7 additions & 0 deletions .solhint.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"extends": "solhint:recommended",
"rules": {
"compiler-version": ["error", "^0.8.0"],
"func-visibility": ["warn", { "ignoreConstructors": true }]
}
}
1 change: 1 addition & 0 deletions .solhintignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
node_modules
46 changes: 46 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
# Advanced Sample Hardhat Project

This project demonstrates an advanced Hardhat use case, integrating other tools commonly used alongside Hardhat in the ecosystem.

The project comes with a sample contract, a test for that contract, a sample script that deploys that contract, and an example of a task implementation, which simply lists the available accounts. It also comes with a variety of other tools, preconfigured to work with the project code.

Try running some of the following tasks:

```shell
npx hardhat accounts
npx hardhat compile
npx hardhat clean
npx hardhat test
npx hardhat node
npx hardhat help
REPORT_GAS=true npx hardhat test
npx hardhat coverage
npx hardhat run scripts/deploy.ts
TS_NODE_FILES=true npx ts-node scripts/deploy.ts
npx eslint '**/*.{js,ts}'
npx eslint '**/*.{js,ts}' --fix
npx prettier '**/*.{json,sol,md}' --check
npx prettier '**/*.{json,sol,md}' --write
npx solhint 'contracts/**/*.sol'
npx solhint 'contracts/**/*.sol' --fix
```

# Etherscan verification

To try out Etherscan verification, you first need to deploy a contract to an Ethereum network that's supported by Etherscan, such as Ropsten.

In this project, copy the .env.example file to a file named .env, and then edit it to fill in the details. Enter your Etherscan API key, your Ropsten node URL (eg from Alchemy), and the private key of the account which will send the deployment transaction. With a valid .env file in place, first deploy your contract:

```shell
hardhat run --network ropsten scripts/sample-script.ts
```

Then, copy the deployment address and paste it in to replace `DEPLOYED_CONTRACT_ADDRESS` in this command:

```shell
npx hardhat verify --network ropsten DEPLOYED_CONTRACT_ADDRESS "Hello, Hardhat!"
```

# Performance optimizations

For faster runs of your tests and scripts, consider skipping ts-node's type checking by setting the environment variable `TS_NODE_TRANSPILE_ONLY` to `1` in hardhat's environment. For more details see [the documentation](https://hardhat.org/guides/typescript.html#performance-optimizations).
137 changes: 137 additions & 0 deletions contracts/CO2KEN_contracts/CarbonOffsetBadges.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
// SPDX-FileCopyrightText: 2021 Toucan Labs
//
// SPDX-License-Identifier: UNLICENSED

// If you encounter a vulnerability or an issue, please contact <[email protected]> or visit security.toucan.earth
pragma solidity ^0.8.0;

import '@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol';
import '@openzeppelin/contracts-upgradeable/token/ERC721/extensions/ERC721EnumerableUpgradeable.sol';
import '@openzeppelin/contracts-upgradeable/utils/CountersUpgradeable.sol';
import '@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol';
import '@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol';

import './IToucanContractRegistry.sol';
import './CarbonOffsetBadgesStorage.sol';
import './CarbonProjects.sol';

/// @notice The `CarbonOffsetBadges` contract lets users mint Badge-NFTs
/// These Badges serve to display how much CO2 a user has offset via the protocols
contract CarbonOffsetBadges is
ERC721EnumerableUpgradeable,
OwnableUpgradeable,
UUPSUpgradeable,
CarbonOffsetBadgesStorage
{
// Libraries
using CountersUpgradeable for CountersUpgradeable.Counter;
using AddressUpgradeable for address;

// Events
event BadgeMinted(uint256 tokenId);

// ----------------------------------------
// Upgradable related functions
// ----------------------------------------

function initialize(address _contractRegistry) public virtual initializer {
__Context_init_unchained();
__ERC721_init_unchained(
'Toucan Protocol: Retirement Badges for Carbon Offset Project Vintage Batches',
'TOUCAN-COBRB'
);
__Ownable_init_unchained();
contractRegistry = _contractRegistry;
}

function _authorizeUpgrade(address newImplementation)
internal
virtual
override
onlyOwner
{}

function setToucanContractRegistry(address _address)
public
virtual
onlyOwner
{
contractRegistry = _address;
}

// Mint new Badge NFT that shows how many offsets have been retired
function mintBadge(
address to,
uint256 projectVintageTokenId,
uint256 amount
) external virtual {
// Logic requires that minting can only originate from a project-vintage ERC20 contract
require(
IToucanContractRegistry(contractRegistry).checkERC20(
_msgSender()
) == true,
'pERC20 not official'
);
_tokenIds.increment();
uint256 newItemId = _tokenIds.current();

_safeMint(to, newItemId);
badges[newItemId].projectVintageTokenId = projectVintageTokenId;
badges[newItemId].retiredAmount = amount;

emit BadgeMinted(newItemId);
}

function setBaseURI(string memory baseURI_) external virtual onlyOwner {
baseURI = baseURI_;
}

function _baseURI() internal view virtual override returns (string memory) {
return baseURI;
}

/// @dev allows setting a URI or a hash to be used by the `tokenURI` getter
/// Unique values are enforced. This approach gives us good flexibility
/// Allows for usage of cloud storage or IPFS pinning (and/or permastorage)
function setTokenURI(uint256 tokenId, string memory _tokenURI)
internal
virtual
{
require(
_exists(tokenId),
'ERC721URIStorage: URI set of nonexistent token'
);
bytes32 h = keccak256(abi.encode(_tokenURI));
require(hashes[h] == false);
hashes[h] = true;
badges[tokenId].tokenURI = _tokenURI;
}

/// @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.
/// based on the ERC721URIStorage implementation
function tokenURI(uint256 tokenId)
public
view
virtual
override
returns (string memory)
{
require(
_exists(tokenId),
'ERC721URIStorage: URI query for nonexistent token'
);

string memory uri = badges[tokenId].tokenURI;
string memory base = _baseURI();

// If there is no base URI, return just the uri (or hash)
if (bytes(base).length == 0) {
return uri;
}
// If both are set, concatenate the baseURI and tokenURI (via abi.encodePacked)
if (bytes(uri).length > 0) {
return string(abi.encodePacked(base, uri));
}
return super.tokenURI(tokenId);
}
}
28 changes: 28 additions & 0 deletions contracts/CO2KEN_contracts/CarbonOffsetBadgesStorage.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
// SPDX-FileCopyrightText: 2021 Toucan Labs
//
// SPDX-License-Identifier: UNLICENSED

// If you encounter a vulnerability or an issue, please contact <[email protected]> or visit security.toucan.earth
pragma solidity ^0.8.0;

import '@openzeppelin/contracts-upgradeable/utils/CountersUpgradeable.sol';

import './IToucanContractRegistry.sol';
import './CarbonProjects.sol';

contract CarbonOffsetBadgesStorage {
using CountersUpgradeable for CountersUpgradeable.Counter;

struct Data {
uint256 projectVintageTokenId;
uint256 retiredAmount;
string tokenURI;
}

string public baseURI;
address public contractRegistry;
CountersUpgradeable.Counter internal _tokenIds;

mapping(uint256 => Data) public badges;
mapping(bytes32 => bool) internal hashes;
}
Loading

0 comments on commit c32e84c

Please sign in to comment.