-
Notifications
You must be signed in to change notification settings - Fork 3
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
fix: Single integration test for deploy campaign #77
Merged
Merged
Changes from all commits
Commits
Show all changes
11 commits
Select commit
Hold shift + click to select a range
204ee89
integration test for deploy campaign that also performs follow up tra…
JamesEarle eb9c7f8
merge feat/deploy-campaign and fix conflict
JamesEarle 25ee307
fix tests with balance issues caused by hh async processes
JamesEarle 06d57d9
remove indent for lint
JamesEarle bb5d7f2
fix merge conflict and fix test failing for pricing issue
JamesEarle 508b1ee
lint fix
JamesEarle e67a992
pr comments
JamesEarle b64aa75
merge feat/deploy-campaign, address small conflicts
JamesEarle cc95072
undo change in pr feedback, use separate promise arrays in test
JamesEarle b6efff9
fix failing tests due to env vars not documented and auto true
JamesEarle e5a1b95
adjust indentation
JamesEarle File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -44,7 +44,7 @@ | |
"@nomicfoundation/hardhat-network-helpers": "^1.0.8", | ||
"@nomicfoundation/hardhat-toolbox": "2.0.2", | ||
"@nomiclabs/hardhat-ethers": "2.2.2", | ||
"@nomiclabs/hardhat-etherscan": "3.0.0", | ||
"@nomiclabs/hardhat-etherscan": "3.1.7", | ||
"@openzeppelin/contracts": "4.8.3", | ||
"@openzeppelin/contracts-400": "npm:@openzeppelin/[email protected]", | ||
"@openzeppelin/contracts-upgradeable": "4.8.3", | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,313 @@ | ||
import * as hre from "hardhat"; | ||
import { SignerWithAddress } from "@nomiclabs/hardhat-ethers/signers"; | ||
import { getConfig } from "../src/deploy/campaign/environments"; | ||
import { getLogger } from "../src/deploy/logger/create-logger"; | ||
import { runZnsCampaign } from "../src/deploy/zns-campaign"; | ||
import { IDeployCampaignConfig, TZNSContractState } from "../src/deploy/campaign/types"; | ||
import { ethers } from "ethers"; | ||
import { IDistributionConfig } from "./helpers/types"; | ||
import { expect } from "chai"; | ||
import { hashDomainLabel, PaymentType, AccessType } from "./helpers"; | ||
import { | ||
approveBulk, | ||
getPriceBulk, | ||
mintBulk, | ||
registerRootDomainBulk, | ||
registerSubdomainBulk, | ||
} from "./helpers/deploy-helpers"; | ||
|
||
describe("DeployCampaign - Integration", () => { | ||
let deployer : SignerWithAddress; | ||
let zeroVault : SignerWithAddress; | ||
let domainAddressMock : SignerWithAddress; | ||
|
||
// Minters | ||
let userA : SignerWithAddress; | ||
let userB : SignerWithAddress; | ||
let userC : SignerWithAddress; | ||
let userD : SignerWithAddress; | ||
let userE : SignerWithAddress; | ||
let userF : SignerWithAddress; | ||
|
||
let zns : TZNSContractState; | ||
|
||
let config : IDeployCampaignConfig; | ||
|
||
let users : Array<SignerWithAddress>; | ||
let distConfig : IDistributionConfig; | ||
|
||
const logger = getLogger(); | ||
|
||
// Default baselength is 4, maxLength is 50 | ||
const shortDomain = "wild"; // Length 4 | ||
const mediumDomain = "wilder"; // Length 6 | ||
const longDomain = "wilderwilderwilderwilderwilderwilderwilderwilderwil"; // Length 51 | ||
const shortHash = hashDomainLabel(shortDomain); | ||
const mediumHash = hashDomainLabel(mediumDomain); | ||
const longHash = hashDomainLabel(longDomain); | ||
|
||
const freeShortSubdomain = "subd"; // Length 4 | ||
const freeMediumSubdomain = "subder"; // Length 6 | ||
const freeLongSubdomain = "subderwilderwilderwilderwilderwilderwilderwilderwil"; // Length 51 | ||
|
||
// Resolve through async call `hashWithParent` in `before` hook | ||
let freeShortSubHash : string; | ||
let freeMediumSubHash : string; | ||
let freeLongSubHash : string; | ||
|
||
const paidShortSubdomain = "surf"; // Length 4 | ||
const paidMediumSubdomain = "surfer"; // Length 6 | ||
const paidLongSubdomain = "surferwilderwilderwilderwilderwilderwilderwilderwil"; // Length 51 | ||
|
||
let paidShortSubHash : string; | ||
let paidMediumSubHash : string; | ||
let paidLongSubHash : string; | ||
|
||
const mintAmount = ethers.utils.parseEther("10000000"); | ||
|
||
const domains = [shortDomain, mediumDomain, longDomain]; | ||
|
||
before(async () => { | ||
[deployer, zeroVault, domainAddressMock, userA, userB, userC, userD, userE, userF] = await hre.ethers.getSigners(); | ||
|
||
// Reads `ENV_LEVEL` environment variable to determine rules to be enforced | ||
config = getConfig(deployer, zeroVault); | ||
|
||
config.mockMeowToken = hre.network.name === "hardhat"; | ||
const campaign = await runZnsCampaign({ config, dbVersion: "1.0.0" }); | ||
|
||
zns = campaign.state.contracts; | ||
|
||
// CurvePricer, stake, open | ||
distConfig = { | ||
pricerContract: zns.curvePricer.address, | ||
paymentType: PaymentType.STAKE, | ||
accessType: AccessType.OPEN, | ||
}; | ||
|
||
users = [ | ||
userA, | ||
userB, | ||
userC, | ||
userD, | ||
userE, | ||
userF, | ||
]; | ||
|
||
freeShortSubHash = await zns.subRegistrar.hashWithParent(shortHash, freeShortSubdomain); | ||
freeMediumSubHash = await zns.subRegistrar.hashWithParent(mediumHash, freeMediumSubdomain); | ||
freeLongSubHash = await zns.subRegistrar.hashWithParent(longHash, freeLongSubdomain); | ||
|
||
paidShortSubHash = await zns.subRegistrar.hashWithParent(shortHash, paidShortSubdomain); | ||
paidMediumSubHash = await zns.subRegistrar.hashWithParent(mediumHash, paidMediumSubdomain); | ||
paidLongSubHash = await zns.subRegistrar.hashWithParent(longHash, paidLongSubdomain); | ||
|
||
await approveBulk(users, zns); | ||
|
||
// Give the user funds | ||
if (config.mockMeowToken) { | ||
await mintBulk( | ||
users, | ||
mintAmount, | ||
zns | ||
); | ||
} | ||
}); | ||
|
||
it("Successfully mints TLDs with varying length", async () => { | ||
// Confirm the domains are available | ||
expect(await zns.registry.exists(shortHash)).to.be.false; | ||
expect(await zns.registry.exists(mediumHash)).to.be.false; | ||
expect(await zns.registry.exists(longHash)).to.be.false; | ||
|
||
// Get domain prices, including stake and protocol fee | ||
const [priceShort, priceMedium, priceLong] = await getPriceBulk(domains, zns); | ||
|
||
logger.info(`Price of ${shortDomain} is ${priceShort.toString()}`); | ||
logger.info(`Price of ${mediumDomain} is ${priceMedium.toString()}`); | ||
logger.info(`Price of ${longDomain} is ${priceLong.toString()}`); | ||
|
||
const balanceBeforePromises = [ | ||
zns.meowToken.balanceOf(userA.address), | ||
zns.meowToken.balanceOf(userB.address), | ||
zns.meowToken.balanceOf(userC.address), | ||
]; | ||
|
||
const [balanceBeforeA, balanceBeforeB, balanceBeforeC ]= await Promise.all(balanceBeforePromises); | ||
|
||
// 1. Register root domains | ||
// Note that this calls `setPriceConfig` internally for each TLD minted so we can also mint subdomains | ||
await registerRootDomainBulk( | ||
users, | ||
domains, | ||
domainAddressMock.address, | ||
"https://zns.domains/", // tokenUri | ||
distConfig, | ||
config.rootPriceConfig, | ||
zns | ||
); | ||
|
||
const balanceAfterPromises = [ | ||
JamesEarle marked this conversation as resolved.
Show resolved
Hide resolved
|
||
zns.meowToken.balanceOf(userA.address), | ||
zns.meowToken.balanceOf(userB.address), | ||
zns.meowToken.balanceOf(userC.address), | ||
]; | ||
|
||
const [balanceAfterA, balanceAfterB, balanceAfterC ]= await Promise.all(balanceAfterPromises); | ||
|
||
expect(balanceAfterA).to.equal(balanceBeforeA.sub(priceShort)); | ||
expect(balanceAfterB).to.equal(balanceBeforeB.sub(priceMedium)); | ||
expect(balanceAfterC).to.equal(balanceBeforeC.sub(priceLong)); | ||
|
||
logger.info(`Domain ${shortHash} registered for user ${userA.address}`); | ||
logger.info(`Domain ${mediumHash} registered for user ${userB.address}`); | ||
logger.info(`Domain ${longHash} registered for user ${userC.address}`); | ||
}); | ||
|
||
it("Mints subdomains with varying length for free as the owner of parent domain", async () => { | ||
// Get price of subdomains | ||
const parents = [shortHash, mediumHash, longHash]; | ||
const subdomains = [freeShortSubdomain, freeMediumSubdomain, freeLongSubdomain]; | ||
|
||
const balancePromises = [ | ||
zns.meowToken.balanceOf(userA.address), | ||
zns.meowToken.balanceOf(userB.address), | ||
zns.meowToken.balanceOf(userC.address), | ||
]; | ||
|
||
const [balanceBeforeA, balanceBeforeB, balanceBeforeC ]= await Promise.all(balancePromises); | ||
|
||
expect(await zns.registry.exists(freeShortSubHash)).to.be.false; | ||
expect(await zns.registry.exists(freeMediumSubHash)).to.be.false; | ||
expect(await zns.registry.exists(freeLongSubHash)).to.be.false; | ||
|
||
// 2. Register subdomains | ||
await registerSubdomainBulk( | ||
users, | ||
parents, | ||
subdomains, | ||
domainAddressMock.address, | ||
"https://zns.domains/", | ||
distConfig, | ||
zns | ||
); | ||
|
||
const [ | ||
balanceAfterA, | ||
balanceAfterB, | ||
balanceAfterC, | ||
]= await Promise.all(balancePromises); | ||
|
||
// Owners of parent domains can mint subdomains for free | ||
expect(balanceBeforeA).to.eq(balanceAfterA); | ||
expect(balanceBeforeB).to.eq(balanceAfterB); | ||
expect(balanceBeforeC).to.eq(balanceAfterC); | ||
|
||
logger.info(`Subdomain ${freeShortSubHash} registered for user ${userA.address}`); | ||
logger.info(`Subdomain ${freeMediumSubHash} registered for user ${userB.address}`); | ||
logger.info(`Subdomain ${freeLongSubHash} registered for user ${userC.address}`); | ||
}); | ||
|
||
it("Mints subdomains with varying length for a cost", async () => { | ||
// Get price of subdomains | ||
const parents = [shortHash, mediumHash, longHash]; | ||
const subdomains = [paidShortSubdomain, paidMediumSubdomain, paidLongSubdomain]; | ||
|
||
const balancePromises = [ | ||
zns.meowToken.balanceOf(userD.address), | ||
zns.meowToken.balanceOf(userE.address), | ||
zns.meowToken.balanceOf(userF.address), | ||
]; | ||
|
||
const [ | ||
balanceBeforeD, | ||
balanceBeforeE, | ||
balanceBeforeF, | ||
]= await Promise.all(balancePromises); | ||
|
||
const [ | ||
priceShort, | ||
priceMedium, | ||
priceLong, | ||
] = await getPriceBulk(subdomains, zns, parents, true); | ||
|
||
expect(await zns.registry.exists(paidShortSubHash)).to.be.false; | ||
expect(await zns.registry.exists(paidMediumSubHash)).to.be.false; | ||
expect(await zns.registry.exists(paidLongSubHash)).to.be.false; | ||
|
||
// 2. Register subdomains | ||
await registerSubdomainBulk( | ||
[userD, userE, userF], | ||
parents, | ||
subdomains, | ||
domainAddressMock.address, | ||
"https://zns.domains/", | ||
distConfig, | ||
zns | ||
); | ||
|
||
const balanceAfterPromises = [ | ||
zns.meowToken.balanceOf(userD.address), | ||
zns.meowToken.balanceOf(userE.address), | ||
zns.meowToken.balanceOf(userF.address), | ||
]; | ||
|
||
const [ | ||
balanceAfterD, | ||
balanceAfterE, | ||
balanceAfterF, | ||
]= await Promise.all(balanceAfterPromises); | ||
|
||
// Owners of parent domains can mint subdomains for free | ||
expect(balanceAfterD).to.eq(balanceBeforeD.sub(priceShort)); | ||
expect(balanceAfterE).to.eq(balanceBeforeE.sub(priceMedium)); | ||
expect(balanceAfterF).to.eq(balanceBeforeF.sub(priceLong)); | ||
|
||
logger.info(`Subdomain ${freeShortSubHash} registered for user ${userA.address}`); | ||
logger.info(`Subdomain ${freeMediumSubHash} registered for user ${userB.address}`); | ||
logger.info(`Subdomain ${freeLongSubHash} registered for user ${userC.address}`); | ||
}); | ||
|
||
it("Revokes a domain correctly", async () => { | ||
// 3. Revoke domain | ||
const tx = zns.rootRegistrar.connect(userA).revokeDomain(freeShortSubHash); | ||
await expect(tx).to.emit(zns.rootRegistrar, "DomainRevoked").withArgs(freeShortSubHash, userA.address, false); | ||
logger.info( | ||
"info", | ||
`Subdomain ${freeShortSubHash} revoked by user ${userA.address}` | ||
); | ||
}); | ||
|
||
it("Reclaims a domain correctly", async () => { | ||
// 4. Reclaim domain | ||
await zns.registry.connect(userB).updateDomainOwner(freeMediumSubHash, userA.address); | ||
logger.info( | ||
"info", | ||
`Subdomain ${freeMediumSubHash} ownership given to user ${userA.address} from user ${userB.address}` | ||
); | ||
|
||
const tx = zns.rootRegistrar.connect(userB).reclaimDomain(freeMediumSubHash); | ||
|
||
await expect(tx).to.emit(zns.rootRegistrar, "DomainReclaimed").withArgs(freeMediumSubHash, userB.address); | ||
expect(await zns.registry.getDomainOwner(freeMediumSubHash)).to.equal(userB.address); | ||
|
||
logger.info(`Subdomain ${freeMediumSubHash} reclaimed by user ${userB.address} from user ${userA.address}`); | ||
}); | ||
|
||
it("Reclaims then revokes correctly", async () => { | ||
// 5. Reclaim and revoke domain | ||
const tx = zns.registry.connect(userC).updateDomainOwner(freeLongSubHash, userA.address); | ||
await expect(tx).to.emit(zns.registry, "DomainOwnerSet").withArgs(freeLongSubHash, userA.address); | ||
logger.info(`Subdomain ${freeLongSubHash} ownership given to user ${userA.address} from user ${userC.address}`); | ||
|
||
const tx1 = zns.rootRegistrar.connect(userC).reclaimDomain(freeLongSubHash); | ||
await expect(tx1).to.emit(zns.rootRegistrar, "DomainReclaimed").withArgs(freeLongSubHash, userC.address); | ||
|
||
logger.info(`Subdomain ${freeLongSubHash} reclaimed by user ${userC.address}`); | ||
expect(await zns.registry.getDomainOwner(freeLongSubHash)).to.equal(userC.address); | ||
|
||
const tx2 = zns.rootRegistrar.connect(userC).revokeDomain(freeLongSubHash); | ||
await expect(tx2).to.emit(zns.rootRegistrar, "DomainRevoked").withArgs(freeLongSubHash, userC.address, false); | ||
logger.info(`Subdomain ${freeLongSubHash} revoked by user ${userC.address}`); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -977,4 +977,4 @@ describe("Deploy Campaign Test", () => { | |
); | ||
}); | ||
}); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
you don't get an error with this? I thought this package is already part of the
hardhat-toolbox
, no?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I had an error without adding this, and this was the resolution. I couldn't setup a Sepolia network anymore in the HH config without upgrading the package