Skip to content

Commit

Permalink
Merge pull request #54 from TogetherCrew/feat/update-contract
Browse files Browse the repository at this point in the history
update contract
  • Loading branch information
mehdi-torabiv authored Nov 26, 2024
2 parents 6507f2c + 29aec65 commit 506853f
Show file tree
Hide file tree
Showing 27 changed files with 69,720 additions and 64,872 deletions.
18 changes: 9 additions & 9 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -36,12 +36,12 @@ jobs:
coverageLocations: |
${{github.workspace}}/coverage/lcov.info:lcov
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
- run: yarn install
- run:
npx hardhat node &
yarn deploy
# deploy:
# runs-on: ubuntu-latest
# steps:
# - uses: actions/checkout@v4
# - uses: actions/setup-node@v4
# - run: yarn install
# - run:
# npx hardhat node &
# yarn deploy
156 changes: 147 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,151 @@
# TogetherCrew Engagement Hardhat Project
# **Engagement Contract**

This project contains the TogetherCrew Engagement contract. It comes with a contract, a test for that contract, and a Hardhat Ignition module that deploys that contract.
## **Overview**
The **Engagement Contract** is a blockchain-based solution for communities to manage reputation and engagement through token issuance and scoring mechanisms. It allows communities to:
- **Issue unique tokens** for their ecosystem.
- **Mint tokens** for individual users based on their activities.
- **Calculate and retrieve reputation scores** for community members using the **OCI (On-Chain Identity) platform**.
- **Manage token metadata** dynamically with customizable URIs.

Try running some of the following tasks:
This project is built with Solidity, Hardhat, and OpenZeppelin libraries, ensuring secure and efficient smart contract development.

```shell
npx hardhat help
npx hardhat test
REPORT_GAS=true npx hardhat test
npx hardhat node
npx hardhat ignition deploy ./ignition/modules/Engagement.ts
## **Contract Addresses**

| Address | Network |
|-------------------------------------------------------------------------------------------------|--------------------------|
| N/A | Sepolia |
| https://sepolia-optimism.etherscan.io/address/0xd826769f1844cc83a16923d2aef8a479e62da732 | Optimisim Sepolia |

---

## **Features**
- **Token Management**:
- Issue new tokens unique to the community.
- Mint tokens for users with checks to prevent duplicate mints.
- Burn tokens for revocation or updates.
- **Reputation Scoring**:
- Calculate and retrieve scores for users based on token data and identifiers.
- Attest reputation scores to users' wallets for on-chain verification.
- **Dynamic Metadata**:
- Supports customizable token URIs for dynamic metadata management.
- **Admin Controls**:
- Update base URIs.
- Manage token issuance securely with access control.

---

## **Tech Stack**
- **Smart Contracts**:
- **Solidity**: Core language for smart contract development.
- **OpenZeppelin**: Secure and reusable contract components.
- **Development Framework**:
- **Hardhat**: Ethereum development environment.
- **Hardhat Ignition**: Advanced deployment and parameter management.
- **Testing and Analysis**:
- **Chai**: For contract testing.
- **Solidity Coverage**: Analyze code coverage for Solidity tests.
- **Linting and Formatting**:
- **Biome**: Code quality and formatting tools.

---

## **Installation**

1. **Clone the Repository**:
```bash
git clone https://github.com/your-username/engagement.git
cd engagement
```

2. **Install Dependencies**:
```bash
npm install
```

3. **Set Environment Variables**:
Create a `.env` file in the root directory and set the following:
```plaintext
TOKEN_URI=http://127.0.0.1:8545/
```

---

## **Usage**

### **Compile Contracts**
Run the following command to compile the contracts:
```bash
npm run compile
```

### **Run Tests**
Execute the test suite to ensure everything is working as expected:
```bash
npm run test
```

### **Deploy Contracts**
To deploy the contracts on a local Hardhat network:
1. Start a local Hardhat node:
```bash
npx hardhat node
```
2. Deploy the contracts:
```bash
npm run deploy:localhost
```

### **Check Coverage**
Analyze the test coverage for your contracts:
```bash
npm run coverage
```

### **Lint and Format Code**
Lint the project for issues:
```bash
npm run lint
```
Format the project files:
```bash
npm run format
```

---

## **Folder Structure**
```plaintext
.
├── contracts/ # Solidity contracts
│ ├── Engagement.sol # Core engagement contract
│ ├── IEngagement.sol # Interface for engagement contract
├── ignition/
│ └── modules/ # Deployment modules for Hardhat Ignition
│ └── Engagement.ts # Engagement contract deployment module
├── scripts/ # Deployment scripts
│ └── deploy.ts # Hardhat deployment script
├── test/ # Test files for the contracts
├── hardhat.config.ts # Hardhat configuration file
├── package.json # Project metadata and scripts
├── .env # Environment variables
└── README.md # Project documentation
```

---

## **Contributing**

Contributions are welcome! Please follow these steps:
1. Fork the repository.
2. Create a new branch (`git checkout -b feature-name`).
3. Commit your changes (`git commit -m "Add feature-name"`).
4. Push to your branch (`git push origin feature-name`).
5. Submit a pull request.

---

## **Acknowledgments**
- **OpenZeppelin**: For providing secure and reusable smart contract components.
- **Hardhat Team**: For building a robust Ethereum development environment.
- **OCI Platform**: For enabling seamless identity and reputation management.
- **TogetherCrew**: For driving innovation in community engagement and blockchain-based solutions.
39 changes: 39 additions & 0 deletions biome.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
{
"$schema": "https://biomejs.dev/schemas/1.9.4/schema.json",
"vcs": {
"enabled": false,
"clientKind": "git",
"useIgnoreFile": false
},
"files": {
"ignoreUnknown": false,
"ignore": [
"./node_modules",
"./artifacts",
"./coverage",
"./.nyc_output",
"./.vscode"
]
},
"formatter": {
"enabled": true,
"indentStyle": "tab"
},
"organizeImports": {
"enabled": true
},
"linter": {
"enabled": true,
"rules": {
"recommended": true,
"suspicious": {
"noExplicitAny": "off"
}
}
},
"javascript": {
"formatter": {
"quoteStyle": "double"
}
}
}
65 changes: 28 additions & 37 deletions contracts/Engagement.sol
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,12 @@ contract Engagement is IEngagement, ERC1155, AccessControl {
using ERC165Checker for address;

uint private _counter;
bytes32 public constant PROVIDER_ROLE = keccak256("PROVIDER_ROLE");
string private _tokenURI;

mapping(uint tokenId => string metadata) private _tokenMetadata;
mapping(uint date => string cid) private _scores;

constructor() ERC1155("") {
constructor(string memory tokenURI_) ERC1155("") {
requireNonEmptyURI(tokenURI_);
_grantRole(DEFAULT_ADMIN_ROLE, msg.sender);
_tokenURI = tokenURI_;
}

function _checkTokenId(uint tokenId) private view {
Expand All @@ -26,6 +25,12 @@ contract Engagement is IEngagement, ERC1155, AccessControl {
}
}

function requireNonEmptyURI(string memory newUri) internal pure {
if (bytes(newUri).length == 0) {
revert URIEmpty("URI cannot be empty");
}
}

modifier validTokenId(uint tokenId) {
_checkTokenId(tokenId);
_;
Expand All @@ -38,13 +43,19 @@ contract Engagement is IEngagement, ERC1155, AccessControl {
_;
}

modifier nonEmptyAccount(string memory account) {
if (bytes(account).length == 0) {
revert EmptyAccountNotAllowed("Account cannot be empty");
}
_;
}

function counter() external view returns (uint) {
return _counter;
}

function issue(string memory hash_) external {
function issue() external {
uint counterCache = _counter;
_tokenMetadata[counterCache] = hash_;
_mint(msg.sender, counterCache, 1, "");
emit Issue(msg.sender, counterCache);
_counter = counterCache + 1;
Expand Down Expand Up @@ -72,33 +83,6 @@ contract Engagement is IEngagement, ERC1155, AccessControl {
emit Burn(account, tokenId, 1);
}

function getScores(
uint date,
uint id,
string memory account
) external view override validTokenId(id) returns (string memory) {
return
string(
abi.encodePacked(
"ipfs://",
_scores[date],
"/",
Strings.toString(id),
"/",
account,
".json"
)
);
}

function updateScores(
uint date,
string memory cid
) external override onlyRole(PROVIDER_ROLE) {
_scores[date] = cid;
emit UpdateScores(msg.sender, date, cid);
}

function supportsInterface(
bytes4 interfaceId
) public view override(AccessControl, ERC1155) returns (bool) {
Expand All @@ -108,12 +92,19 @@ contract Engagement is IEngagement, ERC1155, AccessControl {
return false;
}

function updateBaseURI(string memory newURI) external onlyRole(DEFAULT_ADMIN_ROLE) {
requireNonEmptyURI(newURI);
emit BaseURIUpdated(_tokenURI, newURI);
_tokenURI = newURI;
}

function uri(
uint tokenId
) public view override validTokenId(tokenId) returns (string memory) {
uint tokenId,
string memory account
) public view validTokenId(tokenId) nonEmptyAccount(account) returns (string memory) {
return
string(
abi.encodePacked("ipfs://", _tokenMetadata[tokenId], ".json")
abi.encodePacked(_tokenURI,"/api/v1/nft/",Strings.toString(tokenId),"/",account,"/reputation-score")
);
}
}
14 changes: 5 additions & 9 deletions contracts/IEngagement.sol
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,17 @@ interface IEngagement {
event Issue(address indexed account, uint indexed tokenId);
event Mint(address indexed account, uint indexed tokenId, uint amount);
event Burn(address indexed account, uint indexed tokenId, uint amount);
event UpdateScores(address indexed account, uint indexed date, string cid);
event BaseURIUpdated(string oldURI, string newURI);

error NotFound(uint tokenId);
error MintLimit(address account, uint tokenId);
error NotAllowed(address account, uint tokenId);
error URIEmpty(string message);
error EmptyAccountNotAllowed(string message);

function counter() external view returns (uint);

function issue(string memory hash) external;
function issue() external;

function mint(
address account,
Expand All @@ -24,11 +26,5 @@ interface IEngagement {

function burn(address account, uint tokenId, uint amount) external;

function getScores(
uint date,
uint id,
string memory account
) external view returns (string memory);

function updateScores(uint date, string memory cid) external;
function updateBaseURI(string memory newURI) external;
}
Loading

0 comments on commit 506853f

Please sign in to comment.