Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Royalty Info External Traits #1173

Merged
merged 38 commits into from
Oct 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
512bf84
Introduce additional interfaces for ERC2981
immrsd Oct 2, 2024
3bb2cab
Implement additional ERC2981 traits
immrsd Oct 2, 2024
df81d9b
Add access module as a dependency of token module
immrsd Oct 2, 2024
f67c9f6
Make improvements to ERC2981 tests
immrsd Oct 2, 2024
d97dd7c
Add Ownable and AccessControl versions for ERC2981 mocks
immrsd Oct 2, 2024
c1f0382
Add tests for external calls to ERC2981 mocks with Ownable/AccessCont…
immrsd Oct 2, 2024
b4dc8d1
Remove unnecessary impl names, fix typo
immrsd Oct 2, 2024
1c6baa7
Fix tests
immrsd Oct 2, 2024
1fc0682
Fix ERC2981 AccessControl mock
immrsd Oct 2, 2024
dcc741c
Merge main
immrsd Oct 14, 2024
6398821
Run linter
immrsd Oct 14, 2024
e99d1b7
Update changelog
immrsd Oct 14, 2024
1dcbea5
Add ERC2981 mocks to external contracts built
immrsd Oct 14, 2024
c2cc806
Fix changelog
immrsd Oct 14, 2024
942c114
Improve changelog update
immrsd Oct 15, 2024
d1db561
Restructure mocks trait impls
immrsd Oct 15, 2024
d55e5fc
Minor doc improvements
immrsd Oct 15, 2024
9ef67e1
Add API references for new ERC2981 external interfaces
immrsd Oct 15, 2024
04b908c
Improve documentation, fix inconsistencies
immrsd Oct 15, 2024
db40963
Rename IERC2981StateInfo to IERC2981Info
immrsd Oct 18, 2024
ccd3e06
Rename IERC2981AdminAccessControlImpl to ERC2981AdminAccessControlImpl
immrsd Oct 18, 2024
0d09e94
Rename IERC2981AdminOwnableImpl to ERC2981AdminOwnableImpl
immrsd Oct 18, 2024
9af4636
Fix self type in doc
immrsd Oct 18, 2024
287a829
Address tests review comments
immrsd Oct 18, 2024
ae936b1
Merge main
immrsd Oct 18, 2024
712c170
Fix linter issues
immrsd Oct 18, 2024
e9d94af
Prefix ERC2981 internal functions with underscore
immrsd Oct 18, 2024
3b0653f
Support function name changes in doc
immrsd Oct 18, 2024
c37b8b3
Refactor ERC2981 AccessControl tests
immrsd Oct 18, 2024
94005f8
Fix function calls
immrsd Oct 18, 2024
6f7380f
Refactor ERC2981 ownable tests
immrsd Oct 18, 2024
bd5d840
Run linter
immrsd Oct 18, 2024
6ad03b9
Run linter
immrsd Oct 18, 2024
dbeefd7
Update changelog
immrsd Oct 22, 2024
bd2ef56
Fix version mentioned in doc
immrsd Oct 22, 2024
0401d90
Fix doc comment for ROYALTY_ADMIN_ROLE role
immrsd Oct 22, 2024
d1533aa
Improve section names slightly
immrsd Oct 22, 2024
7c69560
Update changelog
immrsd Oct 22, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,18 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## Unreleased

### Added

- Embeddable impls for ERC2981 component (#1173)
- `ERC2981Info` with read functions for discovering the component's state
- `ERC2981AdminOwnable` providing admin functions for a token that implements Ownable component
- `ERC2981AdminAccessControl` providing admin functions for a token that implements AccessControl component

### Changed (Breaking)

- Apply underscore pattern to the internal functions of `ERC2981Component` to prevent collisions
with new external functions (#1173)

## 0.18.0 (2024-10-17)

### Added
Expand Down
1 change: 1 addition & 0 deletions Scarb.lock
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,7 @@ dependencies = [
name = "openzeppelin_token"
version = "0.18.0"
dependencies = [
"openzeppelin_access",
"openzeppelin_account",
"openzeppelin_introspection",
"openzeppelin_test_common",
Expand Down
288 changes: 267 additions & 21 deletions docs/modules/ROOT/pages/api/token_common.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ This module provides extensions and utilities that are common to multiple token

[.hljs-theme-dark]
```cairo
use openzeppelin_token::common::erc2981::IERC2981;
use openzeppelin_token::common::erc2981::interface::IERC2981;
```

[.contract-index]
Expand Down Expand Up @@ -44,6 +44,98 @@ Returns how much royalty is owed and to whom, based on a sale price that may be
in any unit of exchange. The royalty amount is denominated and must be paid in that same
unit of exchange.

[.contract]
[[IERC2981Info]]
=== `++IERC2981Info++` link:https://github.com/OpenZeppelin/cairo-contracts/blob/release-v0.18.0/packages/token/src/common/erc2981/interface.cairo[{github-icon},role=heading-link]

[.hljs-theme-dark]
```cairo
use openzeppelin_token::common::erc2981::interface::IERC2981Info;
```

Interface providing external read functions for discovering the state of ERC2981 component.

[.contract-index]
.Functions
--
* xref:#IERC2981Info-default_royalty[`++default_royalty()++`]
* xref:#IERC2981Info-token_royalty[`++token_royalty(token_id)++`]
--

[#IERC2981Info-Functions]
==== Functions

[.contract-item]
[[IERC2981Info-default_royalty]]
==== `[.contract-item-name]#++default_royalty++#++() → (ContractAddress, u128, u128)++` [.item-kind]#external#

Returns the royalty information that all ids in this contract will default to.

The returned tuple contains:

- `t.0`: The receiver of the royalty payment.
- `t.1`: The numerator of the royalty fraction.
- `t.2`: The denominator of the royalty fraction.

[.contract-item]
[[IERC2981Info-token_royalty]]
==== `[.contract-item-name]#++token_royalty++#++(token_id: u256) → (ContractAddress, u128, u128)++` [.item-kind]#external#

Returns the royalty information specific to a token.

The returned tuple contains:

- `t.0`: The receiver of the royalty payment.
- `t.1`: The numerator of the royalty fraction.
- `t.2`: The denominator of the royalty fraction.

[.contract]
[[IERC2981Admin]]
=== `++IERC2981Admin++` link:https://github.com/OpenZeppelin/cairo-contracts/blob/release-v0.18.0/packages/token/src/common/erc2981/interface.cairo[{github-icon},role=heading-link]

[.hljs-theme-dark]
```cairo
use openzeppelin_token::common::erc2981::interface::IERC2981Admin;
```

Interface providing external admin functions for managing the settings of ERC2981 component.

[.contract-index]
.Functions
--
* xref:#IERC2981Admin-set_default_royalty[`++set_default_royalty(receiver, fee_numerator)++`]
* xref:#IERC2981Admin-delete_default_royalty[`++delete_default_royalty()++`]
* xref:#IERC2981Admin-set_token_royalty[`++set_token_royalty(token_id, receiver, fee_numerator)++`]
* xref:#IERC2981Admin-reset_token_royalty[`++reset_token_royalty(token_id)++`]
--

[#IERC2981Admin-Functions]
==== Functions

[.contract-item]
[[IERC2981Admin-set_default_royalty]]
==== `[.contract-item-name]#++set_default_royalty++#++(receiver: ContractAddress, fee_numerator: u128)++` [.item-kind]#external#

Sets the royalty information that all ids in this contract will default to.

[.contract-item]
[[IERC2981Admin-delete_default_royalty]]
==== `[.contract-item-name]#++delete_default_royalty++#++()++` [.item-kind]#external#

Removes default royalty information.

[.contract-item]
[[IERC2981Admin-set_token_royalty]]
==== `[.contract-item-name]#++set_token_royalty++#++(token_id: u256, receiver: ContractAddress, fee_numerator: u128)++` [.item-kind]#external#

Sets the royalty information for a specific token id that takes precedence over the global default.

[.contract-item]
[[IERC2981Admin-reset_token_royalty]]
==== `[.contract-item-name]#++reset_token_royalty++#++(token_id: u256)++` [.item-kind]#external#

Resets royalty information for the token id back to unset.

[.contract]
[[ERC2981Component]]
=== `++ERC2981Component++` link:https://github.com/OpenZeppelin/cairo-contracts/blob/release-v0.18.0/packages/token/src/common/erc2981/erc2981.cairo[{github-icon},role=heading-link]
Expand All @@ -70,19 +162,38 @@ ERC2981 component extending <<IERC2981,IERC2981>>.
[.sub-index#ERC2981Component-Embeddable-Impls-ERC20Impl]
.ERC2981Impl
* xref:#ERC2981Component-royalty_info[`++royalty_info(self, token_id, sale_price)++`]

[.sub-index#ERC2981Component-Embeddable-Impls-ERC2981InfoImpl]
.ERC2981InfoImpl
* xref:#ERC2981InfoImpl-default_royalty[`++default_royalty(self)++`]
* xref:#ERC2981InfoImpl-token_royalty[`++token_royalty(self, token_id)++`]

[.sub-index#ERC2981Component-Embeddable-Impls-ERC2981AdminOwnableImpl]
.ERC2981AdminOwnableImpl
* xref:#ERC2981AdminOwnableImpl-set_default_royalty[`++set_default_royalty(self, receiver, fee_numerator)++`]
* xref:#ERC2981AdminOwnableImpl-delete_default_royalty[`++delete_default_royalty(self)++`]
* xref:#ERC2981AdminOwnableImpl-set_token_royalty[`++set_token_royalty(self, token_id, receiver, fee_numerator)++`]
* xref:#ERC2981AdminOwnableImpl-reset_token_royalty[`++reset_token_royalty(self, token_id)++`]

[.sub-index#ERC2981Component-Embeddable-Impls-ERC2981AdminAccessControlImpl]
.ERC2981AdminAccessControlImpl
* xref:#ERC2981AdminAccessControlImpl-set_default_royalty[`++set_default_royalty(self, receiver, fee_numerator)++`]
* xref:#ERC2981AdminAccessControlImpl-delete_default_royalty[`++delete_default_royalty(self)++`]
* xref:#ERC2981AdminAccessControlImpl-set_token_royalty[`++set_token_royalty(self, token_id, receiver, fee_numerator)++`]
* xref:#ERC2981AdminAccessControlImpl-reset_token_royalty[`++reset_token_royalty(self, token_id)++`]
--

[.contract-index]
.Internal implementations
--
.InternalImpl
* xref:#ERC2981Component-initializer[`++initializer(self, default_receiver, default_royalty_fraction)++`]
* xref:#ERC2981Component-default_royalty[`++default_royalty(self)++`]
* xref:#ERC2981Component-set_default_royalty[`++set_default_royalty(self, receiver, fee_numerator)++`]
* xref:#ERC2981Component-delete_default_royalty[`++delete_default_royalty(self)++`]
* xref:#ERC2981Component-token_royalty[`++token_royalty(self, token_id)++`]
* xref:#ERC2981Component-set_token_royalty[`++set_token_royalty(self, token_id, receiver, fee_numerator)++`]
* xref:#ERC2981Component-reset_token_royalty[`++reset_token_royalty(self, token_id)++`]
* xref:#ERC2981Component-_default_royalty[`++_default_royalty(self)++`]
* xref:#ERC2981Component-_set_default_royalty[`++_set_default_royalty(self, receiver, fee_numerator)++`]
* xref:#ERC2981Component-_delete_default_royalty[`++_delete_default_royalty(self)++`]
* xref:#ERC2981Component-_token_royalty[`++_token_royalty(self, token_id)++`]
* xref:#ERC2981Component-_set_token_royalty[`++_set_token_royalty(self, token_id, receiver, fee_numerator)++`]
* xref:#ERC2981Component-_reset_token_royalty[`++_reset_token_royalty(self, token_id)++`]
--

[#ERC2981Component-Immutable-Config]
Expand All @@ -93,7 +204,7 @@ ERC2981 component extending <<IERC2981,IERC2981>>.
==== `[.contract-item-name]#++FEE_DENOMINATOR:++#++ u128++` [.item-kind]#constant#

The denominator with which to interpret the fee set in
`set_token_royalty` and `set_default_royalty` as a fraction of the sale price.
`_set_token_royalty` and `_set_default_royalty` as a fraction of the sale price.

[.contract-item]
[[ERC2981Component-IC-validate]]
Expand Down Expand Up @@ -123,6 +234,141 @@ The returned tuple contains:
- `t.0`: The receiver of the royalty payment.
- `t.1`: The amount of royalty payment.

[.contract-item]
[[ERC2981InfoImpl-default_royalty]]
==== `[.contract-item-name]#++default_royalty++#++(@self: ContractState) → (ContractAddress, u128, u128)++` [.item-kind]#external#

Returns the royalty information that all ids in this contract will default to.

The returned tuple contains:

- `t.0`: The receiver of the royalty payment.
- `t.1`: The numerator of the royalty fraction.
- `t.2`: The denominator of the royalty fraction.

[.contract-item]
[[ERC2981InfoImpl-token_royalty]]
==== `[.contract-item-name]#++token_royalty++#++(self: @ContractState, token_id: u256) → (ContractAddress, u128, u128)++` [.item-kind]#external#

Returns the royalty information specific to a token.
If no specific royalty information is set for the token, the default is returned.

The returned tuple contains:

- `t.0`: The receiver of the royalty payment.
- `t.1`: The numerator of the royalty fraction.
- `t.2`: The denominator of the royalty fraction.

[#ERC2981Component-ERC2981AdminOwnableImpl]
==== ERC2981AdminOwnableImpl

:ownable-component: xref:/api/access.adoc#OwnableComponent[OwnableComponent]

Provides admin functions for managing royalty settings that are restricted to be called only by the contract's owner.
Requires the contract to implement {ownable-component}.

[.contract-item]
[[ERC2981AdminOwnableImpl-set_default_royalty]]
==== `[.contract-item-name]#++set_default_royalty++#++(ref self: ContractState, receiver: ContractAddress, fee_numerator: u128)++` [.item-kind]#external#

Sets the royalty information that all ids in this contract will default to.

Requirements:

- The caller is the contract owner.
- `receiver` cannot be the zero address.
- `fee_numerator` cannot be greater than the fee denominator.

[.contract-item]
[[ERC2981AdminOwnableImpl-delete_default_royalty]]
==== `[.contract-item-name]#++delete_default_royalty++#++(ref self: ContractState)++` [.item-kind]#external#

Removes default royalty information.

Requirements:

- The caller is the contract owner.

[.contract-item]
[[ERC2981AdminOwnableImpl-set_token_royalty]]
==== `[.contract-item-name]#++set_token_royalty++#++(ref self: ContractState, token_id: u256, receiver: ContractAddress, fee_numerator: u128)++` [.item-kind]#external#

Sets the royalty information for a specific token id that takes precedence over the global default.

Requirements:

- The caller is the contract owner.
- `receiver` cannot be the zero address.
- `fee_numerator` cannot be greater than the fee denominator.

[.contract-item]
[[ERC2981AdminOwnableImpl-reset_token_royalty]]
==== `[.contract-item-name]#++reset_token_royalty++#++(ref self: ContractState, token_id: u256)++` [.item-kind]#external#

Resets royalty information for the token id back to unset.

Requirements:

- The caller is the contract owner.

[#ERC2981Component-ERC2981AdminAccessControlImpl]
==== ERC2981AdminAccessControlImpl

:accesscontrol-component: xref:api/access.adoc#AccessControlComponent[AccessControlComponent]

Provides admin functions for managing royalty settings that require `ROYALTY_ADMIN_ROLE` to be granted to the caller.
Requires the contract to implement {accesscontrol-component}.

[.contract-item]
[[ERC2981AdminAccessControlImpl-ROYALTY_ADMIN_ROLE]]
==== `[.contract-item-name]#++ROYALTY_ADMIN_ROLE:++#++ felt252++` [.item-kind]#constant#

Role for the admin responsible for managing royalty settings.

[.contract-item]
[[ERC2981AdminAccessControlImpl-set_default_royalty]]
==== `[.contract-item-name]#++set_default_royalty++#++(ref self: ContractState, receiver: ContractAddress, fee_numerator: u128)++` [.item-kind]#external#

Sets the royalty information that all ids in this contract will default to.

Requirements:

- The caller must have `ROYALTY_ADMIN_ROLE` role.
- `receiver` cannot be the zero address.
- `fee_numerator` cannot be greater than the fee denominator.

[.contract-item]
[[ERC2981AdminAccessControlImpl-delete_default_royalty]]
==== `[.contract-item-name]#++delete_default_royalty++#++(ref self: ContractState)++` [.item-kind]#external#

Removes default royalty information.

Requirements:

- The caller must have `ROYALTY_ADMIN_ROLE` role.

[.contract-item]
[[ERC2981AdminAccessControlImpl-set_token_royalty]]
==== `[.contract-item-name]#++set_token_royalty++#++(ref self: ContractState, token_id: u256, receiver: ContractAddress, fee_numerator: u128)++` [.item-kind]#external#

Sets the royalty information for a specific token id that takes precedence over the global default.

Requirements:

- The caller must have `ROYALTY_ADMIN_ROLE` role.
- `receiver` cannot be the zero address.
- `fee_numerator` cannot be greater than the fee denominator.

[.contract-item]
[[ERC2981AdminAccessControlImpl-reset_token_royalty]]
==== `[.contract-item-name]#++reset_token_royalty++#++(ref self: ContractState, token_id: u256)++` [.item-kind]#external#

Resets royalty information for the token id back to unset.

Requirements:

- The caller must have `ROYALTY_ADMIN_ROLE` role.

[#ERC2981Component-Internal-functions]
==== Internal functions

Expand All @@ -141,8 +387,8 @@ Requirements:
NOTE: The fee denominator is set by the contract using the {immutable-config}.

[.contract-item]
[[ERC2981Component-default_royalty]]
==== `[.contract-item-name]#++default_royalty++#++(self: @ContractState) → (ContractAddress, u128, u128)++` [.item-kind]#internal#
[[ERC2981Component-_default_royalty]]
==== `[.contract-item-name]#++_default_royalty++#++(self: @ContractState) → (ContractAddress, u128, u128)++` [.item-kind]#internal#

Returns the royalty information that all ids in this contract will default to.

Expand All @@ -153,8 +399,8 @@ The returned tuple contains:
- `t.2`: The denominator of the royalty fraction.

[.contract-item]
[[ERC2981Component-set_default_royalty]]
==== `[.contract-item-name]#++set_default_royalty++#++(ref self: ContractState, receiver: ContractAddress, fee_numerator: u128)++` [.item-kind]#internal#
[[ERC2981Component-_set_default_royalty]]
==== `[.contract-item-name]#++_set_default_royalty++#++(ref self: ContractState, receiver: ContractAddress, fee_numerator: u128)++` [.item-kind]#internal#

Sets the royalty information that all ids in this contract will default to.

Expand All @@ -164,14 +410,14 @@ Requirements:
- `fee_numerator` cannot be greater than the fee denominator.

[.contract-item]
[[ERC2981Component-delete_default_royalty]]
==== `[.contract-item-name]#++delete_default_royalty++#++(ref self: ContractState)++` [.item-kind]#internal#
[[ERC2981Component-_delete_default_royalty]]
==== `[.contract-item-name]#++_delete_default_royalty++#++(ref self: ContractState)++` [.item-kind]#internal#

Removes default royalty information.

[.contract-item]
[[ERC2981Component-token_royalty]]
==== `[.contract-item-name]#++token_royalty++#++(self: @ContractState, token_id: u256) → (ContractAddress, u256, u256)++` [.item-kind]#internal#
[[ERC2981Component-_token_royalty]]
==== `[.contract-item-name]#++_token_royalty++#++(self: @ContractState, token_id: u256) → (ContractAddress, u256, u256)++` [.item-kind]#internal#

Returns the royalty information that all ids in this contract will default to.

Expand All @@ -182,18 +428,18 @@ The returned tuple contains:
- `t.2`: The denominator of the royalty fraction.

[.contract-item]
[[ERC2981Component-set_token_royalty]]
==== `[.contract-item-name]#++set_token_royalty++#++(ref self: ContractState, token_id: u256, receiver: ContractAddress, fee_numerator: u128)++` [.item-kind]#internal#
[[ERC2981Component-_set_token_royalty]]
==== `[.contract-item-name]#++_set_token_royalty++#++(ref self: ContractState, token_id: u256, receiver: ContractAddress, fee_numerator: u128)++` [.item-kind]#internal#

Sets the royalty information for a specific token id, overriding the global default.
Sets the royalty information for a specific token id that takes precedence over the global default.

Requirements:

- `receiver` cannot be the zero address.
- `fee_numerator` cannot be greater than the fee denominator.

[.contract-item]
[[ERC2981Component-reset_token_royalty]]
==== `[.contract-item-name]#++reset_token_royalty++#++(ref self: ContractState, token_id: u256)++` [.item-kind]#internal#
[[ERC2981Component-_reset_token_royalty]]
==== `[.contract-item-name]#++_reset_token_royalty++#++(ref self: ContractState, token_id: u256)++` [.item-kind]#internal#

Resets royalty information for the token id back to unset.
Loading