Skip to content

Commit

Permalink
feat: added External Contributors NFT collection
Browse files Browse the repository at this point in the history
  • Loading branch information
bezerrablockchain committed Oct 21, 2024
1 parent 92f735e commit 7b4bf07
Show file tree
Hide file tree
Showing 5 changed files with 171 additions and 0 deletions.
28 changes: 28 additions & 0 deletions contracts/NFT/ExternalContributorsEcosystemPartner.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
// SPDX-License-Identifier: MIT
// Compatible with OpenZeppelin Contracts ^5.0.0
pragma solidity ^0.8.20;

import {ERC721UpgradableAirdroppable} from "./ERC721UpgradableAirdroppable.sol";

contract ExternalContributorsEcosystemPartner is ERC721UpgradableAirdroppable {
/// @custom:oz-upgrades-unsafe-allow constructor
constructor() {
_disableInitializers();
}

function initialize(
string calldata contractName,
string calldata symbol,
address initialOwner,
uint256 maxNftSupply
) public initializer {
__ERC721Airdroppable_init(maxNftSupply);
__ERC721UpgradableBase_init(contractName, symbol, initialOwner);
}

function _authorizeUpgrade(address newImplementation) internal virtual override onlyOwner {}

function _baseURI() internal pure override returns (string memory) {
return "ipfs://";
}
}
35 changes: 35 additions & 0 deletions ignition/modules/ExternalContributorsEcosystemPartner.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { buildModule } from '@nomicfoundation/hardhat-ignition/modules'

export const extContributersEpProxyModule = buildModule('ExtContributorsEP', m => {
// deploy implementation
const implementation = m.contract('ExternalContributorsEcosystemPartner', [], { id: 'Implementation' })

// initializer parameters
const contractName = m.getParameter('contractName')
const contractSymbol = m.getParameter('symbol')
const deployer = m.getAccount(0)
const maxNftSupply = m.getParameter('maxNftSupply')

// deploy proxy
const proxy = m.contract('ERC1967Proxy', [
implementation,
m.encodeFunctionCall(
implementation,
'initialize',
[contractName, contractSymbol, deployer, maxNftSupply],
{ id: 'Proxy' },
),
])
const ExtContributorsEP = m.contractAt('ExternalContributorsEcosystemPartner', proxy, {
id: 'Contract',
})

// Airdrop
const ipfsCids = m.getParameter('ipfsCids')
const airdropAddresses = m.getParameter('airdropAddresses')
m.call(ExtContributorsEP, 'airdrop', [ipfsCids, airdropAddresses])

return { ExtContributorsEP }
})

export default extContributersEpProxyModule
9 changes: 9 additions & 0 deletions params/ExtContributorsEP/mainnet.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"ExtContributorsEP": {
"contractName": "ExternalContributorsEcosystemPartner",
"symbol": "ECEP",
"maxNftSupply": 5,
"ipfsCids": [],
"airdropAddresses": []
}
}
21 changes: 21 additions & 0 deletions params/ExtContributorsEP/testnet.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{
"ExtContributorsEP": {
"contractName": "ExternalContributorsEcosystemPartner",
"symbol": "ECEP",
"maxNftSupply": 5,
"ipfsCids": [
"QmeGNJxhSToWYvHucUMX4D2fX8Uk2aL8CujwFuGw2Moy9U",
"QmPFcgjgqCMoEbBmkbnvwaknENTH3WckjCGYekQhXJFVzn",
"Qme6NCykZUUv78jXydTgmmehHThVXpJHFxAbZvEJkkPk5o",
"QmUrqydS9kLYDJtv6dY7suhT5m5UPxJe1K1yq9b7QoY1VD",
"QmcbYfu8CuhHRfRmDHwc8P8vqpgnYSCuzLcwtr5n4afMKb"
],
"airdropAddresses": [
"0x70997970C51812dc3A010C7d01b50e0d17dc79C8",
"0x3C44CdDdB6a900fa2b585dd299e03d12FA4293BC",
"0x90F79bf6EB2c4f870365E785982E1f101E93b906",
"0x15d34AAf54267DB7D7c367839AAf71A00a2C6A65",
"0x9965507D1a55bcC2695C58ba16FB37d819B0A4dc"
]
}
}
78 changes: 78 additions & 0 deletions test/ExtContributorsEP.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
import { expect } from 'chai'
import hre, { ethers, ignition } from 'hardhat'
import { ExternalContributorsEcosystemPartner } from '../typechain-types'
import { SignerWithAddress } from '@nomicfoundation/hardhat-ethers/signers'
import { extContributersEpProxyModule } from '../ignition/modules/ExternalContributorsEcosystemPartner'
import deployParams from '../params/ExtContributorsEP/testnet.json'

describe('ExternalContributorsEcosystemPartner NFT', () => {
let deployer: SignerWithAddress
let alice: SignerWithAddress
const oldGangsters: SignerWithAddress[] = []
let extContEP: ExternalContributorsEcosystemPartner

before(async () => {
;[deployer, alice] = await ethers.getSigners()
const contract = await ignition.deploy(extContributersEpProxyModule, {
parameters: deployParams,
})
// impersonating airdrop receivers
for (let i = 0; i < deployParams.ExtContributorsEP.airdropAddresses.length; i++) {
const senderAddr = deployParams.ExtContributorsEP.airdropAddresses[i]
await hre.network.provider.request({
method: 'hardhat_impersonateAccount',
params: [senderAddr],
})
const sender = await ethers.getSigner(senderAddr)
oldGangsters.push(sender)
}
extContEP = contract.ExtContributorsEP as unknown as ExternalContributorsEcosystemPartner
})

describe('Upon deployment', () => {
it('should set up proper NFT name and symbol', async () => {
expect(await extContEP.connect(deployer).name()).to.equal(deployParams.ExtContributorsEP.contractName)
expect(await extContEP.symbol()).to.equal(deployParams.ExtContributorsEP.symbol)
})

it('should have performed airdrop during deployment', async () => {
const ipfsCids = deployParams.ExtContributorsEP.ipfsCids
for (let i = 0; i < oldGangsters.length; i++) {
expect(await extContEP.ownerOf(i + 1)).to.equal(oldGangsters[i].address)
expect(await extContEP.tokenURI(i + 1)).to.equal(`ipfs://${ipfsCids[i]}`)
}
})
})

describe('Transfer functionality is disabled', () => {
it('transfers should be forbidden after airdrop', async () => {
await Promise.all(
oldGangsters.map(async (sender, i) => {
await expect(
extContEP.connect(sender).transferFrom(sender.address, alice.address, i + 1),
).to.be.revertedWithCustomError(extContEP, 'TransfersDisabled')
}),
)
})

it('approvals should be forbidden', async () => {
await Promise.all(
oldGangsters.map(async (sender, i) => {
await expect(

Check warning on line 61 in test/ExtContributorsEP.test.ts

View workflow job for this annotation

GitHub Actions / test

Replace `⏎············extContEP.connect(sender).approve(alice.address,·i·+·1),⏎··········).to.be.revertedWithCustomError(extContEP,·'TransfersDisabled'` with `extContEP.connect(sender).approve(alice.address,·i·+·1)).to.be.revertedWithCustomError(⏎············extContEP,⏎············'TransfersDisabled',⏎··········`
extContEP.connect(sender).approve(alice.address, i + 1),
).to.be.revertedWithCustomError(extContEP, 'TransfersDisabled')
}),
)
})

it('setApprovalForAll should be forbidden', async () => {
await Promise.all(
oldGangsters.map(async sender => {
await expect(
extContEP.connect(sender).setApprovalForAll(alice.address, true),
).to.be.revertedWithCustomError(extContEP, 'TransfersDisabled')
}),
)
})
})
})

0 comments on commit 7b4bf07

Please sign in to comment.