ERC2981.behavior.js 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  1. const { BN, constants } = require('@openzeppelin/test-helpers');
  2. const { expect } = require('chai');
  3. const { ZERO_ADDRESS } = constants;
  4. const { shouldSupportInterfaces } = require('../../utils/introspection/SupportsInterface.behavior');
  5. const { expectRevertCustomError } = require('../../helpers/customError');
  6. function shouldBehaveLikeERC2981() {
  7. const royaltyFraction = new BN('10');
  8. shouldSupportInterfaces(['ERC2981']);
  9. describe('default royalty', function () {
  10. beforeEach(async function () {
  11. await this.token.$_setDefaultRoyalty(this.account1, royaltyFraction);
  12. });
  13. it('checks royalty is set', async function () {
  14. const royalty = new BN((this.salePrice * royaltyFraction) / 10000);
  15. const initInfo = await this.token.royaltyInfo(this.tokenId1, this.salePrice);
  16. expect(initInfo[0]).to.be.equal(this.account1);
  17. expect(initInfo[1]).to.be.bignumber.equal(royalty);
  18. });
  19. it('updates royalty amount', async function () {
  20. const newPercentage = new BN('25');
  21. // Updated royalty check
  22. await this.token.$_setDefaultRoyalty(this.account1, newPercentage);
  23. const royalty = new BN((this.salePrice * newPercentage) / 10000);
  24. const newInfo = await this.token.royaltyInfo(this.tokenId1, this.salePrice);
  25. expect(newInfo[0]).to.be.equal(this.account1);
  26. expect(newInfo[1]).to.be.bignumber.equal(royalty);
  27. });
  28. it('holds same royalty value for different tokens', async function () {
  29. const newPercentage = new BN('20');
  30. await this.token.$_setDefaultRoyalty(this.account1, newPercentage);
  31. const token1Info = await this.token.royaltyInfo(this.tokenId1, this.salePrice);
  32. const token2Info = await this.token.royaltyInfo(this.tokenId2, this.salePrice);
  33. expect(token1Info[1]).to.be.bignumber.equal(token2Info[1]);
  34. });
  35. it('Remove royalty information', async function () {
  36. const newValue = new BN('0');
  37. await this.token.$_deleteDefaultRoyalty();
  38. const token1Info = await this.token.royaltyInfo(this.tokenId1, this.salePrice);
  39. const token2Info = await this.token.royaltyInfo(this.tokenId2, this.salePrice);
  40. // Test royalty info is still persistent across all tokens
  41. expect(token1Info[0]).to.be.bignumber.equal(token2Info[0]);
  42. expect(token1Info[1]).to.be.bignumber.equal(token2Info[1]);
  43. // Test information was deleted
  44. expect(token1Info[0]).to.be.equal(ZERO_ADDRESS);
  45. expect(token1Info[1]).to.be.bignumber.equal(newValue);
  46. });
  47. it('reverts if invalid parameters', async function () {
  48. const royaltyDenominator = await this.token.$_feeDenominator();
  49. await expectRevertCustomError(
  50. this.token.$_setDefaultRoyalty(ZERO_ADDRESS, royaltyFraction),
  51. 'ERC2981InvalidDefaultRoyaltyReceiver',
  52. [ZERO_ADDRESS],
  53. );
  54. const anotherRoyaltyFraction = new BN('11000');
  55. await expectRevertCustomError(
  56. this.token.$_setDefaultRoyalty(this.account1, anotherRoyaltyFraction),
  57. 'ERC2981InvalidDefaultRoyalty',
  58. [anotherRoyaltyFraction, royaltyDenominator],
  59. );
  60. });
  61. });
  62. describe('token based royalty', function () {
  63. beforeEach(async function () {
  64. await this.token.$_setTokenRoyalty(this.tokenId1, this.account1, royaltyFraction);
  65. });
  66. it('updates royalty amount', async function () {
  67. const newPercentage = new BN('25');
  68. let royalty = new BN((this.salePrice * royaltyFraction) / 10000);
  69. // Initial royalty check
  70. const initInfo = await this.token.royaltyInfo(this.tokenId1, this.salePrice);
  71. expect(initInfo[0]).to.be.equal(this.account1);
  72. expect(initInfo[1]).to.be.bignumber.equal(royalty);
  73. // Updated royalty check
  74. await this.token.$_setTokenRoyalty(this.tokenId1, this.account1, newPercentage);
  75. royalty = new BN((this.salePrice * newPercentage) / 10000);
  76. const newInfo = await this.token.royaltyInfo(this.tokenId1, this.salePrice);
  77. expect(newInfo[0]).to.be.equal(this.account1);
  78. expect(newInfo[1]).to.be.bignumber.equal(royalty);
  79. });
  80. it('holds different values for different tokens', async function () {
  81. const newPercentage = new BN('20');
  82. await this.token.$_setTokenRoyalty(this.tokenId2, this.account1, newPercentage);
  83. const token1Info = await this.token.royaltyInfo(this.tokenId1, this.salePrice);
  84. const token2Info = await this.token.royaltyInfo(this.tokenId2, this.salePrice);
  85. // must be different even at the same this.salePrice
  86. expect(token1Info[1]).to.not.be.equal(token2Info.royaltyFraction);
  87. });
  88. it('reverts if invalid parameters', async function () {
  89. const royaltyDenominator = await this.token.$_feeDenominator();
  90. await expectRevertCustomError(
  91. this.token.$_setTokenRoyalty(this.tokenId1, ZERO_ADDRESS, royaltyFraction),
  92. 'ERC2981InvalidTokenRoyaltyReceiver',
  93. [this.tokenId1.toString(), ZERO_ADDRESS],
  94. );
  95. const anotherRoyaltyFraction = new BN('11000');
  96. await expectRevertCustomError(
  97. this.token.$_setTokenRoyalty(this.tokenId1, this.account1, anotherRoyaltyFraction),
  98. 'ERC2981InvalidTokenRoyalty',
  99. [this.tokenId1.toString(), anotherRoyaltyFraction, royaltyDenominator],
  100. );
  101. });
  102. it('can reset token after setting royalty', async function () {
  103. const newPercentage = new BN('30');
  104. const royalty = new BN((this.salePrice * newPercentage) / 10000);
  105. await this.token.$_setTokenRoyalty(this.tokenId1, this.account2, newPercentage);
  106. const tokenInfo = await this.token.royaltyInfo(this.tokenId1, this.salePrice);
  107. // Tokens must have own information
  108. expect(tokenInfo[1]).to.be.bignumber.equal(royalty);
  109. expect(tokenInfo[0]).to.be.equal(this.account2);
  110. await this.token.$_setTokenRoyalty(this.tokenId2, this.account1, new BN('0'));
  111. const result = await this.token.royaltyInfo(this.tokenId2, this.salePrice);
  112. // Token must not share default information
  113. expect(result[0]).to.be.equal(this.account1);
  114. expect(result[1]).to.be.bignumber.equal(new BN('0'));
  115. });
  116. it('can hold default and token royalty information', async function () {
  117. const newPercentage = new BN('30');
  118. const royalty = new BN((this.salePrice * newPercentage) / 10000);
  119. await this.token.$_setTokenRoyalty(this.tokenId2, this.account2, newPercentage);
  120. const token1Info = await this.token.royaltyInfo(this.tokenId1, this.salePrice);
  121. const token2Info = await this.token.royaltyInfo(this.tokenId2, this.salePrice);
  122. // Tokens must not have same values
  123. expect(token1Info[1]).to.not.be.bignumber.equal(token2Info[1]);
  124. expect(token1Info[0]).to.not.be.equal(token2Info[0]);
  125. // Updated token must have new values
  126. expect(token2Info[0]).to.be.equal(this.account2);
  127. expect(token2Info[1]).to.be.bignumber.equal(royalty);
  128. });
  129. });
  130. }
  131. module.exports = {
  132. shouldBehaveLikeERC2981,
  133. };