Skip to content

Conversation

@onurinanc
Copy link
Contributor

@onurinanc onurinanc commented Aug 7, 2025

PR Checklist

  • Tests
  • Documentation
  • Changelog

ERC6909 Implementation in rust-contracts-stylus

Summary

This PR implements the ERC-6909 token and Supply extension in Rust for Arbitrum Stylus.

The following implementation is provided in this PR:

  • ERC-6909 + unit tests with motsu
  • Supply Extension + unit tests with motsu
  • Example usage of ERC-6909 and Supply Extension
  • Integration Tests for ERC-6909 and Supply Extension
  • Benchmark for both ERC6909 and Supply Extension

Comments

Integration tests and the benchmarks inside rust-contracts-stylus, which use nitro-testnode, didn't work with the M3 Pro Chip (would be an issue related to Docker). To solve the problem, firstly, [nitro-devnode] is tried to use. However, I observed that it is not suitable for the e2e::test workflow. So, an LTS Ubuntu machine is rented on AWS to run the integration tests and the benchmark.

For the Supply Extension implementation, Deref traits are implemented. Using Deref allows direct access to Erc6909 methods, improving readability and maintainability. However, deferencing operations might increase the gas. Designing Supply Token Extension in this way increases the abstraction and makes it easy to use for users who would like to use the Supply Extension with ERC-6909 Token Contract.

Future Improvements

Currently, this PR does not include other ERC-6909 Extensions, specifically ContentURI and Metadata. Their example usage and the benchmarks should be added to the repository.

The unit tests that differentiate the id should be added.

Benchmark

Benchmarks for ERC-6909 can be seen as follows:

| Contract::function                                                        | WASM Opt & Cached | Cached | Not Cached |
| ------------------------------------------------------------------------- | ----------------- | ------ | ---------- |
| Erc6909::mint(address,uint256,uint256)                                    |             27925 |  29307 |      45089 |
| Erc6909::balanceOf(address,uint256)                                       |              5101 |   6448 |      22230 |
| Erc6909::allowance(address,address,uint256)                               |              5875 |   7228 |      23010 |
| Erc6909::isOperator(address,address)                                      |              5322 |   6666 |      22448 |
| Erc6909::setOperator(address,bool)                                        |             27045 |  28433 |      44215 |
| Erc6909::transfer(address,uint256,uint256)                                |             34364 |  35786 |      51568 |
| Erc6909::approve(address,uint256,uint256)                                 |             27939 |  29332 |      45114 |
| Erc6909::transferFrom(address,address,uint256,uint256)                    |             20503 |  21943 |      37725 |
| Erc6909::burn(address,uint256,uint256)                                    |             11495 |  12893 |      28675 |

@netlify
Copy link

netlify bot commented Aug 7, 2025

Deploy Preview for contracts-stylus ready!

Name Link
🔨 Latest commit 9c7ebe6
🔍 Latest deploy log https://app.netlify.com/projects/contracts-stylus/deploys/69273d17ec869400071bedca
😎 Deploy Preview https://deploy-preview-777--contracts-stylus.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@bidzyyys bidzyyys changed the title Feature/erc6909 feat: add ERC-6909 Token and Supply extension Aug 7, 2025
@bidzyyys bidzyyys linked an issue Aug 7, 2025 that may be closed by this pull request
1 task
@onurinanc onurinanc requested a review from 0xNeshi August 13, 2025 12:58
@onurinanc
Copy link
Contributor Author

Hey, any update on this PR @0xNeshi ?

@bidzyyys
Copy link
Collaborator

bidzyyys commented Sep 2, 2025

Hey, any update on this PR @0xNeshi ?

Hey @onurinanc!
We will review your changes early next week -- we are currently applying audit fixes for v0.3.

@codecov
Copy link

codecov bot commented Nov 19, 2025

Codecov Report

❌ Patch coverage is 99.28498% with 7 lines in your changes missing coverage. Please review.
✅ Project coverage is 95.68%. Comparing base (b648011) to head (04440c5).
✅ All tests successful. No failed tests found.

Files with missing lines Patch % Lines
contracts/src/token/erc6909/mod.rs 99.13% 4 Missing ⚠️
...racts/src/token/erc6909/extensions/token_supply.rs 99.42% 3 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #777      +/-   ##
==========================================
+ Coverage   95.46%   95.68%   +0.22%     
==========================================
  Files          89       91       +2     
  Lines       15814    16793     +979     
==========================================
+ Hits        15097    16069     +972     
- Misses        717      724       +7     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

Copy link
Member

@qalisander qalisander left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@onurinanc great job and lgtm!

Copy link
Collaborator

@0xNeshi 0xNeshi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔥

Comment on lines +119 to +124
/// Re-export of [`Erc6909::_mint`].
///
/// # Errors
///
/// * [`Error::InvalidReceiver`] - If the `to` address is [`Address::ZERO`].
pub fn _mint(
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not a re-export of Erc6909::_mint but a "re-implementation", maybe it makes sense to add missing doc sections:
https://github.com/OpenZeppelin/rust-contracts-stylus/pull/777/files#diff-c485e1cc294c36163cf1b14720fb9741e48b604c3db9c817def3aed1db955ed6R620

Same for other internal fns

Comment on lines +468 to +469
/// NOTE: This function is not virtual, {_update} should be overridden
/// instead.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do these notes make sense in Stylus?

/// receiver are [`Address::ZERO`], which means it cannot mint or burn
/// tokens.
///
/// Relies on the `_update` mechanism.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: link to the _update fn

@0xNeshi 0xNeshi self-requested a review November 26, 2025 09:26
/// Sets `amount` as the allowance of `spender` over the `owner`'s `id`
/// tokens.
///
/// This internal function is equivalent to `approve`, and can be used to
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: link to approve; check that other fn mentions are properly linked

Comment on lines +362 to +363
/// This internal function is equivalent to `approve`, and can be used to
/// e.g. set automatic allowances for certain subsystems, etc.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This sentence exists in Solidity too, but I'm not sure I really get its purpose.


/// Approve `spender` to operate on all of `owner`'s tokens
///
/// This internal function is equivalent to `setOperator`, and can be used
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: fix name and link to actual fn

/// Updates `owner`'s allowance for `spender` based on spent `amount`.
///
/// Does not update the allowance value in case of infinite allowance.
/// Revert if not enough allowance is available.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
/// Revert if not enough allowance is available.

already documented in # Errors

Copy link
Collaborator

@bidzyyys bidzyyys left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

First pass.

- `SafeErc20` now implements: `try_safe_transfer`, `try_safe_transfer_from`, `transfer_and_call_relaxed`, `transfer_from_and_call_relaxed` and `approve_and_call_relaxed`. #765
- Add bidirectional conversions between `ruint::Uint` and crypto library `Uint` types behind `ruint` feature toggle. #758
- Add bidirectional conversions between `Uint` and `u8`, `u16`, `u32`, `u64`, `u128` types. #764
- Add `Erc6909` contract and `Erc6909TokenSupply` extension. #777
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should be added to "Unreleased" section.

[[usage]]
== Usage

In order to make an xref:erc6909.adoc[ERC-6909] token with https://docs.rs/openzeppelin-stylus/0.3.0-alpha.1/openzeppelin_stylus/token/erc6909/extensions/supply/index.html[Supply] flavour,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need to decide on version, but the one is wrong.

While ERC-1155 introduced a multi-token interface capable of managing both fungible and non-fungible assets (such as ERC-20 and ERC-721) within a single smart contract, ERC-6909 streamlines this approach for greater efficiency by overcoming the limitations of ERC-1155 by removing contract-level callbacks and batch transfers, and by replacing the single-operator permission model with a hybrid allowance–operator system that enables more fine-grained token management.

The OpenZeppelin Stylus Contracts provides a complete implementation of the ERC-6909 standard.
On the https://docs.rs/openzeppelin-stylus/0.3.0-rc.1/openzeppelin_stylus/token/erc6909/struct.Erc6909.html[`API reference`] you'll find detailed information on their properties and usage.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Version issue here.

#[entrypoint]
#[storage]
struct VaultManager {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would use exactly the same code from the example; No VaultManager.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feature]: Add ERC-6909 Supply Extension [Feature]: Implement ERC-6909 Token

4 participants