Skip to content

Commit

Permalink
Merge branch 'main' into ERC4626-Extension-
Browse files Browse the repository at this point in the history
  • Loading branch information
Ifechukwudaniel authored Jan 2, 2025
2 parents ac8409e + 3ab0f31 commit 215595a
Show file tree
Hide file tree
Showing 29 changed files with 103 additions and 35 deletions.
18 changes: 18 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).


# [Unreleased]

### Added
Expand All @@ -14,6 +15,23 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Changed

-
## [Unreleased]

### Added

-

### Changed

- Use `AddAssignUnchecked` and `SubAssignUnchecked` in `erc20::_update` calculations. #467

### Changed (Breaking)

- `Nonce::use_nonce` now panics on exceeding `U256::MAX`. #467

### Fixed

-

## [v0.2.0-alpha.2] - 2024-12-18

Expand Down
1 change: 1 addition & 0 deletions contracts/src/access/control.rs
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,7 @@ pub struct RoleData {
#[storage]
pub struct AccessControl {
/// Role identifier -> Role information.
#[allow(clippy::used_underscore_binding)]
pub _roles: StorageMap<FixedBytes<32>, RoleData>,
}

Expand Down
1 change: 1 addition & 0 deletions contracts/src/access/ownable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ impl MethodError for Error {
#[storage]
pub struct Ownable {
/// The current owner of this contract.
#[allow(clippy::used_underscore_binding)]
pub _owner: StorageAddress,
}

Expand Down
2 changes: 2 additions & 0 deletions contracts/src/access/ownable_two_step.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,10 @@ pub enum Error {
#[storage]
pub struct Ownable2Step {
/// [`Ownable`] contract.
#[allow(clippy::used_underscore_binding)]
pub _ownable: Ownable,
/// Pending owner of the contract.
#[allow(clippy::used_underscore_binding)]
pub _pending_owner: StorageAddress,
}

Expand Down
4 changes: 4 additions & 0 deletions contracts/src/finance/vesting_wallet.rs
Original file line number Diff line number Diff line change
Expand Up @@ -107,12 +107,16 @@ pub struct VestingWallet {
/// [`Ownable`] contract.
pub ownable: Ownable,
/// Amount of Ether already released.
#[allow(clippy::used_underscore_binding)]
pub _released: StorageU256,
/// Amount of ERC-20 tokens already released.
#[allow(clippy::used_underscore_binding)]
pub _erc20_released: StorageMap<Address, StorageU256>,
/// Start timestamp.
#[allow(clippy::used_underscore_binding)]
pub _start: StorageU64,
/// Vesting duration.
#[allow(clippy::used_underscore_binding)]
pub _duration: StorageU64,
/// [`SafeErc20`] contract.
pub safe_erc20: SafeErc20,
Expand Down
1 change: 1 addition & 0 deletions contracts/src/token/erc1155/extensions/metadata_uri.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ mod sol {
pub struct Erc1155MetadataUri {
/// Used as the URI for all token types by relying on ID substitution,
/// e.g. https://token-cdn-domain/{id}.json.
#[allow(clippy::used_underscore_binding)]
pub _uri: StorageString,
}

Expand Down
2 changes: 2 additions & 0 deletions contracts/src/token/erc1155/extensions/supply.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,10 @@ pub struct Erc1155Supply {
/// ERC-1155 contract storage.
pub erc1155: Erc1155,
/// Mapping from token id to total supply.
#[allow(clippy::used_underscore_binding)]
pub _total_supply: StorageMap<U256, StorageU256>,
/// Total supply of all token ids.
#[allow(clippy::used_underscore_binding)]
pub _total_supply_all: StorageU256,
}

Expand Down
2 changes: 2 additions & 0 deletions contracts/src/token/erc1155/extensions/uri_storage.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,10 @@ use super::metadata_uri::{IErc1155MetadataUri, URI};
#[storage]
pub struct Erc1155UriStorage {
/// Optional base URI.
#[allow(clippy::used_underscore_binding)]
pub _base_uri: StorageString,
/// Optional mapping for token URIs.
#[allow(clippy::used_underscore_binding)]
pub _token_uris: StorageMap<U256, StorageString>,
}

Expand Down
2 changes: 2 additions & 0 deletions contracts/src/token/erc1155/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -188,8 +188,10 @@ impl MethodError for Error {
#[storage]
pub struct Erc1155 {
/// Maps users to balances.
#[allow(clippy::used_underscore_binding)]
pub _balances: StorageMap<U256, StorageMap<Address, StorageU256>>,
/// Maps owners to a mapping of operator approvals.
#[allow(clippy::used_underscore_binding)]
pub _operator_approvals:
StorageMap<Address, StorageMap<Address, StorageBool>>,
}
Expand Down
1 change: 1 addition & 0 deletions contracts/src/token/erc20/extensions/capped.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ pub enum Error {
#[storage]
pub struct Capped {
/// A cap to the supply of tokens.
#[allow(clippy::used_underscore_binding)]
pub _cap: StorageU256,
}

Expand Down
1 change: 1 addition & 0 deletions contracts/src/token/erc20/extensions/metadata.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ use crate::utils::Metadata;
#[storage]
pub struct Erc20Metadata {
/// Common Metadata.
#[allow(clippy::used_underscore_binding)]
pub _metadata: Metadata,
}

Expand Down
14 changes: 9 additions & 5 deletions contracts/src/token/erc20/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,10 @@ use stylus_sdk::{
stylus_proc::{public, SolidityError},
};

use crate::utils::introspection::erc165::{Erc165, IErc165};
use crate::utils::{
introspection::erc165::{Erc165, IErc165},
math::storage::{AddAssignUnchecked, SubAssignUnchecked},
};

pub mod extensions;
pub mod utils;
Expand Down Expand Up @@ -123,10 +126,13 @@ impl MethodError for Error {
#[storage]
pub struct Erc20 {
/// Maps users to balances.
#[allow(clippy::used_underscore_binding)]
pub _balances: StorageMap<Address, StorageU256>,
/// Maps users to a mapping of each spender's allowance.
#[allow(clippy::used_underscore_binding)]
pub _allowances: StorageMap<Address, StorageMap<Address, StorageU256>>,
/// The total supply of the token.
#[allow(clippy::used_underscore_binding)]
pub _total_supply: StorageU256,
}

Expand Down Expand Up @@ -489,17 +495,15 @@ impl Erc20 {
}

if to.is_zero() {
let total_supply = self.total_supply();
// Overflow not possible:
// `value` <= `_total_supply` or
// `value` <= `from_balance` <= `_total_supply`.
self._total_supply.set(total_supply - value);
self._total_supply.sub_assign_unchecked(value);
} else {
let balance_to = self._balances.get(to);
// Overflow not possible:
// `balance_to` + `value` is at most `total_supply`,
// which fits into a `U256`.
self._balances.setter(to).set(balance_to + value);
self._balances.setter(to).add_assign_unchecked(value);
}

evm::log(Transfer { from, to, value });
Expand Down
4 changes: 4 additions & 0 deletions contracts/src/token/erc721/extensions/consecutive.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,16 +62,20 @@ pub struct Erc721Consecutive {
/// Erc721 contract storage.
pub erc721: Erc721,
/// Checkpoint library contract for sequential ownership.
#[allow(clippy::used_underscore_binding)]
pub _sequential_ownership: Trace<S160>,
/// BitMap library contract for sequential burn of tokens.
#[allow(clippy::used_underscore_binding)]
pub _sequential_burn: BitMap,
/// Used to offset the first token id in
/// [`Erc721Consecutive::_next_consecutive_id`].
#[allow(clippy::used_underscore_binding)]
pub _first_consecutive_id: StorageU96,
/// Maximum size of a batch of consecutive tokens. This is designed to
/// limit stress on off-chain indexing services that have to record one
/// entry per token, and have protections against "unreasonably large"
/// batches of tokens.
#[allow(clippy::used_underscore_binding)]
pub _max_batch_size: StorageU96,
}

Expand Down
4 changes: 4 additions & 0 deletions contracts/src/token/erc721/extensions/enumerable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,12 +62,16 @@ pub enum Error {
#[storage]
pub struct Erc721Enumerable {
/// Maps owners to a mapping of indices to tokens ids.
#[allow(clippy::used_underscore_binding)]
pub _owned_tokens: StorageMap<Address, StorageMap<U256, StorageU256>>,
/// Maps tokens ids to indices in `_owned_tokens`.
#[allow(clippy::used_underscore_binding)]
pub _owned_tokens_index: StorageMap<U256, StorageU256>,
/// Stores all tokens ids.
#[allow(clippy::used_underscore_binding)]
pub _all_tokens: StorageVec<StorageU256>,
/// Maps indices at `_all_tokens` to tokens ids.
#[allow(clippy::used_underscore_binding)]
pub _all_tokens_index: StorageMap<U256, StorageU256>,
}

Expand Down
2 changes: 2 additions & 0 deletions contracts/src/token/erc721/extensions/metadata.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,10 @@ use crate::{
#[storage]
pub struct Erc721Metadata {
/// Common Metadata.
#[allow(clippy::used_underscore_binding)]
pub _metadata: Metadata,
/// Base URI for tokens.
#[allow(clippy::used_underscore_binding)]
pub _base_uri: StorageString,
}

Expand Down
1 change: 1 addition & 0 deletions contracts/src/token/erc721/extensions/uri_storage.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ mod sol {
#[storage]
pub struct Erc721UriStorage {
/// Optional mapping for token URIs.
#[allow(clippy::used_underscore_binding)]
pub _token_uris: StorageMap<U256, StorageString>,
}

Expand Down
4 changes: 4 additions & 0 deletions contracts/src/token/erc721/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -197,12 +197,16 @@ mod receiver {
#[storage]
pub struct Erc721 {
/// Maps tokens to owners.
#[allow(clippy::used_underscore_binding)]
pub _owners: StorageMap<U256, StorageAddress>,
/// Maps users to balances.
#[allow(clippy::used_underscore_binding)]
pub _balances: StorageMap<Address, StorageU256>,
/// Maps tokens to approvals.
#[allow(clippy::used_underscore_binding)]
pub _token_approvals: StorageMap<U256, StorageAddress>,
/// Maps owners to a mapping of operator approvals.
#[allow(clippy::used_underscore_binding)]
pub _operator_approvals:
StorageMap<Address, StorageMap<Address, StorageBool>>,
}
Expand Down
2 changes: 2 additions & 0 deletions contracts/src/utils/metadata.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,10 @@ use stylus_sdk::{
#[storage]
pub struct Metadata {
/// Token name.
#[allow(clippy::used_underscore_binding)]
pub _name: StorageString,
/// Token symbol.
#[allow(clippy::used_underscore_binding)]
pub _symbol: StorageString,
}

Expand Down
32 changes: 13 additions & 19 deletions contracts/src/utils/nonces.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ mod sol {
/// The nonce used for an `account` is not the expected current nonce.
#[derive(Debug)]
#[allow(missing_docs)]
error InvalidAccountNonce(address account, uint256 currentNonce);
error InvalidAccountNonce(address account, uint256 current_nonce);
}
}

Expand All @@ -35,6 +35,7 @@ pub enum Error {
#[storage]
pub struct Nonces {
/// Mapping from address to its nonce.
#[allow(clippy::used_underscore_binding)]
pub _nonces: StorageMap<Address, StorageU256>,
}

Expand Down Expand Up @@ -62,14 +63,13 @@ impl Nonces {
///
/// # Panics
///
/// This function will panic if the nonce for the given `owner` has reached
/// the maximum value representable by `U256`, causing the `checked_add`
/// method to return `None`.
/// If the nonce for the given `owner` exceeds `U256::MAX`.
pub fn use_nonce(&mut self, owner: Address) -> U256 {
let nonce = self._nonces.get(owner);
self._nonces
.setter(owner)
.set(unsafe { nonce.checked_add(ONE).unwrap_unchecked() });
let updated_nonce = nonce
.checked_add(ONE)
.expect("nonce should not exceed `U256::MAX`");
self._nonces.setter(owner).set(updated_nonce);

nonce
}
Expand All @@ -83,34 +83,28 @@ impl Nonces {
/// * `owner` - The address for which to consume the nonce.
/// * `nonce` - The nonce to consume.
///
/// # Panics
///
/// This function will panic if the nonce for the given `owner` has reached
/// the maximum value representable by `U256`, causing the `checked_add`
/// method to return `None`.
///
/// # Errors
///
/// Returns an error if the `nonce` is not the next valid nonce for the
/// owner.
///
/// # Panics
///
/// If the nonce for the given `owner` exceeds `U256::MAX`.
pub fn use_checked_nonce(
&mut self,
owner: Address,
nonce: U256,
) -> Result<(), Error> {
let current_nonce = self._nonces.get(owner);
let current_nonce = self.use_nonce(owner);

if nonce != current_nonce {
return Err(Error::InvalidAccountNonce(InvalidAccountNonce {
account: owner,
currentNonce: current_nonce,
current_nonce,
}));
}

self._nonces
.setter(owner)
.set(unsafe { nonce.checked_add(ONE).unwrap_unchecked() });

Ok(())
}
}
Expand Down
1 change: 1 addition & 0 deletions contracts/src/utils/pausable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ pub enum Error {
#[storage]
pub struct Pausable {
/// Indicates whether the contract is `Paused`.
#[allow(clippy::used_underscore_binding)]
pub _paused: StorageBool,
}

Expand Down
1 change: 1 addition & 0 deletions contracts/src/utils/structs/bitmap.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ const HEX_FF: U256 = uint!(0xff_U256);
#[storage]
pub struct BitMap {
/// Inner laying mapping.
#[allow(clippy::used_underscore_binding)]
pub _data: StorageMap<U256, StorageU256>,
}

Expand Down
3 changes: 3 additions & 0 deletions contracts/src/utils/structs/checkpoints/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,15 +51,18 @@ impl MethodError for Error {
#[storage]
pub struct Trace<S: Size> {
/// Stores checkpoints in a dynamic array sorted by key.
#[allow(clippy::used_underscore_binding)]
pub _checkpoints: StorageVec<Checkpoint<S>>,
}

/// State of a single checkpoint.
#[storage]
pub struct Checkpoint<S: Size> {
/// The key of the checkpoint. Used as a sorting key.
#[allow(clippy::used_underscore_binding)]
pub _key: S::KeyStorage,
/// The value corresponding to the key.
#[allow(clippy::used_underscore_binding)]
pub _value: S::ValueStorage,
}

Expand Down
4 changes: 4 additions & 0 deletions examples/erc1155/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,10 @@ impl Erc1155Example {
Erc1155::supports_interface(interface_id)
}

/// WARNING: These functions are intended for **testing purposes** only. In
/// **production**, ensure strict access control to prevent unauthorized
/// pausing or unpausing, which can disrupt contract functionality. Remove
/// or secure these functions before deployment.
fn pause(&mut self) -> Result<(), Vec<u8>> {
self.pausable.pause().map_err(|e| e.into())
}
Expand Down
4 changes: 4 additions & 0 deletions examples/erc20/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,10 @@ impl Erc20Example {
|| Erc20Metadata::supports_interface(interface_id)
}

/// WARNING: These functions are intended for **testing purposes** only. In
/// **production**, ensure strict access control to prevent unauthorized
/// pausing or unpausing, which can disrupt contract functionality. Remove
/// or secure these functions before deployment.
pub fn pause(&mut self) -> Result<(), Vec<u8>> {
self.pausable.pause().map_err(|e| e.into())
}
Expand Down
Loading

0 comments on commit 215595a

Please sign in to comment.