UNPKG

@gooddollar/goodprotocol

Version:
540 lines (453 loc) 18 kB
import hre, { ethers, upgrades } from "hardhat"; import { loadFixture } from "@nomicfoundation/hardhat-network-helpers"; import { expect } from "chai"; import { IGoodDollar, IIdentityV2, IIdentity, IdentityV2 } from "../../types"; import { createDAO, increaseTime, advanceBlocks } from "../helpers"; import { SignerWithAddress } from "@nomiclabs/hardhat-ethers/signers"; const BN = ethers.BigNumber; describe("Identity", () => { let identity: IdentityV2, founder: SignerWithAddress; let user1 = ethers.Wallet.createRandom().connect(ethers.provider); let user2 = ethers.Wallet.createRandom().connect(ethers.provider); let signers: Array<SignerWithAddress>; let genericCall; let avatar, gd: IGoodDollar, Controller, id: IIdentity; before(async () => { [founder, ...signers] = await ethers.getSigners(); let { controller, avatar: av, gd: gooddollar, identity: idv2, genericCall: gc } = await loadFixture(createDAO); genericCall = gc; identity = (await ethers.getContractAt("IdentityV2", idv2)) as IdentityV2; Controller = controller; avatar = av; // await daoCreator.setSchemes( // avatar, // [identity], // [ethers.constants.HashZero], // ["0x0000001F"], // "" // ); gd = (await ethers.getContractAt( "IGoodDollar", gooddollar, founder )) as IGoodDollar; }); it("should set DAO by creator", async () => { let f = await ethers.getContractFactory("IdentityV2"); let newid = (await upgrades.deployProxy( f, [signers[0].address, ethers.constants.AddressZero], { kind: "uups" } )) as IdentityV2; expect(await newid.dao()).eq(ethers.constants.AddressZero); await expect( newid.connect(signers[0]).initDAO(await identity.nameService()) ).not.reverted; expect(await newid.dao()).not.eq(ethers.constants.AddressZero); }); it("should not be able to set DAO by non-creator", async () => { let f = await ethers.getContractFactory("IdentityV2"); let newid = (await upgrades.deployProxy( f, [signers[0].address, ethers.constants.AddressZero], { kind: "uups" } )) as IdentityV2; expect(await newid.dao()).eq(ethers.constants.AddressZero); await expect(newid.initDAO(await identity.nameService())).reverted; }); it("should blacklist address", async () => { let blacklisted = signers[1]; await identity.addBlacklisted(blacklisted.address); expect(await identity.isBlacklisted(blacklisted.address)).true; await identity.removeBlacklisted(blacklisted.address); expect(await identity.isBlacklisted(blacklisted.address)).false; }); it("should add, check and remove whitelisted", async () => { let whitelisted = signers[1]; await identity.addWhitelisted(whitelisted.address); expect(await identity.isWhitelisted(whitelisted.address)).true; const id = await identity.identities(whitelisted.address); expect(id.whitelistedOnChainId).gt(0); await identity.removeWhitelisted(whitelisted.address); expect(await identity.isWhitelisted(whitelisted.address)).false; }); it("should increment and decrement whitelisteds when adding whitelisted", async () => { let whitelisted = signers[1]; const oldWhitelistedCount = (await identity.whitelistedCount()) as any; await identity.addWhitelisted(whitelisted.address); const diffWhitelistedCount = ( (await identity.whitelistedCount()) as any ).sub(oldWhitelistedCount); expect(diffWhitelistedCount.toString()).to.be.equal("1"); await identity.removeWhitelisted(whitelisted.address); const whitelistedCount = (await identity.whitelistedCount()) as any; expect(whitelistedCount.toString()).to.be.equal( oldWhitelistedCount.toString() ); }); it("should revert when non admin tries to add whitelisted", async () => { let whitelisted = signers[1]; await expect( identity.connect(signers[2]).addWhitelisted(whitelisted.address) ).revertedWith(/AccessControl: account/); }); it("should revert when non admin tries to add blacklist", async () => { let blacklisted = signers[1]; await expect( identity.connect(signers[2]).addBlacklisted(blacklisted.address) ).revertedWith(/AccessControl: account/); }); it("should revert when non admin tries to set the authentication period", async () => { await expect(identity.connect(signers[2]).setAuthenticationPeriod(10)) .reverted; }); it("should let owner set auth period", async () => { const encoded = identity.interface.encodeFunctionData( "setAuthenticationPeriod", [10] ); await genericCall(identity.address, encoded); expect(await identity.authenticationPeriod()).eq(10); }); it("should revert when non admin tries to pause", async () => { await expect(identity.connect(signers[2]).pause(true)).reverted; }); it("should let admin pause", async () => { await expect(identity.pause(true)).not.reverted; await expect(identity.pause(false)).not.reverted; }); it("should revert when non admin tries to authentice a user", async () => { let authuser = signers[0].address; await expect( identity.connect(signers[2]).authenticate(authuser) ).revertedWith(/AccessControl: account/); }); it("should authenticate the user with the correct timestamp", async () => { let authuser = signers[0].address; await identity.addWhitelisted(authuser); await identity.authenticate(authuser); let dateAuthenticated1 = await identity.lastAuthenticated(authuser); await increaseTime(10); await identity.authenticate(authuser); let dateAuthenticated2 = await identity.lastAuthenticated(authuser); expect(dateAuthenticated2.toNumber() - dateAuthenticated1.toNumber()).gt(0); }); it("should add identity admin", async () => { let outsider = signers[5].address; await identity.grantRole(await identity.IDENTITY_ADMIN_ROLE(), outsider); expect( await identity.hasRole(await identity.IDENTITY_ADMIN_ROLE(), outsider) ).true; }); it("should remove identity admin", async () => { let outsider = signers[5].address; await identity.revokeRole(await identity.IDENTITY_ADMIN_ROLE(), outsider); expect( await identity.hasRole(await identity.IDENTITY_ADMIN_ROLE(), outsider) ).false; }); it("should revert when adding to whitelisted twice", async () => { let whitelisted = signers[1]; await identity.addWhitelisted(whitelisted.address); await expect(identity.addWhitelisted(whitelisted.address)).reverted; await identity.removeWhitelisted(whitelisted.address); }); it("should not increment whitelisted counter when adding whitelisted", async () => { let whitelisted = signers[1]; await identity.addWhitelisted(whitelisted.address); let whitelistedCount = await identity.whitelistedCount(); await expect(identity.addWhitelisted(whitelisted.address)).reverted; let whitelistedCountNew = await identity.whitelistedCount(); expect(whitelistedCountNew).to.be.equal(whitelistedCount).gt(0); await identity.removeWhitelisted(whitelisted.address); }); it("should renounce whitelisted", async () => { let whitelisted = signers[1]; await identity.addWhitelisted(whitelisted.address); expect(await identity.isWhitelisted(whitelisted.address)).true; await identity.connect(whitelisted).renounceWhitelisted(); expect(await identity.isWhitelisted(whitelisted.address)).false; }); it("should add with did", async () => { let whitelisted = signers[1]; await identity.addWhitelistedWithDID(whitelisted.address, "testString"); const id = await identity.identities(whitelisted.address); expect(id.did).to.be.equal("testString"); }); it("should not allow adding with used did", async () => { let whitelisted2 = signers[2]; await expect( identity.addWhitelistedWithDID(whitelisted2.address, "testString") ).revertedWith(/DID already registered/); }); it("should not allow adding non contract to contracts", async () => { let outsider = signers[0]; await expect(identity.addContract(outsider.address)).revertedWith( /Given address is not a contract/ ); }); it("should add contract to contracts", async () => { await identity.addContract(gd.address); const wasAdded = await identity.isDAOContract(gd.address); expect(wasAdded).to.be.true; }); const connectedFixture = async () => { const toconnect = signers[10]; const toconnect2 = signers[11]; let whitelisted = signers[1]; const curBlock = await ethers.provider.getBlockNumber(); const deadline = curBlock + 10; const signed = await toconnect._signTypedData( { name: "Identity", version: "1.0.0", chainId: 4447, verifyingContract: identity.address }, { ConnectIdentity: [ { name: "whitelisted", type: "address" }, { name: "connected", type: "address" }, { name: "deadline", type: "uint256" } ] }, { whitelisted: whitelisted.address, connected: toconnect.address, deadline } ); const signed2 = await toconnect2._signTypedData( { name: "Identity", version: "1.0.0", chainId: 4447, verifyingContract: identity.address }, { ConnectIdentity: [ { name: "whitelisted", type: "address" }, { name: "connected", type: "address" }, { name: "deadline", type: "uint256" } ] }, { whitelisted: whitelisted.address, connected: toconnect2.address, deadline } ); await identity .connect(whitelisted) .connectAccount(toconnect.address, signed, deadline); await identity .connect(whitelisted) .connectAccount(toconnect2.address, signed2, deadline); return { signed }; }; it("should allow to connect account", async () => { const toconnect = signers[10]; let whitelisted = signers[1]; expect(await identity.getWhitelistedRoot(toconnect.address)).eq( ethers.constants.AddressZero ); await loadFixture(connectedFixture); expect(await identity.getWhitelistedRoot(whitelisted.address)).eq( whitelisted.address ); expect(await identity.getWhitelistedRoot(toconnect.address)).eq( whitelisted.address ); }); it("should require valid deadline", async () => { const toconnect = signers[10]; let whitelisted = signers[1]; await expect( identity .connect(whitelisted) .connectAccount( toconnect.address, "0x", await ethers.provider.getBlockNumber() ) ).revertedWith(/invalid deadline/); await expect( identity.connect(whitelisted).connectAccount(toconnect.address, "0x", 0) ).revertedWith(/invalid deadline/); }); it("should not allow to replay signature", async () => { const toconnect = signers[10]; let whitelisted = signers[1]; const { signed } = await loadFixture(connectedFixture); await expect( identity.connect(whitelisted).disconnectAccount(toconnect.address) ).not.reverted; await expect( identity .connect(whitelisted) .connectAccount( toconnect.address, signed, (await ethers.provider.getBlockNumber()) + 10 ) ).revertedWith(/invalid signature/); }); it("should not allow to connect account already whitelisted", async () => { await loadFixture(connectedFixture); await identity.addWhitelisted(signers[2].address); let whitelisted = signers[1]; await expect( identity .connect(whitelisted) .connectAccount(signers[2].address, "0x", 20000000) ).revertedWith(/invalid account/); }); it("should allow to disconnect account by owner or connected", async () => { await loadFixture(connectedFixture); const connected = signers[10]; const whitelisted = signers[1]; await identity.connect(connected).disconnectAccount(connected.address); expect(await identity.getWhitelistedRoot(connected.address)).eq( ethers.constants.AddressZero ); await loadFixture(connectedFixture); await identity.connect(whitelisted).disconnectAccount(connected.address); expect(await identity.getWhitelistedRoot(connected.address)).eq( ethers.constants.AddressZero ); }); it("should not allow to disconnect account not by owner or by connected", async () => { await loadFixture(connectedFixture); const connected = signers[10]; const whitelisted = signers[1]; await expect(identity.disconnectAccount(connected.address)).revertedWith( /unauthorized/ ); }); it("should not allow to connect to an already connected account", async () => { await loadFixture(connectedFixture); await identity.addWhitelisted(signers[2].address); expect(await identity.isWhitelisted(signers[2].address)).true; const connected = signers[10]; await expect( identity .connect(signers[2]) .connectAccount(connected.address, "0x", 200000) ).revertedWith(/already connected/); }); it("should return same root for multiple connected accounts", async () => { await loadFixture(connectedFixture); const connected = signers[10]; const connected2 = signers[11]; const whitelisted = signers[1]; expect(await identity.getWhitelistedRoot(connected.address)) .eq(await identity.getWhitelistedRoot(connected2.address)) .eq(whitelisted.address); }); it("should add whitelisted with orgchain and dateauthenticated", async () => { await loadFixture(connectedFixture); const toWhitelist = signers[2]; const ts = (Date.now() / 1000 - 100000).toFixed(0); await identity.addWhitelistedWithDIDAndChain( toWhitelist.address, "xxx", 1234, ts ); const record = await identity.identities(toWhitelist.address); expect(record.whitelistedOnChainId).eq(1234); expect(record.dateAuthenticated).eq(ts); }); const oldidFixture = async () => { const newid = (await upgrades.deployProxy( await ethers.getContractFactory("IdentityV2"), [founder.address, identity.address] )) as IdentityV2; await identity.grantRole( await identity.IDENTITY_ADMIN_ROLE(), newid.address ); await identity.addBlacklisted(signers[4].address); await identity.addContract(identity.address); await identity.removeWhitelisted(signers[3].address); await identity.addWhitelistedWithDID(signers[3].address, "testolddid"); return { newid }; }; it("should default to old identity isWhitelisted, isBlacklisted, isContract", async () => { const { newid } = await loadFixture(oldidFixture); expect(await (await identity.identities(signers[3].address)).did).eq( "testolddid" ); expect(await (await newid.identities(signers[3].address)).did).eq(""); expect(await identity.addrToDID(signers[3].address)).eq("testolddid"); expect(await newid.addrToDID(signers[3].address)).eq("testolddid"); expect(await newid.isBlacklisted(signers[4].address)).true; expect(await newid.isWhitelisted(signers[3].address)).true; expect(await newid.isDAOContract(identity.address)).true; }); it("should remove whitelisted,blacklisted,contract from old identity", async () => { const { newid } = await loadFixture(oldidFixture); await newid.removeBlacklisted(signers[4].address); await newid.removeWhitelisted(signers[3].address); await newid.removeContract(identity.address); expect(await newid.addrToDID(signers[3].address)).eq(""); expect(await newid.isBlacklisted(signers[4].address)).false; expect(await newid.isWhitelisted(signers[3].address)).false; expect(await newid.isDAOContract(identity.address)).false; expect(await identity.isBlacklisted(signers[4].address)).false; expect(await identity.isWhitelisted(signers[3].address)).false; expect(await identity.isDAOContract(identity.address)).false; }); it("should not set did if set in oldidentity", async () => { const { newid } = await loadFixture(oldidFixture); await expect( newid .connect(signers[1]) ["setDID(address,string)"](signers[1].address, "testolddid") ).revertedWith(/DID already registered oldIdentity/); }); it("should set did if set in oldidentity by same owner", async () => { const { newid } = await loadFixture(oldidFixture); await expect( newid .connect(signers[3]) ["setDID(address,string)"](signers[3].address, "testolddid") ).not.reverted; expect(await newid.addrToDID(signers[3].address)).eq("testolddid"); }); it("should set did if set in oldidentity by different owner but updated in new identity", async () => { const { newid } = await loadFixture(oldidFixture); await expect( newid .connect(signers[3]) ["setDID(address,string)"](signers[3].address, "newdid") ).not.reverted; expect(await newid.addrToDID(signers[3].address)).eq("newdid"); await expect( newid .connect(signers[1]) ["setDID(address,string)"](signers[1].address, "testolddid") ).not.reverted; expect(await newid.addrToDID(signers[1].address)).eq("testolddid"); }); it("should let admin setDID", async () => { await expect( identity["setDID(address,string)"](signers[1].address, "admindid") ).not.reverted; expect(await identity.addrToDID(signers[1].address)).eq("admindid"); await expect( identity .connect(signers[2]) ["setDID(address,string)"](signers[1].address, "admindid") ).reverted; }); it("should be registered for v1 compatability", async () => { expect(await identity.isRegistered()).true; }); });