1
+ //! Implementation of the ERC-721 token standard.
2
+ use alloc:: vec;
3
+
1
4
use alloy_primitives:: { fixed_bytes, Address , FixedBytes , U128 , U256 } ;
2
5
use derive_more:: From ;
3
6
use stylus_sdk:: {
@@ -88,13 +91,26 @@ sol! {
88
91
/// [ERC-6093]: https://eips.ethereum.org/EIPS/eip-6093
89
92
#[ derive( SolidityError , Debug , From ) ]
90
93
pub enum Error {
94
+ /// Indicates that an address can't be an owner.
95
+ /// For example, `address(0)` is a forbidden owner in ERC-721. Used in
96
+ /// balance queries.
91
97
InvalidOwner ( ERC721InvalidOwner ) ,
98
+ /// Indicates a `tokenId` whose `owner` is the zero address.
92
99
NonexistentToken ( ERC721NonexistentToken ) ,
100
+ /// Indicates an error related to the ownership over a particular token.
101
+ /// Used in transfers.
93
102
IncorrectOwner ( ERC721IncorrectOwner ) ,
103
+ /// Indicates a failure with the token `sender`. Used in transfers.
94
104
InvalidSender ( ERC721InvalidSender ) ,
105
+ /// Indicates a failure with the token `receiver`. Used in transfers.
95
106
InvalidReceiver ( ERC721InvalidReceiver ) ,
107
+ /// Indicates a failure with the `operator`’s approval. Used in transfers.
96
108
InsufficientApproval ( ERC721InsufficientApproval ) ,
109
+ /// Indicates a failure with the `approver` of a token to be approved. Used
110
+ /// in approvals.
97
111
InvalidApprover ( ERC721InvalidApprover ) ,
112
+ /// Indicates a failure with the `operator` to be approved. Used in
113
+ /// approvals.
98
114
InvalidOperator ( ERC721InvalidOperator ) ,
99
115
}
100
116
@@ -120,13 +136,15 @@ sol_interface! {
120
136
}
121
137
122
138
sol_storage ! {
139
+ /// State of an ERC-721 token.
123
140
pub struct ERC721 {
141
+ /// Maps tokens to owners.
124
142
mapping( uint256 => address) _owners;
125
-
143
+ /// Maps users to balances.
126
144
mapping( address => uint256) _balances;
127
-
145
+ /// Maps tokens to approvals.
128
146
mapping( uint256 => address) _token_approvals;
129
-
147
+ /// Maps owners to a mapping of operator approvals.
130
148
mapping( address => mapping( address => bool ) ) _operator_approvals;
131
149
}
132
150
}
@@ -272,7 +290,7 @@ impl ERC721 {
272
290
data : Bytes ,
273
291
) -> Result < ( ) , Error > {
274
292
self . transfer_from ( from, to, token_id) ?;
275
- self . _check_on_erc721_received ( msg:: sender ( ) , from, to, token_id, data)
293
+ self . _check_on_erc721_received ( msg:: sender ( ) , from, to, token_id, & data)
276
294
}
277
295
278
296
/// Transfers `token_id` token from `from` to `to`.
@@ -706,7 +724,7 @@ impl ERC721 {
706
724
Address :: ZERO ,
707
725
to,
708
726
token_id,
709
- data,
727
+ & data,
710
728
)
711
729
}
712
730
@@ -847,7 +865,7 @@ impl ERC721 {
847
865
data : Bytes ,
848
866
) -> Result < ( ) , Error > {
849
867
self . _transfer ( from, to, token_id) ?;
850
- self . _check_on_erc721_received ( msg:: sender ( ) , from, to, token_id, data)
868
+ self . _check_on_erc721_received ( msg:: sender ( ) , from, to, token_id, & data)
851
869
}
852
870
853
871
/// Variant of `approve_inner` with an optional flag to enable or disable
@@ -989,7 +1007,7 @@ impl ERC721 {
989
1007
from : Address ,
990
1008
to : Address ,
991
1009
token_id : U256 ,
992
- data : Bytes ,
1010
+ data : & Bytes ,
993
1011
) -> Result < ( ) , Error > {
994
1012
const IERC721RECEIVER_INTERFACE_ID : FixedBytes < 4 > =
995
1013
fixed_bytes ! ( "150b7a02" ) ;
@@ -1017,7 +1035,7 @@ impl ERC721 {
1017
1035
}
1018
1036
}
1019
1037
1020
- #[ cfg( test) ]
1038
+ #[ cfg( all ( test, feature = "tests" ) ) ]
1021
1039
mod tests {
1022
1040
use alloy_primitives:: address;
1023
1041
use once_cell:: sync:: Lazy ;
0 commit comments