Skip to content

Commit

Permalink
Add sequencial and admin generation modes
Browse files Browse the repository at this point in the history
  • Loading branch information
RubenSousaDinis committed Apr 16, 2024
1 parent 2c819d9 commit a11e7c5
Show file tree
Hide file tree
Showing 7 changed files with 378 additions and 37 deletions.
84 changes: 76 additions & 8 deletions contracts/passport/PassportRegistry.sol
Original file line number Diff line number Diff line change
Expand Up @@ -30,14 +30,20 @@ contract PassportRegistry is Ownable, Pausable {
// Total number of passports created
Counters.Counter public totalCreates;

// Total number of passports publicly created
Counters.Counter public totalPublicCreates;
// Total number of passports sequencially created
Counters.Counter public totalSequencialCreates;

// Total number of passports created by admins
Counters.Counter public totalAdminsCreates;

// Total number of passport transfers
Counters.Counter public totalPassportTransfers;

// Initial id of passport creations
uint256 public initialPassportId = 1000;
// The next id to be issued
uint256 private _nextSequencialPassportId;

// Smart contract id in sequencial mode
bool private _sequencial;

// A new passport has been created
event Create(address indexed wallet, uint256 passportId, string source);
Expand All @@ -51,17 +57,54 @@ contract PassportRegistry is Ownable, Pausable {
// A passport has been activated
event Activate(address indexed wallet, uint256 passportId);

// Passport generation mode changed
event PassportGenerationChanged(bool sequencial, uint256 nextSequencialPassportId);

/**
* @dev Modifier to make a function callable only when the contract is in sequencial mode.
*
* Requirements:
*
* - The contract must be in sequencial mode.
*/
modifier whenSequencialGeneration() {
require(sequencial(), "Admin generation mode");
_;
}

/**
* @dev Modifier to make a function callable only when the contract is in admin generation mode.
*
* Requirements:
*
* - The contract must be in admin generation mode.
*/
modifier whenAdminGeneration() {
require(!sequencial(), "Sequencial generation mode");
_;
}

constructor(address contractOwner) {
transferOwnership(contractOwner);
_sequencial = false;
}

function create(string memory source) public whenNotPaused {
function create(string memory source) public whenNotPaused whenSequencialGeneration {
require(passportId[msg.sender] == 0, "Passport already exists");

uint256 newPassportId = SafeMath.add(initialPassportId, SafeMath.add(totalPublicCreates.current(), 1));
totalPublicCreates.increment();
totalSequencialCreates.increment();

_create(msg.sender, _nextSequencialPassportId, source);
_nextSequencialPassportId += 1;
}

function adminCreate(string memory source, address wallet, uint256 id) public whenNotPaused whenAdminGeneration {
require(passportId[wallet] == 0, "Passport already exists");
require(idPassport[id] == address(0), "Passport id already issued");

totalAdminsCreates.increment();

_create(msg.sender, newPassportId, source);
_create(wallet, id, source);
}

/**
Expand Down Expand Up @@ -157,6 +200,31 @@ contract PassportRegistry is Ownable, Pausable {
_unpause();
}

/**
* @notice Changes the contract generation mode.
* @dev Can only be called by the owner.
*/
function setGenerationMode(bool sequencialFlag, uint256 nextSequencialPassportId) public whenNotPaused onlyOwner {
_sequencial = sequencialFlag;
_nextSequencialPassportId = nextSequencialPassportId;

emit PassportGenerationChanged(sequencialFlag, nextSequencialPassportId);
}

/**
* @dev Returns true if the contract is in sequencial mode, and false otherwise.
*/
function sequencial() public view virtual returns (bool) {
return _sequencial;
}

/**
* @dev Returns the next id to be generated.
*/
function nextId() public view virtual returns (uint256) {
return _nextSequencialPassportId;
}

// private

function _create(address wallet, uint256 id, string memory source) private {
Expand Down
24 changes: 16 additions & 8 deletions hardhat.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { task } from "hardhat/config";

import "@typechain/hardhat";
import "@nomiclabs/hardhat-ethers";
// import "@nomicfoundation/hardhat-viem";
import "@nomiclabs/hardhat-etherscan";
import "@nomiclabs/hardhat-waffle";
import "@openzeppelin/hardhat-upgrades";
Expand All @@ -13,11 +14,11 @@ dotenv.config();

import type { HardhatUserConfig } from "hardhat/config";

const deployer = {
mnemonic: process.env.MNEMONIC || "test test test test test test test test test test test junk",
};
// const deployer = {
// mnemonic: process.env.MNEMONIC || "test test test test test test test test test test test junk",
// };

// const deployer = [""];
const deployer = [""];

task("accounts", "Prints the list of accounts", async (args, hre) => {
const accounts = await hre.ethers.getSigners();
Expand Down Expand Up @@ -60,13 +61,13 @@ const config: HardhatUserConfig = {
gasMultiplier: 1.5,
},
baseSepolia: {
url: "https://sepolia.base.org",
url: "https://api.developer.coinbase.com/rpc/v1/base-sepolia/Ip9cOQPtBOm81rN2I9_1rBiMXOfKBxii",
accounts: deployer,
chainId: 84532,
gasMultiplier: 1.5,
},
base: {
url: "https://mainnet.base.org",
url: "https://api.developer.coinbase.com/rpc/v1/base/Ip9cOQPtBOm81rN2I9_1rBiMXOfKBxii",
accounts: deployer,
chainId: 8453,
gasMultiplier: 1.5,
Expand All @@ -82,8 +83,7 @@ const config: HardhatUserConfig = {
alfajores: process.env.CELO_API_KEY || "",
polygon: process.env.POLYGON_API_KEY || "",
polygonMumbai: process.env.POLYGON_API_KEY || "",
baseSepolia: process.env.BASE_SEPOLIA_API_KEY || "",
base: process.env.BASE_SEPOLIA_API_KEY || "",
base: "DZFZ6C44B5F6TKQV1DN8F1RDSNZPVBKCKS",
},
// Custom chains that are not supported by default
customChains: [
Expand Down Expand Up @@ -111,6 +111,14 @@ const config: HardhatUserConfig = {
browserURL: "https://sepolia.basescan.org",
},
},
{
network: "base",
chainId: 8453,
urls: {
apiURL: "https://api.basescan.org/api",
browserURL: "https://basescan.org",
},
},
],
},
};
Expand Down
10 changes: 6 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
"@ethersproject/abi": "^5.0.0",
"@ethersproject/bytes": "^5.0.0",
"@ethersproject/providers": "^5.0.0",
"@nomicfoundation/hardhat-viem": "^2.0.0",
"@nomiclabs/hardhat-ethers": "^2.0.2",
"@nomiclabs/hardhat-ganache": "^2.0.0",
"@nomiclabs/hardhat-waffle": "^2.0.1",
Expand All @@ -25,14 +26,18 @@
"nft.storage": "^7.0.0",
"node-fetch": "3.3.1",
"openzeppelin-solidity": "^4.2.0",
"permissionless": "^0.1.4",
"solhint": "^3.3.6",
"solidity-coverage": "^0.8.2",
"solidity-docgen": "^0.5.16",
"ts-node": "^10.8.2",
"typechain": "^8.1.1",
"typescript": "^4.4.2"
"typescript": "^4.4.2",
"viem": "^2.7.15"
},
"devDependencies": {
"@nomicfoundation/hardhat-chai-matchers": "^1.0.6",
"@nomicfoundation/hardhat-network-helpers": "^1.0.8",
"@nomiclabs/hardhat-etherscan": "^3.1.7",
"@types/chai": "^4.3.4",
"@types/chai-as-promised": "^7.1.4",
Expand All @@ -46,10 +51,7 @@
"dotenv": "^16.0.3",
"eslint": "^8.19.0",
"ethereum-waffle": "^3.4.0",
"@nomicfoundation/hardhat-chai-matchers": "^1.0.6",
"@nomicfoundation/hardhat-network-helpers": "^1.0.8",
"hardhat-celo": "^0.0.4",
"@nomiclabs/hardhat-etherscan": "^3.1.7",
"prettier": "^2.4.1",
"prettier-plugin-solidity": "^1.0.0-beta.18",
"solc": "^0.8.17"
Expand Down
2 changes: 1 addition & 1 deletion scripts/passport/deployPassportRegistry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { ethers, network } from "hardhat";
import { deployPassport } from "../shared";

async function main() {
console.log(`Deploying buy vTal package ${network.name}`);
console.log(`Deploying passport registry at ${network.name}`);

const [admin] = await ethers.getSigners();

Expand Down
58 changes: 58 additions & 0 deletions scripts/passport/transferPassportOwnership.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import hre from "hardhat";

import { createPublicClient, http, getContract } from "viem";
import { baseSepolia, base } from "viem/chains";
import { privateKeyToSimpleSmartAccount } from "permissionless/accounts";
import { createPimlicoPaymasterClient } from "permissionless/clients/pimlico";

import { ethers } from "hardhat";

import * as PassportRegistry from "../../artifacts/contracts/passport/PassportRegistry.sol/PassportRegistry.json";

const ENTRYPOINT = "0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789";

async function main() {
const [admin] = await hre.viem.getWalletClients();
const publicClient = await hre.viem.getPublicClient();
const chain = baseSepolia;

console.log(`Changing owner on chain ${chain.name}`);

// https://api.developer.coinbase.com/rpc/v1/base/w6ubd9S5jJzUzPlMn0yYmuP9UWbjKvrH
const rpcUrl = "https://api.developer.coinbase.com/rpc/v1/base-sepolia/Ip9cOQPtBOm81rN2I9_1rBiMXOfKBxii";
const contractAddress = "0x7aFEB24C9448139c82ECD3427F4cFf2c9630Aa0B";
const privateKey = "0x0";

console.log("privateKey", privateKey);
const smartAccount = await privateKeyToSimpleSmartAccount(publicClient, {
privateKey,
entryPoint: ENTRYPOINT, // global entrypoint
factoryAddress: "0x9406Cc6185a346906296840746125a0E44976454",
});

console.log(`Owner SCA ${smartAccount.address}`);

const passportRegistry = getContract({
address: contractAddress,
abi: PassportRegistry.abi,
client: {
public: publicClient,
wallet: admin,
},
});

const tx = await passportRegistry.write.transferOwnership([smartAccount.address]);

await publicClient.waitForTransactionReceipt({ hash: tx });

const owner = await passportRegistry.read.owner();

console.log(`New owner: ${owner}`);
}

main()
.then(() => process.exit(0))
.catch((error) => {
console.error(error);
process.exit(1);
});
Loading

0 comments on commit a11e7c5

Please sign in to comment.