Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SUStainability Tokens (SUST): Everyone's Crypto #74

Open
wants to merge 37 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
67d73ef
ReadMe changes
munivenkateswarluk Sep 21, 2022
837081d
ReadMe Updates
munivenkateswarluk Sep 21, 2022
c2a3a0f
ReadMe Updates
munivenkateswarluk Sep 21, 2022
dab7ddb
Adding image
munivenkateswarluk Sep 21, 2022
024c2bc
Adding image
munivenkateswarluk Sep 21, 2022
80f609c
System design image
munivenkateswarluk Sep 21, 2022
4c8d84d
Trying relative images
munivenkateswarluk Sep 21, 2022
ab49b97
Relative image
munivenkateswarluk Sep 21, 2022
0f22b4a
System design update
munivenkateswarluk Sep 21, 2022
658acf3
Added smart contracts
munivenkateswarluk Sep 26, 2022
1a0f4e0
Working smart contracts
munivenkateswarluk Sep 27, 2022
b327e81
Working bare smart contracts
munivenkateswarluk Sep 27, 2022
7e262d2
creating oracle impl file
munivenkateswarluk Oct 1, 2022
6c19b53
Oracle consumption requester
munivenkateswarluk Oct 5, 2022
d1d34d7
Access control contract added
munivenkateswarluk Oct 7, 2022
e2e1ebc
String to byte and int functionality
munivenkateswarluk Oct 7, 2022
11a5bd1
Ethprice oracle
munivenkateswarluk Oct 14, 2022
04d3252
ethprice requestor
munivenkateswarluk Oct 14, 2022
ff1b9cb
Acess control interface defined
munivenkateswarluk Oct 14, 2022
7b7e9a3
Access control setup
munivenkateswarluk Oct 21, 2022
04cacc4
Adding access control to ERC20
munivenkateswarluk Oct 21, 2022
36058ee
Access roles defined for each function
munivenkateswarluk Oct 21, 2022
11b51f1
Access roles redefined and tested on token factory contract
munivenkateswarluk Oct 28, 2022
f686635
Randomization oracle is added
munivenkateswarluk Oct 29, 2022
355afad
EthPrice Provable contract added
munivenkateswarluk Nov 1, 2022
934e40a
Working implementation
munivenkateswarluk Nov 1, 2022
21e9c64
Project UI
munivenkateswarluk Nov 5, 2022
e83fcd3
Submission version
munivenkateswarluk Nov 14, 2022
b44446d
Final submission - Phase 1
munivenkateswarluk Nov 14, 2022
44c274d
SUST UI
munivenkateswarluk Nov 14, 2022
307edb9
SUST UI
munivenkateswarluk Nov 14, 2022
f63eb4c
delete ui folder
munivenkateswarluk Nov 14, 2022
263f520
delete folder
munivenkateswarluk Nov 14, 2022
297128c
Final Version - Frontend and smart contracts
munivenkateswarluk Nov 14, 2022
8da4ba4
ReadMe update - Project execution steps included
munivenkateswarluk Nov 14, 2022
0f5c587
Readme update - Project executions steps updated
munivenkateswarluk Nov 14, 2022
6b05317
Readme update - next steps removed
munivenkateswarluk Nov 14, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added .DS_Store
Binary file not shown.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@

*.DS_Store
Binary file not shown.
40 changes: 40 additions & 0 deletions SUStaianabilityTokens_EveryonesCrypto/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@

## ⚡ SUStainability Tokens (SUST): Everyone's Crypto ⚡

### Team name
Catalyst Technologies Ltd
#### Hackathon Track
DeFi (ReFi) - Public Good
##### Region location
Calgary, Canada
##### Team Members
- Muni V K, Blockchain Developer, Catalyst Technologies Ltd.

#### Project Description
Aligning with Celo’s mission to enable a financial system that creates the conditions for prosperity and bring the benefits of digital assets to all, our goal is to recognize and reward both crypto and non-crypto savvy individuals, for their regenerative behaviour and practices for the prosperity of a healthy planet.

The aim of our project is to create a global regenerative economy by providing equal opportunity for every individual on the planet to get incentives from the new crypto market initiatives such as airdrops. The incentives encourage the individuals to adopt and/or continue sustainable practices to preserve and restore natural habituate of the planet.
For example, we create opportunities for individuals (called users hereafter) to get continuous crypto incentives for their sustainable practices like, when they use their own reusable bags or at the least not to buy new bags (especially plastic) when they do shopping (e.g., grocery shopping at a Walmart), when they recycle (e.g., depositing recycling plastic with a bottle depot), when they participate in a community sustainable projects (e.g., ocean cleanup organized by NGOs), clean and green energy initiative (e.g., installing solar power system), etc.

#### Summary
To aligning with Celo’s mission of bringing the benefits of digital assets to all by removing systemic inequalities, we propose to tokenize sustainability behaviours and efforts to reward the individuals exercising the regenerative behaviour.
For example, let us take the example of using reusable bags or avoiding plastic bags usage while shopping. Users who exercise this sustainability behaviour will be issued a specific ERC20 token, called SUStainability Token (SUST), on Celo platform. SUST holders are given preference when new crypto projects are launched and opt to distribute their tokens out to the greater population through airdrops. Higher the number of token holdings higher the priority during the airdrops.

#### How to run the project
- Step 1 : Clone the repo
- Step 2 : Make sure you have Node installed
- Step 3 : Open the terminal and navigate to the "frontend" folder
- Step 4 : run the command "npm install"
- Step 5 : run the command "npm start"
- Step 6 : Open a web browser and type localhost:3000 and enter
- Step 7 : Have fun with the UI

#### URLs
Check this video for the sample execution of the project:
https://youtube.com/playlist?list=PLi6LaqPTG8nZ1y17BvBlvLYjX__5BuRZ3

#### System design
![System design](SUST_system_design.png)

#### License
This repository includes an [unlicensed](http://unlicense.org/) statement though you may want to [choose a different license](https://choosealicense.com/).
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
126 changes: 126 additions & 0 deletions SUStaianabilityTokens_EveryonesCrypto/contracts/1Roles.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
//SPDX-License-Identifier: MIT

import "@openzeppelin/contracts/access/AccessControl.sol";
import "@openzeppelin/contracts/security/Pausable.sol";

pragma solidity >=0.8.0;

/************************************** CONTRACT **************************************/

contract Roles is AccessControl, Pausable {
bytes32 public constant ADDRESS_MANAGER_ROLE = keccak256("ADDRESS_MANAGER_ROLE");
bytes32 public constant MINTER_ROLE = keccak256("MINTER_ROLE");
bytes32 public constant PAUSER_ROLE = keccak256("PAUSER_ROLE");

constructor()
Pausable() {

_setupRole(DEFAULT_ADMIN_ROLE, msg.sender);

_grantRole(ADDRESS_MANAGER_ROLE, msg.sender);
_grantRole(MINTER_ROLE, msg.sender);
_grantRole(PAUSER_ROLE, msg.sender);

_setRoleAdmin(ADDRESS_MANAGER_ROLE, DEFAULT_ADMIN_ROLE);
_setRoleAdmin(MINTER_ROLE, DEFAULT_ADMIN_ROLE);
_setRoleAdmin(PAUSER_ROLE, DEFAULT_ADMIN_ROLE);
}

/************************************** ROLES **************************************/

/******* ADMIN_ROLE *******/
function grantSuperAdminRole(address account) public whenNotPaused {
require(hasRole(DEFAULT_ADMIN_ROLE, msg.sender), "Access Denied: Caller is NOT SUPER ADMIN!");
require(account != address(0), "Account: Zero or Invalid address!");

grantRole(DEFAULT_ADMIN_ROLE, account);
grantRole(ADDRESS_MANAGER_ROLE, account);
grantRole(MINTER_ROLE, account);
grantRole(PAUSER_ROLE, account);
}

function revokeSuperAdminRole(address account) public {
require(hasRole(DEFAULT_ADMIN_ROLE, msg.sender), "Access Denied: Caller is NOT SUPER ADMIN!");
require(account != address(0), "Account: Zero or Invalid address!");

revokeRole(DEFAULT_ADMIN_ROLE, account);
revokeRole(ADDRESS_MANAGER_ROLE, account);
revokeRole(MINTER_ROLE, account);
revokeRole(PAUSER_ROLE, account);
}

function isSuperAdmin(address account) public virtual view returns(bool) {
return hasRole(DEFAULT_ADMIN_ROLE, account);
}


/******* ADDRESS_MANAGER_ROLE *******/
function grantAddressManagerRole(address account) public whenNotPaused {
require(hasRole(DEFAULT_ADMIN_ROLE, msg.sender), "Access Denied: Caller is NOT SUPER ADMIN!");
require(account != address(0), "Account: Zero or Invalid address!");
grantRole(ADDRESS_MANAGER_ROLE, account);
}

function revokeAddressManagerRole(address account) public {
require(hasRole(DEFAULT_ADMIN_ROLE, msg.sender), "Access Denied: Caller is NOT SUPER ADMIN!");
require(account != address(0), "Account: Zero or Invalid address!");
revokeRole(ADDRESS_MANAGER_ROLE, account);
}

function isAddressManager(address account) public virtual view returns(bool) {
return hasRole(ADDRESS_MANAGER_ROLE, account);
}

/******* MINTER_ROLE *******/
function grantMinterRole(address account) public whenNotPaused {
require(hasRole(DEFAULT_ADMIN_ROLE, msg.sender), "Access Denied: Caller is NOT SUPER ADMIN!");
require(account != address(0), "Account: Zero or Invalid address!");
grantRole(MINTER_ROLE, account);
}

function revokeMinterRole(address account) public { //onlyRole(ROLES_MANAGER) {
require(hasRole(DEFAULT_ADMIN_ROLE, msg.sender), "Access Denied: Caller is NOT SUPER ADMIN!");
require(account != address(0), "Account: Zero or Invalid address!");
revokeRole(MINTER_ROLE, account);
}

function isMinter(address account) public virtual view returns(bool) {
return hasRole(MINTER_ROLE, account);
}

/******* PAUSER_ROLE *******/
function grantPauserRole(address account) public whenNotPaused {
require(hasRole(DEFAULT_ADMIN_ROLE, msg.sender), "Access Denied: Caller is NOT SUPER ADMIN!");
require(account != address(0), "Account: Zero or Invalid address!");
grantRole(PAUSER_ROLE, account);
}

function revokePauserRole(address account) public {
require(hasRole(DEFAULT_ADMIN_ROLE, msg.sender), "Access Denied: Caller is NOT SUPER ADMIN!");
require(account != address(0), "Account: Zero or Invalid address!");
revokeRole(PAUSER_ROLE, account);
}

function isPauser(address account) public virtual view returns(bool) {
return hasRole(PAUSER_ROLE, account);
}


//----------------------- PAUSER FUNCTIONS -----------------------//

function pauseContract() public whenNotPaused {
require(hasRole(PAUSER_ROLE, msg.sender), "Access Denied: Caller is NOT PAUSER!");
_pause();
}

function unpauseContract() public whenPaused {
require(hasRole(PAUSER_ROLE, msg.sender), "Access Denied: Caller is NOT PAUSER!");
_unpause();
}

//----------------------- KILL FUNCTIONS -----------------------//
function killRolesContract() public {
require(hasRole(DEFAULT_ADMIN_ROLE, msg.sender), "Access Denied: Caller is NOT SUPER ADMIN!");
selfdestruct(payable(msg.sender));
}
}
67 changes: 67 additions & 0 deletions SUStaianabilityTokens_EveryonesCrypto/contracts/2SUST_ERC20.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
// SPDX-License-Identifier: MIT
pragma solidity >=0.8.0;

import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import "@openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol";
import "@openzeppelin/contracts/security/Pausable.sol";
import "@openzeppelin/contracts/access/AccessControl.sol";

interface RolesI {
function isSuperAdmin(address account) external view returns(bool);
function isAddressManager(address account) external view returns(bool);
function isMinter(address account) external view returns(bool);
function isPauser(address account) external view returns(bool);
}

contract SUStaianablilityTokens is ERC20, ERC20Burnable, Pausable, AccessControl {

address private rolesSC;

event MintEvent(address, uint256);

constructor(address _rolesContractAddress) ERC20("SUStaianable Tokens", "SUST") {
rolesSC = _rolesContractAddress;
}

function mintSUST(address to, uint256 amount) public { //onlyRole(MINTER_ROLE) {
require(RolesI(rolesSC).isMinter(msg.sender), "Access Denied: Caller is NOT Minter!");
_mint(to, amount);

emit MintEvent(to, amount);
}

function _beforeTokenTransfer(address from, address to, uint256 amount)
internal
whenNotPaused
override
{
super._beforeTokenTransfer(from, to, amount);
}

//----------------------- SET ADDRESS FUNCTIONS -----------------------//

function setRolesContractAddress(address _rolesSC) public whenNotPaused {
require(RolesI(rolesSC).isAddressManager(msg.sender), "Access Denied: Caller is NOT Address Manager!");
require(_rolesSC != address(0), "Account: Zero or Invalid address!");
rolesSC = _rolesSC;
}

//----------------- PAUSER FUNCTION ----------------//

function pauseContract() public whenNotPaused {
require(RolesI(rolesSC).isPauser(msg.sender), "Access Denied: Caller is NOT Pauser!");
_pause();
}

function unpauseContract() public whenPaused {
require(RolesI(rolesSC).isPauser(msg.sender), "Access Denied: Caller is NOT Pauser!");
_unpause();
}

//----------------- KILL FUNCTION ----------------//

function killCarbonCreditsERC20() public whenNotPaused {
require(RolesI(rolesSC).isSuperAdmin(msg.sender), "Access Denied: Caller is NOT a SUPER ADMIN!");
selfdestruct(payable(msg.sender));
}
}
73 changes: 73 additions & 0 deletions SUStaianabilityTokens_EveryonesCrypto/contracts/3BandOracle.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;
pragma experimental ABIEncoderV2;

interface IStdReference {
/// A structure returned whenever someone requests for standard reference data.
struct ReferenceData {
uint256 rate; // base/quote exchange rate, multiplied by 1e18.
uint256 lastUpdatedBase; // UNIX epoch of the last time when base price gets updated.
uint256 lastUpdatedQuote; // UNIX epoch of the last time when quote price gets updated.
}

/// Returns the price data for the given base/quote pair. Revert if not available.
function getReferenceData(string memory _base, string memory _quote)
external
view
returns (ReferenceData memory);

/// Similar to getReferenceData, but with multiple base/quote pairs at once.
function getReferenceDataBulk(string[] memory _bases, string[] memory _quotes)
external
view
returns (ReferenceData[] memory);
}

contract BandOracle {
IStdReference ref;
uint flag = 1;

uint256 public price;

constructor(IStdReference _ref) {
ref = _ref;
}

function getPrice() external view returns (uint256){
IStdReference.ReferenceData memory data = ref.getReferenceData("CELO","USD");
if(flag == 1)
return data.rate;
else
return 0;
}

function flipFlag() external {
if(flag == 0)
flag = 1;
else
flag = 0;
}

function getMultiPrices() external view returns (uint256[] memory){
string[] memory baseSymbols = new string[](2);
baseSymbols[0] = "CELO";
baseSymbols[1] = "CELO";

string[] memory quoteSymbols = new string[](2);
quoteSymbols[0] = "USD";
quoteSymbols[1] = "ETH";
IStdReference.ReferenceData[] memory data = ref.getReferenceDataBulk(baseSymbols,quoteSymbols);

uint256[] memory prices = new uint256[](2);
prices[0] = data[0].rate;
prices[1] = data[1].rate;

return prices;
}

function savePrice(string memory base, string memory quote) external {
IStdReference.ReferenceData memory data = ref.getReferenceData(base,quote);
price = data.rate;
}
}
60 changes: 60 additions & 0 deletions SUStaianabilityTokens_EveryonesCrypto/contracts/4FrontFace.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
//SPDX-License-Identifier: MIT

pragma solidity >=0.8.0;

import "@openzeppelin/contracts/access/AccessControl.sol";
import "@openzeppelin/contracts/security/Pausable.sol";
import "@openzeppelin/contracts/security/ReentrancyGuard.sol";

/************************************** INTERFACES **************************************/
interface RolesI {
function isSuperAdmin(address account) external view returns(bool);
function isAddressManager(address account) external view returns(bool);
function isMinter(address account) external view returns(bool);
function isPauser(address account) external view returns(bool);
}

interface SUSTokenFactoryI {
function mintSUST(address, uint256) external;
}

interface BandOracleI {
function getPrice() external view returns (uint256);
}

contract FrontFace is Pausable, AccessControl {
address private tokenFactoryAddress;
address private rolesSC;
address private bandOracleAddress;

constructor (address _rolesContractAddress, address _tokenFactoryAddress, address _bandOracleAddress) {
tokenFactoryAddress = _tokenFactoryAddress;
rolesSC = _rolesContractAddress;
bandOracleAddress = _bandOracleAddress;
}

//----------------------- SET ADDRESS FUNCTIONS -----------------------//
function setTokenFactoryAddress(address _tokenFactoryAddress) public whenNotPaused {
require(RolesI(rolesSC).isAddressManager(msg.sender), "Access Denied: Caller is NOT Super Admin!");
require(_tokenFactoryAddress != address(0), "Account: Zero or Invalid address!");
tokenFactoryAddress = _tokenFactoryAddress;
}

function setRolesContractAddress(address _rolesSC) public whenNotPaused {
require(RolesI(rolesSC).isAddressManager(msg.sender), "Access Denied: Caller is NOT Super Admin!");
require(_rolesSC != address(0), "Account: Zero or Invalid address!");
rolesSC = _rolesSC;
}

//----------------------- SEND RECEIPT FUNCTION -----------------------//
function sendReceipt(uint receiptNum) public whenNotPaused {
require(receiptNum != 0, "Input Error: Receipt number is zero or invalid!");
require(BandOracleI(bandOracleAddress).getPrice() != 0, "CELO/USD price is ZERO!");
SUSTokenFactoryI(tokenFactoryAddress).mintSUST(msg.sender, 10 * (10 ** 18));
}

function killContract() public whenNotPaused{
require(RolesI(rolesSC).isSuperAdmin(msg.sender), "Access Denied: Caller is NOT SUPER ADMIN!");
selfdestruct(payable(msg.sender));
}
}
23 changes: 23 additions & 0 deletions SUStaianabilityTokens_EveryonesCrypto/frontend/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.

# dependencies
/node_modules
/.pnp
.pnp.js

# testing
/coverage

# production
/build

# misc
.DS_Store
.env.local
.env.development.local
.env.test.local
.env.production.local

npm-debug.log*
yarn-debug.log*
yarn-error.log*
Loading