Skip to content

Commit

Permalink
Merge pull request #16 from majin-land/update-eas-logic
Browse files Browse the repository at this point in the history
Update eas logic
  • Loading branch information
imajindev authored Aug 11, 2024
2 parents 67a3d86 + cd77802 commit 7319b44
Show file tree
Hide file tree
Showing 22 changed files with 939 additions and 137 deletions.
26 changes: 26 additions & 0 deletions apps/contract/scripts/deploy-purchase-ticket.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
// We require the Hardhat Runtime Environment explicitly here. This is optional
// but useful for running the script in a standalone fashion through `node <script>`.
//
// When running the script with `npx hardhat run <script>` you'll find the Hardhat
// Runtime Environment's members available in the global scope.
require('dotenv').config({ path: '../.env' })
const { ethers } = require('hardhat')

async function main() {
const [deployer] = await ethers.getSigners()
console.log('Deploying contracts with the account:', deployer.address)

console.log('deployer', deployer)

const PurchaseTicket = await ethers.getContractFactory('PurchaseTicket')
const purchaseTicket = await PurchaseTicket.deploy('0xcDbFCE45c57b31Dc8B196aB58F74E2b8e478fc7e')

console.log('PurchaseTicket details:', purchaseTicket)
}

// We recommend this pattern to be able to use async/await everywhere
// and properly handle errors.
main().catch((error) => {
console.error(error)
process.exitCode = 1
})
26 changes: 26 additions & 0 deletions apps/contract/scripts/deploy-ticket-redeem-v2.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
// We require the Hardhat Runtime Environment explicitly here. This is optional
// but useful for running the script in a standalone fashion through `node <script>`.
//
// When running the script with `npx hardhat run <script>` you'll find the Hardhat
// Runtime Environment's members available in the global scope.
require('dotenv').config({ path: '../.env' })
const { ethers } = require('hardhat')

async function main() {
const [deployer] = await ethers.getSigners()
console.log('Deploying contracts with the account:', deployer.address)

console.log('deployer', deployer)

const RedeemResolverV2 = await ethers.getContractFactory('RedeemResolverV2')
const redeemResolverV2 = await RedeemResolverV2.deploy('0x4200000000000000000000000000000000000021', '0xcDbFCE45c57b31Dc8B196aB58F74E2b8e478fc7e')

console.log('RedeemResolverV2 details:', redeemResolverV2)
}

// We recommend this pattern to be able to use async/await everywhere
// and properly handle errors.
main().catch((error) => {
console.error(error)
process.exitCode = 1
})
7 changes: 0 additions & 7 deletions apps/contract/scripts/deploy-ticket-redeem.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,9 @@ async function main() {

console.log('deployer', deployer)

// const deployerBalance = (await deployer.getBalance()).toString()
// console.log('Account balance:', deployerBalance)

// if (deployerBalance === '0') return // deployment will fail

const RedeemResolver = await ethers.getContractFactory('RedeemResolver')
const redeemResolver = await RedeemResolver.deploy('0x4200000000000000000000000000000000000021')
await redeemResolver.deployed()

console.log('RedeemResolver deployed to:', redeemResolver.address)
console.log('RedeemResolver details:', redeemResolver)
}

Expand Down
40 changes: 0 additions & 40 deletions apps/contract/src/PuchaseTicket.sol

This file was deleted.

59 changes: 59 additions & 0 deletions apps/contract/src/PurchaseTicket.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
// SPDX-License-Identifier: MIT
pragma solidity 0.8.20;

import "@openzeppelin/contracts/access/Ownable.sol";
import { Address } from "@openzeppelin/contracts/utils/Address.sol";

contract PurchaseTicket is Ownable {
using Address for address payable;

error AlreadyPurchased();
error AlreadyIssued();
error Duplicate();
error Insufficient();

address private paymentAddress;

mapping(string => mapping(string => uint256)) private prices;
mapping(string => mapping(string => bool)) private proofs;
mapping(string => mapping(string => bool)) private ticketSeats;

constructor(address _paymentAddress) Ownable(msg.sender) {
paymentAddress = _paymentAddress;
}

function setPrice(string memory eventId, string memory ticketType, uint256 price) external onlyOwner {
prices[eventId][ticketType] = price;
}

function getPrice(string memory eventId, string memory ticketType) public view returns (uint256) {
return prices[eventId][ticketType];
}

function purchase(
string memory eventId,
string memory seat,
string memory ticketType,
string memory worldProof
) external payable {
bool purchased = proofs[eventId][worldProof];
if (purchased == true) {
revert AlreadyPurchased();
}

bool issued = ticketSeats[eventId][seat];
if (issued == true) {
revert AlreadyIssued();
}

uint256 price = prices[eventId][ticketType];
if (msg.value < price) {
revert Insufficient();
}

proofs[eventId][worldProof] = true;
ticketSeats[eventId][seat] = true;
payable(paymentAddress).transfer(msg.value);
}

}
2 changes: 0 additions & 2 deletions apps/contract/src/RedeemResolver.sol
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@

// redeem ticket attestation resolver
// SPDX-License-Identifier: MIT
pragma solidity 0.8.20;

Expand Down
116 changes: 116 additions & 0 deletions apps/contract/src/RedeemResolverV2.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
// SPDX-License-Identifier: MIT
pragma solidity 0.8.20;

import { SchemaResolver } from "@ethereum-attestation-service/eas-contracts/contracts/resolver/SchemaResolver.sol";
import { IEAS, Attestation } from "@ethereum-attestation-service/eas-contracts/contracts/IEAS.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
import { Address } from "@openzeppelin/contracts/utils/Address.sol";

contract RedeemResolverV2 is SchemaResolver, Ownable {
using Address for address payable;

error OutOfBounds();
error AlreadyPurchased();
error AlreadyIssued();
error Duplicate();
error Insufficient();

address private paymentAddress;

mapping(bytes32 => bool) private redeemedMap;
mapping(string => mapping(string => uint256)) private prices;
mapping(string => mapping(string => bool)) private proofs;
mapping(string => mapping(string => bool)) private ticketSeats;
mapping(address => mapping(string => bool)) private ticketRecipients;
mapping(address => string[]) private ticketRecipientsArr;

constructor(IEAS eas, address _paymentAddress) SchemaResolver(eas) Ownable(msg.sender) {
paymentAddress = _paymentAddress;
}

function isPayable() public pure override returns (bool) {
return true;
}

function setPrice(string memory eventId, string memory ticketType, uint256 price) external onlyOwner {
prices[eventId][ticketType] = price;
}

function getPrice(string memory eventId, string memory ticketType) public view returns (uint256) {
return prices[eventId][ticketType];
}

function getTickets() public view returns (string[] memory) {
return ticketRecipientsArr[msg.sender];
}

function purchase(
string memory eventId,
string memory seat,
string memory ticketType,
string memory worldProof,
string memory attestationId
) external payable {
bool purchased = proofs[eventId][worldProof];
if (purchased == true) {
revert AlreadyPurchased();
}

bool issued = ticketSeats[eventId][seat];
if (issued == true) {
revert AlreadyIssued();
}

bool recipient = ticketRecipients[msg.sender][attestationId];
if (recipient == true) {
revert Duplicate();
}

uint256 price = prices[eventId][ticketType];
if (msg.value < price) {
revert Insufficient();
}

proofs[eventId][worldProof] = true;
ticketSeats[eventId][seat] = true;
ticketRecipients[msg.sender][attestationId] = true;
ticketRecipientsArr[msg.sender].push(attestationId);
payable(paymentAddress).transfer(msg.value);
}

function onAttest(Attestation calldata attestation, uint256 /*value*/) internal view override returns (bool) {
bytes32 uid = _toBytes32(attestation.data, 0);
string memory uidStr = string(abi.encodePacked(uid));
bool exist = ticketRecipients[attestation.recipient][uidStr];
if (exist == true) {
return true;
}

return false;
}

function onRevoke(Attestation calldata /*attestation*/, uint256 /*value*/) internal pure override returns (bool) {
return true;
}

function toBytes32(bytes memory data, uint256 start) external pure returns (bytes32) {
return _toBytes32(data, start);
}

function _toBytes32(bytes memory data, uint256 start) private pure returns (bytes32) {
unchecked {
if (data.length < start + 32) {
revert OutOfBounds();
}
}

bytes32 tempBytes32;

// solhint-disable-next-line no-inline-assembly
assembly {
tempBytes32 := mload(add(add(data, 0x20), start))
}

return tempBytes32;
}
}
Loading

0 comments on commit 7319b44

Please sign in to comment.