Skip to content
This repository was archived by the owner on Feb 11, 2023. It is now read-only.

Commit 4849002

Browse files
authored
fix(bug): clear hyperspace when burning cert (#46)
1 parent 3c7f2d1 commit 4849002

File tree

4 files changed

+31
-4
lines changed

4 files changed

+31
-4
lines changed

contracts/HyperCertMinter.sol

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -263,7 +263,8 @@ contract HyperCertMinter is Initializable, ERC3525SlotEnumerableUpgradeable, Acc
263263
}
264264

265265
function burn(uint256 tokenId_) public {
266-
Claim storage claim = _hyperCerts[slotOf(tokenId_)];
266+
uint256 claimId = slotOf(tokenId_);
267+
Claim storage claim = _hyperCerts[claimId];
267268
if (msg.sender != claim.minter) {
268269
revert NotApprovedOrOwner();
269270
}
@@ -272,6 +273,7 @@ contract HyperCertMinter is Initializable, ERC3525SlotEnumerableUpgradeable, Acc
272273
revert InsufficientBalance(claim.totalUnits, balanceOf(tokenId_));
273274
}
274275

276+
_clearContributorsClaims(claim.claimHash, claim.contributors);
275277
_burn(tokenId_);
276278
claim.exists = false;
277279
}
@@ -410,6 +412,16 @@ contract HyperCertMinter is Initializable, ERC3525SlotEnumerableUpgradeable, Acc
410412
}
411413
}
412414

415+
/// @notice Stores contributor claims in the `contributorImpacts` mapping; guards against overlapping claims
416+
/// @param claimHash ID of hypercert
417+
/// @param contributors Array of addresses for contributors
418+
function _clearContributorsClaims(bytes32 claimHash, address[] memory contributors) internal {
419+
uint256 len = contributors.length;
420+
for (uint256 i = 0; i < len; i++) {
421+
_contributorImpacts[contributors[i]][claimHash] = false;
422+
}
423+
}
424+
413425
/// @notice Checks whether the supplied mapping contains the supplied key
414426
/// @param map mapping to search
415427
/// @param key key to search

hardhat.config.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ const config: HardhatUserConfig = {
108108
// https://hardhat.org/hardhat-network/#solidity-optimizer-support
109109
optimizer: {
110110
enabled: true,
111-
runs: 200,
111+
runs: 100,
112112
details: { yul: true },
113113
},
114114
},

test/hypercert_minter/HyperCertMinter.integration.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,4 +25,19 @@ export function shouldBehaveLikeHypercertMinterIntegration(): void {
2525
await expect(deployer.minter.mint(deployer.address, secondData)).to.emit(minter, "ImpactClaimed");
2626
await expect(deployer.minter.split(7, [500, 500])).to.emit(minter, "TransferValue");
2727
});
28+
29+
it("supports minting the same claim after it's been burned", async function () {
30+
const { deployer, minter, user, anon } = await setupTest();
31+
const claim = await newClaim({ contributors: [deployer.address, user.address, anon.address], fractions: [100] });
32+
const data = encodeClaim(claim);
33+
34+
await expect(deployer.minter.mint(deployer.address, data)).to.emit(minter, "ImpactClaimed");
35+
expect(await deployer.minter["balanceOf(uint256)"](1)).to.be.eq("100");
36+
37+
await expect(deployer.minter.mint(deployer.address, data)).to.be.revertedWith("ConflictingClaim()");
38+
39+
await expect(deployer.minter.burn(1)).to.emit(minter, "SlotChanged");
40+
41+
await expect(deployer.minter.mint(deployer.address, data)).to.emit(minter, "ImpactClaimed");
42+
});
2843
}

test/utils.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -209,7 +209,7 @@ export const validateMetadata = async (metadata64: string, expected: string | Cl
209209
try {
210210
const metadata = <Metadata>JSON.parse(metadataJson);
211211

212-
expect(metadata.name).to.eq(expected.name);
212+
expect(metadata.name).to.eq(expected.name); //slice because of string splitting
213213
expect(metadata.description).to.eq(expected.description);
214214
await validateSVG(
215215
decode64(metadata.image),
@@ -246,7 +246,7 @@ export const validateSVG = async (svg: string, expected: SVGInput, fraction: boo
246246
const nameParts = expected.name.split(" ");
247247
const svgName = svgDoc.get("//*[@id='name-color']")?.text();
248248
for (let i = 0; i < Math.min(nameParts.length, 2); i++) {
249-
expect(svgName).to.contain(nameParts[i].substring(0, 13), `Name "${nameParts[i]}" not found: ${svg}`);
249+
expect(svgName).to.contain(nameParts[i].substring(0, 10), `Name "${nameParts[i]}" not found: ${svg}`);
250250
}
251251

252252
const truncScope = truncate(expected.impactScopes[0]);

0 commit comments

Comments
 (0)