@coti-io/coti-contracts 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/workflows/npm-publish.yml +52 -0
- package/CODE_OF_CONDUCT.md +44 -0
- package/CONTRIBUTING.md +101 -0
- package/LICENSE +201 -0
- package/README.md +48 -0
- package/contracts/access/DataPrivacyFramework/DataPrivacyFramework.sol +480 -0
- package/contracts/access/DataPrivacyFramework/README.md +68 -0
- package/contracts/access/DataPrivacyFramework/extensions/DataPrivacyFrameworkMpc.sol +1139 -0
- package/contracts/mocks/README.md +5 -0
- package/contracts/mocks/access/DataPrivacyFramework/DataPrivacyFrameworkMock.sol +9 -0
- package/contracts/mocks/token/PrivateERC20/PrivateERC20Mock.sol +17 -0
- package/contracts/mocks/token/PrivateERC721/PrivateERC721URIStorageMock.sol +34 -0
- package/contracts/mocks/utils/mpc/ArithmeticTestsContract.sol +431 -0
- package/contracts/mocks/utils/mpc/BitwiseTestsContract.sol +361 -0
- package/contracts/mocks/utils/mpc/Comparison1Tests.Contract.sol +307 -0
- package/contracts/mocks/utils/mpc/Comparison2TestsContract.sol +307 -0
- package/contracts/mocks/utils/mpc/MinMaxTestsContract.sol +297 -0
- package/contracts/mocks/utils/mpc/Miscellaneous1TestsContract.sol +185 -0
- package/contracts/mocks/utils/mpc/Miscellaneous2TestsContract.sol +448 -0
- package/contracts/mocks/utils/mpc/OffboardToUserKeyTestsContract.sol +81 -0
- package/contracts/mocks/utils/mpc/README.md +486 -0
- package/contracts/mocks/utils/mpc/ShiftTestsContract.sol +311 -0
- package/contracts/mocks/utils/mpc/StringTestsContract.sol +59 -0
- package/contracts/mocks/utils/mpc/TransferScalarTestsContract.sol +271 -0
- package/contracts/mocks/utils/mpc/TransferTestsContract.sol +715 -0
- package/contracts/mocks/wallet/PrivateERC20Wallet/PrivateERC20WalletMock.sol +25 -0
- package/contracts/onboard/AccountOnboard.sol +21 -0
- package/contracts/onboard/README.md +65 -0
- package/contracts/package.json +11 -0
- package/contracts/token/PrivateERC20/IPrivateERC20.sol +142 -0
- package/contracts/token/PrivateERC20/PrivateERC20.sol +478 -0
- package/contracts/token/PrivateERC20/README.md +104 -0
- package/contracts/token/PrivateERC721/PrivateERC721.sol +458 -0
- package/contracts/token/PrivateERC721/README.md +282 -0
- package/contracts/token/PrivateERC721/extensions/PrivateERC721URIStorage.sol +87 -0
- package/contracts/utils/mpc/MpcCore.sol +3215 -0
- package/contracts/utils/mpc/MpcInterface.sol +41 -0
- package/contracts/utils/mpc/README.md +82 -0
- package/hardhat.config.ts +18 -0
- package/package.json +14 -0
- package/test/access/DataPrivacyFramework/DataPrivacyFramework.test.ts +780 -0
- package/test/onboard/AccountOnboard.test.ts +45 -0
- package/test/token/PrivateERC20/PrivateERC20.test.ts +546 -0
- package/test/token/PrivateERC721/PrivateERC721.test.ts +223 -0
- package/test/utils/accounts.ts +55 -0
- package/test/utils/mpc/Precompile.test.ts +113 -0
- package/test/utils/mpc/String.test.ts +227 -0
- package/tsconfig.json +11 -0
- package/typechain-types/@openzeppelin/contracts/index.ts +9 -0
- package/typechain-types/@openzeppelin/contracts/interfaces/IERC4906.ts +462 -0
- package/typechain-types/@openzeppelin/contracts/interfaces/draft-IERC6093.sol/IERC1155Errors.ts +69 -0
- package/typechain-types/@openzeppelin/contracts/interfaces/draft-IERC6093.sol/IERC20Errors.ts +69 -0
- package/typechain-types/@openzeppelin/contracts/interfaces/draft-IERC6093.sol/IERC721Errors.ts +69 -0
- package/typechain-types/@openzeppelin/contracts/interfaces/draft-IERC6093.sol/index.ts +6 -0
- package/typechain-types/@openzeppelin/contracts/interfaces/index.ts +6 -0
- package/typechain-types/@openzeppelin/contracts/token/ERC721/IERC721.ts +393 -0
- package/typechain-types/@openzeppelin/contracts/token/ERC721/IERC721Receiver.ts +110 -0
- package/typechain-types/@openzeppelin/contracts/token/ERC721/index.ts +5 -0
- package/typechain-types/@openzeppelin/contracts/token/index.ts +5 -0
- package/typechain-types/@openzeppelin/contracts/utils/index.ts +5 -0
- package/typechain-types/@openzeppelin/contracts/utils/introspection/ERC165.ts +94 -0
- package/typechain-types/@openzeppelin/contracts/utils/introspection/IERC165.ts +94 -0
- package/typechain-types/@openzeppelin/contracts/utils/introspection/index.ts +5 -0
- package/typechain-types/@openzeppelin/index.ts +5 -0
- package/typechain-types/common.ts +131 -0
- package/typechain-types/contracts/access/DataPrivacyFramework/DataPrivacyFramework.ts +598 -0
- package/typechain-types/contracts/access/DataPrivacyFramework/extensions/DataPrivacyFrameworkMpc.ts +598 -0
- package/typechain-types/contracts/access/DataPrivacyFramework/extensions/index.ts +4 -0
- package/typechain-types/contracts/access/DataPrivacyFramework/index.ts +6 -0
- package/typechain-types/contracts/access/index.ts +5 -0
- package/typechain-types/contracts/index.ts +13 -0
- package/typechain-types/contracts/mocks/access/DataPrivacyFramework/DataPrivacyFrameworkMock.ts +598 -0
- package/typechain-types/contracts/mocks/access/DataPrivacyFramework/index.ts +4 -0
- package/typechain-types/contracts/mocks/access/index.ts +5 -0
- package/typechain-types/contracts/mocks/index.ts +11 -0
- package/typechain-types/contracts/mocks/token/PrivateERC20/PrivateERC20Mock.ts +543 -0
- package/typechain-types/contracts/mocks/token/PrivateERC20/index.ts +4 -0
- package/typechain-types/contracts/mocks/token/PrivateERC721/PrivateERC721URIStorageMock.ts +576 -0
- package/typechain-types/contracts/mocks/token/PrivateERC721/index.ts +4 -0
- package/typechain-types/contracts/mocks/token/index.ts +7 -0
- package/typechain-types/contracts/mocks/utils/index.ts +5 -0
- package/typechain-types/contracts/mocks/utils/mpc/ArithmeticTestsContract.ts +354 -0
- package/typechain-types/contracts/mocks/utils/mpc/BitwiseTestsContract.ts +340 -0
- package/typechain-types/contracts/mocks/utils/mpc/Comparison1Tests.Contract.sol/Comparison1TestsContract.ts +340 -0
- package/typechain-types/contracts/mocks/utils/mpc/Comparison1Tests.Contract.sol/index.ts +4 -0
- package/typechain-types/contracts/mocks/utils/mpc/Comparison2TestsContract.ts +340 -0
- package/typechain-types/contracts/mocks/utils/mpc/MinMaxTestsContract.ts +321 -0
- package/typechain-types/contracts/mocks/utils/mpc/Miscellaneous1TestsContract.ts +199 -0
- package/typechain-types/contracts/mocks/utils/mpc/Miscellaneous2TestsContract.ts +384 -0
- package/typechain-types/contracts/mocks/utils/mpc/OffboardToUserKeyTestsContract.sol/OffboardToUserKeyTestContract.ts +218 -0
- package/typechain-types/contracts/mocks/utils/mpc/OffboardToUserKeyTestsContract.sol/index.ts +4 -0
- package/typechain-types/contracts/mocks/utils/mpc/ShiftTestsContract.ts +339 -0
- package/typechain-types/contracts/mocks/utils/mpc/StringTestsContract.ts +211 -0
- package/typechain-types/contracts/mocks/utils/mpc/TransferScalarTestsContract.ts +266 -0
- package/typechain-types/contracts/mocks/utils/mpc/TransferTestsContract.ts +288 -0
- package/typechain-types/contracts/mocks/utils/mpc/index.ts +17 -0
- package/typechain-types/contracts/mocks/wallet/PrivateERC20Wallet/PrivateERC20WalletMock.ts +173 -0
- package/typechain-types/contracts/mocks/wallet/PrivateERC20Wallet/index.ts +4 -0
- package/typechain-types/contracts/mocks/wallet/index.ts +5 -0
- package/typechain-types/contracts/onboard/AccountOnboard.ts +135 -0
- package/typechain-types/contracts/onboard/index.ts +4 -0
- package/typechain-types/contracts/token/PrivateERC20/IPrivateERC20.ts +437 -0
- package/typechain-types/contracts/token/PrivateERC20/PrivateERC20.ts +505 -0
- package/typechain-types/contracts/token/PrivateERC20/index.ts +5 -0
- package/typechain-types/contracts/token/PrivateERC721/PrivateERC721.ts +409 -0
- package/typechain-types/contracts/token/PrivateERC721/extensions/PrivateERC721URIStorage.ts +501 -0
- package/typechain-types/contracts/token/PrivateERC721/extensions/index.ts +4 -0
- package/typechain-types/contracts/token/PrivateERC721/index.ts +6 -0
- package/typechain-types/contracts/token/index.ts +7 -0
- package/typechain-types/contracts/utils/index.ts +5 -0
- package/typechain-types/contracts/utils/mpc/MpcInterface.sol/ExtendedOperations.ts +698 -0
- package/typechain-types/contracts/utils/mpc/MpcInterface.sol/index.ts +4 -0
- package/typechain-types/contracts/utils/mpc/index.ts +5 -0
- package/typechain-types/factories/@openzeppelin/contracts/index.ts +6 -0
- package/typechain-types/factories/@openzeppelin/contracts/interfaces/IERC4906__factory.ts +339 -0
- package/typechain-types/factories/@openzeppelin/contracts/interfaces/draft-IERC6093.sol/IERC1155Errors__factory.ts +127 -0
- package/typechain-types/factories/@openzeppelin/contracts/interfaces/draft-IERC6093.sol/IERC20Errors__factory.ts +111 -0
- package/typechain-types/factories/@openzeppelin/contracts/interfaces/draft-IERC6093.sol/IERC721Errors__factory.ts +128 -0
- package/typechain-types/factories/@openzeppelin/contracts/interfaces/draft-IERC6093.sol/index.ts +6 -0
- package/typechain-types/factories/@openzeppelin/contracts/interfaces/index.ts +5 -0
- package/typechain-types/factories/@openzeppelin/contracts/token/ERC721/IERC721Receiver__factory.ts +59 -0
- package/typechain-types/factories/@openzeppelin/contracts/token/ERC721/IERC721__factory.ts +307 -0
- package/typechain-types/factories/@openzeppelin/contracts/token/ERC721/index.ts +5 -0
- package/typechain-types/factories/@openzeppelin/contracts/token/index.ts +4 -0
- package/typechain-types/factories/@openzeppelin/contracts/utils/index.ts +4 -0
- package/typechain-types/factories/@openzeppelin/contracts/utils/introspection/ERC165__factory.ts +41 -0
- package/typechain-types/factories/@openzeppelin/contracts/utils/introspection/IERC165__factory.ts +41 -0
- package/typechain-types/factories/@openzeppelin/contracts/utils/introspection/index.ts +5 -0
- package/typechain-types/factories/@openzeppelin/index.ts +4 -0
- package/typechain-types/factories/contracts/access/DataPrivacyFramework/DataPrivacyFramework__factory.ts +621 -0
- package/typechain-types/factories/contracts/access/DataPrivacyFramework/extensions/DataPrivacyFrameworkMpc__factory.ts +621 -0
- package/typechain-types/factories/contracts/access/DataPrivacyFramework/extensions/index.ts +4 -0
- package/typechain-types/factories/contracts/access/DataPrivacyFramework/index.ts +5 -0
- package/typechain-types/factories/contracts/access/index.ts +4 -0
- package/typechain-types/factories/contracts/index.ts +8 -0
- package/typechain-types/factories/contracts/mocks/access/DataPrivacyFramework/DataPrivacyFrameworkMock__factory.ts +670 -0
- package/typechain-types/factories/contracts/mocks/access/DataPrivacyFramework/index.ts +4 -0
- package/typechain-types/factories/contracts/mocks/access/index.ts +4 -0
- package/typechain-types/factories/contracts/mocks/index.ts +7 -0
- package/typechain-types/factories/contracts/mocks/token/PrivateERC20/PrivateERC20Mock__factory.ts +615 -0
- package/typechain-types/factories/contracts/mocks/token/PrivateERC20/index.ts +4 -0
- package/typechain-types/factories/contracts/mocks/token/PrivateERC721/PrivateERC721URIStorageMock__factory.ts +630 -0
- package/typechain-types/factories/contracts/mocks/token/PrivateERC721/index.ts +4 -0
- package/typechain-types/factories/contracts/mocks/token/index.ts +5 -0
- package/typechain-types/factories/contracts/mocks/utils/index.ts +4 -0
- package/typechain-types/factories/contracts/mocks/utils/mpc/ArithmeticTestsContract__factory.ts +374 -0
- package/typechain-types/factories/contracts/mocks/utils/mpc/BitwiseTestsContract__factory.ts +361 -0
- package/typechain-types/factories/contracts/mocks/utils/mpc/Comparison1Tests.Contract.sol/Comparison1TestsContract__factory.ts +361 -0
- package/typechain-types/factories/contracts/mocks/utils/mpc/Comparison1Tests.Contract.sol/index.ts +4 -0
- package/typechain-types/factories/contracts/mocks/utils/mpc/Comparison2TestsContract__factory.ts +361 -0
- package/typechain-types/factories/contracts/mocks/utils/mpc/MinMaxTestsContract__factory.ts +337 -0
- package/typechain-types/factories/contracts/mocks/utils/mpc/Miscellaneous1TestsContract__factory.ts +236 -0
- package/typechain-types/factories/contracts/mocks/utils/mpc/Miscellaneous2TestsContract__factory.ts +432 -0
- package/typechain-types/factories/contracts/mocks/utils/mpc/OffboardToUserKeyTestsContract.sol/OffboardToUserKeyTestContract__factory.ts +245 -0
- package/typechain-types/factories/contracts/mocks/utils/mpc/OffboardToUserKeyTestsContract.sol/index.ts +4 -0
- package/typechain-types/factories/contracts/mocks/utils/mpc/ShiftTestsContract__factory.ts +374 -0
- package/typechain-types/factories/contracts/mocks/utils/mpc/StringTestsContract__factory.ts +264 -0
- package/typechain-types/factories/contracts/mocks/utils/mpc/TransferScalarTestsContract__factory.ts +360 -0
- package/typechain-types/factories/contracts/mocks/utils/mpc/TransferTestsContract__factory.ts +441 -0
- package/typechain-types/factories/contracts/mocks/utils/mpc/index.ts +15 -0
- package/typechain-types/factories/contracts/mocks/wallet/PrivateERC20Wallet/PrivateERC20WalletMock__factory.ts +194 -0
- package/typechain-types/factories/contracts/mocks/wallet/PrivateERC20Wallet/index.ts +4 -0
- package/typechain-types/factories/contracts/mocks/wallet/index.ts +4 -0
- package/typechain-types/factories/contracts/onboard/AccountOnboard__factory.ts +104 -0
- package/typechain-types/factories/contracts/onboard/index.ts +4 -0
- package/typechain-types/factories/contracts/token/PrivateERC20/IPrivateERC20__factory.ts +406 -0
- package/typechain-types/factories/contracts/token/PrivateERC20/PrivateERC20__factory.ts +532 -0
- package/typechain-types/factories/contracts/token/PrivateERC20/index.ts +5 -0
- package/typechain-types/factories/contracts/token/PrivateERC721/PrivateERC721__factory.ts +439 -0
- package/typechain-types/factories/contracts/token/PrivateERC721/extensions/PrivateERC721URIStorage__factory.ts +512 -0
- package/typechain-types/factories/contracts/token/PrivateERC721/extensions/index.ts +4 -0
- package/typechain-types/factories/contracts/token/PrivateERC721/index.ts +5 -0
- package/typechain-types/factories/contracts/token/index.ts +5 -0
- package/typechain-types/factories/contracts/utils/index.ts +4 -0
- package/typechain-types/factories/contracts/utils/mpc/MpcInterface.sol/ExtendedOperations__factory.ts +919 -0
- package/typechain-types/factories/contracts/utils/mpc/MpcInterface.sol/index.ts +4 -0
- package/typechain-types/factories/contracts/utils/mpc/index.ts +4 -0
- package/typechain-types/factories/index.ts +5 -0
- package/typechain-types/hardhat.d.ts +621 -0
- package/typechain-types/index.ts +72 -0
|
@@ -0,0 +1,223 @@
|
|
|
1
|
+
import hre from "hardhat"
|
|
2
|
+
import { expect } from "chai"
|
|
3
|
+
|
|
4
|
+
import { setupAccounts } from "../../utils/accounts"
|
|
5
|
+
import { ContractTransactionReceipt, itString } from "@coti-io/coti-ethers"
|
|
6
|
+
|
|
7
|
+
const gasLimit = 12000000
|
|
8
|
+
|
|
9
|
+
async function deploy() {
|
|
10
|
+
const [owner, otherAccount] = await setupAccounts()
|
|
11
|
+
|
|
12
|
+
const factory = await hre.ethers.getContractFactory("PrivateERC721URIStorageMock")
|
|
13
|
+
const contract = await factory.connect(owner).deploy({ gasLimit })
|
|
14
|
+
|
|
15
|
+
await contract.waitForDeployment()
|
|
16
|
+
|
|
17
|
+
return { contract, contractAddress: await contract.getAddress(), owner, otherAccount }
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
describe("Private ERC721", function () {
|
|
21
|
+
let deployment: Awaited<ReturnType<typeof deploy>>
|
|
22
|
+
|
|
23
|
+
before(async function () {
|
|
24
|
+
deployment = await deploy()
|
|
25
|
+
})
|
|
26
|
+
|
|
27
|
+
describe("Deployment", function () {
|
|
28
|
+
it("Deployed address should be a valid Ethereum address", async function () {
|
|
29
|
+
expect(hre.ethers.isAddress(deployment.contractAddress)).to.eq(true)
|
|
30
|
+
})
|
|
31
|
+
|
|
32
|
+
it("Name should match deployment name", async function () {
|
|
33
|
+
expect(await deployment.contract.name()).to.equal("Example")
|
|
34
|
+
})
|
|
35
|
+
|
|
36
|
+
it("Symbol should match deployment symbol", async function () {
|
|
37
|
+
expect(await deployment.contract.symbol()).to.equal("EXL")
|
|
38
|
+
})
|
|
39
|
+
})
|
|
40
|
+
|
|
41
|
+
describe("Minting", function () {
|
|
42
|
+
const tokenURI = 'https://api.pudgypenguins.io/lil/18707'
|
|
43
|
+
|
|
44
|
+
describe("Successful mint", function () {
|
|
45
|
+
let tx: ContractTransactionReceipt | null
|
|
46
|
+
|
|
47
|
+
before(async function () {
|
|
48
|
+
const { contract, contractAddress, owner, otherAccount } = deployment
|
|
49
|
+
|
|
50
|
+
const encryptedTokenURI = await owner.encryptValue(tokenURI, contractAddress, contract.mint.fragment.selector) as itString
|
|
51
|
+
|
|
52
|
+
tx = await (
|
|
53
|
+
await contract
|
|
54
|
+
.connect(owner)
|
|
55
|
+
.mint(
|
|
56
|
+
otherAccount.address,
|
|
57
|
+
encryptedTokenURI,
|
|
58
|
+
{ gasLimit })
|
|
59
|
+
).wait()
|
|
60
|
+
})
|
|
61
|
+
|
|
62
|
+
it("Should emit a 'Minted' event", async function () {
|
|
63
|
+
const { contract } = deployment
|
|
64
|
+
|
|
65
|
+
expect(tx).to.emit(contract, "Minted")
|
|
66
|
+
})
|
|
67
|
+
|
|
68
|
+
it("Should update the owners mapping", async function () {
|
|
69
|
+
const { contract, otherAccount } = deployment
|
|
70
|
+
|
|
71
|
+
expect(await contract.ownerOf(BigInt(0))).to.equal(otherAccount.address)
|
|
72
|
+
})
|
|
73
|
+
|
|
74
|
+
it("Should update the balances mapping", async function () {
|
|
75
|
+
const { contract, otherAccount } = deployment
|
|
76
|
+
|
|
77
|
+
expect(await contract.balanceOf(otherAccount.address)).to.equal(BigInt(1))
|
|
78
|
+
})
|
|
79
|
+
|
|
80
|
+
})
|
|
81
|
+
|
|
82
|
+
it("Should fail to mint if the encrypted token URI is faulty", async function () {
|
|
83
|
+
const { contract, contractAddress, otherAccount, owner } = deployment
|
|
84
|
+
|
|
85
|
+
const ownerEncryptedTokenURI = await owner.encryptValue(tokenURI, contractAddress, contract.mint.fragment.selector) as itString
|
|
86
|
+
const otherAccountEncryptedTokenURI = await otherAccount.encryptValue(tokenURI, contractAddress, contract.mint.fragment.selector) as itString
|
|
87
|
+
|
|
88
|
+
const encryptedTokenURI = {
|
|
89
|
+
ciphertext: ownerEncryptedTokenURI.ciphertext,
|
|
90
|
+
signature: otherAccountEncryptedTokenURI.signature
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
const tx = await contract
|
|
94
|
+
.connect(otherAccount)
|
|
95
|
+
.mint(
|
|
96
|
+
otherAccount.address,
|
|
97
|
+
encryptedTokenURI,
|
|
98
|
+
{ gasLimit }
|
|
99
|
+
)
|
|
100
|
+
|
|
101
|
+
expect(tx).to.be.reverted
|
|
102
|
+
})
|
|
103
|
+
})
|
|
104
|
+
|
|
105
|
+
describe("URI", function () {
|
|
106
|
+
it("should return 0 for token URI if not set", async function () {
|
|
107
|
+
const { contract, owner } = deployment
|
|
108
|
+
|
|
109
|
+
const tokenId = BigInt(1)
|
|
110
|
+
const ctURI = await contract.connect(owner).tokenURI(tokenId)
|
|
111
|
+
const uri = await owner.decryptValue(ctURI)
|
|
112
|
+
|
|
113
|
+
expect(uri).to.equal("")
|
|
114
|
+
})
|
|
115
|
+
})
|
|
116
|
+
|
|
117
|
+
describe("Transfers", function () {
|
|
118
|
+
describe("Successful transfer", function () {
|
|
119
|
+
const tokenId = BigInt(0)
|
|
120
|
+
const tokenURI = 'https://api.pudgypenguins.io/lil/18707'
|
|
121
|
+
|
|
122
|
+
before(async function () {
|
|
123
|
+
const { contract, owner, otherAccount } = deployment
|
|
124
|
+
|
|
125
|
+
await (await contract.connect(otherAccount).approve(owner.address, tokenId, { gasLimit })).wait()
|
|
126
|
+
|
|
127
|
+
await (
|
|
128
|
+
await contract
|
|
129
|
+
.connect(owner)
|
|
130
|
+
.transferFrom(otherAccount.address, owner.address, tokenId, { gasLimit })
|
|
131
|
+
).wait()
|
|
132
|
+
})
|
|
133
|
+
|
|
134
|
+
it("Should transfer token to other account", async function () {
|
|
135
|
+
const { contract, owner, otherAccount } = deployment
|
|
136
|
+
|
|
137
|
+
expect(await contract.ownerOf(tokenId)).to.equal(owner.address)
|
|
138
|
+
expect(await contract.balanceOf(owner.address)).to.equal(BigInt(1))
|
|
139
|
+
expect(await contract.balanceOf(otherAccount.address)).to.equal(BigInt(0))
|
|
140
|
+
})
|
|
141
|
+
|
|
142
|
+
it("Should allow the new owner to decrypt the token URI", async function () {
|
|
143
|
+
const { contract, owner } = deployment
|
|
144
|
+
|
|
145
|
+
const encryptedTokenURI = await contract.tokenURI(tokenId)
|
|
146
|
+
|
|
147
|
+
const decryptedTokenURI = await owner.decryptValue(encryptedTokenURI)
|
|
148
|
+
|
|
149
|
+
expect(decryptedTokenURI).to.equal(tokenURI)
|
|
150
|
+
})
|
|
151
|
+
|
|
152
|
+
it("Should not allow the previous owner to decrypt the token URI", async function () {
|
|
153
|
+
const { contract, otherAccount } = deployment
|
|
154
|
+
|
|
155
|
+
const encryptedTokenURI = await contract.tokenURI(tokenId)
|
|
156
|
+
|
|
157
|
+
const decryptedTokenURI = await otherAccount.decryptValue(encryptedTokenURI)
|
|
158
|
+
|
|
159
|
+
expect(decryptedTokenURI).to.not.equal(tokenURI)
|
|
160
|
+
})
|
|
161
|
+
})
|
|
162
|
+
|
|
163
|
+
describe("Failed transfers", function () {
|
|
164
|
+
const tokenURI = 'https://api.pudgypenguins.io/lil/9040'
|
|
165
|
+
|
|
166
|
+
it("Should fail transfer token to other account for when no allowance", async function () {
|
|
167
|
+
const { contract, contractAddress, owner, otherAccount } = deployment
|
|
168
|
+
|
|
169
|
+
const encryptedTokenURI = await owner.encryptValue(tokenURI, contractAddress, contract.mint.fragment.selector) as itString
|
|
170
|
+
|
|
171
|
+
const tokenId = await deployment.contract.totalSupply()
|
|
172
|
+
|
|
173
|
+
await (
|
|
174
|
+
await contract
|
|
175
|
+
.connect(owner)
|
|
176
|
+
.mint(
|
|
177
|
+
owner.address,
|
|
178
|
+
encryptedTokenURI,
|
|
179
|
+
{ gasLimit }
|
|
180
|
+
)
|
|
181
|
+
).wait()
|
|
182
|
+
|
|
183
|
+
const tx = await contract
|
|
184
|
+
.connect(otherAccount)
|
|
185
|
+
.transferFrom(owner.address, otherAccount.address, tokenId, { gasLimit })
|
|
186
|
+
let reverted = true
|
|
187
|
+
try {
|
|
188
|
+
await tx.wait()
|
|
189
|
+
reverted = false
|
|
190
|
+
} catch (error) {}
|
|
191
|
+
expect(reverted).to.eq(true, "Should have reverted")
|
|
192
|
+
})
|
|
193
|
+
|
|
194
|
+
it("Should fail to transfer from non-owner", async function () {
|
|
195
|
+
const { contract, contractAddress, owner, otherAccount } = deployment
|
|
196
|
+
|
|
197
|
+
const encryptedTokenURI = await owner.encryptValue(tokenURI, contractAddress, contract.mint.fragment.selector) as itString
|
|
198
|
+
|
|
199
|
+
const tokenId = await deployment.contract.totalSupply()
|
|
200
|
+
|
|
201
|
+
await (
|
|
202
|
+
await contract
|
|
203
|
+
.connect(owner)
|
|
204
|
+
.mint(
|
|
205
|
+
owner.address,
|
|
206
|
+
encryptedTokenURI,
|
|
207
|
+
{ gasLimit }
|
|
208
|
+
)
|
|
209
|
+
).wait()
|
|
210
|
+
|
|
211
|
+
const tx = await contract
|
|
212
|
+
.connect(otherAccount)
|
|
213
|
+
.transferFrom(owner.address, otherAccount.address, tokenId, { gasLimit })
|
|
214
|
+
let reverted = true
|
|
215
|
+
try {
|
|
216
|
+
await tx.wait()
|
|
217
|
+
reverted = false
|
|
218
|
+
} catch (error) {}
|
|
219
|
+
expect(reverted).to.eq(true, "Should have reverted")
|
|
220
|
+
})
|
|
221
|
+
})
|
|
222
|
+
})
|
|
223
|
+
})
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import fs from "fs"
|
|
2
|
+
import { CotiNetwork, getDefaultProvider, parseEther, Wallet } from "@coti-io/coti-ethers"
|
|
3
|
+
|
|
4
|
+
let pks = process.env.SIGNING_KEYS ? process.env.SIGNING_KEYS.split(",") : []
|
|
5
|
+
|
|
6
|
+
export async function setupAccounts() {
|
|
7
|
+
const provider = getDefaultProvider(CotiNetwork.Devnet);
|
|
8
|
+
|
|
9
|
+
if (pks.length == 0) {
|
|
10
|
+
const key1 = Wallet.createRandom(provider)
|
|
11
|
+
const key2 = Wallet.createRandom(provider)
|
|
12
|
+
pks = [key1.privateKey, key2.privateKey]
|
|
13
|
+
|
|
14
|
+
setEnvValue("PUBLIC_KEYS", `${key1.address},${key2.address}`)
|
|
15
|
+
setEnvValue("SIGNING_KEYS", `${key1.privateKey},${key2.privateKey}`)
|
|
16
|
+
|
|
17
|
+
throw new Error(`Created new random accounts ${key1.address} and ${key2.address}. Please use faucet to fund it.`)
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
const wallets = pks.map((pk) => new Wallet(pk, provider))
|
|
21
|
+
if ((await provider.getBalance(wallets[0].address)) === BigInt("0")) {
|
|
22
|
+
throw new Error(`Please use faucet to fund account ${wallets[0].address}`)
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
let userKeys = process.env.USER_KEYS ? process.env.USER_KEYS.split(",") : []
|
|
26
|
+
|
|
27
|
+
const toAccount = async (wallet: Wallet, userKey?: string) => {
|
|
28
|
+
if (userKey) {
|
|
29
|
+
wallet.setAesKey(userKey)
|
|
30
|
+
return wallet
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
console.log("************* Onboarding user ", wallet.address, " *************")
|
|
34
|
+
await wallet.generateOrRecoverAes()
|
|
35
|
+
console.log("************* Onboarded! created user key and saved into .env file *************")
|
|
36
|
+
|
|
37
|
+
return wallet
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
let accounts: Wallet[] = []
|
|
41
|
+
if (userKeys.length !== wallets.length) {
|
|
42
|
+
await (await wallets[0].sendTransaction({ to: wallets[1].address, value: parseEther("0.1") })).wait()
|
|
43
|
+
|
|
44
|
+
accounts = await Promise.all(wallets.map(async (account, i) => await toAccount(account)))
|
|
45
|
+
setEnvValue("USER_KEYS", accounts.map((a) => a.getUserOnboardInfo()?.aesKey).join(","))
|
|
46
|
+
} else {
|
|
47
|
+
accounts = await Promise.all(wallets.map(async (account, i) => await toAccount(account, userKeys[i])))
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
return accounts
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
function setEnvValue(key: string, value: string) {
|
|
54
|
+
fs.appendFileSync("./.env", `\n${key}=${value}`, "utf8")
|
|
55
|
+
}
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import hre from "hardhat"
|
|
2
|
+
import { expect } from "chai"
|
|
3
|
+
import { setupAccounts } from "../accounts"
|
|
4
|
+
|
|
5
|
+
const gasLimit = 12000000
|
|
6
|
+
let last_random_value = 0
|
|
7
|
+
|
|
8
|
+
function buildTest(
|
|
9
|
+
contractName: string,
|
|
10
|
+
func: string,
|
|
11
|
+
resFunc: string,
|
|
12
|
+
params: (bigint | number | boolean)[],
|
|
13
|
+
...expectedResults: (number | boolean | bigint)[]
|
|
14
|
+
) {
|
|
15
|
+
it(`${contractName}.${func}(${params}) should return ${expectedResults}`, async function () {
|
|
16
|
+
const [owner] = await setupAccounts()
|
|
17
|
+
|
|
18
|
+
const factory = await hre.ethers.getContractFactory(contractName, owner)
|
|
19
|
+
const contract = await factory.deploy({ gasLimit })
|
|
20
|
+
await contract.waitForDeployment()
|
|
21
|
+
|
|
22
|
+
await (await contract.getFunction(func)(...params, { gasLimit })).wait()
|
|
23
|
+
const result = await contract.getFunction(resFunc)()
|
|
24
|
+
if (resFunc === "getRandom") {
|
|
25
|
+
expect(result).to.not.equal(expectedResults[0])
|
|
26
|
+
last_random_value = result
|
|
27
|
+
} else if (expectedResults.length === 1) {
|
|
28
|
+
expect(result).to.equal(expectedResults[0])
|
|
29
|
+
} else {
|
|
30
|
+
expect(result).to.deep.equal(expectedResults)
|
|
31
|
+
}
|
|
32
|
+
})
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
function buildTestWithUser(contractName: string, func: string, resFunc: string, param: bigint | number | boolean) {
|
|
36
|
+
it(`${contractName}.${func}(${params}, <address>) should return the correct user decrypted value`, async function () {
|
|
37
|
+
const [owner] = await setupAccounts()
|
|
38
|
+
|
|
39
|
+
const factory = await hre.ethers.getContractFactory(contractName, owner)
|
|
40
|
+
const contract = await factory.deploy({ gasLimit })
|
|
41
|
+
await contract.waitForDeployment()
|
|
42
|
+
|
|
43
|
+
await (await contract.getFunction(func)(param, owner.address, { gasLimit: 12000000 })).wait()
|
|
44
|
+
const results = await contract.getFunction(resFunc)()
|
|
45
|
+
for (const result of results) {
|
|
46
|
+
expect(await owner.decryptValue(result)).to.equal(param)
|
|
47
|
+
}
|
|
48
|
+
})
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
const params = [10, 5]
|
|
52
|
+
const shift = 2
|
|
53
|
+
const bit = false
|
|
54
|
+
const numBits = 7
|
|
55
|
+
const bool_a = true
|
|
56
|
+
const bool_b = false
|
|
57
|
+
const [a, b] = params
|
|
58
|
+
describe("Precompile", function () {
|
|
59
|
+
buildTest("ArithmeticTestsContract", "addTest", "getResult", params, a + b)
|
|
60
|
+
buildTest("ArithmeticTestsContract", "subTest", "getResult", params, a - b)
|
|
61
|
+
buildTest("ArithmeticTestsContract", "mulTest", "getResult16", params, a * b)
|
|
62
|
+
|
|
63
|
+
buildTest("Miscellaneous2TestsContract", "divTest", "getResult", params, a / b)
|
|
64
|
+
buildTest("Miscellaneous2TestsContract", "remTest", "getResult", params, a % b)
|
|
65
|
+
|
|
66
|
+
buildTest("BitwiseTestsContract", "andTest", "getResult", params, a & b)
|
|
67
|
+
buildTest("BitwiseTestsContract", "orTest", "getResult", params, a | b)
|
|
68
|
+
buildTest("BitwiseTestsContract", "xorTest", "getResult", params, a ^ b)
|
|
69
|
+
|
|
70
|
+
buildTest(
|
|
71
|
+
"ShiftTestsContract",
|
|
72
|
+
"shlTest",
|
|
73
|
+
"getAllShiftResults",
|
|
74
|
+
[a, shift],
|
|
75
|
+
...[2, 4, 8, 16].map((x) => BigInt(a << shift) & BigInt(`0x${"f".repeat(x)}`))
|
|
76
|
+
)
|
|
77
|
+
buildTest("ShiftTestsContract", "shrTest", "getResult", params, a >> b)
|
|
78
|
+
|
|
79
|
+
buildTest("MinMaxTestsContract", "minTest", "getResult", params, Math.min(a, b))
|
|
80
|
+
buildTest("MinMaxTestsContract", "maxTest", "getResult", params, Math.max(a, b))
|
|
81
|
+
buildTest("Comparison2TestsContract", "eqTest", "getResult", params, a == b)
|
|
82
|
+
buildTest("Comparison2TestsContract", "neTest", "getResult", params, a != b)
|
|
83
|
+
buildTest("Comparison2TestsContract", "geTest", "getResult", params, a >= b)
|
|
84
|
+
buildTest("Comparison1TestsContract", "gtTest", "getResult", params, a > b)
|
|
85
|
+
buildTest("Comparison1TestsContract", "leTest", "getResult", params, a <= b)
|
|
86
|
+
buildTest("Comparison1TestsContract", "ltTest", "getResult", params, a < b)
|
|
87
|
+
buildTest("Miscellaneous2TestsContract", "muxTest", "getResult", [bit, a, b], bit === false ? a : b)
|
|
88
|
+
|
|
89
|
+
buildTest("TransferTestsContract", "transferTest", "getResults", [a, b, b], a - b, b + b, true)
|
|
90
|
+
buildTest("TransferScalarTestsContract", "transferScalarTest", "getResults", [a, b, b], a - b, b + b, true)
|
|
91
|
+
|
|
92
|
+
buildTest("Miscellaneous2TestsContract", "offboardOnboardTest", "getResult", [a, a, a, a], a)
|
|
93
|
+
buildTest("Miscellaneous2TestsContract", "notTest", "getBoolResult", [!!a], !a)
|
|
94
|
+
|
|
95
|
+
buildTestWithUser("OffboardToUserKeyTestContract", "offboardToUserTest", "getCTs", a)
|
|
96
|
+
|
|
97
|
+
buildTest("Miscellaneous1TestsContract", "randomTest", "getRandom", [], last_random_value)
|
|
98
|
+
buildTest("Miscellaneous1TestsContract", "randomBoundedTest", "getRandom", [numBits], last_random_value)
|
|
99
|
+
buildTest(
|
|
100
|
+
"Miscellaneous1TestsContract",
|
|
101
|
+
"booleanTest",
|
|
102
|
+
"getBooleanResults",
|
|
103
|
+
[bool_a, bool_b, bit],
|
|
104
|
+
bool_a && bool_b,
|
|
105
|
+
bool_a || bool_b,
|
|
106
|
+
bool_a != (bool_b as boolean),
|
|
107
|
+
!bool_a,
|
|
108
|
+
bool_a === (bool_b as boolean),
|
|
109
|
+
bool_a != (bool_b as boolean),
|
|
110
|
+
bit ? bool_b : bool_a,
|
|
111
|
+
bool_a
|
|
112
|
+
)
|
|
113
|
+
})
|
|
@@ -0,0 +1,227 @@
|
|
|
1
|
+
import hre from "hardhat"
|
|
2
|
+
import { expect } from "chai"
|
|
3
|
+
import { setupAccounts } from "../accounts"
|
|
4
|
+
import { itString } from "@coti-io/coti-ethers"
|
|
5
|
+
|
|
6
|
+
const gasLimit = 12000000
|
|
7
|
+
|
|
8
|
+
async function deploy() {
|
|
9
|
+
const [owner, otherAccount] = await setupAccounts()
|
|
10
|
+
|
|
11
|
+
const factory = await hre.ethers.getContractFactory("StringTestsContract")
|
|
12
|
+
const contract = await factory.connect(owner).deploy({ gasLimit })
|
|
13
|
+
await contract.waitForDeployment()
|
|
14
|
+
|
|
15
|
+
return { contract, contractAddress: await contract.getAddress(), owner, otherAccount }
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
function formatString(str: string) {
|
|
19
|
+
return str.replace(/\0/g, '')
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
describe("MPC Core", function () {
|
|
23
|
+
let deployment: Awaited<ReturnType<typeof deploy>>
|
|
24
|
+
|
|
25
|
+
before(async function () {
|
|
26
|
+
deployment = await deploy()
|
|
27
|
+
})
|
|
28
|
+
|
|
29
|
+
describe("Set user-encrypted string using an encrypted value", function () {
|
|
30
|
+
const str = "Hello, World!"
|
|
31
|
+
|
|
32
|
+
it("Should store the string encrypted using the users key", async function () {
|
|
33
|
+
const { contract, contractAddress, owner } = deployment
|
|
34
|
+
|
|
35
|
+
const itString = await owner.encryptValue(
|
|
36
|
+
str,
|
|
37
|
+
contractAddress,
|
|
38
|
+
contract.setUserEncryptedString.fragment.selector
|
|
39
|
+
) as itString
|
|
40
|
+
|
|
41
|
+
const tx = await contract
|
|
42
|
+
.connect(owner)
|
|
43
|
+
.setUserEncryptedString(itString, { gasLimit })
|
|
44
|
+
|
|
45
|
+
await tx.wait()
|
|
46
|
+
})
|
|
47
|
+
|
|
48
|
+
it("Should retrieve the string encrypted with the users key", async function () {
|
|
49
|
+
const { contract, owner } = deployment
|
|
50
|
+
|
|
51
|
+
const userEncryptedString = await contract.getUserEncryptedString()
|
|
52
|
+
|
|
53
|
+
const decryptedStr = await owner.decryptValue(userEncryptedString)
|
|
54
|
+
|
|
55
|
+
expect(decryptedStr).to.equal(str)
|
|
56
|
+
})
|
|
57
|
+
|
|
58
|
+
it("Should fail to decrypt the string encrypted with the users key", async function () {
|
|
59
|
+
const { contract, otherAccount } = deployment
|
|
60
|
+
|
|
61
|
+
const userEncryptedString = await contract.getUserEncryptedString()
|
|
62
|
+
|
|
63
|
+
const decryptedStr = await otherAccount.decryptValue(userEncryptedString)
|
|
64
|
+
|
|
65
|
+
expect(decryptedStr).to.not.equal(str)
|
|
66
|
+
})
|
|
67
|
+
})
|
|
68
|
+
|
|
69
|
+
describe("Set network-encrypted string using an encrypted value", function () {
|
|
70
|
+
const str = "Hi, Mom!"
|
|
71
|
+
|
|
72
|
+
it("Should store the string encrypted using the network key", async function () {
|
|
73
|
+
const { contract, contractAddress, owner } = deployment
|
|
74
|
+
|
|
75
|
+
const itString = await owner.encryptValue(
|
|
76
|
+
str,
|
|
77
|
+
contractAddress,
|
|
78
|
+
contract.setNetworkEncryptedString.fragment.selector
|
|
79
|
+
) as itString
|
|
80
|
+
|
|
81
|
+
const tx = await contract
|
|
82
|
+
.connect(owner)
|
|
83
|
+
.setNetworkEncryptedString(itString, { gasLimit })
|
|
84
|
+
|
|
85
|
+
await tx.wait()
|
|
86
|
+
})
|
|
87
|
+
|
|
88
|
+
it("Should decrypt the network-encrypted string and store it in clear text", async function () {
|
|
89
|
+
const { contract, owner } = deployment
|
|
90
|
+
|
|
91
|
+
const tx = await contract
|
|
92
|
+
.connect(owner)
|
|
93
|
+
.decryptNetworkEncryptedString()
|
|
94
|
+
|
|
95
|
+
await tx.wait()
|
|
96
|
+
|
|
97
|
+
const decryptedStr = await contract.plaintext()
|
|
98
|
+
|
|
99
|
+
expect(formatString(decryptedStr)).to.equal(str)
|
|
100
|
+
})
|
|
101
|
+
})
|
|
102
|
+
|
|
103
|
+
describe("Set user-encrypted string using a non-encrypted value", function () {
|
|
104
|
+
const str = "Hello darkness, my old friend."
|
|
105
|
+
|
|
106
|
+
it("Should store the string encrypted using the users key", async function () {
|
|
107
|
+
const { contract, owner } = deployment
|
|
108
|
+
|
|
109
|
+
const tx = await contract
|
|
110
|
+
.connect(owner)
|
|
111
|
+
.setPublicString(str, { gasLimit })
|
|
112
|
+
|
|
113
|
+
await tx.wait()
|
|
114
|
+
})
|
|
115
|
+
|
|
116
|
+
it("Should retrieve the string encrypted with the users key", async function () {
|
|
117
|
+
const { contract, owner } = deployment
|
|
118
|
+
|
|
119
|
+
const userEncryptedString = await contract.getUserEncryptedString()
|
|
120
|
+
|
|
121
|
+
const decryptedStr = await owner.decryptValue(userEncryptedString)
|
|
122
|
+
|
|
123
|
+
expect(decryptedStr).to.equal(str)
|
|
124
|
+
})
|
|
125
|
+
})
|
|
126
|
+
|
|
127
|
+
describe("Set isEqual using two encrypted values", function () {
|
|
128
|
+
const a = "ABC"
|
|
129
|
+
const b = "DEF"
|
|
130
|
+
|
|
131
|
+
describe("Using eq", function () {
|
|
132
|
+
it("Should set isEqual to true", async function () {
|
|
133
|
+
const { contract, contractAddress, owner } = deployment
|
|
134
|
+
|
|
135
|
+
const itString = await owner.encryptValue(
|
|
136
|
+
a,
|
|
137
|
+
contractAddress,
|
|
138
|
+
contract.setIsEqual.fragment.selector
|
|
139
|
+
) as itString
|
|
140
|
+
|
|
141
|
+
const tx = await contract
|
|
142
|
+
.connect(owner)
|
|
143
|
+
.setIsEqual(itString, itString, true, { gasLimit })
|
|
144
|
+
|
|
145
|
+
await tx.wait()
|
|
146
|
+
|
|
147
|
+
const isEqual = await contract.isEqual()
|
|
148
|
+
|
|
149
|
+
expect(isEqual).to.equal(true)
|
|
150
|
+
})
|
|
151
|
+
|
|
152
|
+
it("Should set isEqual to false", async function () {
|
|
153
|
+
const { contract, contractAddress, owner } = deployment
|
|
154
|
+
|
|
155
|
+
const itStringA = await owner.encryptValue(
|
|
156
|
+
a,
|
|
157
|
+
contractAddress,
|
|
158
|
+
contract.setIsEqual.fragment.selector
|
|
159
|
+
) as itString
|
|
160
|
+
|
|
161
|
+
const itStringB = await owner.encryptValue(
|
|
162
|
+
b,
|
|
163
|
+
contractAddress,
|
|
164
|
+
contract.setIsEqual.fragment.selector
|
|
165
|
+
) as itString
|
|
166
|
+
|
|
167
|
+
const tx = await contract
|
|
168
|
+
.connect(owner)
|
|
169
|
+
.setIsEqual(itStringA, itStringB, true, { gasLimit })
|
|
170
|
+
|
|
171
|
+
await tx.wait()
|
|
172
|
+
|
|
173
|
+
const isEqual = await contract.isEqual()
|
|
174
|
+
|
|
175
|
+
expect(isEqual).to.equal(false)
|
|
176
|
+
})
|
|
177
|
+
})
|
|
178
|
+
|
|
179
|
+
describe("Using ne", function () {
|
|
180
|
+
it("Should set isEqual to true", async function () {
|
|
181
|
+
const { contract, contractAddress, owner } = deployment
|
|
182
|
+
|
|
183
|
+
const itStringA = await owner.encryptValue(
|
|
184
|
+
a,
|
|
185
|
+
contractAddress,
|
|
186
|
+
contract.setIsEqual.fragment.selector
|
|
187
|
+
) as itString
|
|
188
|
+
|
|
189
|
+
const itStringB = await owner.encryptValue(
|
|
190
|
+
b,
|
|
191
|
+
contractAddress,
|
|
192
|
+
contract.setIsEqual.fragment.selector
|
|
193
|
+
) as itString
|
|
194
|
+
|
|
195
|
+
const tx = await contract
|
|
196
|
+
.connect(owner)
|
|
197
|
+
.setIsEqual(itStringA, itStringB, false, { gasLimit })
|
|
198
|
+
|
|
199
|
+
await tx.wait()
|
|
200
|
+
|
|
201
|
+
const isEqual = await contract.isEqual()
|
|
202
|
+
|
|
203
|
+
expect(isEqual).to.equal(false)
|
|
204
|
+
})
|
|
205
|
+
|
|
206
|
+
it("Should set isEqual to false", async function () {
|
|
207
|
+
const { contract, contractAddress, owner } = deployment
|
|
208
|
+
|
|
209
|
+
const itString = await owner.encryptValue(
|
|
210
|
+
a,
|
|
211
|
+
contractAddress,
|
|
212
|
+
contract.setIsEqual.fragment.selector
|
|
213
|
+
) as itString
|
|
214
|
+
|
|
215
|
+
const tx = await contract
|
|
216
|
+
.connect(owner)
|
|
217
|
+
.setIsEqual(itString, itString, false, { gasLimit })
|
|
218
|
+
|
|
219
|
+
await tx.wait()
|
|
220
|
+
|
|
221
|
+
const isEqual = await contract.isEqual()
|
|
222
|
+
|
|
223
|
+
expect(isEqual).to.equal(true)
|
|
224
|
+
})
|
|
225
|
+
})
|
|
226
|
+
})
|
|
227
|
+
})
|
package/tsconfig.json
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/* Autogenerated file. Do not edit manually. */
|
|
2
|
+
/* tslint:disable */
|
|
3
|
+
/* eslint-disable */
|
|
4
|
+
import type * as interfaces from "./interfaces";
|
|
5
|
+
export type { interfaces };
|
|
6
|
+
import type * as token from "./token";
|
|
7
|
+
export type { token };
|
|
8
|
+
import type * as utils from "./utils";
|
|
9
|
+
export type { utils };
|