Skip to content

Commit

Permalink
Merge branch 'main' into feature/erc20-burnable
Browse files Browse the repository at this point in the history
  • Loading branch information
bidzyyys committed Apr 9, 2024
2 parents 65f7a75 + cf32874 commit 53c4aef
Show file tree
Hide file tree
Showing 11 changed files with 131 additions and 53 deletions.
13 changes: 11 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

15 changes: 14 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
[workspace]
members = ["contracts", "lib/crypto", "lib/grip", "lib/grip-proc"]
members = [
"contracts",
"lib/crypto",
"lib/grip",
"lib/grip-proc",
"examples/erc20",
]
# Explicitly set the resolver to version 2, which is the default for packages
# with edition >= 2021.
# https://doc.rust-lang.org/edition-guide/rust-2021/default-cargo-resolver.html
Expand All @@ -12,6 +18,13 @@ license = "MIT"
keywords = ["arbitrum", "ethereum", "stylus"]
repository = "https://github.com/OpenZeppelin/rust-contracts-stylus"

[workspace.dependencies]
alloy-primitives = { version = "0.3.1", default-features = false }
alloy-sol-types = { version = "0.3.1", default-features = false }
stylus-sdk = { version = "0.4.3", default-features = false }
stylus-proc = { version = "0.4.3", default-features = false }
mini-alloc = "0.4.2"

[profile.release]
codegen-units = 1
panic = "abort"
Expand Down
35 changes: 8 additions & 27 deletions contracts/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,13 @@ repository.workspace = true
version = "0.1.0"

[dependencies]
alloy-primitives = { version = "0.3.1", default-features = false }
alloy-sol-types = { version = "0.3.1", default-features = false }
stylus-sdk = { version = "0.4.3", default-features = false }
stylus-proc = { version = "0.4.3", default-features = false }
mini-alloc = "0.4.2"
alloy-primitives.workspace = true
alloy-sol-types.workspace = true
stylus-sdk.workspace = true
stylus-proc.workspace = true
mini-alloc.workspace = true
derive_more = "0.99.17"
cfg-if = "1.0"

[dev-dependencies]
grip = { path = "../lib/grip" }
Expand All @@ -24,31 +25,11 @@ once_cell = "1.19.0"

[features]
default = []
tests = []
erc20 = []
erc20_metadata = ["erc20"]
erc20_burnable = ["erc20"]
erc721 = []

[lib]
# The Stylus team sets new crates with the following types:
# `lib` - The default, which gets turned to `rlib` by cargo and is needed to
# link the crate as a dependency of binaries.
# `cdylib` - A dynamic system library to be loaded from `wasm`.
#
# See <https://doc.rust-lang.org/reference/linkage.html>
#
# This means our crate would be built twice: once as a rust library and once as
# a dynamic library. When running `cargo test`, cargo invokes rustc twice, but
# when it build the rust library, it doesn't set the `test` feature flag, so we
# can't use it.
#
# The reason to add `lib` is to be able to use the `export-abi` feature of the
# SDK. We don't set `lib` here because our contracts are meant to be used as an
# addition to other contracts. For this use case, the abi of those contracts
# will contain ours.
#
# The trade-off is being able to run `cargo test` with conditional compilation
# vs being able to run `cargo stylus export-abi`.
#
# This may change in the future, so this behavior should not be relied upon.
crate-type = ["cdylib"]
crate-type = ["lib", "cdylib"]
4 changes: 2 additions & 2 deletions contracts/src/erc20/extensions/metadata.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ impl Metadata {
/// * `name` - The name of the token.
/// * `symbol` - The symbol of the token.
pub fn constructor(&mut self, name: String, symbol: String) {
if self._initialized.get() == true {
if self._initialized.get() {
return;
}

Expand Down Expand Up @@ -87,7 +87,7 @@ impl Metadata {
}
}

#[cfg(test)]
#[cfg(all(test, feature = "tests"))]
mod tests {
use alloy_primitives::U256;
use stylus_sdk::storage::{StorageBool, StorageString, StorageType};
Expand Down
16 changes: 12 additions & 4 deletions contracts/src/erc20/extensions/mod.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
#[cfg(any(test, erc20_metadata))]
pub mod metadata;
//! Common extensions to the ERC-20 standard.
#[cfg(any(test, erc20_burnable))]
pub mod burnable;
cfg_if::cfg_if! {
if #[cfg(any(test, feature = "erc20_metadata"))] {
pub mod metadata;
pub use metadata::Metadata;
}
}
cfg_if::cfg_if! {
if #[cfg(any(test, feature = "erc20_burnable"))] {
pub mod burnable;
}
}
2 changes: 1 addition & 1 deletion contracts/src/erc20/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -437,7 +437,7 @@ impl ERC20 {
}
}

#[cfg(test)]
#[cfg(all(test, feature = "tests"))]
mod tests {
use alloy_primitives::{address, Address, U256};
use stylus_sdk::{
Expand Down
34 changes: 26 additions & 8 deletions contracts/src/erc721/mod.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
//! Implementation of the ERC-721 token standard.
use alloc::vec;

use alloy_primitives::{fixed_bytes, Address, FixedBytes, U128, U256};
use derive_more::From;
use stylus_sdk::{
Expand Down Expand Up @@ -88,13 +91,26 @@ sol! {
/// [ERC-6093]: https://eips.ethereum.org/EIPS/eip-6093
#[derive(SolidityError, Debug, From)]
pub enum Error {
/// Indicates that an address can't be an owner.
/// For example, `address(0)` is a forbidden owner in ERC-721. Used in
/// balance queries.
InvalidOwner(ERC721InvalidOwner),
/// Indicates a `tokenId` whose `owner` is the zero address.
NonexistentToken(ERC721NonexistentToken),
/// Indicates an error related to the ownership over a particular token.
/// Used in transfers.
IncorrectOwner(ERC721IncorrectOwner),
/// Indicates a failure with the token `sender`. Used in transfers.
InvalidSender(ERC721InvalidSender),
/// Indicates a failure with the token `receiver`. Used in transfers.
InvalidReceiver(ERC721InvalidReceiver),
/// Indicates a failure with the `operator`’s approval. Used in transfers.
InsufficientApproval(ERC721InsufficientApproval),
/// Indicates a failure with the `approver` of a token to be approved. Used
/// in approvals.
InvalidApprover(ERC721InvalidApprover),
/// Indicates a failure with the `operator` to be approved. Used in
/// approvals.
InvalidOperator(ERC721InvalidOperator),
}

Expand All @@ -120,13 +136,15 @@ sol_interface! {
}

sol_storage! {
/// State of an ERC-721 token.
pub struct ERC721 {
/// Maps tokens to owners.
mapping(uint256 => address) _owners;

/// Maps users to balances.
mapping(address => uint256) _balances;

/// Maps tokens to approvals.
mapping(uint256 => address) _token_approvals;

/// Maps owners to a mapping of operator approvals.
mapping(address => mapping(address => bool)) _operator_approvals;
}
}
Expand Down Expand Up @@ -272,7 +290,7 @@ impl ERC721 {
data: Bytes,
) -> Result<(), Error> {
self.transfer_from(from, to, token_id)?;
self._check_on_erc721_received(msg::sender(), from, to, token_id, data)
self._check_on_erc721_received(msg::sender(), from, to, token_id, &data)
}

/// Transfers `token_id` token from `from` to `to`.
Expand Down Expand Up @@ -706,7 +724,7 @@ impl ERC721 {
Address::ZERO,
to,
token_id,
data,
&data,
)
}

Expand Down Expand Up @@ -847,7 +865,7 @@ impl ERC721 {
data: Bytes,
) -> Result<(), Error> {
self._transfer(from, to, token_id)?;
self._check_on_erc721_received(msg::sender(), from, to, token_id, data)
self._check_on_erc721_received(msg::sender(), from, to, token_id, &data)
}

/// Variant of `approve_inner` with an optional flag to enable or disable
Expand Down Expand Up @@ -989,7 +1007,7 @@ impl ERC721 {
from: Address,
to: Address,
token_id: U256,
data: Bytes,
data: &Bytes,
) -> Result<(), Error> {
const IERC721RECEIVER_INTERFACE_ID: FixedBytes<4> =
fixed_bytes!("150b7a02");
Expand Down Expand Up @@ -1017,7 +1035,7 @@ impl ERC721 {
}
}

#[cfg(test)]
#[cfg(all(test, feature = "tests"))]
mod tests {
use alloy_primitives::address;
use once_cell::sync::Lazy;
Expand Down
8 changes: 4 additions & 4 deletions contracts/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,19 +1,19 @@
#![doc = include_str!("../../README.md")]
#![warn(missing_docs, unreachable_pub, rust_2021_compatibility)]
#![warn(clippy::all, clippy::pedantic)]
#![cfg_attr(not(test), no_std, no_main)]
#![cfg_attr(not(feature = "tests"), no_std, no_main)]
extern crate alloc;

#[global_allocator]
static ALLOC: mini_alloc::MiniAlloc = mini_alloc::MiniAlloc::INIT;

mod arithmetic;
#[cfg(any(test, erc20))]
#[cfg(any(feature = "tests", feature = "erc20"))]
pub mod erc20;
#[cfg(any(test, erc721))]
#[cfg(any(feature = "tests", feature = "erc721"))]
pub mod erc721;

#[cfg(not(any(test, target_arch = "wasm32-unknown-unknown")))]
#[cfg(not(any(feature = "tests", target_arch = "wasm32-unknown-unknown")))]
#[panic_handler]
fn panic(_info: &core::panic::PanicInfo) -> ! {
loop {}
Expand Down
16 changes: 16 additions & 0 deletions examples/erc20/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
[package]
name = "erc20-example"
edition.workspace = true
license.workspace = true
repository.workspace = true
publish = false
version = "0.0.0"

[dependencies]
contracts = { path = "../../contracts", features = ["erc20", "erc20_metadata"] }
stylus-sdk.workspace = true
stylus-proc.workspace = true
mini-alloc.workspace = true

[lib]
crate-type = ["lib", "cdylib"]
35 changes: 35 additions & 0 deletions examples/erc20/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
#![cfg_attr(not(test), no_main, no_std)]
extern crate alloc;

use alloc::string::String;

use contracts::erc20::{extensions::Metadata, ERC20};
use stylus_sdk::prelude::{entrypoint, external, sol_storage};

const DECIMALS: u8 = 10;

sol_storage! {
#[entrypoint]
struct Token {
#[borrow]
ERC20 erc20;
#[borrow]
Metadata metadata;
}
}

#[external]
#[inherit(ERC20, Metadata)]
impl Token {
pub fn constructor(&mut self, name: String, symbol: String) {
self.metadata.constructor(name, symbol);
}

// Overrides the default [`Metadata::decimals`], and sets it to `10`.
//
// If you don't provide this method in the `entrypoint` contract, it will
// default to `18`.
pub fn decimals(&self) -> u8 {
DECIMALS
}
}
6 changes: 2 additions & 4 deletions lib/crypto/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,9 @@ license.workspace = true
repository.workspace = true
version = "0.1.0"

[dependencies]
alloy-primitives = { version = "0.6.4", default-features = false }

[dev-dependencies]
const-hex = "1.11.1"
alloy-primitives = { version = "0.6.4", default-features = false }
const-hex = { version = "1.11.1", default-features = false }
rand = "0.8.5"

[features]
Expand Down

0 comments on commit 53c4aef

Please sign in to comment.