Skip to content

Commit d1a775b

Browse files
author
Yash Agrawal
committed
Merge remote-tracking branch 'origin/main' into feat-add-test
2 parents a67fe2c + 7163544 commit d1a775b

File tree

11 files changed

+1109
-36
lines changed

11 files changed

+1109
-36
lines changed

.env.example

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
1+
PRIVATE_KEY=''
12
MNEMONIC='Mnemonic'
3+
24
INFURA_KEY=''
3-
ETHERSCAN_KEY=''
5+
ALCHEMY_API_KEY=''
6+
47
ARBISCAN_KEY=''
8+
ETHERSCAN_KEY=''
59
POLYGONSCAN_KEY=''

.eslintrc.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
},
2222
"overrides": [
2323
{
24-
"files": ["test/**/*.ts"],
24+
"files": ["test/**/*.ts", "scripts/**/*.ts"],
2525
"rules": {
2626
"@typescript-eslint/no-unsafe-call": "off",
2727
"@typescript-eslint/no-unsafe-assignment": "off"

.prettierignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,4 @@ cache
33
artifacts/
44
typechain-types/
55
cache/
6+
.openzeppelin/

contracts/SBTFactory.sol

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ contract SBTFactory is ISBTFactory, OwnableUpgradeable {
2727
address[] calldata minters,
2828
bytes calldata identifier
2929
) external override onlyOwner returns (address) {
30+
require(sbtProxyMapping[identifier] == address(0), "Identifier already used");
31+
3032
// Create the implementation.
3133
address implementation = address(
3234
new SBT{salt: keccak256(identifier)}()

hardhat.config.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
import '@typechain/hardhat'
2+
import * as dotenv from 'dotenv'
23
import '@nomiclabs/hardhat-ethers'
34
import '@nomiclabs/hardhat-waffle'
4-
import '@nomiclabs/hardhat-etherscan'
5+
import '@nomicfoundation/hardhat-verify'
6+
import '@openzeppelin/hardhat-upgrades'
57
import type { HardhatUserConfig } from 'hardhat/config'
6-
import * as dotenv from 'dotenv'
78

89
dotenv.config()
910

@@ -59,7 +60,8 @@ const config: HardhatUserConfig = {
5960
},
6061
},
6162
polygonMumbai: {
62-
url: `https://polygon-mumbai.infura.io/v3/${process.env.INFURA_KEY!}`,
63+
url: `https://polygon-mumbai.g.alchemy.com/v2/${process.env
64+
.ALCHEMY_API_KEY!}`,
6365
accounts: {
6466
mnemonic: mnemnoc,
6567
},

package.json

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,16 +15,18 @@
1515
"build": "tsc -p tsconfig.build.json",
1616
"prebuild": "yarn generate",
1717
"clean": "del 'artifacts'",
18-
"prepare": "husky install"
18+
"prepare": "husky install",
19+
"deploy:polygonMumbai": "npx hardhat run scripts/deploy.ts --network polygonMumbai"
1920
},
2021
"author": "Dev Protocol",
2122
"license": "MPL-2.0",
2223
"devDependencies": {
2324
"@devprotocol/util-contracts": "^3.3.0",
25+
"@nomicfoundation/hardhat-verify": "^2.0.5",
2426
"@nomiclabs/hardhat-ethers": "2.2.3",
25-
"@nomiclabs/hardhat-etherscan": "3.1.8",
2627
"@nomiclabs/hardhat-waffle": "2.0.6",
2728
"@openzeppelin/contracts": "4.8.2",
29+
"@openzeppelin/hardhat-upgrades": "1.28.0",
2830
"@types/chai": "4.3.11",
2931
"@types/dotenv": "8.2.0",
3032
"@types/mocha": "10.0.6",

scripts/deploy.ts

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
import { ethers, run } from 'hardhat'
2+
import { type ContractTransaction } from 'ethers'
3+
4+
async function main() {
5+
console.log('Starting deploy script on sbt-tokens...')
6+
7+
const [signer] = await ethers.getSigners()
8+
console.log('Signer is: ', signer.address)
9+
console.log()
10+
11+
// @TODO: modify this when deploying...
12+
const minterUpdater = signer.address
13+
// @TODO: modify this when deploying...
14+
const minters = [signer.address]
15+
// @TODO: modify this address when deploying...
16+
const proxyAdmin = '0xec4562C829661c891FcEadb44F831c8a5e71bC8F'
17+
18+
// >>> Deploy SBT implementation >>>
19+
console.log('Deploying SBT implementation...')
20+
const sbtFactory = await ethers.getContractFactory('SBT')
21+
const sbtImplementation = await sbtFactory.deploy()
22+
const sbtImplementationDeployTxn = sbtImplementation.deployTransaction
23+
console.log(
24+
` - SBT implementation deploying at txn hash:${sbtImplementationDeployTxn.hash}`
25+
)
26+
await sbtImplementation.deployed()
27+
console.log(
28+
` - SBT implementation deployed at address:${sbtImplementation.address}`
29+
)
30+
await sbtImplementationDeployTxn.wait(2)
31+
console.log()
32+
33+
// >>> Deploy SBTProxy >>>
34+
console.log('Deploying SBT proxy...')
35+
const sbtProxyFactory = await ethers.getContractFactory('SBTProxy')
36+
const sbtProxyInstance = await sbtProxyFactory.deploy(
37+
sbtImplementation.address,
38+
proxyAdmin,
39+
ethers.utils.arrayify('0x')
40+
)
41+
const sbtProxyInstanceDeployTxn = sbtProxyInstance.deployTransaction
42+
console.log(
43+
` - SBT proxy deploying at txn hash:${sbtProxyInstanceDeployTxn.hash}`
44+
)
45+
await sbtProxyInstance.deployed()
46+
console.log(` - SBT proxy deployed at address:${sbtProxyInstance.address}`)
47+
await sbtProxyInstanceDeployTxn.wait(2)
48+
console.log()
49+
50+
// >>> Initialize SBT Proxy >>>
51+
console.log('Initializing SBT proxy...')
52+
const sbtProxy = sbtFactory.attach(sbtProxyInstance.address)
53+
const tx = (await sbtProxy.functions.initialize(
54+
minterUpdater,
55+
minters
56+
)) as ContractTransaction
57+
console.log(` - Initializing at transaction with hash:${tx.hash}`)
58+
await tx.wait(1)
59+
console.log(` - Initializing done.`)
60+
console.log()
61+
62+
// >>> Verify SBTImplementation code >>>
63+
console.log('Verifying SBT implementation contract...')
64+
await run(`verify:verify`, {
65+
address: sbtImplementation.address,
66+
constructorArguments: [],
67+
})
68+
console.log()
69+
70+
// >>> Verify SBTProxy code >>>
71+
console.log('Verifying SBT proxy contract...')
72+
await run(`verify:verify`, {
73+
address: sbtProxyInstance.address,
74+
contract: 'contracts/SBTProxy.sol:SBTProxy',
75+
constructorArguments: [
76+
sbtImplementation.address,
77+
proxyAdmin,
78+
ethers.utils.arrayify('0x'),
79+
],
80+
})
81+
console.log()
82+
}
83+
84+
main()
85+
.then(() => process.exit(0))
86+
.catch((error) => {
87+
console.error(error)
88+
process.exit(1)
89+
})

scripts/deploySBTFactory.ts

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
import { ethers, run, upgrades } from 'hardhat'
2+
import type { SBTFactory__factory } from '../typechain-types'
3+
4+
async function main() {
5+
console.log('Starting deploySBTFactory script on sbt-tokens...')
6+
7+
const [signer] = await ethers.getSigners()
8+
console.log('Signer is: ', signer.address)
9+
console.log()
10+
11+
// >>> Deploy SBTFactory >>>
12+
console.log('Deploying SBTFactory...')
13+
const sbtFactoryFactory = (await ethers.getContractFactory(
14+
'SBTFactory'
15+
)) as SBTFactory__factory
16+
const sbtFactoryInstance = await upgrades.deployProxy(sbtFactoryFactory, [])
17+
18+
const sbtFactoryInstanceDeployTxn = sbtFactoryInstance.deployTransaction
19+
console.log(
20+
` - SBTFactory deploying at txn:${sbtFactoryInstanceDeployTxn.hash}`
21+
)
22+
await sbtFactoryInstance.deployed()
23+
console.log(` - SBTFactory deployed at address:${sbtFactoryInstance.address}`)
24+
await sbtFactoryInstanceDeployTxn.wait(2)
25+
console.log()
26+
27+
// >>> Verify SBTFactory code >>>
28+
console.log('Verifying SBTFactory contract...')
29+
await run(`verify:verify`, {
30+
address: sbtFactoryInstance.address,
31+
constructorArguments: [],
32+
})
33+
console.log()
34+
}
35+
36+
main()
37+
.then(() => process.exit(0))
38+
.catch((error) => {
39+
console.error(error)
40+
process.exit(1)
41+
})

scripts/deployWithSBTFactory.ts

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
/* eslint-disable @typescript-eslint/prefer-readonly-parameter-types */
2+
3+
import { ethers, run } from 'hardhat'
4+
import type { ContractTransaction } from 'ethers'
5+
6+
import { wait } from './utils/wait'
7+
8+
async function main() {
9+
console.log('Starting deploySBTFactory script on sbt-tokens...')
10+
11+
const [signer] = await ethers.getSigners()
12+
console.log('Signer is: ', signer.address)
13+
console.log()
14+
15+
// @TODO: modify this when deploying...
16+
const minterUpdater = signer.address
17+
// @TODO: modify this when deploying...
18+
const minters = [signer.address]
19+
// @TODO: change this whenever required.
20+
const proxyCalldata = ethers.utils.arrayify('0x')
21+
// @TODO: modify this address when deploying...
22+
const proxyAdmin = '0xec4562C829661c891FcEadb44F831c8a5e71bC8F'
23+
// @TODO: check and change this whenever required.
24+
const identifier = ethers.utils.formatBytes32String('Test Achievement SBT')
25+
// @TODO: check and change this whenever required.
26+
const sbtFactoryAddress = '0x0F0b8697169aF45FC61814C3e5b4d784a909b9A7'
27+
28+
// >>> Deploy using SBTFactory >>>
29+
console.log('Deploying new SBT using SBTFactory...')
30+
const sbtFactoryInstance = await ethers.getContractAt(
31+
'SBTFactory',
32+
sbtFactoryAddress
33+
)
34+
const txn = (await sbtFactoryInstance.functions.makeNewSBT(
35+
proxyAdmin,
36+
proxyCalldata,
37+
minterUpdater,
38+
minters,
39+
identifier
40+
)) as ContractTransaction
41+
console.log(` - SBT deployment using SBTFactory at txn:${txn.hash}`)
42+
const txReceipt = await txn.wait(10)
43+
const logs = txReceipt.logs.map((log) => {
44+
try {
45+
// Because here events/logs contains some deployment/general blockchain events which cannot be parsed by contract.interface.
46+
const l = sbtFactoryInstance.interface.parseLog(log)
47+
return l
48+
} catch (err) {
49+
// Hence, we are removing those as we do not need those events.
50+
return { name: '', args: [] }
51+
}
52+
})
53+
const proxyCreationLog = logs.find((log) => log.name === 'SBTProxyCreated')
54+
const implementationCreationLog = logs.find(
55+
(log) => log.name === 'SBTImplementationCreated'
56+
)
57+
58+
const proxyContractAddress = proxyCreationLog?.args.at(1) as string
59+
const implementationContractAddress = implementationCreationLog?.args.at(
60+
1
61+
) as string
62+
63+
await wait(30 * 1000) // For block explorer to scan newly deployed address and attach it's bytecode to it.
64+
if (implementationCreationLog) {
65+
console.log(
66+
` - SBT implementation deployed at addr:${implementationContractAddress}`
67+
)
68+
console.log(' - Verifying SBT implementation contract...')
69+
await run(`verify:verify`, {
70+
address: implementationContractAddress,
71+
contract: 'contracts/SBT.sol:SBT',
72+
constructorArguments: [],
73+
})
74+
}
75+
76+
await wait(30 * 1000) // For block explorer to scan newly deployed address and attach it's bytecode to it.
77+
78+
if (proxyCreationLog) {
79+
console.log(` - SBT proxy deployed at addr:${proxyContractAddress}`)
80+
console.log(' - Verifying SBT proxy contract...')
81+
await run(`verify:verify`, {
82+
address: proxyContractAddress,
83+
contract: 'contracts/SBTProxy.sol:SBTProxy',
84+
constructorArguments: [
85+
implementationContractAddress,
86+
proxyAdmin,
87+
proxyCalldata,
88+
],
89+
})
90+
}
91+
92+
console.log()
93+
}
94+
95+
main()
96+
.then(() => process.exit(0))
97+
.catch((error) => {
98+
console.error(error)
99+
process.exit(1)
100+
})

scripts/utils/wait.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
export const wait = async (ms: number) =>
2+
new Promise((resolve) => {
3+
setInterval(resolve, ms)
4+
})

0 commit comments

Comments
 (0)