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

Team Vought #35

Open
wants to merge 6 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
12 changes: 12 additions & 0 deletions vought/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
node_modules
.env
coverage
coverage.json
typechain
typechain-types

frontend/node_modules
# Hardhat files
cache
artifacts

85 changes: 85 additions & 0 deletions vought/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
# ICC Eliminator Submission

We have fully implemented the plethora of ideas that we proposed and gone beyond that as well. Going forward, this can be integrated with ICC apps to increase revenue, fan engagement, and much more!

## Team Information
---

### Team Name - Vought

### Track - Fintech track

### Brief Description

A complete end-to-end application on blockchain integrating all ICC products, gamifying and incentivising fan interactions for better engagement, and onboarding users to Web3.

![image](https://user-images.githubusercontent.com/58487637/222705512-b1ae3484-2af0-41f3-9275-39101ea49917.png)

## Features and screenshots
---
You can either checkout the [video demo](https://drive.google.com/file/d/1xc-V2izsE-yKXzvprn5py-Rr9IxVYq5w/view?usp=sharing) (less than 4 minutes) or view the screenshots below!

### Smooth onboarding for Web2 users
#### Option to login with wallet (like Metamask) or socials (like Google, Facebook, Email).

![onboard](https://user-images.githubusercontent.com/58487637/222707145-f7f653a7-73cd-43cc-842b-2fb8610b4204.png)

### Dashboard
#### All your score and activity tracked across ICC products. Streak is also maintained so the users have motivation to use the app daily.

![localhost_3000_](https://user-images.githubusercontent.com/58487637/222706590-5e5b1610-b97f-4367-96f8-ccc236a8c27c.png)

### Leaderboard
#### Leaderboard based on your interaction activity. Increases engagement by social proof. Fans divided into leagues. High leagues unlock special benefits.

![Leaderboard](https://user-images.githubusercontent.com/58487637/222707473-0a5b37b2-4374-4171-b926-289eec566504.png)

### Tickets
#### Tickets are sold as NFTs that allow asset tracking, curb ticket scalping, provide access to exclusive content and communities. Financial transactions like buying tickets award loyalty points. These can also be sold for sentimental values or for the runs and points they award.

![ticket](https://user-images.githubusercontent.com/58487637/222708085-1ef33ee4-fe9f-403d-9414-83e083d697e9.png)

### Merchandise
#### Loyalty points can be redeemed to buy merch.

![merchandise](https://user-images.githubusercontent.com/58487637/222707584-d9fc3c43-1121-4e4e-8a80-a3a765c8be89.png)

### Buy points
#### Loyalty points can also be bought for in-app payments. Acts as additional revenue stream.

![points](https://user-images.githubusercontent.com/58487637/222708626-e7db6715-74c4-4ad0-8464-5ed343a8040a.png)

### ICC TV
#### Fans watch ICC TV and are rewarded based on their watch time.

![iccTV](https://user-images.githubusercontent.com/58487637/222707917-630f03b5-e44d-4e13-92d5-286ff5c0fb6e.png)

### ICC Awards
#### Fans can vote for their favorite players on Awards and get runs to climb the leaderboard and progress through leagues.

![iccAwards](https://user-images.githubusercontent.com/58487637/222708763-fd145b04-ca47-4618-8821-e9d18db5ac04.png)

### Quizzes
#### Events like quizzes and polls can be conducted on a regular basis. Fans are awarded runs based on their performance.

![quiz](https://user-images.githubusercontent.com/58487637/222709151-2cd953d3-951f-4199-b016-685b5231946b.png)

### Buy Crypto
#### In-app crypto purchases to pay for tickets, points, etc.

![transak](https://user-images.githubusercontent.com/58487637/222709267-9542330e-7db6-4201-826a-808db673ad40.png)

### View NFTs
#### All your ICC assets such as tickets can be viewed here.

![nfts](https://user-images.githubusercontent.com/58487637/222709532-7e9bd31d-6543-43d9-9150-68cfd7b61fcd.png)

### Testing playground
#### Some functionalities that can't be demonstrated without repeated use of the app, we have created a playground to test those functionalities. (We didn't miss a single detail!!!)

![testing](https://user-images.githubusercontent.com/58487637/222710252-1aaf28d6-fa96-488f-8e68-89c0bb173c6b.png)

### Notifications
#### Reminders about streaks, leaderboard position changes, etc are sent out through notifications. This keeps bringing the fans back to our app.

![notify](https://user-images.githubusercontent.com/58487637/222711241-76989c7c-c46a-494c-8285-019dd57c8708.jpg)
56 changes: 56 additions & 0 deletions vought/contracts/1_Seamless.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.9;

import "hardhat/console.sol";

contract Seamless {
address payable public owner;
uint costPerPoint = 5 wei;

struct ScoreCard {
uint runs;
uint streak;
uint lastActivityDay;
int points;
}

mapping(address => ScoreCard) public scores;

event Activity(address user, string name, uint runs, int points);

constructor() {
owner = payable(msg.sender);
}

function awardScore(uint _runs, int _points, address _to) internal returns (ScoreCard memory) {
scores[_to].runs += _runs;
scores[_to].points += _points;

uint currentDay = block.timestamp / 86400;
uint difference = currentDay - scores[_to].lastActivityDay;
if(difference == 1) scores[_to].streak++;
else if(difference > 1) scores[_to].streak = 1;

scores[_to].lastActivityDay = currentDay;
return scores[_to];
}

function performActivity(address _user, string memory _activityName, uint _runs, int _points) public returns (ScoreCard memory) {
emit Activity(_user, _activityName, _runs, _points);

ScoreCard memory updatedScoreCard = awardScore(_runs, _points, _user);
return updatedScoreCard;
}

function redeemPoints(address user, int points, uint runs, string memory item) external {
require(scores[user].points >= points, "Not enough points");
performActivity(user, item, runs, -points);
}

function buyPoints(int _points) external payable {
require(costPerPoint * uint(_points) <= msg.value, "Not enough funds sent to buy points.");

emit Activity(msg.sender, "Bought points", 0, _points);
scores[msg.sender].points += _points;
}
}
88 changes: 88 additions & 0 deletions vought/contracts/2_MatchTicket.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.9;

import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
import "@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/utils/Counters.sol";

import "./1_Seamless.sol";

import "hardhat/console.sol";

contract MatchTicket is ERC721, ERC721Enumerable, Ownable {
using Counters for Counters.Counter;

Counters.Counter private _tokenIdCounter;
Seamless private seamless;

struct Ticket {
string seat;
uint matchId;
bool checkedIn;
string matchName;
string venue;
string date;
string matchType;
}

event StadiumCheckin(address user, uint matchid, string seat);
event BuyTicket(address user, string seat, uint matchId, string matchName, string venue, string date, string matchType);

mapping(uint => Ticket) public tokenData;

constructor(Seamless _seamless) ERC721("MatchTicket", "ICC") {
seamless = _seamless;
}

function changeSeamless(Seamless _seamless) external onlyOwner {
seamless = _seamless;
}

function safeMint(address to, string memory seat, uint matchId, uint price, uint runs, int points, string memory matchName, string memory venue, string memory date, string memory matchType) external payable {
require(msg.value >= price, "Not enough funds provided to buy the ticket");

uint256 tokenId = _tokenIdCounter.current();
_tokenIdCounter.increment();
_safeMint(to, tokenId);
tokenData[tokenId] = Ticket(seat, matchId, false, matchName, venue, date, matchType);
seamless.performActivity(to, "Bought match ticket", runs, points);
emit BuyTicket(to, seat, matchId, matchName, venue, date, matchType);
}

function areStringsEqual(string memory a, string memory b) internal pure returns (bool) {
return (keccak256(abi.encodePacked((a))) == keccak256(abi.encodePacked((b))));
}

function ticketCheckin(address user, string memory seat, uint matchId) external returns (bool) {
uint numberOfNFTs = balanceOf(user);

for(uint i = 0; i < numberOfNFTs; ++i) {
uint tokenId = tokenOfOwnerByIndex(user, i);
if(tokenData[tokenId].matchId == matchId && areStringsEqual(tokenData[tokenId].seat, seat)) {
if(tokenData[tokenId].checkedIn == true) return true;
tokenData[tokenId].checkedIn = true;
seamless.performActivity(user, "Checked in to stadium", 25, 0);
emit StadiumCheckin(user, matchId, seat);
return true;
}
}
return false;
}

function _beforeTokenTransfer(address from, address to, uint256 tokenId, uint256 batchSize)
internal
override(ERC721, ERC721Enumerable)
{
super._beforeTokenTransfer(from, to, tokenId, batchSize);
}

function supportsInterface(bytes4 interfaceId)
public
view
override(ERC721, ERC721Enumerable)
returns (bool)
{
return super.supportsInterface(interfaceId);
}
}
70 changes: 70 additions & 0 deletions vought/frontend/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
# Getting Started with Create React App

This project was bootstrapped with [Create React App](https://github.com/facebook/create-react-app).

## Available Scripts

In the project directory, you can run:

### `npm start`

Runs the app in the development mode.\
Open [http://localhost:3000](http://localhost:3000) to view it in your browser.

The page will reload when you make changes.\
You may also see any lint errors in the console.

### `npm test`

Launches the test runner in the interactive watch mode.\
See the section about [running tests](https://facebook.github.io/create-react-app/docs/running-tests) for more information.

### `npm run build`

Builds the app for production to the `build` folder.\
It correctly bundles React in production mode and optimizes the build for the best performance.

The build is minified and the filenames include the hashes.\
Your app is ready to be deployed!

See the section about [deployment](https://facebook.github.io/create-react-app/docs/deployment) for more information.

### `npm run eject`

**Note: this is a one-way operation. Once you `eject`, you can't go back!**

If you aren't satisfied with the build tool and configuration choices, you can `eject` at any time. This command will remove the single build dependency from your project.

Instead, it will copy all the configuration files and the transitive dependencies (webpack, Babel, ESLint, etc) right into your project so you have full control over them. All of the commands except `eject` will still work, but they will point to the copied scripts so you can tweak them. At this point you're on your own.

You don't have to ever use `eject`. The curated feature set is suitable for small and middle deployments, and you shouldn't feel obligated to use this feature. However we understand that this tool wouldn't be useful if you couldn't customize it when you are ready for it.

## Learn More

You can learn more in the [Create React App documentation](https://facebook.github.io/create-react-app/docs/getting-started).

To learn React, check out the [React documentation](https://reactjs.org/).

### Code Splitting

This section has moved here: [https://facebook.github.io/create-react-app/docs/code-splitting](https://facebook.github.io/create-react-app/docs/code-splitting)

### Analyzing the Bundle Size

This section has moved here: [https://facebook.github.io/create-react-app/docs/analyzing-the-bundle-size](https://facebook.github.io/create-react-app/docs/analyzing-the-bundle-size)

### Making a Progressive Web App

This section has moved here: [https://facebook.github.io/create-react-app/docs/making-a-progressive-web-app](https://facebook.github.io/create-react-app/docs/making-a-progressive-web-app)

### Advanced Configuration

This section has moved here: [https://facebook.github.io/create-react-app/docs/advanced-configuration](https://facebook.github.io/create-react-app/docs/advanced-configuration)

### Deployment

This section has moved here: [https://facebook.github.io/create-react-app/docs/deployment](https://facebook.github.io/create-react-app/docs/deployment)

### `npm run build` fails to minify

This section has moved here: [https://facebook.github.io/create-react-app/docs/troubleshooting#npm-run-build-fails-to-minify](https://facebook.github.io/create-react-app/docs/troubleshooting#npm-run-build-fails-to-minify)
31 changes: 31 additions & 0 deletions vought/frontend/config-overrides.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
const webpack = require("webpack");

module.exports = function override(config) {
const fallback = config.resolve.fallback || {};
Object.assign(fallback, {
crypto: require.resolve("crypto-browserify"),
stream: require.resolve("stream-browserify"),
assert: require.resolve("assert"),
http: require.resolve("stream-http"),
https: require.resolve("https-browserify"),
os: require.resolve("os-browserify"),
url: require.resolve("url"),
});
config.resolve.fallback = fallback;
config.plugins = (config.plugins || []).concat([
new webpack.ProvidePlugin({
process: "process/browser",
Buffer: ["buffer", "Buffer"],
}),
]);
config.ignoreWarnings = [/Failed to parse source map/];
config.module.rules.push({
test: /\.(js|mjs|jsx)$/,
enforce: "pre",
loader: require.resolve("source-map-loader"),
resolve: {
fullySpecified: false,
},
});
return config;
};
Loading