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

Add ERC721EnumerableComponent extension #983

Merged
merged 83 commits into from
Aug 29, 2024
Merged
Show file tree
Hide file tree
Changes from 64 commits
Commits
Show all changes
83 commits
Select commit Hold shift + click to select a range
e5c5e5f
feat: working in logic
ericnordelo Apr 15, 2024
110d8f7
feat: add empty impl
ericnordelo Apr 23, 2024
4a7f8a5
Merge branch 'main' of github.com:OpenZeppelin/cairo-contracts into f…
ericnordelo Apr 23, 2024
d71ee92
feat: finish docs
ericnordelo Apr 23, 2024
d61e449
feat: update CHANGELOG
ericnordelo Apr 23, 2024
8e894ea
draft erc721 enum
andrew-fleming Apr 28, 2024
295530b
fix comp, start testing
andrew-fleming Apr 28, 2024
d5838d3
fix fmt
andrew-fleming Apr 28, 2024
b225343
fix fmt
andrew-fleming Apr 30, 2024
649c7c6
change fn name
andrew-fleming Apr 30, 2024
cff482a
add more tests for interface fns
andrew-fleming Apr 30, 2024
f76da3e
add in-code comments
andrew-fleming May 3, 2024
96f9d09
add more tests
andrew-fleming May 3, 2024
d9455ae
fix formatting
andrew-fleming May 3, 2024
73fbbc9
remove unused imports, clean up code
andrew-fleming May 3, 2024
5a128ca
remove space
andrew-fleming May 4, 2024
5987c8f
start erc721enum section
andrew-fleming May 4, 2024
0fcfc13
fix fn order
andrew-fleming May 5, 2024
fc27ae7
add in-code comments, fix fn order
andrew-fleming May 5, 2024
1266c55
add interface docs and start component docs
andrew-fleming May 5, 2024
2409cd3
document privateimpl in enum extension
andrew-fleming May 6, 2024
6f3524f
add privateimpl in erc721enum
andrew-fleming May 6, 2024
8d02fb4
add tests checking order of owner index
andrew-fleming May 6, 2024
72c65c1
fix supply tests, add camel tests
andrew-fleming May 6, 2024
7ef4de4
add ierc721enumerable selectors
andrew-fleming May 6, 2024
984000e
add dualcase erc721enumerable
andrew-fleming May 6, 2024
4e02b3c
add dualcase erc721enum tests
andrew-fleming May 6, 2024
a261677
fix formatting
andrew-fleming May 6, 2024
2c0474e
update changelog
andrew-fleming May 6, 2024
7f849dc
update changelog entry
andrew-fleming May 7, 2024
c3a029e
change _update to before_update
andrew-fleming May 7, 2024
72b75cd
fix formatting
andrew-fleming May 7, 2024
3170a7b
remove unused imports
andrew-fleming May 7, 2024
f904280
remove excess error, fix _remove_token_from_owner_enumeration
andrew-fleming May 11, 2024
33ee6b7
add internal tests
andrew-fleming May 11, 2024
66d7471
fix formatting
andrew-fleming May 11, 2024
33025cd
fix conflicts
andrew-fleming May 14, 2024
2a1f876
fix before_update description
andrew-fleming May 14, 2024
c5fdc29
revert comment change
andrew-fleming May 14, 2024
8e815ed
match comment with api description
andrew-fleming May 14, 2024
48b30c3
Apply suggestions from code review
andrew-fleming May 15, 2024
7b37352
remove enum selectors
andrew-fleming May 21, 2024
ffe01ad
remove dual_case and camel impls from erc721_enum
andrew-fleming May 21, 2024
359c711
remove unused mocks, fix mock name
andrew-fleming May 21, 2024
01b8687
remove dual and camel tests for erc721_enum
andrew-fleming May 21, 2024
e7e1459
remove camel impl from erc721_enum
andrew-fleming May 21, 2024
5a41e4e
Merge branch 'main' into erc721-enum
andrew-fleming May 21, 2024
68db79a
fix changelog
andrew-fleming May 21, 2024
a38c338
Merge branch 'erc721-enum' of https://github.com/andrew-fleming/cairo…
andrew-fleming May 21, 2024
0de7db4
fix conflicts, migrate to 2023_11
andrew-fleming Jun 18, 2024
65f6259
fix conflicts
andrew-fleming Jul 13, 2024
640faab
bump scarb to rc.2
andrew-fleming Jul 13, 2024
2a3af3f
use Map, allow tests to read storage
andrew-fleming Jul 13, 2024
a2e9bf7
fix fmt
andrew-fleming Jul 13, 2024
404c945
fix Contracts version
andrew-fleming Jul 13, 2024
867c2cf
fix test_names
andrew-fleming Jul 22, 2024
c4c78dc
fix spelling
andrew-fleming Jul 22, 2024
c8bbf06
move erc721 enum component section to core
andrew-fleming Jul 22, 2024
9fccfea
add component description
andrew-fleming Jul 22, 2024
45b66d0
fix intro section
andrew-fleming Jul 22, 2024
e462e2e
fix fmt
andrew-fleming Jul 22, 2024
fc68c8f
fix conflicts
andrew-fleming Jul 25, 2024
94f0854
fix conflicts
andrew-fleming Aug 2, 2024
3c9c325
change to while loops in assertions
andrew-fleming Aug 2, 2024
3dd3698
simplify fn calls with self
andrew-fleming Aug 13, 2024
dba11f5
remove zero var
andrew-fleming Aug 13, 2024
dd5f907
remove dual in helpers
andrew-fleming Aug 13, 2024
b983aa0
check supply/owner bal == expected token list
andrew-fleming Aug 13, 2024
80cff05
fix test names/add comments for ctx
andrew-fleming Aug 15, 2024
7ac8b36
improve assertion name
andrew-fleming Aug 15, 2024
8b79881
fix conflicts
andrew-fleming Aug 15, 2024
5b691a7
fix fmt
andrew-fleming Aug 15, 2024
b6c5611
update spdx license id
andrew-fleming Aug 15, 2024
9478f72
update version in docs
andrew-fleming Aug 16, 2024
1ede105
Apply suggestions from code review
andrew-fleming Aug 20, 2024
0d61150
remove privateimpl from code
andrew-fleming Aug 20, 2024
0b5e92c
remove privateimpl from docs
andrew-fleming Aug 20, 2024
a81fcac
remove after_update hook from mocks
andrew-fleming Aug 20, 2024
4bb50b6
Apply suggestions from code review
andrew-fleming Aug 23, 2024
0f863ba
use simpler hook impl
andrew-fleming Aug 23, 2024
9ae2345
add before_update code example
andrew-fleming Aug 23, 2024
0982314
fix conflicts
andrew-fleming Aug 23, 2024
abf6b66
Apply suggestions from code review
andrew-fleming Aug 29, 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
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Added

- ERC721Enumerable component (#983)
- TimelockController component (#996)
- HashCall implementation (#996)
- Separated package for each submodule (#1065)
Expand Down
1 change: 0 additions & 1 deletion docs/modules/ROOT/pages/api/erc20.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -477,7 +477,6 @@ WARNING: To track voting units, this extension requires that the
xref:#ERC20VotesComponent-transfer_voting_units[transfer_voting_units] function is called after every transfer,
mint, or burn operation. For this, the xref:ERC20Component-ERC20HooksTrait[ERC20HooksTrait] must be used.


This extension keeps a history (checkpoints) of each account’s vote power. Vote power can be delegated either by calling
the xref:#ERC20VotesComponent-delegate[delegate] function directly, or by providing a signature to be used with
xref:#ERC20VotesComponent-delegate_by_sig[delegate_by_sig]. Voting power can be queried through the public accessors
Expand Down
163 changes: 163 additions & 0 deletions docs/modules/ROOT/pages/api/erc721.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,48 @@ Returns the NFT ticker symbol.
Returns the Uniform Resource Identifier (URI) for the `token_id` token.
If the URI is not set for `token_id`, the return value will be an empty `ByteArray`.

[.contract]
[[IERC721Enumerable]]
=== `++IERC721Enumerable++` link:https://github.com/OpenZeppelin/cairo-contracts/blob/release-v0.15.0-rc.0/src/token/erc721/extensions/erc721_enumerable/interface.cairo[{github-icon},role=heading-link]

Interface for the optional enumerable functions in {eip721}.

[.contract-index]
.{inner-src5}
--
0x16bc0f502eeaf65ce0b3acb5eea656e2f26979ce6750e8502a82f377e538c87
--

[.contract-index]
.Functions
--
* xref:#IERC721Enumerable-total_supply[`++total_supply()++`]
* xref:#IERC721Enumerable-token_by_index[`++token_by_index(index)++`]
* xref:#IERC721Enumerable-token_of_owner_by_index[`++token_of_owner_by_index(owner, index)++`]
--

==== Functions

[.contract-item]
[[IERC721Enumerable-total_supply]]
==== `[.contract-item-name]#++total_supply++#++() -> u256++` [.item-kind]#external#

Returns the total amount of tokens stored by the contract.

[.contract-item]
[[IERC721Metadata-token_by_index]]
==== `[.contract-item-name]#++token_by_index++#++(index) -> u256++` [.item-kind]#external#
andrew-fleming marked this conversation as resolved.
Show resolved Hide resolved

Returns a token id at a given `index` of all the tokens stored by the contract.
Use along with xref:#IERC721Enumerable-total_supply[IERC721Enumerable::total_supply] to enumerate all tokens.

[.contract-item]
[[IERC721Metadata-token_of_owner_by_index]]
==== `[.contract-item-name]#++token_of_owner_by_index++#++(owner, index) -> u256++` [.item-kind]#external#
andrew-fleming marked this conversation as resolved.
Show resolved Hide resolved

Returns the token id owned by `owner` at a given `index` of its token list.
Use along with xref:#IERC721-balance_of[IERC721::balance_of] to enumerate all of ``owner``'s tokens.

[.contract]
[[ERC721Component]]
=== `++ERC721Component++` link:https://github.com/OpenZeppelin/cairo-contracts/blob/release-v0.15.0-rc.0/src/token/erc721/erc721.cairo#L7[{github-icon},role=heading-link]
Expand Down Expand Up @@ -629,6 +671,8 @@ Requirements:

Emits an <<IERC721-Approval,Approval>> event.

Emits an <<IERC721-Approval,Approval>> event.

andrew-fleming marked this conversation as resolved.
Show resolved Hide resolved
[.contract-item]
[[ERC721Component-_set_base_uri]]
==== `[.contract-item-name]#++_set_base_uri++#++(ref self: ContractState, base_uri: ByteArray)++` [.item-kind]#internal#
Expand Down Expand Up @@ -689,6 +733,125 @@ See <<IERC721-ApprovalForAll,IERC721::ApprovalForAll>>.

See <<IERC721-Transfer,IERC721::Transfer>>.

[.contract]
[[ERC721EnumerableComponent]]
=== `++ERC721EnumerableComponent++` link:https://github.com/OpenZeppelin/cairo-contracts/blob/release-v0.15.0-rc.0/src/token/erc721/extensions/erc721_enumerable.cairo[{github-icon},role=heading-link]

```cairo
use openzeppelin::token::extensions::ERC721EnumerableComponent;
andrew-fleming marked this conversation as resolved.
Show resolved Hide resolved
```

Extension of ERC721 as defined in the EIP that adds enumerability of all the token ids in the contract as well as all token ids owned by each account.
This extension allows contracts to publish their entire list of NFTs and make them discoverable.

NOTE: Implementing xref:#ERC721Component[ERC721Component] is a requirement for this component to be implemented.

WARNING: To properly track token ids, this extension requires that the xref:#ERC721EnumerableComponent-before_update[ERC721EnumerableComponent::before_update] function is called after every transfer, mint, or burn operation.
andrew-fleming marked this conversation as resolved.
Show resolved Hide resolved
For this, the xref:ERC721Component-before_update[ERC721HooksTrait::before_update] hook must be used.

[.contract-index#ERC721EnumerableComponent-Embeddable-Impls]
.Embeddable Implementations
--
[.sub-index#ERC721EnumerableComponent-Embeddable-Impls-ERC721EnumerableImpl]
.ERC721EnumerableImpl
* xref:#ERC721EnumerableComponent-total_supply[`++total_supply(self)++`]
* xref:#ERC721EnumerableComponent-token_by_index[`++token_by_index(self, index)++`]
* xref:#ERC721EnumerableComponent-token_of_owner_by_index[`++token_of_owner_by_index(self, address, index)++`]
--

[.contract-index]
.Internal implementations
andrew-fleming marked this conversation as resolved.
Show resolved Hide resolved
--
.InternalImpl
* xref:#ERC721EnumerableComponent-initializer[`++initializer(self)++`]
* xref:#ERC721EnumerableComponent-before_update[`++before_update(self, to, token_id)++`]

.PrivateImpl
* xref:#ERC721EnumerableComponent-_add_token_to_owner_enumeration[`++_add_token_to_owner_enumeration(self, to, token_id)++`]
* xref:#ERC721EnumerableComponent-_add_token_to_all_tokens_enumeration[`++_add_token_to_all_tokens_enumeration(self, token_id)++`]
* xref:#ERC721EnumerableComponent-_remove_token_from_owner_enumeration[`++_remove_token_from_owner_enumeration(self, from, token_id)++`]
* xref:#ERC721EnumerableComponent-_remove_token_from_all_tokens_enumeration[`++_remove_token_from_all_tokens_enumeration(self, token_id)++`]
--

[#ERC721EnumerableComponent-Embeddable-functions]
==== Embeddable functions

[.contract-item]
[[ERC721EnumerableComponent-total_supply]]
==== `[.contract-item-name]#++total_supply++#++(self: @ContractState) → u256++` [.item-kind]#external#

Returns the current amount of votes that `account` has.

[.contract-item]
[[ERC721EnumerableComponent-token_by_index]]
==== `[.contract-item-name]#++token_by_index++#++(self: @ContractState, index: u256) → u256++` [.item-kind]#external#

See xref:#IERC721Enumerable-token_by_index[IERC721Enumerable::token_by_index].

Requirements:

- `index` is less than the total token supply.

[.contract-item]
[[ERC721EnumerableComponent-token_of_owner_by_index]]
==== `[.contract-item-name]#++token_of_owner_by_index++#++(self: @ContractState, owner: ContractAddress, index: u256) → u256++` [.item-kind]#external#

See xref:#IERC721Enumerable-token_of_owner_by_index[IERC721Enumerable::token_of_owner_by_index].

Requirements:

- `index` is less than ``owner``'s token balance.
- `owner` is not the zero address.

[#ERC721EnumerableComponent-Internal-functions]
==== Internal functions

[.contract-item]
[[ERC721EnumerableComponent-initializer]]
==== `[.contract-item-name]#++initializer++#++(ref self: ContractState)++` [.item-kind]#internal#

Registers the `IERC721Enumerable` interface ID as supported through introspection.

[.contract-item]
[[ERC721EnumerableComponent-before_update]]
==== `[.contract-item-name]#++before_update++#++(ref self: ContractState, to: ContractAddress, token_id: u256)++` [.item-kind]#internal#

Updates the ownership and token-tracking data structures.

When a token is minted (or burned), `token_id` is added to (or removed from) the token-tracking structures.

When a token is transferred, minted, or burned, the ownership-tracking data structures reflect the change in ownership of `token_id`.

This must be added to the implementing contract's xref:ERC721Component-before_update[ERC721HooksTrait::before_update] hook.

[.contract-item]
[[ERC721EnumerableComponent-_add_token_to_owner_enumeration]]
==== `[.contract-item-name]#++_add_token_to_owner_enumeration++#++(ref self: ContractState, to: ContractAddress, token_id: u256)++` [.item-kind]#private#

Adds token to this extension's ownership-tracking data structures.

[.contract-item]
[[ERC721EnumerableComponent-_add_token_to_all_tokens_enumeration]]
==== `[.contract-item-name]#++_add_token_to_all_tokens_enumeration++#++(ref self: ContractState, token_id: u256)++` [.item-kind]#private#

Adds token to this extension's token-tracking data structures.

[.contract-item]
[[ERC721EnumerableComponent-_remove_token_from_owner_enumeration]]
==== `[.contract-item-name]#++_remove_token_from_owner_enumeration++#++(ref self: ContractState, from: ContractAddress, token_id: u256)++` [.item-kind]#private#

Removes a token from this extension's ownership-tracking data structures.

This has 0(1) time complexity but alters the indexed order of owned tokens by swapping `token_id` and the index thereof with the last token id and the index thereof e.g. removing `1` from `[1, 2, 3, 4]` results in `[4, 2, 3]`.

[.contract-item]
[[ERC721EnumerableComponent-_remove_token_from_all_tokens_enumeration]]
==== `[.contract-item-name]#++_remove_token_from_all_tokens_enumeration++#++(ref self: ContractState, token_id: u256)++` [.item-kind]#private#

Removes `token_id` from this extension's token-tracking data structures.

This has 0(1) time complexity but alters the indexed order by swapping `token_id` and the index thereof with the last token id and the index thereof e.g. removing `1` from `[1, 2, 3, 4]` results in `[4, 2, 3]`.

== Receiver

[.contract]
Expand Down
2 changes: 1 addition & 1 deletion packages/access/src/accesscontrol/accesscontrol.cairo
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts for Cairo v0.12.0 (access/accesscontrol/accesscontrol.cairo)
// OpenZeppelin Contracts for Cairo v0.15.0-rc.0 (access/accesscontrol/accesscontrol.cairo)

/// # AccessControl Component
///
Expand Down
1 change: 1 addition & 0 deletions packages/token/src/erc721.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ pub mod dual721;
pub mod dual721_receiver;
pub mod erc721;
pub mod erc721_receiver;
pub mod extensions;
pub mod interface;

pub use erc721::ERC721Component;
Expand Down
3 changes: 3 additions & 0 deletions packages/token/src/erc721/extensions.cairo
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
pub mod erc721_enumerable;

pub use erc721_enumerable::ERC721EnumerableComponent;
4 changes: 4 additions & 0 deletions packages/token/src/erc721/extensions/erc721_enumerable.cairo
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
pub mod erc721_enumerable;
pub mod interface;

pub use erc721_enumerable::ERC721EnumerableComponent;
Loading