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

add redeem resolver #12

Merged
merged 1 commit into from
Aug 10, 2024
Merged
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
11 changes: 10 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -129,4 +129,13 @@ dist
.yarn/install-state.gz
.pnp.*

.nx
.nx

#Hardhat files
coverage
coverage.json
typechain
cache
artifacts
.openzeppelin
build
1 change: 1 addition & 0 deletions apps/contract/.env.sample
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
TESTNET_PRIVATE_KEY=
7 changes: 7 additions & 0 deletions apps/contract/.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 apps/contract/.solhintignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
node_modules
105 changes: 105 additions & 0 deletions apps/contract/hardhat.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
const fs = require('fs')
const fsExtra = require('fs-extra')
const { subtask, task } = require('hardhat/config')
const { TASK_CLEAN, TASK_COMPILE } = require('hardhat/builtin-tasks/task-names')
// require('@nomiclabs/hardhat-waffle')
// require('@nomiclabs/hardhat-ethers')
require('hardhat-deploy')
require('hardhat-contract-sizer')
require('@openzeppelin/hardhat-upgrades')

require('dotenv').config({ path: './.env' })

let mnemonic = process.env.MNEMONIC
if (!mnemonic) {
mnemonic = 'test test test test test test test test test test test junk'
}
const mnemonicAccounts = {
mnemonic,
}

const account = {
Testnet: process.env.TESTNET_PRIVATE_KEY,
Mainnet: process.env.MAINNET_PRIVATE_KEY,
}

// Default output dir to abi contracts in frontend
const contractsFrontDir = './compiled'

// You need to export an object to set up your config
// Go to https://hardhat.org/config/ to learn more

/**
* @type import('hardhat/config').HardhatUserConfig
*/
const config = {
solidity: {
version: '0.8.20',
settings: {
evmVersion: "paris",
optimizer: {
enabled: true,
runs: 200,
},
},
},
paths: {
sources: './src',
tests: './test',
cache: './cache',
artifacts: './artifacts',
},
defaultNetwork: 'optimismSepolia',
networks: {
hardhat: {
accounts: mnemonicAccounts,
},
optimismSepolia: {
url: 'https://sepolia.optimism.io',
chainId: 11155420,
accounts: account.Testnet ? [account.Testnet] : mnemonicAccounts,
},
},
namedAccounts: {
deployer: {
default: 0, // here this will by default take the first account as deployer
},
},
mocha: {
timeout: 50000, // 50 seconds timeout
},
}

// // This is a sample Hardhat task. To learn how to create your own go to
// // https://hardhat.org/guides/create-task.html
// task('accounts', 'Prints the list of accounts', async (taskArgs, hre) => {
// const accounts = await hre.ethers.getSigners()
// accounts.forEach((acc) => {
// console.log(acc.address)
// })
// })

task(TASK_CLEAN, 'Clean all artifacts & folder contracts in frontend').setAction(async (taskArgs, hre, runSuper) => {
await runSuper()
if (fs.existsSync('./deployments')) {
fs.rmdirSync('./deployments', { recursive: true })
}
await hre.run('clean-front-contracts')
})

subtask('clean-front-contracts', 'Clear frontend contracts folder').setAction(async () => {
// Clear if exist
if (fs.existsSync(contractsFrontDir)) {
fsExtra.emptyDirSync(contractsFrontDir)
}
})

task(TASK_COMPILE, 'Deploy contracts').setAction(async (taskArgs, hre, runSuper) => {
console.log('TASK_COMPILE', taskArgs)
if (!fs.existsSync(contractsFrontDir)) {
fs.mkdirSync(contractsFrontDir, { recursive: true })
}
await runSuper(taskArgs)
})

module.exports = config
33 changes: 33 additions & 0 deletions apps/contract/scripts/deploy-ticket-redeem.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
// 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 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)
}

// 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
})
53 changes: 53 additions & 0 deletions apps/contract/src/RedeemResolver.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@

// redeem ticket attestation resolver
// 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";

contract RedeemResolver is SchemaResolver {
error OutOfBounds();

mapping(bytes32 => bool) private redeemedMap;

constructor(IEAS eas) SchemaResolver(eas) {
}

function onAttest(Attestation calldata attestation, uint256 /*value*/) internal override returns (bool) {
bytes32 uid = _toBytes32(attestation.data, 0);

bool redeemed = redeemedMap[uid];
if (redeemed == true) {
return false;
}
redeemedMap[uid] = true;

return true;
}

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