-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy patheip2981_royalties.js
232 lines (215 loc) · 7.35 KB
/
eip2981_royalties.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
// RoyalERC721: EIP-2981 related tests, including ACL
// Zeppelin test helpers
const {
BN,
constants,
expectEvent,
expectRevert,
} = require("@openzeppelin/test-helpers");
const {
assert,
expect,
} = require("chai");
const {
ZERO_ADDRESS,
MAX_UINT256,
} = constants;
// ACL token features and roles
const {
not,
ROLE_URI_MANAGER,
ROLE_ROYALTY_MANAGER,
ROLE_OWNER_MANAGER,
} = require("../../scripts/include/features_roles");
// deployment routines in use, token name and symbol
const {
land_nft_deploy,
} = require("./include/deployment_routines");
// run EIP2981 tests
contract("LandERC721/RoyalERC721: EIP2981 royalties", function(accounts) {
// extract accounts to be used:
// A0 – special default zero account accounts[0] used by Truffle, reserved
// a0 – deployment account having all the permissions, reserved
// H0 – initial token holder account
// a1, a2,... – working accounts to perform tests on
const [A0, a0, H0, a1, a2] = accounts;
// deploy token
let token;
beforeEach(async function() {
token = await land_nft_deploy(a0);
});
describe("EIP2981 Royalties", function() {
it("royaltyReceiver is not set initially", async function() {
expect(await token.royaltyReceiver()).to.equal(ZERO_ADDRESS);
});
it("royaltyPercentage is not set initially", async function() {
expect(await token.royaltyPercentage()).to.be.bignumber.that.is.zero;
});
it("contractURI is not set initially", async function() {
expect(await token.contractURI()).to.equal("");
});
describe("updating the royalty info", function() {
// default operator
const by = a1;
// default royalty receiver
const to = a2;
// default royalty percentage 7.5%
const royalty = 750;
// a function to update royalty info
async function setRoyaltyInfo(_to = to, _royalty = royalty) {
return await token.setRoyaltyInfo(_to, _royalty, {from: by});
}
describe("when sender doesn't have ROLE_ROYALTY_MANAGER permission", function() {
beforeEach(async function() {
await token.updateRole(by, not(ROLE_ROYALTY_MANAGER), {from: a0});
});
it("setRoyaltyInfo fails", async function() {
await expectRevert(setRoyaltyInfo(), "access denied");
});
});
describe("when sender has ROLE_ROYALTY_MANAGER permission", function() {
beforeEach(async function() {
await token.updateRole(by, ROLE_ROYALTY_MANAGER, {from: a0});
});
it("fails if receiver is not set but royalty is set", async function() {
await expectRevert(setRoyaltyInfo(ZERO_ADDRESS, royalty), "invalid receiver");
});
it("fails if royalty percentage exceeds 100%", async function() {
await expectRevert(setRoyaltyInfo(to, 100_01), "royalty percentage exceeds 100%");
});
function succeeds(_to = to, _royalty = royalty) {
let receipt;
beforeEach(async function() {
receipt = await setRoyaltyInfo(_to, _royalty);
});
it("royaltyReceiver gets set as expected", async function() {
expect(await token.royaltyReceiver()).to.equal(_to);
});
it("royaltyPercentage gets set as expected", async function() {
expect(await token.royaltyPercentage()).to.be.bignumber.that.equals(_royalty + "");
});
it("royalty gets calculated as expected", async function() {
const price = 1000;
const info = await token.royaltyInfo(13, price);
expect(info.receiver, "unexpected receiver").to.equal(_to);
expect(
info.royaltyAmount,
"unexpected amount"
).to.be.bignumber.that.equals(Math.floor(price * _royalty / 100_00) + "");
})
it('"RoyaltyInfoUpdated" event is emitted', async function() {
expectEvent(receipt, "RoyaltyInfoUpdated", {
_by: by,
_receiver: _to,
_percentage: _royalty + "",
});
});
}
describe("succeeds if both receiver and royalty are set", function() {
succeeds();
});
describe("succeeds if both receiver and royalty are set (max royalty: 100%)", function() {
succeeds(to, 100_00);
});
describe("succeeds if receiver is set and royalty is not", function() {
succeeds(to, 0);
});
describe("succeeds if both receiver and royalty are not set", function() {
succeeds(ZERO_ADDRESS, 0);
});
});
});
});
describe("OpenSea contract level metadata", function() {
// default operator
const by = a1;
// default contract URI
const contractURI = "https://super-awesome-contract-now-forever-nvm.com/returns/legacy/";
// a function to update contract URI
async function setContractURI() {
return await token.setContractURI(contractURI, {from: by});
}
describe("when sender doesn't have ROLE_URI_MANAGER permission", function() {
beforeEach(async function() {
await token.updateRole(by, not(ROLE_URI_MANAGER), {from: a0});
});
it("setContractURI fails", async function() {
await expectRevert(setContractURI(), "access denied");
});
});
describe("when sender has ROLE_URI_MANAGER permission", function() {
beforeEach(async function() {
await token.updateRole(by, ROLE_URI_MANAGER, {from: a0});
});
describe("setContractURI succeeds", function() {
let receipt;
beforeEach(async function() {
receipt = await setContractURI();
});
it("contractURI gets set as expected", async function() {
expect(await token.contractURI()).to.equal(contractURI);
});
it('"ContractURIUpdated" event is emitted', async function() {
expectEvent(receipt, "ContractURIUpdated", {
_by: by,
_value: contractURI,
});
});
});
});
});
describe('OpenSea/Zeppelin "Ownable" Support', function() {
// default operator
const by = a1;
// default new owner
const to = a2;
// "owner" tests
it('"owner" is set to the deployer address initially', async function() {
expect(await token.owner(), "unexpected owner").to.equal(a0);
expect(await token.isOwner(a0), "isOwner(a0) returns false").to.be.true;
});
// a function to transfer ownership
async function changeOwner() {
return await token.transferOwnership(to, {from: by});
}
describe("when sender doesn't have ROLE_OWNER_MANAGER permission", function() {
beforeEach(async function() {
await token.updateRole(by, not(ROLE_OWNER_MANAGER), {from: a0});
});
it("setOwner fails", async function() {
await expectRevert(changeOwner(), "access denied");
});
});
describe("when sender has ROLE_OWNER_MANAGER permission", function() {
beforeEach(async function() {
await token.updateRole(by, ROLE_OWNER_MANAGER, {from: a0});
});
describe("setOwner succeeds", function() {
let receipt;
beforeEach(async function() {
receipt = await changeOwner();
});
it("owner gets set as expected", async function() {
expect(await token.owner(), "unexpected owner").to.equal(to);
expect(await token.isOwner(to), "isOwner(to) returns false").to.be.true;
});
it('"OwnerUpdated" event is emitted', async function() {
expectEvent(receipt, "OwnerUpdated", {
_by: by,
_oldVal: a0,
_newVal: to,
});
});
it('"OwnershipTransferred" event is emitted', async function() {
expectEvent(receipt, "OwnershipTransferred", {
previousOwner: a0,
newOwner: to,
});
});
it('new "owner" cannot change owner due to lack of ROLE_OWNER_MANAGER permission', async function() {
await expectRevert(token.transferOwnership(by, {from: to}), "access denied");
});
});
});
});
});