diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml
index 7453406..068d0a1 100644
--- a/.github/workflows/lint.yml
+++ b/.github/workflows/lint.yml
@@ -13,7 +13,7 @@ jobs:
steps:
- name: Checkout code
- uses: actions/checkout@v4
+ uses: actions/checkout@v5
- name: Setup pnpm
uses: pnpm/action-setup@v4
@@ -27,4 +27,4 @@ jobs:
run: pnpm run check
- name: Build check
- run: pnpm run build
\ No newline at end of file
+ run: pnpm run build
diff --git a/content/contracts-cairo/1.0.0/accounts.mdx b/content/contracts-cairo/1.0.0/accounts.mdx
index 46a1de6..9362446 100644
--- a/content/contracts-cairo/1.0.0/accounts.mdx
+++ b/content/contracts-cairo/1.0.0/accounts.mdx
@@ -80,12 +80,12 @@ interoperability with the ecosystem.
The Starknet protocol uses a few entrypoints for abstracting the accounts. We already mentioned the first two
as part of the ISRC6 interface, and both are required for enabling accounts to be used for executing transactions. The rest are optional:
-1. `\\__validate__` verifies the validity of the transaction to be executed. This is usually used to validate signatures,
+1. `__validate__` verifies the validity of the transaction to be executed. This is usually used to validate signatures,
but the entrypoint implementation can be customized to feature any validation mechanism [with some limitations](https://docs.starknet.io/architecture-and-concepts/accounts/account-functions/#limitations_of_validation).
-2. `\\__execute__` executes the transaction if the validation is successful.
-3. `\\__validate_declare__` optional entrypoint similar to `\\__validate__` but for transactions
+2. `__execute__` executes the transaction if the validation is successful.
+3. `__validate_declare__` optional entrypoint similar to `__validate__` but for transactions
meant to declare other contracts.
-4. `\\__validate_deploy__` optional entrypoint similar to `\\__validate__` but meant for [counterfactual deployments](/guides/deployment).
+4. `__validate_deploy__` optional entrypoint similar to `__validate__` but meant for [counterfactual deployments](/guides/deployment).
Although these entrypoints are available to the protocol for its regular transaction flow, they can also be called like any other method.
@@ -275,7 +275,7 @@ wraps and exposes the `deploy_syscall` to provide arbitrary deployments through
But if you don’t have an account to invoke it, you will probably want to use the latter.
To do counterfactual deployments, you need to implement another protocol-level entrypoint named
-`\\__validate_deploy__`. Check the [counterfactual deployments](/guides/deployment) guide to learn how.
+`__validate_deploy__`. Check the [counterfactual deployments](/guides/deployment) guide to learn how.
## Sending transactions
@@ -285,7 +285,7 @@ Let’s now explore how to send transactions through these accounts.
First, let’s take the example account we created before and deploy it:
-```[,cairo]
+```rust
#[starknet::contract(account)]
mod MyAccount {
use openzeppelin_account::AccountComponent;
@@ -333,7 +333,7 @@ The flag enables custom account variants.
The following examples use `sncast` [v0.23.0](https://github.com/foundry-rs/starknet-foundry/releases/tag/v0.23.0).
-```[,bash]
+```bash
$ sncast \
--url http://127.0.0.1:5050 \
account create \
@@ -344,7 +344,7 @@ $ sncast \
This command will output the precomputed contract address and the recommended `max-fee`.
To counterfactually deploy the account, send funds to the address and then deploy the custom account.
-```[,bash]
+```bash
$ sncast \
--url http://127.0.0.1:5050 \
account deploy \
@@ -353,7 +353,7 @@ $ sncast \
Once the account is deployed, set the `--account` flag with the custom account name to send transactions from that account.
-```[,bash]
+```bash
$ sncast \
--account my-custom-account \
--url http://127.0.0.1:5050 \
@@ -367,7 +367,7 @@ $ sncast \
First, let’s take the example account we created before and deploy it:
-```[,cairo]
+```rust
#[starknet::contract(account)]
mod MyEthAccount {
use openzeppelin_account::EthAccountComponent;
@@ -417,7 +417,7 @@ Next, precompute the EthAccount contract address using the declared class hash.
The following examples use unreleased features from StarknetJS (`starknetjs@next`) at commit [d002baea0abc1de3ac6e87a671f3dec3757437b3](https://github.com/starknet-io/starknet.js/commit/d002baea0abc1de3ac6e87a671f3dec3757437b3).
-```[,javascript]
+```javascript
import * as dotenv from 'dotenv';
import { CallData, EthSigner, hash } from 'starknet';
import { ABI as ETH_ABI } from '../abis/eth_account.js';
@@ -443,7 +443,7 @@ console.log('Pre-calculated EthAccount address: ', ethContractAddress);
Send funds to the pre-calculated EthAccount address and deploy the contract.
-```[,javascript]
+```javascript
import * as dotenv from 'dotenv';
import { Account, CallData, EthSigner, RpcProvider, stark } from 'starknet';
import { ABI as ETH_ABI } from '../abis/eth_account.js';
@@ -479,7 +479,7 @@ console.log('EthAccount deployed at: ', contract_address);
Once deployed, connect the EthAccount instance to the target contract which enables calls to come from the EthAccount.
Here’s what an ERC20 transfer from an EthAccount looks like.
-```[,javascript]
+```javascript
import * as dotenv from 'dotenv';
import { Account, RpcProvider, Contract, EthSigner } from 'starknet';
dotenv.config();
diff --git a/content/contracts-cairo/1.0.0/erc1155.mdx b/content/contracts-cairo/1.0.0/erc1155.mdx
index fc9e615..7bcace8 100644
--- a/content/contracts-cairo/1.0.0/erc1155.mdx
+++ b/content/contracts-cairo/1.0.0/erc1155.mdx
@@ -79,7 +79,7 @@ mod MyERC1155 {
The following interface represents the full ABI of the Contracts for Cairo [ERC1155Component](/api/erc1155#ERC1155Component).
The interface includes the [IERC1155](/api/erc1155#IERC1155) standard interface and the optional [IERC1155MetadataURI](/api/erc1155#IERC1155MetadataURI) interface together with [ISRC5](/api/introspection#ISRC5).
-To support older token deployments, as mentioned in [Dual interfaces](interfaces#dual_interfaces), the component also includes implementations of the interface written in camelCase.
+To support older token deployments, as mentioned in [Dual interfaces](guides/interfaces-and-dispatchers#dual-interfaces), the component also includes implementations of the interface written in camelCase.
```cairo
#[starknet::interface]
@@ -156,7 +156,7 @@ In the spirit of the standard, we’ve also included batch operations in the non
While [safe_transfer_from](/api/erc1155#IERC1155-safe_transfer_from) and [safe_batch_transfer_from](/api/erc1155#IERC1155-safe_batch_transfer_from) prevent loss by checking the receiver can handle the
-tokens, this yields execution to the receiver which can result in a [reentrant call](security#reentrancy_guard).
+tokens, this yields execution to the receiver which can result in a [reentrant call](security#reentrancy-guard).
## Receiving tokens
@@ -190,7 +190,7 @@ When [safe_transfer_from](/api/erc1155#IERC1155-safe_transfer_from) and [safe_ba
Otherwise, the transaction will fail.
-For information on how to calculate interface IDs, see [Computing the interface ID](introspection#computing_the_interface_id).
+For information on how to calculate interface IDs, see [Computing the interface ID](introspection#computing-the-interface-id).
### Creating a token receiver contract
diff --git a/content/contracts-cairo/1.0.0/erc20.mdx b/content/contracts-cairo/1.0.0/erc20.mdx
index 0934eeb..aaaca17 100644
--- a/content/contracts-cairo/1.0.0/erc20.mdx
+++ b/content/contracts-cairo/1.0.0/erc20.mdx
@@ -71,7 +71,7 @@ For a more complete guide on ERC20 token mechanisms, see [Creating ERC20 Supply]
The following interface represents the full ABI of the Contracts for Cairo [ERC20Component](/api/erc20#ERC20Component).
The interface includes the [IERC20](/api/erc20#IERC20) standard interface as well as the optional [IERC20Metadata](/api/erc20#IERC20Metadata).
-To support older token deployments, as mentioned in [Dual interfaces](/interfaces#dual_interfaces), the component also includes an implementation of the interface written in camelCase.
+To support older token deployments, as mentioned in [Dual interfaces](/guides/interfaces-and-dispatchers#dual-interfaces), the component also includes an implementation of the interface written in camelCase.
```cairo
#[starknet::interface]
@@ -106,7 +106,7 @@ Although Starknet is not EVM compatible, this component aims to be as close as p
Some notable differences, however, can still be found, such as:
* The `ByteArray` type is used to represent strings in Cairo.
-* The component offers a [dual interface](/interfaces#dual_interfaces) which supports both snake_case and camelCase methods, as opposed to just camelCase in Solidity.
+* The component offers a [dual interface](/guides/interfaces-and-dispatchers#dual-interfaces) which supports both snake_case and camelCase methods, as opposed to just camelCase in Solidity.
* `transfer`, `transfer_from` and `approve` will never return anything different from `true` because they will revert on any error.
* Function selectors are calculated differently between [Cairo](https://github.com/starkware-libs/cairo/blob/7dd34f6c57b7baf5cd5a30c15e00af39cb26f7e1/crates/cairo-lang-starknet/src/contract.rs#L39-L48) and [Solidity](https://solidity-by-example.org/function-selector/).
diff --git a/content/contracts-cairo/1.0.0/erc721.mdx b/content/contracts-cairo/1.0.0/erc721.mdx
index 71bf8a4..d41e2f5 100644
--- a/content/contracts-cairo/1.0.0/erc721.mdx
+++ b/content/contracts-cairo/1.0.0/erc721.mdx
@@ -64,7 +64,7 @@ mod MyNFT {
The following interface represents the full ABI of the Contracts for Cairo [ERC721Component](/api/erc721#ERC721Component).
The interface includes the [IERC721](/api/erc721#IERC721) standard interface and the optional [IERC721Metadata](/api/erc721#IERC721Metadata) interface.
-To support older token deployments, as mentioned in [Dual interfaces](interfaces#dual_interfaces), the component also includes implementations of the interface written in camelCase.
+To support older token deployments, as mentioned in [Dual interfaces](guides/interfaces-and-dispatchers#dual-interfaces), the component also includes implementations of the interface written in camelCase.
```cairo
#[starknet::interface]
@@ -158,7 +158,7 @@ When safe methods such as [safe_transfer_from](api/erc721#IERC721-safe_transfer_
Otherwise, the transaction will fail.
-For information on how to calculate interface IDs, see [Computing the interface ID](introspection#computing_the_interface_id).
+For information on how to calculate interface IDs, see [Computing the interface ID](introspection#computing-the-interface-id).
### Creating a token receiver contract
diff --git a/content/contracts-cairo/1.0.0/guides/deployment.mdx b/content/contracts-cairo/1.0.0/guides/deployment.mdx
index ead0e80..b3e320e 100644
--- a/content/contracts-cairo/1.0.0/guides/deployment.mdx
+++ b/content/contracts-cairo/1.0.0/guides/deployment.mdx
@@ -18,7 +18,7 @@ Note that the `class_hash` must be previously declared for the deployment to suc
2. Send funds to the `contract_address`. Usually you will estimate the fee of the transaction first. Existing
tools usually do this for you.
3. Send a `DeployAccount` type transaction to the network.
-4. The protocol will then validate the transaction with the `\\__validate_deploy__` entrypoint of the contract to be deployed.
+4. The protocol will then validate the transaction with the `__validate_deploy__` entrypoint of the contract to be deployed.
5. If the validation succeeds, the protocol will charge the fee and then register the contract as deployed.
@@ -27,7 +27,7 @@ Although this method is very popular to deploy accounts, this works for any kind
## Deployment validation
-To be counterfactually deployed, the deploying contract must implement the `\\__validate_deploy__` entrypoint,
+To be counterfactually deployed, the deploying contract must implement the `__validate_deploy__` entrypoint,
called by the protocol when a `DeployAccount` transaction is sent to the network.
```cairo
diff --git a/content/contracts-cairo/1.0.0/upgrades.mdx b/content/contracts-cairo/1.0.0/upgrades.mdx
index be008be..2cb3663 100644
--- a/content/contracts-cairo/1.0.0/upgrades.mdx
+++ b/content/contracts-cairo/1.0.0/upgrades.mdx
@@ -4,7 +4,7 @@ title: Upgrades
In different blockchains, multiple patterns have been developed for making a contract upgradeable including the widely adopted proxy patterns.
-Starknet has native upgradeability through a syscall that updates the contract source code, removing [the need for proxies](#proxies_in_starknet).
+Starknet has native upgradeability through a syscall that updates the contract source code, removing [the need for proxies](#proxies-in-starknet).
Make sure you follow [our security recommendations](#security) before upgrading.
@@ -39,7 +39,7 @@ OpenZeppelin Contracts for Cairo provides [Upgradeable](https://github.com/OpenZ
### Usage
Upgrades are often very sensitive operations, and some form of access control is usually required to
-avoid unauthorized upgrades. The [Ownable](access#ownership_and_ownable) module is used in this example.
+avoid unauthorized upgrades. The [Ownable](access#ownership-and-ownable) module is used in this example.
We will be using the following module to implement the [IUpgradeable](api/upgrades#IUpgradeable) interface described in the API Reference section.
diff --git a/content/contracts-cairo/1.0.0/utils/_class_hashes.mdx b/content/contracts-cairo/1.0.0/utils/_class_hashes.mdx
deleted file mode 100644
index 57d019e..0000000
--- a/content/contracts-cairo/1.0.0/utils/_class_hashes.mdx
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: _class_hashes
----
-
diff --git a/content/contracts-cairo/1.0.0/utils/_common.mdx b/content/contracts-cairo/1.0.0/utils/_common.mdx
deleted file mode 100644
index 41f52f6..0000000
--- a/content/contracts-cairo/1.0.0/utils/_common.mdx
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: _common
----
-
diff --git a/content/contracts-cairo/2.0.0/accounts.mdx b/content/contracts-cairo/2.0.0/accounts.mdx
index 417dda8..6775d14 100644
--- a/content/contracts-cairo/2.0.0/accounts.mdx
+++ b/content/contracts-cairo/2.0.0/accounts.mdx
@@ -80,12 +80,12 @@ interoperability with the ecosystem.
The Starknet protocol uses a few entrypoints for abstracting the accounts. We already mentioned the first two
as part of the ISRC6 interface, and both are required for enabling accounts to be used for executing transactions. The rest are optional:
-1. `\\__validate__` verifies the validity of the transaction to be executed. This is usually used to validate signatures,
+1. `__validate__` verifies the validity of the transaction to be executed. This is usually used to validate signatures,
but the entrypoint implementation can be customized to feature any validation mechanism [with some limitations](https://docs.starknet.io/architecture-and-concepts/accounts/account-functions/#limitations_of_validation).
-2. `\\__execute__` executes the transaction if the validation is successful.
-3. `\\__validate_declare__` optional entrypoint similar to `\\__validate__` but for transactions
+2. `__execute__` executes the transaction if the validation is successful.
+3. `__validate_declare__` optional entrypoint similar to `__validate__` but for transactions
meant to declare other contracts.
-4. `\\__validate_deploy__` optional entrypoint similar to `\\__validate__` but meant for [counterfactual deployments](/guides/deployment).
+4. `__validate_deploy__` optional entrypoint similar to `__validate__` but meant for [counterfactual deployments](/guides/deployment).
Although these entrypoints are available to the protocol for its regular transaction flow, they can also be called like any other method.
@@ -275,7 +275,7 @@ wraps and exposes the `deploy_syscall` to provide arbitrary deployments through
But if you don’t have an account to invoke it, you will probably want to use the latter.
To do counterfactual deployments, you need to implement another protocol-level entrypoint named
-`\\__validate_deploy__`. Check the [counterfactual deployments](/guides/deployment) guide to learn how.
+`__validate_deploy__`. Check the [counterfactual deployments](/guides/deployment) guide to learn how.
## Sending transactions
@@ -285,7 +285,7 @@ Let’s now explore how to send transactions through these accounts.
First, let’s take the example account we created before and deploy it:
-```[,cairo]
+```rust
#[starknet::contract(account)]
mod MyAccount {
use openzeppelin_account::AccountComponent;
@@ -333,7 +333,7 @@ The flag enables custom account variants.
The following examples use `sncast` [v0.23.0](https://github.com/foundry-rs/starknet-foundry/releases/tag/v0.23.0).
-```[,bash]
+```bash
$ sncast \
--url http://127.0.0.1:5050 \
account create \
@@ -344,7 +344,7 @@ $ sncast \
This command will output the precomputed contract address and the recommended `max-fee`.
To counterfactually deploy the account, send funds to the address and then deploy the custom account.
-```[,bash]
+```bash
$ sncast \
--url http://127.0.0.1:5050 \
account deploy \
@@ -353,7 +353,7 @@ $ sncast \
Once the account is deployed, set the `--account` flag with the custom account name to send transactions from that account.
-```[,bash]
+```bash
$ sncast \
--account my-custom-account \
--url http://127.0.0.1:5050 \
@@ -367,7 +367,7 @@ $ sncast \
First, let’s take the example account we created before and deploy it:
-```[,cairo]
+```rust
#[starknet::contract(account)]
mod MyEthAccount {
use openzeppelin_account::EthAccountComponent;
@@ -417,7 +417,7 @@ Next, precompute the EthAccount contract address using the declared class hash.
The following examples use unreleased features from StarknetJS (`starknetjs@next`) at commit [d002baea0abc1de3ac6e87a671f3dec3757437b3](https://github.com/starknet-io/starknet.js/commit/d002baea0abc1de3ac6e87a671f3dec3757437b3).
-```[,javascript]
+```javascript
import * as dotenv from 'dotenv';
import { CallData, EthSigner, hash } from 'starknet';
import { ABI as ETH_ABI } from '../abis/eth_account.js';
@@ -443,7 +443,7 @@ console.log('Pre-calculated EthAccount address: ', ethContractAddress);
Send funds to the pre-calculated EthAccount address and deploy the contract.
-```[,javascript]
+```javascript
import * as dotenv from 'dotenv';
import { Account, CallData, EthSigner, RpcProvider, stark } from 'starknet';
import { ABI as ETH_ABI } from '../abis/eth_account.js';
@@ -479,7 +479,7 @@ console.log('EthAccount deployed at: ', contract_address);
Once deployed, connect the EthAccount instance to the target contract which enables calls to come from the EthAccount.
Here’s what an ERC20 transfer from an EthAccount looks like.
-```[,javascript]
+```javascript
import * as dotenv from 'dotenv';
import { Account, RpcProvider, Contract, EthSigner } from 'starknet';
dotenv.config();
diff --git a/content/contracts-cairo/2.0.0/erc1155.mdx b/content/contracts-cairo/2.0.0/erc1155.mdx
index fc9e615..7bcace8 100644
--- a/content/contracts-cairo/2.0.0/erc1155.mdx
+++ b/content/contracts-cairo/2.0.0/erc1155.mdx
@@ -79,7 +79,7 @@ mod MyERC1155 {
The following interface represents the full ABI of the Contracts for Cairo [ERC1155Component](/api/erc1155#ERC1155Component).
The interface includes the [IERC1155](/api/erc1155#IERC1155) standard interface and the optional [IERC1155MetadataURI](/api/erc1155#IERC1155MetadataURI) interface together with [ISRC5](/api/introspection#ISRC5).
-To support older token deployments, as mentioned in [Dual interfaces](interfaces#dual_interfaces), the component also includes implementations of the interface written in camelCase.
+To support older token deployments, as mentioned in [Dual interfaces](guides/interfaces-and-dispatchers#dual-interfaces), the component also includes implementations of the interface written in camelCase.
```cairo
#[starknet::interface]
@@ -156,7 +156,7 @@ In the spirit of the standard, we’ve also included batch operations in the non
While [safe_transfer_from](/api/erc1155#IERC1155-safe_transfer_from) and [safe_batch_transfer_from](/api/erc1155#IERC1155-safe_batch_transfer_from) prevent loss by checking the receiver can handle the
-tokens, this yields execution to the receiver which can result in a [reentrant call](security#reentrancy_guard).
+tokens, this yields execution to the receiver which can result in a [reentrant call](security#reentrancy-guard).
## Receiving tokens
@@ -190,7 +190,7 @@ When [safe_transfer_from](/api/erc1155#IERC1155-safe_transfer_from) and [safe_ba
Otherwise, the transaction will fail.
-For information on how to calculate interface IDs, see [Computing the interface ID](introspection#computing_the_interface_id).
+For information on how to calculate interface IDs, see [Computing the interface ID](introspection#computing-the-interface-id).
### Creating a token receiver contract
diff --git a/content/contracts-cairo/2.0.0/erc20.mdx b/content/contracts-cairo/2.0.0/erc20.mdx
index a94545d..ce6acc7 100644
--- a/content/contracts-cairo/2.0.0/erc20.mdx
+++ b/content/contracts-cairo/2.0.0/erc20.mdx
@@ -71,7 +71,7 @@ For a more complete guide on ERC20 token mechanisms, see [Creating ERC20 Supply]
The following interface represents the full ABI of the Contracts for Cairo [ERC20Component](/api/erc20#ERC20Component).
The interface includes the [IERC20](/api/erc20#IERC20) standard interface as well as the optional [IERC20Metadata](/api/erc20#IERC20Metadata).
-To support older token deployments, as mentioned in [Dual interfaces](/interfaces#dual_interfaces), the component also includes an implementation of the interface written in camelCase.
+To support older token deployments, as mentioned in [Dual interfaces](/guides/interfaces-and-dispatchers#dual-interfaces), the component also includes an implementation of the interface written in camelCase.
```cairo
#[starknet::interface]
@@ -106,7 +106,7 @@ Although Starknet is not EVM compatible, this component aims to be as close as p
Some notable differences, however, can still be found, such as:
* The `ByteArray` type is used to represent strings in Cairo.
-* The component offers a [dual interface](/interfaces#dual_interfaces) which supports both snake_case and camelCase methods, as opposed to just camelCase in Solidity.
+* The component offers a [dual interface](/guides/interfaces-and-dispatchers#dual-interfaces) which supports both snake_case and camelCase methods, as opposed to just camelCase in Solidity.
* `transfer`, `transfer_from` and `approve` will never return anything different from `true` because they will revert on any error.
* Function selectors are calculated differently between [Cairo](https://github.com/starkware-libs/cairo/blob/7dd34f6c57b7baf5cd5a30c15e00af39cb26f7e1/crates/cairo-lang-starknet/src/contract.rs#L39-L48) and [Solidity](https://solidity-by-example.org/function-selector/).
diff --git a/content/contracts-cairo/2.0.0/erc721.mdx b/content/contracts-cairo/2.0.0/erc721.mdx
index 71bf8a4..d41e2f5 100644
--- a/content/contracts-cairo/2.0.0/erc721.mdx
+++ b/content/contracts-cairo/2.0.0/erc721.mdx
@@ -64,7 +64,7 @@ mod MyNFT {
The following interface represents the full ABI of the Contracts for Cairo [ERC721Component](/api/erc721#ERC721Component).
The interface includes the [IERC721](/api/erc721#IERC721) standard interface and the optional [IERC721Metadata](/api/erc721#IERC721Metadata) interface.
-To support older token deployments, as mentioned in [Dual interfaces](interfaces#dual_interfaces), the component also includes implementations of the interface written in camelCase.
+To support older token deployments, as mentioned in [Dual interfaces](guides/interfaces-and-dispatchers#dual-interfaces), the component also includes implementations of the interface written in camelCase.
```cairo
#[starknet::interface]
@@ -158,7 +158,7 @@ When safe methods such as [safe_transfer_from](api/erc721#IERC721-safe_transfer_
Otherwise, the transaction will fail.
-For information on how to calculate interface IDs, see [Computing the interface ID](introspection#computing_the_interface_id).
+For information on how to calculate interface IDs, see [Computing the interface ID](introspection#computing-the-interface-id).
### Creating a token receiver contract
diff --git a/content/contracts-cairo/2.0.0/guides/deployment.mdx b/content/contracts-cairo/2.0.0/guides/deployment.mdx
index ead0e80..b3e320e 100644
--- a/content/contracts-cairo/2.0.0/guides/deployment.mdx
+++ b/content/contracts-cairo/2.0.0/guides/deployment.mdx
@@ -18,7 +18,7 @@ Note that the `class_hash` must be previously declared for the deployment to suc
2. Send funds to the `contract_address`. Usually you will estimate the fee of the transaction first. Existing
tools usually do this for you.
3. Send a `DeployAccount` type transaction to the network.
-4. The protocol will then validate the transaction with the `\\__validate_deploy__` entrypoint of the contract to be deployed.
+4. The protocol will then validate the transaction with the `__validate_deploy__` entrypoint of the contract to be deployed.
5. If the validation succeeds, the protocol will charge the fee and then register the contract as deployed.
@@ -27,7 +27,7 @@ Although this method is very popular to deploy accounts, this works for any kind
## Deployment validation
-To be counterfactually deployed, the deploying contract must implement the `\\__validate_deploy__` entrypoint,
+To be counterfactually deployed, the deploying contract must implement the `__validate_deploy__` entrypoint,
called by the protocol when a `DeployAccount` transaction is sent to the network.
```cairo
diff --git a/content/contracts-cairo/2.0.0/upgrades.mdx b/content/contracts-cairo/2.0.0/upgrades.mdx
index 0a53a66..1bb074f 100644
--- a/content/contracts-cairo/2.0.0/upgrades.mdx
+++ b/content/contracts-cairo/2.0.0/upgrades.mdx
@@ -4,7 +4,7 @@ title: Upgrades
In different blockchains, multiple patterns have been developed for making a contract upgradeable including the widely adopted proxy patterns.
-Starknet has native upgradeability through a syscall that updates the contract source code, removing [the need for proxies](#proxies_in_starknet).
+Starknet has native upgradeability through a syscall that updates the contract source code, removing [the need for proxies](#proxies-in-starknet).
Make sure you follow [our security recommendations](#security) before upgrading.
@@ -39,7 +39,7 @@ OpenZeppelin Contracts for Cairo provides [Upgradeable](https://github.com/OpenZ
### Usage
Upgrades are often very sensitive operations, and some form of access control is usually required to
-avoid unauthorized upgrades. The [Ownable](access#ownership_and_ownable) module is used in this example.
+avoid unauthorized upgrades. The [Ownable](access#ownership-and-ownable) module is used in this example.
We will be using the following module to implement the [IUpgradeable](api/upgrades#IUpgradeable) interface described in the API Reference section.
diff --git a/content/contracts-cairo/access.mdx b/content/contracts-cairo/access.mdx
index 21cfc25..4c8d1da 100644
--- a/content/contracts-cairo/access.mdx
+++ b/content/contracts-cairo/access.mdx
@@ -19,7 +19,7 @@ OpenZeppelin Contracts for Cairo provides [OwnableComponent](api/access#OwnableC
Integrating this component into a contract first requires assigning an owner.
The implementing contract’s constructor should set the initial owner by passing the owner’s address to Ownable’s
-[`initializer`](/api/access#OwnableComponent-initializer) like this:
+[`initializer`](api/access#OwnableComponent-initializer) like this:
```rust
#[starknet::contract]
@@ -100,13 +100,13 @@ after an initial stage with centralized administration is over.
Removing the owner altogether will mean that administrative tasks that are protected by `assert_only_owner`
-
will no longer be callable!
+
### Two step transfer
The component also offers a more robust way of transferring ownership via the
-[OwnableTwoStepImpl](/api/access#OwnableTwoStepImpl) implementation. A two step transfer mechanism helps
+[OwnableTwoStepImpl](api/access#OwnableComponent-Embeddable-Impls-OwnableTwoStepImpl) implementation. A two step transfer mechanism helps
to prevent unintended and irreversible owner transfers. Simply replace the `OwnableMixinImpl`
with its respective two step variant:
@@ -146,7 +146,7 @@ flexibility in this regard.
In essence, we will be defining multiple roles, each allowed to perform different sets of actions.
An account may have, for example, 'moderator', 'minter' or 'admin' roles, which you will then check for
-instead of simply using [`assert_only_owner`](/api/access#OwnableComponent-assert_only_owner). This check can be enforced through [`assert_only_role`](/api/access#AccessControlComponent-assert_only_role).
+instead of simply using [`assert_only_owner`](api/access#OwnableComponent-assert_only_owner). This check can be enforced through [`assert_only_role`](api/access#AccessControlComponent-assert_only_role).
Separately, you will be able to define rules for how accounts can be granted a role, have it revoked, and more.
Most software uses access control systems that are role-based: some users are regular users, some may be supervisors
@@ -155,7 +155,7 @@ or managers, and a few will often have administrative privileges.
### Usage
For each role that you want to define, you will create a new _role identifier_ that is used to grant, revoke, and
-check if an account has that role. See [Creating role identifiers](#creating_role_identifiers) for information
+check if an account has that role. See [Creating role identifiers](#creating-role-identifiers) for information
on creating identifiers.
Here’s a simple example of implementing [AccessControl](api/access#AccessControlComponent) on a portion of an ERC20 token contract which defines
@@ -243,8 +243,8 @@ mod MyContract {
Make sure you fully understand how [AccessControl](api/access#AccessControlComponent) works before
-
using it on your system, or copy-pasting the examples from this guide.
+
While clear and explicit, this isn’t anything we wouldn’t have been able to achieve with
[Ownable](api/access#OwnableComponent). Where [AccessControl](api/access#AccessControlComponent) shines the most is in scenarios where granular
@@ -447,8 +447,8 @@ mod MyContract {
The `grant_role` and `revoke_role` functions are automatically exposed as `external` functions
-
from the `AccessControlImpl` by leveraging the `#[abi(embed_v0)]` annotation.
+
Note that, unlike the previous examples, no accounts are granted the 'minter' or 'burner' roles.
However, because those roles' admin role is the default admin role, and that role was granted to the 'admin', that
diff --git a/content/contracts-cairo/accounts.mdx b/content/contracts-cairo/accounts.mdx
index 5e24167..48b399d 100644
--- a/content/contracts-cairo/accounts.mdx
+++ b/content/contracts-cairo/accounts.mdx
@@ -13,7 +13,7 @@ A more detailed discussion on the topic can be found in
[Starknet Shaman’s forum](https://community.starknet.io/t/starknet-account-abstraction-model-part-1/781).
-For detailed information on the usage and implementation check the [API Reference](/api/account) section.
+For detailed information on the usage and implementation check the [API Reference](api/account) section.
## What is an account?
@@ -50,8 +50,8 @@ pub trait ISRC6 {
The `calldata` member of the `Call` struct in the accounts has been updated to `Span` for optimization
-
purposes, but the interface ID remains the same for backwards compatibility. This inconsistency will be fixed in future releases.
+
[SNIP-6](https://github.com/starknet-io/SNIPs/blob/main/SNIPS/snip-6.md) adds the `is_valid_signature` method. This method is not used by the protocol, but it’s useful for
DApps to verify the validity of signatures, supporting features like Sign In with Starknet.
@@ -80,12 +80,12 @@ interoperability with the ecosystem.
The Starknet protocol uses a few entrypoints for abstracting the accounts. We already mentioned the first two
as part of the ISRC6 interface, and both are required for enabling accounts to be used for executing transactions. The rest are optional:
-1. `\\__validate__` verifies the validity of the transaction to be executed. This is usually used to validate signatures,
+1. `__validate__` verifies the validity of the transaction to be executed. This is usually used to validate signatures,
but the entrypoint implementation can be customized to feature any validation mechanism [with some limitations](https://docs.starknet.io/architecture-and-concepts/accounts/account-functions/#limitations_of_validation).
-2. `\\__execute__` executes the transaction if the validation is successful.
-3. `\\__validate_declare__` optional entrypoint similar to `\\__validate__` but for transactions
+2. `__execute__` executes the transaction if the validation is successful.
+3. `__validate_declare__` optional entrypoint similar to `__validate__` but for transactions
meant to declare other contracts.
-4. `\\__validate_deploy__` optional entrypoint similar to `\\__validate__` but meant for [counterfactual deployments](/guides/deployment).
+4. `__validate_deploy__` optional entrypoint similar to `__validate__` but meant for [counterfactual deployments](guides/deployment).
Although these entrypoints are available to the protocol for its regular transaction flow, they can also be called like any other method.
@@ -97,11 +97,11 @@ Starknet native account abstraction pattern allows for the creation of custom ac
usually most account implementations validate transactions using the [Stark curve](https://docs.starknet.io/architecture-and-concepts/cryptography/#stark-curve) which is the most efficient way
of validating signatures since it is a STARK-friendly curve.
-OpenZeppelin Contracts for Cairo provides [AccountComponent](/api/account#AccountComponent) for implementing this validation scheme.
+OpenZeppelin Contracts for Cairo provides [AccountComponent](api/account#AccountComponent) for implementing this validation scheme.
### Usage
-Constructing an account contract requires integrating both [AccountComponent](/api/account#AccountComponent) and [SRC5Component](/api/introspection#SRC5Component). The contract should also set up the constructor to initialize the public key that will be used as the account’s signer. Here’s an example of a basic contract:
+Constructing an account contract requires integrating both [AccountComponent](api/account#AccountComponent) and [SRC5Component](api/introspection#SRC5Component). The contract should also set up the constructor to initialize the public key that will be used as the account’s signer. Here’s an example of a basic contract:
```rust
#[starknet::contract(account)]
@@ -180,11 +180,11 @@ pub trait AccountABI {
## Ethereum Account
Besides the Stark-curve account, OpenZeppelin Contracts for Cairo also offers Ethereum-flavored accounts that use the [secp256k1](https://en.bitcoin.it/wiki/Secp256k1) curve for signature validation.
-For this the [EthAccountComponent](/api/account#EthAccountComponent) must be used.
+For this the [EthAccountComponent](api/account#EthAccountComponent) must be used.
### Usage
-Constructing a secp256k1 account contract also requires integrating both [EthAccountComponent](/api/account#EthAccountComponent) and [SRC5Component](/api/introspection#SRC5Component).
+Constructing a secp256k1 account contract also requires integrating both [EthAccountComponent](api/account#EthAccountComponent) and [SRC5Component](api/introspection#SRC5Component).
The contract should also set up the constructor to initialize the public key that will be used as the account’s signer.
Here’s an example of a basic contract:
@@ -275,7 +275,7 @@ wraps and exposes the `deploy_syscall` to provide arbitrary deployments through
But if you don’t have an account to invoke it, you will probably want to use the latter.
To do counterfactual deployments, you need to implement another protocol-level entrypoint named
-`\\__validate_deploy__`. Check the [counterfactual deployments](/guides/deployment) guide to learn how.
+`__validate_deploy__`. Check the [counterfactual deployments](guides/deployment) guide to learn how.
## Sending transactions
@@ -285,7 +285,7 @@ Let’s now explore how to send transactions through these accounts.
First, let’s take the example account we created before and deploy it:
-```[,cairo]
+```rust
#[starknet::contract(account)]
mod MyAccount {
use openzeppelin_account::AccountComponent;
@@ -333,7 +333,7 @@ The flag enables custom account variants.
The following examples use `sncast` [v0.23.0](https://github.com/foundry-rs/starknet-foundry/releases/tag/v0.23.0).
-```[,bash]
+```bash
$ sncast \
--url http://127.0.0.1:5050 \
account create \
@@ -344,7 +344,7 @@ $ sncast \
This command will output the precomputed contract address and the recommended `max-fee`.
To counterfactually deploy the account, send funds to the address and then deploy the custom account.
-```[,bash]
+```bash
$ sncast \
--url http://127.0.0.1:5050 \
account deploy \
@@ -353,7 +353,7 @@ $ sncast \
Once the account is deployed, set the `--account` flag with the custom account name to send transactions from that account.
-```[,bash]
+```bash
$ sncast \
--account my-custom-account \
--url http://127.0.0.1:5050 \
@@ -367,7 +367,7 @@ $ sncast \
First, let’s take the example account we created before and deploy it:
-```[,cairo]
+```rust
#[starknet::contract(account)]
mod MyEthAccount {
use openzeppelin_account::EthAccountComponent;
@@ -417,7 +417,7 @@ Next, precompute the EthAccount contract address using the declared class hash.
The following examples use unreleased features from StarknetJS (`starknetjs@next`) at commit [d002baea0abc1de3ac6e87a671f3dec3757437b3](https://github.com/starknet-io/starknet.js/commit/d002baea0abc1de3ac6e87a671f3dec3757437b3).
-```[,javascript]
+```javascript
import * as dotenv from 'dotenv';
import { CallData, EthSigner, hash } from 'starknet';
import { ABI as ETH_ABI } from '../abis/eth_account.js';
@@ -443,7 +443,7 @@ console.log('Pre-calculated EthAccount address: ', ethContractAddress);
Send funds to the pre-calculated EthAccount address and deploy the contract.
-```[,javascript]
+```javascript
import * as dotenv from 'dotenv';
import { Account, CallData, EthSigner, RpcProvider, stark } from 'starknet';
import { ABI as ETH_ABI } from '../abis/eth_account.js';
@@ -479,7 +479,7 @@ console.log('EthAccount deployed at: ', contract_address);
Once deployed, connect the EthAccount instance to the target contract which enables calls to come from the EthAccount.
Here’s what an ERC20 transfer from an EthAccount looks like.
-```[,javascript]
+```javascript
import * as dotenv from 'dotenv';
import { Account, RpcProvider, Contract, EthSigner } from 'starknet';
dotenv.config();
diff --git a/content/contracts-cairo/api/access.mdx b/content/contracts-cairo/api/access.mdx
index 096c555..0063a67 100644
--- a/content/contracts-cairo/api/access.mdx
+++ b/content/contracts-cairo/api/access.mdx
@@ -7,11 +7,20 @@ This crate provides ways to restrict who can access the functions of a contract
- [Ownable](#OwnableComponent) is a simple mechanism with a single "owner" role that can be assigned to a single account. This mechanism can be useful in simple scenarios, but fine grained access needs are likely to outgrow it.
- [AccessControl](#AccessControlComponent) provides a general role based access control mechanism. Multiple hierarchical roles can be created and assigned each to multiple accounts.
-## [](#interfaces)Interfaces
+## Interfaces
-Starting from version `3.x.x`, the interfaces are no longer part of the `openzeppelin_access` package. The references documented here are contained in the `openzeppelin_interfaces` package version `v2.1.0`.
+
+Starting from version `3.x.x`, the interfaces are no longer part of the `openzeppelin_access` package. The references
+documented here are contained in the `openzeppelin_interfaces` package version `{{openzeppelin_interfaces_version}}`.
+
-### [](#IAccessControl)`IAccessControl`[](https://github.com/OpenZeppelin/cairo-contracts/blob/release-v3.0.0-alpha.1/packages/interfaces/src/access/accesscontrol.cairo)
+import { UMBRELLA_VERSION } from "../utils/constants.js";
+
+### `IAccessControl` [toc] [#IAccessControl]
+
```rust
use openzeppelin_interfaces::accesscontrol::IAccessControl;
@@ -21,7 +30,9 @@ External interface of AccessControl.
[SRC5 ID](introspection#ISRC5)
+```text
0x23700be02858dbe2ac4dc9c9f66d0b6b0ed81ec7f970ca6844500a56ff61751
+```
Functions
@@ -37,20 +48,32 @@ Events
- [`RoleGranted(role, account, sender)`](#IAccessControl-RoleGranted)
- [`RoleRevoked(role, account, sender)`](#IAccessControl-RoleRevoked)
-#### [](#IAccessControl-Functions)Functions
-#### [](#IAccessControl-has_role)`has_role(role: felt252, account: ContractAddress) → bool` external
+#### Functions [!toc] [#IAccessControl-Functions]
+
Returns whether `account` can act as `role`.
+
-#### [](#IAccessControl-get_role_admin)`get_role_admin(role: felt252) → felt252` external
-
+
Returns the admin role that controls `role`. See [grant\_role](#IAccessControl-grant_role) and [revoke\_role](#IAccessControl-revoke_role).
To change a role’s admin, use [set\_role\_admin](#AccessControlComponent-set_role_admin).
+
-#### [](#IAccessControl-grant_role)`grant_role(role: felt252, account: ContractAddress)` external
-
+
Grants `role` to `account`.
If `account` had not been already granted `role`, emits a [RoleGranted](#IAccessControl-RoleGranted) event.
@@ -58,9 +81,13 @@ If `account` had not been already granted `role`, emits a [RoleGranted](#IAccess
Requirements:
- the caller must have `role`'s admin role.
+
-#### [](#IAccessControl-revoke_role)`revoke_role(role: felt252, account: ContractAddress)` external
-
+
Revokes `role` from `account`.
If `account` had been granted `role`, emits a [RoleRevoked](#IAccessControl-RoleRevoked) event.
@@ -68,9 +95,13 @@ If `account` had been granted `role`, emits a [RoleRevoked](#IAccessControl-Role
Requirements:
- the caller must have `role`'s admin role.
+
-#### [](#IAccessControl-renounce_role)`renounce_role(role: felt252, account: ContractAddress)` external
-
+
Revokes `role` from the calling account.
Roles are often managed via [grant\_role](#IAccessControl-grant_role) and [revoke\_role](#IAccessControl-revoke_role). This function’s purpose is to provide a mechanism for accounts to lose their privileges if they are compromised (such as when a trusted device is misplaced).
@@ -80,31 +111,48 @@ If the calling account had been granted `role`, emits a [RoleRevoked](#IAccessCo
Requirements:
- the caller must be `account`.
+
-#### [](#IAccessControl-Events)Events
-
-#### [](#IAccessControl-RoleAdminChanged)`RoleAdminChanged(role: felt252, previous_admin_role: ContractAddress, new_admin_role: ContractAddress)` event
+#### Events [!toc] [#IAccessControl-Events]
+
Emitted when `new_admin_role` is set as `role`'s admin role, replacing `previous_admin_role`
`DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite [RoleAdminChanged](#IAccessControl-RoleAdminChanged) not being emitted signaling this.
+
-#### [](#IAccessControl-RoleGranted)`RoleGranted(role: felt252, account: ContractAddress, sender: ContractAddress)` event
-
+
Emitted when `account` is granted `role`.
`sender` is the account that originated the contract call, an account with the admin role or the deployer address if `_grant_role` is called from the constructor.
+
-#### [](#IAccessControl-RoleRevoked)`RoleRevoked(role: felt252, account: ContractAddress, sender: ContractAddress)` event
-
+
Emitted when `account` is revoked `role`.
`sender` is the account that originated the contract call:
- if using `revoke_role`, it is the admin role bearer.
- if using `renounce_role`, it is the role bearer (i.e. `account`).
+
-### [](#IAccessControlWithDelay)`IAccessControlWithDelay`[](https://github.com/OpenZeppelin/cairo-contracts/blob/release-v3.0.0-alpha.1/packages/interfaces/src/access/accesscontrol.cairo)
+### `IAccessControlWithDelay` [toc] [#IAccessControlWithDelay]
+
```rust
use openzeppelin_interfaces::accesscontrol::IAccessControlWithDelay;
@@ -121,18 +169,25 @@ Events
- [`RoleGrantedWithDelay(role, account, sender, delay)`](#IAccessControlWithDelay-RoleGrantedWithDelay)
-#### [](#IAccessControlWithDelay-Functions)Functions
-
-#### [](#IAccessControlWithDelay-get_role_status)`get_role_status(role: felt252, account: ContractAddress) → RoleStatus` external
+#### Functions [!toc] [#IAccessControlWithDelay-Functions]
+
Returns the account’s status for the given role. The possible statuses are:
- `NotGranted`: the role has not been granted to the account.
- `Delayed`: The role has been granted to the account but is not yet active due to a time delay.
- `Effective`: the role has been granted to the account and is currently active.
+
-#### [](#IAccessControlWithDelay-grant_role_with_delay)`grant_role_with_delay(role: felt252, account: ContractAddress, delay: u64)` external
-
+
Attempts to grant `role` to `account` with the specified activation delay.
Requirements:
@@ -142,16 +197,25 @@ Requirements:
- the `role` must not be already effective for `account`.
May emit a [RoleGrantedWithDelay](#IAccessControlWithDelay-RoleGrantedWithDelay) event.
+
-#### [](#IAccessControlWithDelay-Events)Events
-
-#### [](#IAccessControlWithDelay-RoleGrantedWithDelay)`RoleGrantedWithDelay(role: felt252, account: ContractAddress, sender: ContractAddress, delay: u64)` event
+#### Events [!toc] [#IAccessControlWithDelay-Events]
+
Emitted when `account` is granted `role` with a delay.
`sender` is the account that originated the contract call, an account with the admin role or the deployer address if [\_grant\_role\_with\_delay](#AccessControlComponent-_grant_role_with_delay) is called from the constructor.
+
-### [](#IAccessControlDefaultAdminRules)`IAccessControlDefaultAdminRules`[](https://github.com/OpenZeppelin/cairo-contracts/blob/release-v3.0.0-alpha.1/packages/interfaces/src/access/accesscontrol_default_admin_rules.cairo)
+### `IAccessControlDefaultAdminRules` [toc] [#IAccessControlDefaultAdminRules]
+
```rust
use openzeppelin_interfaces::accesscontrol_default_admin_rules::IAccessControlDefaultAdminRules;
@@ -161,7 +225,9 @@ External interface of AccessControlDefaultAdminRules declared to support [SRC5](
[SRC5 ID](introspection#ISRC5)
+```text
0x3509b3083c9586afe5dae781146b0608c3846870510f8d4d21ae38676cc33eb
+```
Functions
@@ -183,13 +249,22 @@ Events
- [`DefaultAdminDelayChangeScheduled(new_delay, effect_schedule)`](#IAccessControlDefaultAdminRules-DefaultAdminDelayChangeScheduled)
- [`DefaultAdminDelayChangeCanceled()`](#IAccessControlDefaultAdminRules-DefaultAdminDelayChangeCanceled)
-#### [](#IAccessControlDefaultAdminRules-Functions)Functions
-
-#### [](#IAccessControlDefaultAdminRules-default_admin)`default_admin() → ContractAddress` external
+#### Functions [!toc] [#IAccessControlDefaultAdminRules-Functions]
+
Returns the address of the current `DEFAULT_ADMIN_ROLE` holder.
+
-#### [](#IAccessControlDefaultAdminRules-pending_default_admin)`pending_default_admin() → (ContractAddress, u64)` external
+
+Returns a tuple of a `new_admin` and an `accept_schedule`.
Returns a tuple of a `new_admin` and an `accept_schedule`.
@@ -197,20 +272,32 @@ After the `accept_schedule` passes, the `new_admin` will be able to accept the `
A zero value only in `accept_schedule` indicates no pending admin transfer.
+
A zero address `new_admin` means that `default_admin` is being renounced.
-
-#### [](#IAccessControlDefaultAdminRules-default_admin_delay)`default_admin_delay() → u64` external
-
+
+
+
+
Returns the delay required to schedule the acceptance of a `default_admin` transfer started.
This delay will be added to the current timestamp when calling [begin\_default\_admin\_transfer](#IAccessControlDefaultAdminRules-begin_default_admin_transfer) to set the acceptance schedule.
+
If a delay change has been scheduled, it will take effect as soon as the schedule passes, making this function return the new delay.
+
See [change\_default\_admin\_delay](#IAccessControlDefaultAdminRules-change_default_admin_delay).
+
-#### [](#IAccessControlDefaultAdminRules-pending_default_admin_delay)`pending_default_admin_delay() → (u64, u64)` external
-
+
Returns a tuple of `new_delay` and an `effect_schedule`.
After the `effect_schedule` passes, the `new_delay` will get into effect immediately for every new `default_admin` transfer started with [begin\_default\_admin\_transfer](#IAccessControlDefaultAdminRules-begin_default_admin_transfer).
@@ -218,9 +305,13 @@ After the `effect_schedule` passes, the `new_delay` will get into effect immedia
A zero value only in `effect_schedule` indicates no pending delay change.
A zero value only for `new_delay` means that the next [default\_admin\_delay](#IAccessControlDefaultAdminRules-default_admin_delay) will be zero after the effect schedule.
+
-#### [](#IAccessControlDefaultAdminRules-begin_default_admin_transfer)`begin_default_admin_transfer(new_admin)` external
-
+
Starts a `default_admin` transfer by setting a [pending\_default\_admin](#IAccessControlDefaultAdminRules-pending_default_admin) scheduled for acceptance after the current timestamp plus a [default\_admin\_delay](#IAccessControlDefaultAdminRules-default_admin_delay).
Requirements:
@@ -228,9 +319,13 @@ Requirements:
- Only can be called by the current `default_admin`.
Emits a [DefaultAdminTransferScheduled](#IAccessControlDefaultAdminRules-DefaultAdminTransferScheduled) event.
+
-#### [](#IAccessControlDefaultAdminRules-cancel_default_admin_transfer)`cancel_default_admin_transfer()` external
-
+
Cancels a `default_admin` transfer previously started with [begin\_default\_admin\_transfer](#IAccessControlDefaultAdminRules-begin_default_admin_transfer).
A [pending\_default\_admin](#IAccessControlDefaultAdminRules-pending_default_admin) not yet accepted can also be cancelled with this function.
@@ -240,9 +335,13 @@ Requirements:
- Only can be called by the current `default_admin`.
May emit a [DefaultAdminTransferCanceled](#IAccessControlDefaultAdminRules-DefaultAdminTransferCanceled) event.
+
-#### [](#IAccessControlDefaultAdminRules-accept_default_admin_transfer)`accept_default_admin_transfer()` external
-
+
Completes a `default_admin` transfer previously started with [begin\_default\_admin\_transfer](#IAccessControlDefaultAdminRules-begin_default_admin_transfer).
After calling the function:
@@ -255,9 +354,13 @@ Requirements:
- Only can be called by the [pending\_default\_admin](#IAccessControlDefaultAdminRules-pending_default_admin)'s `new_admin`.
- The [pending\_default\_admin](#IAccessControlDefaultAdminRules-pending_default_admin)'s `accept_schedule` should’ve passed.
+
-#### [](#IAccessControlDefaultAdminRules-change_default_admin_delay)`change_default_admin_delay(new_delay)` external
-
+
Initiates a [default\_admin\_delay](#IAccessControlDefaultAdminRules-default_admin_delay) update by setting a [pending\_default\_admin\_delay](#IAccessControlDefaultAdminRules-pending_default_admin_delay) scheduled to take effect after the current timestamp plus a [default\_admin\_delay](#IAccessControlDefaultAdminRules-default_admin_delay).
This function guarantees that any call to [begin\_default\_admin\_transfer](#IAccessControlDefaultAdminRules-begin_default_admin_transfer) done between the timestamp this method is called and the [pending\_default\_admin\_delay](#IAccessControlDefaultAdminRules-pending_default_admin_delay) effect schedule will use the current [default\_admin\_delay](#IAccessControlDefaultAdminRules-default_admin_delay) set before calling.
@@ -276,8 +379,13 @@ Requirements:
- Only can be called by the current `default_admin`.
Emits a [DefaultAdminDelayChangeScheduled](#IAccessControlDefaultAdminRules-DefaultAdminDelayChangeScheduled) event and may emit a [DefaultAdminDelayChangeCanceled](#IAccessControlDefaultAdminRules-DefaultAdminDelayChangeCanceled) event.
+
-#### [](#IAccessControlDefaultAdminRules-rollback_default_admin_delay)`rollback_default_admin_delay()` external
+
Cancels a scheduled [default\_admin\_delay](#IAccessControlDefaultAdminRules-default_admin_delay) change.
@@ -286,38 +394,59 @@ Requirements:
- Only can be called by the current `default_admin`.
May emit a [DefaultAdminDelayChangeCanceled](#IAccessControlDefaultAdminRules-DefaultAdminDelayChangeCanceled) event.
+
-#### [](#IAccessControlDefaultAdminRules-default_admin_delay_increase_wait)`default_admin_delay_increase_wait() → u64` external
-
+
Maximum time in seconds for an increase to [default\_admin\_delay](#IAccessControlDefaultAdminRules-default_admin_delay) (that is scheduled using [change\_default\_admin\_delay](#IAccessControlDefaultAdminRules-change_default_admin_delay)) to take effect. Defaults to 5 days.
When the [default\_admin\_delay](#IAccessControlDefaultAdminRules-default_admin_delay) is scheduled to be increased, it goes into effect after the new delay has passed with the purpose of giving enough time for reverting any accidental change (i.e. using milliseconds instead of seconds) that may lock the contract. However, to avoid excessive schedules, the wait is capped by this function and it can be overridden for a custom [default\_admin\_delay](#IAccessControlDefaultAdminRules-default_admin_delay) increase scheduling.
Make sure to add a reasonable amount of time while overriding this value, otherwise, there’s a risk of setting a high new delay that goes into effect almost immediately without the possibility of human intervention in the case of an input error (e.g. set milliseconds instead of seconds).
+
-#### [](#IAccessControlDefaultAdminRules-Events)Events
-
-#### [](#IAccessControlDefaultAdminRules-DefaultAdminTransferScheduled)`DefaultAdminTransferScheduled(new_admin: ContractAddress, accept_schedule: u64)` event
+#### Events [!toc] [#IAccessControlDefaultAdminRules-Events]
+
Emitted when a `default_admin` transfer is started.
Sets `new_admin` as the next address to become the `default_admin` by calling [accept\_default\_admin\_transfer](#IAccessControlDefaultAdminRules-accept_default_admin_transfer) only after `accept_schedule` passes.
+
-#### [](#IAccessControlDefaultAdminRules-DefaultAdminTransferCanceled)`DefaultAdminTransferCanceled()` event
-
+
Emitted when a [pending\_default\_admin](#IAccessControlDefaultAdminRules-pending_default_admin) is reset if it was never accepted, regardless of its schedule.
+
-#### [](#IAccessControlDefaultAdminRules-DefaultAdminDelayChangeScheduled)`DefaultAdminDelayChangeScheduled(new_delay: u64, effect_schedule: u64)` event
-
+
Emitted when a [default\_admin\_delay](#IAccessControlDefaultAdminRules-default_admin_delay) change is started.
Sets `new_delay` as the next delay to be applied between default admins transfers after `effect_schedule` has passed.
Emitted when a [pending\_default\_admin\_delay](#IAccessControlDefaultAdminRules-pending_default_admin_delay) is reset if its schedule didn’t pass.
+
-## [](#core)Core
+## Core
-### [](#OwnableComponent)`OwnableComponent`[](https://github.com/OpenZeppelin/cairo-contracts/blob/release-v3.0.0-alpha.1/packages/access/src/ownable/ownable.cairo)
+### `OwnableComponent` [toc] [#OwnableComponent]
+
```rust
use openzeppelin_access::ownable::OwnableComponent;
@@ -329,25 +458,25 @@ This module includes the internal `assert_only_owner` to restrict a function to
[Embeddable Mixin Implementations](../components#mixins)
-OwnableMixinImpl
+#### OwnableMixinImpl [!toc] [#OwnableComponent-Embeddable-Impls-OwnableMixinImpl]
- [`OwnableImpl`](#OwnableComponent-Embeddable-Impls-OwnableImpl)
- [`OwnableCamelOnlyImpl`](#OwnableComponent-Embeddable-Impls-OwnableCamelOnlyImpl)
-OwnableTwoStepMixinImpl
+#### OwnableTwoStepMixinImpl [!toc] [#OwnableComponent-Embeddable-Impls-OwnableTwoStepMixinImpl]
- [`OwnableTwoStepImpl`](#OwnableComponent-Embeddable-Impls-OwnableTwoStepImpl)
- [`OwnableTwoStepCamelOnlyImpl`](#OwnableComponent-Embeddable-Impls-OwnableTwoStepCamelOnlyImpl)
Embeddable Implementations
-OwnableImpl
+#### OwnableImpl [!toc] [#OwnableComponent-Embeddable-Impls-OwnableImpl]
- [`owner(self)`](#OwnableComponent-owner)
- [`transfer_ownership(self, new_owner)`](#OwnableComponent-transfer_ownership)
- [`renounce_ownership(self)`](#OwnableComponent-renounce_ownership)
-OwnableTwoStepImpl
+#### OwnableTwoStepImpl [!toc] [#OwnableComponent-Embeddable-Impls-OwnableTwoStepImpl]
- [`owner(self)`](#OwnableComponent-two-step-owner)
- [`pending_owner(self)`](#OwnableComponent-two-step-pending_owner)
@@ -355,12 +484,12 @@ OwnableTwoStepImpl
- [`transfer_ownership(self, new_owner)`](#OwnableComponent-two-step-transfer_ownership)
- [`renounce_ownership(self)`](#OwnableComponent-two-step-renounce_ownership)
-OwnableCamelOnlyImpl
+#### OwnableCamelOnlyImpl [!toc] [#OwnableComponent-Embeddable-Impls-OwnableCamelOnlyImpl]
- [`transferOwnership(self, newOwner)`](#OwnableComponent-transferOwnership)
- [`renounceOwnership(self)`](#OwnableComponent-renounceOwnership)
-OwnableTwoStepCamelOnlyImpl
+#### OwnableTwoStepCamelOnlyImpl [!toc] [#OwnableComponent-Embeddable-Impls-OwnableTwoStepCamelOnlyImpl]
- [`pendingOwner(self)`](#OwnableComponent-two-step-pendingOwner)
- [`acceptOwnership(self)`](#OwnableComponent-two-step-acceptOwnership)
@@ -369,7 +498,7 @@ OwnableTwoStepCamelOnlyImpl
Internal Implementations
-InternalImpl
+#### InternalImpl [!toc] [#OwnableComponent-InternalImpl]
- [`initializer(self, owner)`](#OwnableComponent-initializer)
- [`assert_only_owner(self)`](#OwnableComponent-assert_only_owner)
@@ -381,82 +510,145 @@ Events
- [`OwnershipTransferStarted(previous_owner, new_owner)`](#OwnableComponent-OwnershipTransferStarted)
- [`OwnershipTransferred(previous_owner, new_owner)`](#OwnableComponent-OwnershipTransferred)
-#### [](#OwnableComponent-Embeddable-Functions)Embeddable functions
-
-#### [](#OwnableComponent-owner)`owner(self: @ContractState) → ContractAddress` external
+#### Embeddable functions [!toc] [#OwnableComponent-Embeddable-Functions]
+
Returns the address of the current owner.
+
-#### [](#OwnableComponent-transfer_ownership)`transfer_ownership(ref self: ContractState, new_owner: ContractAddress)` external
-
+
Transfers ownership of the contract to a new account (`new_owner`). Can only be called by the current owner.
Emits an [OwnershipTransferred](#OwnableComponent-OwnershipTransferred) event.
+
-#### [](#OwnableComponent-renounce_ownership)`renounce_ownership(ref self: ContractState)` external
-
+
Leaves the contract without owner. It will not be possible to call `assert_only_owner` functions anymore. Can only be called by the current owner.
+
Renouncing ownership will leave the contract without an owner, thereby removing any functionality that is only available to the owner.
+
+
-#### [](#OwnableComponent-Embeddable-Functions-Two-Step)Embeddable functions (two step transfer)
-
-#### [](#OwnableComponent-two-step-owner)`owner(self: @ContractState) → ContractAddress` external
+#### Embeddable functions (two step transfer) [!toc] [#OwnableComponent-Embeddable-Functions-Two-Step]
+
Returns the address of the current owner.
+
-#### [](#OwnableComponent-two-step-pending_owner)`pending_owner(self: @ContractState) → ContractAddress` external
-
+
Returns the address of the pending owner.
+
-#### [](#OwnableComponent-two-step-accept_ownership)`accept_ownership(ref self: ContractState)` external
-
+
Transfers ownership of the contract to the pending owner. Can only be called by the pending owner. Resets pending owner to zero address.
Emits an [OwnershipTransferred](#OwnableComponent-OwnershipTransferred) event.
+
-#### [](#OwnableComponent-two-step-transfer_ownership)`transfer_ownership(ref self: ContractState, new_owner: ContractAddress)` external
-
+
Starts the two step ownership transfer process, by setting the pending owner. Setting `new_owner` to the zero address is allowed, this can be used to cancel an initiated ownership transfer.
Can only be called by the current owner.
Emits an [OwnershipTransferStarted](#OwnableComponent-OwnershipTransferStarted) event.
+
-#### [](#OwnableComponent-two-step-renounce_ownership)`renounce_ownership(ref self: ContractState)` external
-
+
Leaves the contract without owner. It will not be possible to call `assert_only_owner` functions anymore. Can only be called by the current owner.
+
Renouncing ownership will leave the contract without an owner, thereby removing any functionality that is only available to the owner.
-
-#### [](#OwnableComponent-transferOwnership)`transferOwnership(ref self: ContractState, newOwner: ContractAddress)` external
-
+
+
+
+
See [transfer\_ownership](#OwnableComponent-transfer_ownership).
+
-#### [](#OwnableComponent-renounceOwnership)`renounceOwnership(ref self: ContractState)` external
-
+
See [renounce\_ownership](#OwnableComponent-renounce_ownership).
+
-#### [](#OwnableComponent-two-step-pendingOwner)`pendingOwner(self: @ContractState)` external
-
+
See [pending\_owner](#OwnableComponent-two-step-pending_owner).
+
-#### [](#OwnableComponent-two-step-acceptOwnership)`acceptOwnership(self: @ContractState)` external
-
+
See [accept\_ownership](#OwnableComponent-two-step-accept_ownership).
+
-#### [](#OwnableComponent-two-step-transferOwnership)`transferOwnership(self: @ContractState)` external
-
+
See [transfer\_ownership](#OwnableComponent-two-step-transfer_ownership).
+
-#### [](#OwnableComponent-two-step-renounceOwnership)`renounceOwnership(self: @ContractState)` external
-
+
See [renounce\_ownership](#OwnableComponent-two-step-renounce_ownership).
+
-#### [](#OwnableComponent-Internal-Functions)Internal functions
-
-#### [](#OwnableComponent-initializer)`initializer(ref self: ContractState, owner: ContractAddress)` internal
+#### Internal functions [!toc] [#OwnableComponent-Internal-Functions]
+
Initializes the contract and sets `owner` as the initial owner.
Requirements:
@@ -464,36 +656,61 @@ Requirements:
- `owner` cannot be the zero address.
Emits an [OwnershipTransferred](#OwnableComponent-OwnershipTransferred) event.
+
-#### [](#OwnableComponent-assert_only_owner)`assert_only_owner(self: @ContractState)` internal
-
+
Panics if called by any account other than the owner.
+
-#### [](#OwnableComponent-_transfer_ownership)`_transfer_ownership(ref self: ContractState, new_owner: ContractAddress)` internal
-
+
Transfers ownership of the contract to a new account (`new_owner`). Internal function without access restriction.
Emits an [OwnershipTransferred](#OwnableComponent-OwnershipTransferred) event.
+
-#### [](#OwnableComponent-_propose_owner)`_propose_owner(ref self: ContractState, new_owner: ContractAddress)` internal
-
+
Sets a new pending owner in a two step transfer.
Internal function without access restriction.
Emits an [OwnershipTransferStarted](#OwnableComponent-OwnershipTransferStarted) event.
+
-#### [](#OwnableComponent-Events)Events
-
-#### [](#OwnableComponent-OwnershipTransferStarted)`OwnershipTransferStarted(previous_owner: ContractAddress, new_owner: ContractAddress)` event
+#### Events [!toc] [#OwnableComponent-Events]
+
Emitted when the pending owner is updated.
+
-#### [](#OwnableComponent-OwnershipTransferred)`OwnershipTransferred(previous_owner: ContractAddress, new_owner: ContractAddress)` event
-
+
Emitted when the ownership is transferred.
+
-### [](#AccessControlComponent)`AccessControlComponent`[](https://github.com/OpenZeppelin/cairo-contracts/blob/release-v3.0.0-alpha.1/packages/access/src/accesscontrol/accesscontrol.cairo)
+### `AccessControlComponent` [toc] [#AccessControlComponent]
+
```rust
use openzeppelin_access::accesscontrol::AccessControlComponent;
@@ -522,11 +739,13 @@ Roles can be granted and revoked dynamically via the [grant\_role](#AccessContro
By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means that only accounts with this role will be able to grant or revoke other roles. More complex role relationships can be created by using [set\_role\_admin](#AccessControlComponent-set_role_admin).
+
The `DEFAULT_ADMIN_ROLE` is also its own admin: it has permission to grant and revoke this role. Extra precautions should be taken to secure accounts that have been granted it. See [AccessControlDefaultAdminRulesComponent](#AccessControlDefaultAdminRulesComponent).
+
[Embeddable Mixin Implementations](../components#mixins)
-AccessControlMixinImpl
+#### AccessControlMixinImpl [!toc] [#AccessControlComponent-Embeddable-Impls-AccessControlMixinImpl]
- [`AccessControlImpl`](#AccessControlComponent-Embeddable-Impls-AccessControlImpl)
- [`AccessControlCamelImpl`](#AccessControlComponent-Embeddable-Impls-AccessControlCamelImpl)
@@ -535,7 +754,7 @@ AccessControlMixinImpl
Embeddable Implementations
-AccessControlImpl
+#### AccessControlImpl [!toc] [#AccessControlComponent-Embeddable-Impls-AccessControlImpl]
- [`has_role(self, role, account)`](#AccessControlComponent-has_role)
- [`get_role_admin(self, role)`](#AccessControlComponent-get_role_admin)
@@ -543,7 +762,7 @@ AccessControlImpl
- [`revoke_role(self, role, account)`](#AccessControlComponent-revoke_role)
- [`renounce_role(self, role, account)`](#AccessControlComponent-renounce_role)
-AccessControlCamelImpl
+#### AccessControlCamelImpl [!toc] [#AccessControlComponent-Embeddable-Impls-AccessControlCamelImpl]
- [`hasRole(self, role, account)`](#AccessControlComponent-hasRole)
- [`getRoleAdmin(self, role)`](#AccessControlComponent-getRoleAdmin)
@@ -551,18 +770,18 @@ AccessControlCamelImpl
- [`revokeRole(self, role, account)`](#AccessControlComponent-revokeRole)
- [`renounceRole(self, role, account)`](#AccessControlComponent-renounceRole)
-AccessControlWithDelayImpl
+#### AccessControlWithDelayImpl [!toc] [#AccessControlComponent-Embeddable-Impls-AccessControlWithDelayImpl]
- [`get_role_status(self, role, account)`](#AccessControlComponent-get_role_status)
- [`grant_role_with_delay(self, role, account, delay)`](#AccessControlComponent-grant_role_with_delay)
-SRC5Impl
+#### SRC5Impl [!toc] [#AccessControlComponent-Embeddable-Impls-SRC5Impl]
- [`supports_interface(self, interface_id: felt252)`](introspection#ISRC5-supports_interface)
Internal Implementations
-InternalImpl
+#### InternalImpl [!toc] [#AccessControlComponent-InternalImpl]
- [`initializer(self)`](#AccessControlComponent-initializer)
- [`assert_only_role(self, role)`](#AccessControlComponent-assert_only_role)
@@ -576,30 +795,41 @@ InternalImpl
Events
-IAccessControl
+#### IAccessControl [!toc] [#AccessControlComponent-Events-IAccessControl]
- [`RoleAdminChanged(role, previous_admin_role, new_admin_role)`](#AccessControlComponent-RoleAdminChanged)
- [`RoleGranted(role, account, sender)`](#AccessControlComponent-RoleGranted)
- [`RoleRevoked(role, account, sender)`](#AccessControlComponent-RoleRevoked)
-IAccessControlWithDelay
+#### IAccessControlWithDelay [!toc] [#AccessControlComponent-Events-IAccessControlWithDelay]
- [`RoleGrantedWithDelay(role, account, sender, delay)`](#AccessControlComponent-RoleGrantedWithDelay)
-#### [](#AccessControlComponent-Embeddable-Functions)Embeddable functions
-
-#### [](#AccessControlComponent-has_role)`has_role(self: @ContractState, role: felt252, account: ContractAddress) → bool` external
+#### Embeddable functions [!toc] [#AccessControlComponent-Embeddable-Functions]
+
Returns whether `account` can act as `role`.
+
-#### [](#AccessControlComponent-get_role_admin)`get_role_admin(self: @ContractState, role: felt252) → felt252` external
-
+
Returns the admin role that controls `role`. See [grant\_role](#AccessControlComponent-grant_role) and [revoke\_role](#AccessControlComponent-revoke_role).
To change a role’s admin, use [set\_role\_admin](#AccessControlComponent-set_role_admin).
+
-#### [](#AccessControlComponent-get_role_status)`get_role_status(self: @ContractState, role: felt252, account: ContractAddress) → RoleStatus` external
-
+
Returns the account’s status for the given role.
The possible statuses are:
@@ -607,9 +837,13 @@ The possible statuses are:
- `NotGranted`: the role has not been granted to the account.
- `Delayed`: The role has been granted to the account but is not yet active due to a time delay.
- `Effective`: the role has been granted to the account and is currently active.
+
-#### [](#AccessControlComponent-grant_role)`grant_role(ref self: ContractState, role: felt252, account: ContractAddress)` external
-
+
Grants `role` to `account`.
If `account` had not been already granted `role`, emits a [RoleGranted](#IAccessControl-RoleGranted) event.
@@ -619,9 +853,13 @@ Requirements:
- the caller must have `role`'s admin role.
May emit a [RoleGranted](#IAccessControl-RoleGranted) event.
+
-#### [](#AccessControlComponent-grant_role_with_delay)`grant_role_with_delay(ref self: ContractState, role: felt252, account: ContractAddress, delay: u64)` external
-
+
Attempts to grant `role` to `account` with the specified activation delay.
Requirements:
@@ -631,9 +869,13 @@ Requirements:
- the `role` must not be already effective for `account`.
May emit a [RoleGrantedWithDelay](#IAccessControlWithDelay-RoleGrantedWithDelay) event.
+
-#### [](#AccessControlComponent-revoke_role)`revoke_role(ref self: ContractState, role: felt252, account: ContractAddress)` external
-
+
Revokes `role` from `account`.
If `account` had been granted `role`, emits a [RoleRevoked](#IAccessControl-RoleRevoked) event.
@@ -643,9 +885,13 @@ Requirements:
- the caller must have `role`'s admin role.
May emit a [RoleRevoked](#IAccessControl-RoleRevoked) event.
+
-#### [](#AccessControlComponent-renounce_role)`renounce_role(ref self: ContractState, role: felt252, account: ContractAddress)` external
-
+
Revokes `role` from the calling account.
Roles are often managed via [grant\_role](#AccessControlComponent-grant_role) and [revoke\_role](#AccessControlComponent-revoke_role). This function’s purpose is to provide a mechanism for accounts to lose their privileges if they are compromised (such as when a trusted device is misplaced).
@@ -657,51 +903,93 @@ Requirements:
- the caller must be `account`.
May emit a [RoleRevoked](#IAccessControl-RoleRevoked) event.
+
-#### [](#AccessControlComponent-supports_interface)`supports_interface(self: @ContractState, interface_id: felt252) → bool` external
-
+
See [ISRC5::supports\_interface](introspection#ISRC5-supports_interface).
+
-#### [](#AccessControlComponent-hasRole)`hasRole(self: @ContractState, role: felt252, account: ContractAddress) → bool` external
-
+
See [has\_role](#AccessControlComponent-has_role).
+
-#### [](#AccessControlComponent-getRoleAdmin)`getRoleAdmin(self: @ContractState, role: felt252) → felt252` external
-
+
See [get\_role\_admin](#AccessControlComponent-get_role_admin).
+
-#### [](#AccessControlComponent-grantRole)`grantRole(ref self: ContractState, role: felt252, account: ContractAddress)` external
-
+
See [grant\_role](#AccessControlComponent-grant_role).
+
-#### [](#AccessControlComponent-revokeRole)`revokeRole(ref self: ContractState, role: felt252, account: ContractAddress)` external
-
+
See [revoke\_role](#AccessControlComponent-revoke_role).
+
-#### [](#AccessControlComponent-renounceRole)`renounceRole(ref self: ContractState, role: felt252, account: ContractAddress)` external
-
+
See [renounce\_role](#AccessControlComponent-renounce_role).
+
-#### [](#AccessControlComponent-Internal-Functions)Internal functions
-
-#### [](#AccessControlComponent-initializer)`initializer(ref self: ContractState)` internal
+#### Internal functions [!toc] [#AccessControlComponent-Internal-Functions]
+
Initializes the contract by registering the [IAccessControl](#IAccessControl) interface ID.
+
-#### [](#AccessControlComponent-assert_only_role)`assert_only_role(self: @ContractState, role: felt252)` internal
-
+
Validates that the caller can act as the given role. Otherwise it panics.
+
-#### [](#AccessControlComponent-is_role_effective)`is_role_effective(self: @ContractState, role: felt252, account: ContractAddress) → bool` internal
-
+
Returns whether the account can act as the given role.
The account can act as the role if it is active and the `effective_from` time is before or equal to the current time.
+
If the `effective_from` timepoint is 0, the role is effective immediately. This is backwards compatible with implementations that didn’t use delays but a single boolean flag.
-
-#### [](#AccessControlComponent-resolve_role_status)`resolve_role_status(self: @ContractState, role: felt252, account: ContractAddress) → RoleStatus` internal
-
+
+
+
+
Returns the account’s status for the given role.
The possible statuses are:
@@ -709,31 +997,49 @@ The possible statuses are:
- `NotGranted`: the role has not been granted to the account.
- `Delayed`: The role has been granted to the account but is not yet active due to a time delay.
- `Effective`: the role has been granted to the account and is currently active.
+
-#### [](#AccessControlComponent-is_role_granted)`is_role_granted(self: @ContractState, role: felt252, account: ContractAddress) → bool` internal
-
+
Returns whether the account has the given role granted.
+
The account may not be able to act as the role yet, if a delay was set and has not passed yet. Use `is_role_effective` to check if the account can act as the role.
-
-#### [](#AccessControlComponent-set_role_admin)`set_role_admin(ref self: ContractState, role: felt252, admin_role: felt252)` internal
-
+
+
+
+
Sets `admin_role` as `role`'s admin role.
Internal function without access restriction.
Emits a [RoleAdminChanged](#IAccessControl-RoleAdminChanged) event.
+
-#### [](#AccessControlComponent-_grant_role)`_grant_role(ref self: ContractState, role: felt252, account: ContractAddress)` internal
-
+
Attempts to grant `role` to `account`. The function does nothing if `role` is already effective for `account`. If `role` has been granted to `account`, but is not yet active due to a time delay, the delay is removed and `role` becomes effective immediately.
Internal function without access restriction.
May emit a [RoleGranted](#IAccessControl-RoleGranted) event.
+
-#### [](#AccessControlComponent-_grant_role_with_delay)`_grant_role_with_delay(ref self: ContractState, role: felt252, account: ContractAddress, delay: u64)` internal
-
+
Attempts to grant `role` to `account` with the specified activation delay.
The role will become effective after the given delay has passed. If the role is already active (`Effective`) for the account, the function will panic. If the role has been granted but is not yet active (being in the `Delayed` state), the existing delay will be overwritten with the new `delay`.
@@ -746,36 +1052,61 @@ Requirements:
- the `role` must not be already effective for `account`.
May emit a [RoleGrantedWithDelay](#IAccessControlWithDelay-RoleGrantedWithDelay) event.
+
-#### [](#AccessControlComponent-_revoke_role)`_revoke_role(ref self: ContractState, role: felt252, account: ContractAddress)` internal
-
+
Revokes `role` from `account`.
Internal function without access restriction.
May emit a [RoleRevoked](#IAccessControl-RoleRevoked) event.
+
-#### [](#AccessControlComponent-Events)Events
-
-#### [](#AccessControlComponent-RoleAdminChanged)`RoleAdminChanged(role: felt252, previous_admin_role: ContractAddress, new_admin_role: ContractAddress)` event
+#### Events [!toc] [#AccessControlComponent-Events]
+
See [IAccessControl::RoleAdminChanged](#IAccessControl-RoleAdminChanged).
+
-#### [](#AccessControlComponent-RoleGranted)`RoleGranted(role: felt252, account: ContractAddress, sender: ContractAddress)` event
-
+
See [IAccessControl::RoleGranted](#IAccessControl-RoleGranted).
+
-#### [](#AccessControlComponent-RoleGrantedWithDelay)`RoleGrantedWithDelay(role: felt252, account: ContractAddress, sender: ContractAddress, delay: u64)` event
-
+
See [IAccessControlWithDelay::RoleGrantedWithDelay](#IAccessControlWithDelay-RoleGrantedWithDelay).
+
-#### [](#AccessControlComponent-RoleRevoked)`RoleRevoked(role: felt252, account: ContractAddress, sender: ContractAddress)` event
-
+
See [IAccessControl::RoleRevoked](#IAccessControl-RoleRevoked).
+
-## [](#extensions)Extensions
+## Extensions
-### [](#AccessControlDefaultAdminRulesComponent)`AccessControlDefaultAdminRulesComponent`[](https://github.com/OpenZeppelin/cairo-contracts/blob/release-v3.0.0-alpha.1/packages/access/src/accesscontrol/extensions/accesscontrol_default_admin_rules.cairo)
+### `AccessControlDefaultAdminRulesComponent` [toc] [#AccessControlDefaultAdminRulesComponent]
+
```rust
use openzeppelin_access::accesscontrol::extensions::AccessControlDefaultAdminRulesComponent;
@@ -795,7 +1126,7 @@ This contract implements the following risk mitigations on top of [AccessControl
[Embeddable Mixin Implementations](../components#mixins)
-AccessControlMixinImpl
+#### AccessControlMixinImpl [!toc] [#AccessControlDefaultAdminRulesComponent-Embeddable-Impls-AccessControlMixinImpl]
- [`AccessControlDefaultAdminRulesImpl`](#AccessControlDefaultAdminRulesComponent-Embeddable-Impls-AccessControlDefaultAdminRulesImpl)
- [`AccessControlImpl`](#AccessControlDefaultAdminRulesComponent-Embeddable-Impls-AccessControlImpl)
@@ -805,7 +1136,7 @@ AccessControlMixinImpl
Embeddable Implementations
-AccessControlDefaultAdminRulesImpl
+#### AccessControlDefaultAdminRulesImpl [!toc] [#AccessControlDefaultAdminRulesComponent-Embeddable-Impls-AccessControlDefaultAdminRulesImpl]
- [`default_admin(self)`](#IAccessControlDefaultAdminRules-default_admin)
- [`pending_default_admin(self)`](#IAccessControlDefaultAdminRules-pending_default_admin)
@@ -818,7 +1149,7 @@ AccessControlDefaultAdminRulesImpl
- [`rollback_default_admin_delay(self)`](#IAccessControlDefaultAdminRules-rollback_default_admin_delay)
- [`default_admin_delay_increase_wait(self)`](#IAccessControlDefaultAdminRules-default_admin_delay_increase_wait)
-AccessControlImpl
+#### AccessControlImpl [!toc] [#AccessControlDefaultAdminRulesComponent-Embeddable-Impls-AccessControlImpl]
- [`has_role(self, role, account)`](#AccessControlDefaultAdminRulesComponent-has_role)
- [`get_role_admin(self, role)`](#AccessControlDefaultAdminRulesComponent-get_role_admin)
@@ -826,7 +1157,7 @@ AccessControlImpl
- [`revoke_role(self, role, account)`](#AccessControlDefaultAdminRulesComponent-revoke_role)
- [`renounce_role(self, role, account)`](#AccessControlDefaultAdminRulesComponent-renounce_role)
-AccessControlCamelImpl
+#### AccessControlCamelImpl [!toc] [#AccessControlDefaultAdminRulesComponent-Embeddable-Impls-AccessControlCamelImpl]
- [`hasRole(self, role, account)`](#AccessControlDefaultAdminRulesComponent-hasRole)
- [`getRoleAdmin(self, role)`](#AccessControlDefaultAdminRulesComponent-getRoleAdmin)
@@ -834,18 +1165,18 @@ AccessControlCamelImpl
- [`revokeRole(self, role, account)`](#AccessControlDefaultAdminRulesComponent-revokeRole)
- [`renounceRole(self, role, account)`](#AccessControlDefaultAdminRulesComponent-renounceRole)
-AccessControlWithDelayImpl
+#### AccessControlWithDelayImpl [!toc] [#AccessControlDefaultAdminRulesComponent-Embeddable-Impls-AccessControlWithDelayImpl]
- [`get_role_status(self, role, account)`](#AccessControlDefaultAdminRulesComponent-get_role_status)
- [`grant_role_with_delay(self, role, account, delay)`](#AccessControlDefaultAdminRulesComponent-grant_role_with_delay)
-SRC5Impl
+#### SRC5Impl [!toc] [#AccessControlDefaultAdminRulesComponent-Embeddable-Impls-SRC5Impl]
- [`supports_interface(self, interface_id: felt252)`](introspection#ISRC5-supports_interface)
Internal Implementations
-InternalImpl
+#### InternalImpl [!toc] [#AccessControlDefaultAdminRulesComponent-InternalImpl]
- [`initializer(self, initial_delay, initial_default_admin)`](#AccessControlDefaultAdminRulesComponent-initializer)
- [`assert_only_role(self, role)`](#AccessControlDefaultAdminRulesComponent-assert_only_role)
@@ -862,51 +1193,70 @@ InternalImpl
Events
-IAccessControl
+#### IAccessControl [!toc] [#AccessControlDefaultAdminRulesComponent-Events-IAccessControl]
- [`RoleAdminChanged(role, previous_admin_role, new_admin_role)`](#AccessControlDefaultAdminRulesComponent-RoleAdminChanged)
- [`RoleGranted(role, account, sender)`](#AccessControlDefaultAdminRulesComponent-RoleGranted)
- [`RoleRevoked(role, account, sender)`](#AccessControlDefaultAdminRulesComponent-RoleRevoked)
-IAccessControlWithDelay
+#### IAccessControlWithDelay [!toc] [#AccessControlDefaultAdminRulesComponent-Events-IAccessControlWithDelay]
- [`RoleGrantedWithDelay(role, account, sender, delay)`](#AccessControlDefaultAdminRulesComponent-RoleGrantedWithDelay)
-IAccessControlDefaultAdminRules
+#### IAccessControlDefaultAdminRules [!toc] [#AccessControlDefaultAdminRulesComponent-Events-IAccessControlDefaultAdminRules]
- [`DefaultAdminTransferScheduled(new_admin, accept_schedule)`](#AccessControlDefaultAdminRulesComponent-DefaultAdminTransferScheduled)
- [`DefaultAdminTransferCanceled()`](#AccessControlDefaultAdminRulesComponent-DefaultAdminTransferCanceled)
- [`DefaultAdminDelayChangeScheduled(new_delay, effect_schedule)`](#AccessControlDefaultAdminRulesComponent-DefaultAdminDelayChangeScheduled)
- [`DefaultAdminDelayChangeCanceled()`](#AccessControlDefaultAdminRulesComponent-DefaultAdminDelayChangeCanceled)
-#### [](#AccessControlDefaultAdminRulesComponent-Embeddable-Functions)Embeddable functions
-
-#### [](#AccessControlDefaultAdminRulesComponent-default_admin)`default_admin(self: @ContractState) → ContractAddress` external
+#### Embeddable functions [!toc] [#AccessControlDefaultAdminRulesComponent-Embeddable-Functions]
+
Returns the address of the current `DEFAULT_ADMIN_ROLE` holder.
+
-#### [](#AccessControlDefaultAdminRulesComponent-pending_default_admin)`pending_default_admin(self: @ContractState) → (ContractAddress, u64)` external
-
+
Returns a tuple of a `new_admin` and an `accept_schedule`.
After the `accept_schedule` passes, the `new_admin` will be able to accept the `default_admin` role by calling [accept\_default\_admin\_transfer](#AccessControlDefaultAdminRulesComponent-accept_default_admin_transfer), completing the role transfer.
A zero value only in `accept_schedule` indicates no pending admin transfer.
+
A zero address `new_admin` means that `default_admin` is being renounced.
-
-#### [](#AccessControlDefaultAdminRulesComponent-default_admin_delay)`default_admin_delay(self: @ContractState) → u64` external
-
+
+
+
+
Returns the delay required to schedule the acceptance of a `default_admin` transfer started.
This delay will be added to the current timestamp when calling [begin\_default\_admin\_transfer](#AccessControlDefaultAdminRulesComponent-begin_default_admin_transfer) to set the acceptance schedule.
+
If a delay change has been scheduled, it will take effect as soon as the schedule passes, making this function returns the new delay.
+
See [change\_default\_admin\_delay](#AccessControlDefaultAdminRulesComponent-change_default_admin_delay).
+
-#### [](#AccessControlDefaultAdminRulesComponent-pending_default_admin_delay)`pending_default_admin_delay(self: @ContractState) → (u64, u64)` external
-
+
Returns a tuple of `new_delay` and an `effect_schedule`.
After the `effect_schedule` passes, the `new_delay` will get into effect immediately for every new `default_admin` transfer started with [begin\_default\_admin\_transfer](#AccessControlDefaultAdminRulesComponent-begin_default_admin_transfer).
@@ -914,9 +1264,13 @@ After the `effect_schedule` passes, the `new_delay` will get into effect immedia
A zero value only in `effect_schedule` indicates no pending delay change.
A zero value only for `new_delay` means that the next [default\_admin\_delay](#AccessControlDefaultAdminRulesComponent-default_admin_delay) will be zero after the effect schedule.
+
-#### [](#AccessControlDefaultAdminRulesComponent-begin_default_admin_transfer)`begin_default_admin_transfer(ref self: ContractState, new_admin: ContractAddress)` external
-
+
Starts a `default_admin` transfer by setting a [pending\_default\_admin](#AccessControlDefaultAdminRulesComponent-pending_default_admin) scheduled for acceptance after the current timestamp plus a [default\_admin\_delay](#AccessControlDefaultAdminRulesComponent-default_admin_delay).
Requirements:
@@ -924,9 +1278,13 @@ Requirements:
- Only can be called by the current `default_admin`.
Emits a [DefaultAdminTransferScheduled](#AccessControlDefaultAdminRulesComponent-DefaultAdminTransferScheduled) event.
+
-#### [](#AccessControlDefaultAdminRulesComponent-cancel_default_admin_transfer)`cancel_default_admin_transfer(ref self: ContractState)` external
-
+
Cancels a `default_admin` transfer previously started with [begin\_default\_admin\_transfer](#AccessControlDefaultAdminRulesComponent-begin_default_admin_transfer).
A [pending\_default\_admin](#AccessControlDefaultAdminRulesComponent-pending_default_admin) not yet accepted can also be cancelled with this function.
@@ -936,9 +1294,13 @@ Requirements:
- Only can be called by the current `default_admin`.
May emit a [DefaultAdminTransferCanceled](#AccessControlDefaultAdminRulesComponent-DefaultAdminTransferCanceled) event.
+
-#### [](#AccessControlDefaultAdminRulesComponent-accept_default_admin_transfer)`accept_default_admin_transfer(ref self: ContractState)` external
-
+
Completes a `default_admin` transfer previously started with [begin\_default\_admin\_transfer](#AccessControlDefaultAdminRulesComponent-begin_default_admin_transfer).
After calling the function:
@@ -951,9 +1313,13 @@ Requirements:
- Only can be called by the [pending\_default\_admin](#AccessControlDefaultAdminRulesComponent-pending_default_admin)'s `new_admin`.
- The [pending\_default\_admin](#AccessControlDefaultAdminRulesComponent-pending_default_admin)'s `accept_schedule` should’ve passed.
+
-#### [](#AccessControlDefaultAdminRulesComponent-change_default_admin_delay)`change_default_admin_delay(ref self: ContractState, new_delay: u64)` external
-
+
Initiates a [default\_admin\_delay](#AccessControlDefaultAdminRulesComponent-default_admin_delay) update by setting a [pending\_default\_admin\_delay](#AccessControlDefaultAdminRulesComponent-pending_default_admin_delay) scheduled for getting into effect after the current timestamp plus a [default\_admin\_delay](#AccessControlDefaultAdminRulesComponent-default_admin_delay).
This function guarantees that any call to [begin\_default\_admin\_transfer](#AccessControlDefaultAdminRulesComponent-begin_default_admin_transfer) done between the timestamp this method is called and the [pending\_default\_admin\_delay](#AccessControlDefaultAdminRulesComponent-pending_default_admin_delay) effect schedule will use the current [default\_admin\_delay](#AccessControlDefaultAdminRulesComponent-default_admin_delay) set before calling.
@@ -972,9 +1338,13 @@ Requirements:
- Only can be called by the current `default_admin`.
Emits a [DefaultAdminDelayChangeScheduled](#AccessControlDefaultAdminRulesComponent-DefaultAdminDelayChangeScheduled) event and may emit a [DefaultAdminDelayChangeCanceled](#AccessControlDefaultAdminRulesComponent-DefaultAdminDelayChangeCanceled) event.
+
-#### [](#AccessControlDefaultAdminRulesComponent-rollback_default_admin_delay)`rollback_default_admin_delay(ref self: ContractState)` external
-
+
Cancels a scheduled [default\_admin\_delay](#AccessControlDefaultAdminRulesComponent-default_admin_delay) change.
Requirements:
@@ -982,27 +1352,45 @@ Requirements:
- Only can be called by the current `default_admin`.
May emit a [DefaultAdminDelayChangeCanceled](#AccessControlDefaultAdminRulesComponent-DefaultAdminDelayChangeCanceled) event.
+
-#### [](#AccessControlDefaultAdminRulesComponent-default_admin_delay_increase_wait)`default_admin_delay_increase_wait(self: @ContractState) → u64` external
-
+
Maximum time in seconds for an increase to [default\_admin\_delay](#AccessControlDefaultAdminRulesComponent-default_admin_delay) (that is scheduled using [change\_default\_admin\_delay](#AccessControlDefaultAdminRulesComponent-change_default_admin_delay)) to take effect. Defaults to 5 days.
When the [default\_admin\_delay](#AccessControlDefaultAdminRulesComponent-default_admin_delay) is scheduled to be increased, it goes into effect after the new delay has passed with the purpose of giving enough time for reverting any accidental change (i.e. using milliseconds instead of seconds) that may lock the contract. However, to avoid excessive schedules, the wait is capped by this function and it can be overridden for a custom [default\_admin\_delay](#AccessControlDefaultAdminRulesComponent-default_admin_delay) increase scheduling.
+
Make sure to add a reasonable amount of time while overriding this value, otherwise, there’s a risk of setting a high new delay that goes into effect almost immediately without the possibility of human intervention in the case of an input error (eg. set milliseconds instead of seconds).
-
-#### [](#AccessControlDefaultAdminRulesComponent-has_role)`has_role(self: @ContractState, role: felt252, account: ContractAddress) → bool` external
-
+
+
+
+
Returns whether `account` can act as `role`.
+
-#### [](#AccessControlDefaultAdminRulesComponent-get_role_admin)`get_role_admin(self: @ContractState, role: felt252) → felt252` external
-
+
Returns the admin role that controls `role`. See [grant\_role](#AccessControlComponent-grant_role) and [revoke\_role](#AccessControlComponent-revoke_role).
To change a role’s admin, use [set\_role\_admin](#AccessControlComponent-set_role_admin).
+
-#### [](#AccessControlDefaultAdminRulesComponent-get_role_status)`get_role_status(self: @ContractState, role: felt252, account: ContractAddress) → RoleStatus` external
-
+
Returns the account’s status for the given role.
The possible statuses are:
@@ -1010,9 +1398,13 @@ The possible statuses are:
- `NotGranted`: the role has not been granted to the account.
- `Delayed`: The role has been granted to the account but is not yet active due to a time delay.
- `Effective`: the role has been granted to the account and is currently active.
+
-#### [](#AccessControlDefaultAdminRulesComponent-grant_role)`grant_role(ref self: ContractState, role: felt252, account: ContractAddress)` external
-
+
Grants `role` to `account`.
If `account` had not been already granted `role`, emits a [RoleGranted](#AccessControlDefaultAdminRulesComponent-RoleGranted) event.
@@ -1022,9 +1414,13 @@ Requirements:
- the caller must have `role`'s admin role.
May emit a [RoleGranted](#AccessControlDefaultAdminRulesComponent-RoleGranted) event.
+
-#### [](#AccessControlDefaultAdminRulesComponent-grant_role_with_delay)`grant_role_with_delay(ref self: ContractState, role: felt252, account: ContractAddress, delay: u64)` external
-
+
Attempts to grant `role` to `account` with the specified activation delay.
Requirements:
@@ -1034,9 +1430,13 @@ Requirements:
- the `role` must not be already effective for `account`.
May emit a [RoleGrantedWithDelay](#AccessControlDefaultAdminRulesComponent-RoleGrantedWithDelay) event.
+
-#### [](#AccessControlDefaultAdminRulesComponent-revoke_role)`revoke_role(ref self: ContractState, role: felt252, account: ContractAddress)` external
-
+
Revokes `role` from `account`.
If `account` had been granted `role`, emits a [RoleRevoked](#AccessControlDefaultAdminRulesComponent-RoleRevoked) event.
@@ -1046,9 +1446,13 @@ Requirements:
- the caller must have `role`'s admin role.
May emit a [RoleRevoked](#AccessControlDefaultAdminRulesComponent-RoleRevoked) event.
+
-#### [](#AccessControlDefaultAdminRulesComponent-renounce_role)`renounce_role(ref self: ContractState, role: felt252, account: ContractAddress)` external
-
+
Revokes `role` from the calling account.
Roles are often managed via [grant\_role](#AccessControlComponent-grant_role) and [revoke\_role](#AccessControlComponent-revoke_role). This function’s purpose is to provide a mechanism for accounts to lose their privileges if they are compromised (such as when a trusted device is misplaced).
@@ -1060,55 +1464,97 @@ Requirements:
- the caller must be `account`.
May emit a [RoleRevoked](#AccessControlDefaultAdminRulesComponent-RoleRevoked) event.
+
-#### [](#AccessControlDefaultAdminRulesComponent-supports_interface)`supports_interface(self: @ContractState, interface_id: felt252) → bool` external
-
+
See [ISRC5::supports\_interface](introspection#ISRC5-supports_interface).
+
-#### [](#AccessControlDefaultAdminRulesComponent-hasRole)`hasRole(self: @ContractState, role: felt252, account: ContractAddress) → bool` external
-
+
See [has\_role](#AccessControlDefaultAdminRulesComponent-has_role).
+
-#### [](#AccessControlDefaultAdminRulesComponent-getRoleAdmin)`getRoleAdmin(self: @ContractState, role: felt252) → felt252` external
-
+
See [get\_role\_admin](#AccessControlDefaultAdminRulesComponent-get_role_admin).
+
-#### [](#AccessControlDefaultAdminRulesComponent-grantRole)`grantRole(ref self: ContractState, role: felt252, account: ContractAddress)` external
-
+
See [grant\_role](#AccessControlDefaultAdminRulesComponent-grant_role).
+
-#### [](#AccessControlDefaultAdminRulesComponent-revokeRole)`revokeRole(ref self: ContractState, role: felt252, account: ContractAddress)` external
-
+
See [revoke\_role](#AccessControlDefaultAdminRulesComponent-revoke_role).
+
-#### [](#AccessControlDefaultAdminRulesComponent-renounceRole)`renounceRole(ref self: ContractState, role: felt252, account: ContractAddress)` external
-
+
See [renounce\_role](#AccessControlDefaultAdminRulesComponent-renounce_role).
+
-#### [](#AccessControlDefaultAdminRulesComponent-Internal-Functions)Internal functions
-
-#### [](#AccessControlDefaultAdminRulesComponent-initializer)`initializer(ref self: ContractState, initial_delay: u64, initial_default_admin: ContractAddress)` external
+#### Internal functions [!toc] [#AccessControlDefaultAdminRulesComponent-Internal-Functions]
+
Initializes the contract by registering the IAccessControl interface ID and setting the initial delay and default admin.
Requirements:
- `initial_default_admin` must not be the zero address.
+
-#### [](#AccessControlDefaultAdminRulesComponent-assert_only_role)`assert_only_role(self: @ContractState, role: felt252)` external
-
+
Validates that the caller can act as the given role. Otherwise it panics.
+
-#### [](#AccessControlDefaultAdminRulesComponent-is_role_effective)`is_role_effective(self: @ContractState, role: felt252, account: ContractAddress) → bool` external
-
+
Returns whether the account can act as the given role.
The account can act as the role if it is active and the `effective_from` time is before or equal to the current time.
+
If the `effective_from` timepoint is 0, the role is effective immediately. This is backwards compatible with implementations that didn’t use delays but a single boolean flag.
-
-#### [](#AccessControlDefaultAdminRulesComponent-resolve_role_status)`resolve_role_status(self: @ContractState, role: felt252, account: ContractAddress) → RoleStatus` external
-
+
+
+
+
Returns the account’s status for the given role.
The possible statuses are:
@@ -1116,15 +1562,25 @@ The possible statuses are:
- `NotGranted`: the role has not been granted to the account.
- `Delayed`: The role has been granted to the account but is not yet active due to a time delay.
- `Effective`: the role has been granted to the account and is currently active.
+
-#### [](#AccessControlDefaultAdminRulesComponent-is_role_granted)`is_role_granted(self: @ContractState, role: felt252, account: ContractAddress) → bool` external
-
+
Returns whether the account has the given role granted.
+
The account may not be able to act as the role yet, if a delay was set and has not passed yet. Use is\_role\_effective to check if the account can act as the role.
-
-#### [](#AccessControlDefaultAdminRulesComponent-set_role_admin)`set_role_admin(ref self: ContractState, role: felt252, admin_role: felt252)` external
-
+
+
+
+
Sets `admin_role` as \`role’s admin role.
Internal function without access restriction.
@@ -1134,9 +1590,13 @@ Requirements:
- `role` must not be `DEFAULT_ADMIN_ROLE`.
Emits a [RoleAdminChanged](#AccessControlDefaultAdminRulesComponent-RoleAdminChanged) event.
+
-#### [](#AccessControlDefaultAdminRulesComponent-_grant_role)`_grant_role(ref self: ContractState, role: felt252, account: ContractAddress)` external
-
+
Attempts to grant `role` to `account`. The function does nothing if `role` is already effective for `account`. If `role` has been granted to `account`, but is not yet active due to a time delay, the delay is removed and `role` becomes effective immediately.
Internal function without access restriction.
@@ -1146,9 +1606,13 @@ For `DEFAULT_ADMIN_ROLE`, it only allows granting if there isn’t already a `de
Exposing this function through another mechanism may make the `DEFAULT_ADMIN_ROLE` assignable again. Make sure to guarantee this is the expected behavior in your implementation.
May emit a [RoleGranted](#AccessControlDefaultAdminRulesComponent-RoleGranted) event.
+
-#### [](#AccessControlDefaultAdminRulesComponent-_grant_role_with_delay)`_grant_role_with_delay(ref self: ContractState, role: felt252, account: ContractAddress, delay: u64)` external
-
+
Attempts to grant `role` to `account` with the specified activation delay.
The role will become effective after the given delay has passed. If the role is already active (`Effective`) for the account, the function will panic. If the role has been granted but is not yet active (being in the `Delayed` state), the existing delay will be overwritten with the new `delay`.
@@ -1162,78 +1626,124 @@ Requirements:
- `role` must not be `DEFAULT_ADMIN_ROLE`.
May emit a [RoleGrantedWithDelay](#AccessControlDefaultAdminRulesComponent-RoleGrantedWithDelay) event.
+
-#### [](#AccessControlDefaultAdminRulesComponent-_revoke_role)`_revoke_role(ref self: ContractState, role: felt252, account: ContractAddress)` external
-
+
Attempts to revoke `role` from `account`. The function does nothing if `role` is not effective for `account`. If `role` has been revoked from `account`, but is still active due to a time delay, the delay is removed and `role` becomes inactive immediately.
Internal function without access restriction.
May emit a [RoleRevoked](#AccessControlDefaultAdminRulesComponent-RoleRevoked) event.
+
-#### [](#AccessControlDefaultAdminRulesComponent-set_pending_default_admin)`set_pending_default_admin(ref self: ContractState, new_admin: ContractAddress, new_schedule: u64)` external
-
+
Setter of the tuple for pending admin and its schedule.
May emit a DefaultAdminTransferCanceled event.
+
-#### [](#AccessControlDefaultAdminRulesComponent-set_pending_delay)`set_pending_delay(ref self: ContractState, new_delay: u64, new_schedule: u64)` external
-
+
Setter of the tuple for pending delay and its schedule.
May emit a DefaultAdminDelayChangeCanceled event.
+
-#### [](#AccessControlDefaultAdminRulesComponent-delay_change_wait)`delay_change_wait(self: @ContractState, new_delay: u64) → u64` external
-
+
Returns the amount of seconds to wait after the `new_delay` will become the new `default_admin_delay`.
The value returned guarantees that if the delay is reduced, it will go into effect after a wait that honors the previously set delay.
See [default\_admin\_delay\_increase\_wait](#AccessControlDefaultAdminRulesComponent-default_admin_delay_increase_wait).
+
-#### [](#AccessControlDefaultAdminRulesComponent-Events)Events
-
-#### [](#AccessControlDefaultAdminRulesComponent-RoleAdminChanged)`RoleAdminChanged(role: felt252, previous_admin_role: felt252, new_admin_role: felt252)` event
+#### Events [!toc] [#AccessControlDefaultAdminRulesComponent-Events]
-Emitted when `new_admin_role` is set as ``role’s admin role, replacing `previous_admin_role``
+
+Emitted when `new_admin_role` is set as role’s admin role, replacing `previous_admin_role`
`DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite `RoleAdminChanged` not being emitted signaling this.
+
-#### [](#AccessControlDefaultAdminRulesComponent-RoleGranted)`RoleGranted(role: felt252, account: ContractAddress, sender: ContractAddress)` event
-
+
Emitted when `account` is granted `role`.
`sender` is the account that originated the contract call, an account with the admin role or the deployer address if `_grant_role` is called from the constructor.
+
-#### [](#AccessControlDefaultAdminRulesComponent-RoleRevoked)`RoleRevoked(role: felt252, account: ContractAddress, sender: ContractAddress)` event
-
+
Emitted when `role` is revoked for `account`.
`sender` is the account that originated the contract call:
- If using `revoke_role`, it is the admin role bearer.
- If using `renounce_role`, it is the role bearer (i.e. `account`).
+
-#### [](#AccessControlDefaultAdminRulesComponent-RoleGrantedWithDelay)`RoleGrantedWithDelay(role: felt252, account: ContractAddress, sender: ContractAddress, delay: u64)` event
-
+
Emitted when `account` is granted `role` with a delay.
`sender` is the account that originated the contract call, an account with the admin role or the deployer address if `_grant_role_with_delay` is called from the constructor.
+
-#### [](#AccessControlDefaultAdminRulesComponent-DefaultAdminTransferScheduled)`DefaultAdminTransferScheduled(new_admin: ContractAddress, accept_schedule: u64)` event
-
+
Emitted when a `default_admin` transfer is started.
Sets `new_admin` as the next address to become the `default_admin` by calling [accept\_default\_admin\_transfer](#AccessControlDefaultAdminRulesComponent-accept_default_admin_transfer) only after `accept_schedule` passes.
+
-#### [](#AccessControlDefaultAdminRulesComponent-DefaultAdminTransferCanceled)`DefaultAdminTransferCanceled()` event
-
+
Emitted when a [pending\_default\_admin](#AccessControlDefaultAdminRulesComponent-pending_default_admin) is reset if it was never accepted, regardless of its schedule.
+
-#### [](#AccessControlDefaultAdminRulesComponent-DefaultAdminDelayChangeScheduled)`DefaultAdminDelayChangeScheduled(new_delay: u64, effect_schedule: u64)` event
+
Emitted when a [default\_admin\_delay](#AccessControlDefaultAdminRulesComponent-default_admin_delay) change is started.
Sets `new_delay` as the next delay to be applied between default admins transfers after `effect_schedule` has passed.
Emitted when a [pending\_default\_admin\_delay](#AccessControlDefaultAdminRulesComponent-pending_default_admin_delay) is reset if its schedule didn’t pass.
+
diff --git a/content/contracts-cairo/api/account.mdx b/content/contracts-cairo/api/account.mdx
index b1f91bc..d5c6266 100644
--- a/content/contracts-cairo/api/account.mdx
+++ b/content/contracts-cairo/api/account.mdx
@@ -4,11 +4,20 @@ title: Account
This crate provides components to implement account contracts that can be used for interacting with the network.
-## [](#interfaces)Interfaces
+## Interfaces
-Starting from version `3.x.x`, the interfaces are no longer part of the `openzeppelin_account` package. The references documented here are contained in the `openzeppelin_interfaces` package version `v2.1.0`.
+
+Starting from version `3.x.x`, the interfaces are no longer part of the `openzeppelin_access` package. The references documented here are
+contained in the `openzeppelin_interfaces` package version `{{openzeppelin_interfaces_version}}`.
+
-### [](#ISRC6)`ISRC6`[](https://github.com/OpenZeppelin/cairo-contracts/blob/release-v3.0.0-alpha.1/packages/interfaces/src/account/accounts.cairo)
+import { UMBRELLA_VERSION } from "../utils/constants.js";
+
+### `ISRC6` [toc] [#ISRC6]
+
```rust
use openzeppelin_interfaces::accounts::ISRC6;
@@ -18,7 +27,9 @@ Interface of the SRC6 Standard Account as defined in the [SNIP-6](https://github
[SRC5 ID](introspection#ISRC5)
+```text
0x2ceccef7f994940b3962a6c67e0ba4fcd37df7d131417c604f91e03caecc1cd
+```
Functions
@@ -26,27 +37,43 @@ Functions
- [`__validate__(calls)`](#ISRC6-__validate__)
- [`is_valid_signature(hash, signature)`](#ISRC6-is_valid_signature)
-#### [](#ISRC6-Functions)Functions
-
-#### [](#ISRC6-__execute__)`__execute__(calls: Array)` external
+#### Functions [!toc] [#ISRC6-Functions]
+
Executes the list of calls as a transaction after validation.
The `Call` struct is defined in [corelib](https://github.com/starkware-libs/cairo/blob/main/corelib/src/starknet/account.cairo#L3).
+
-#### [](#ISRC6-__validate__)`__validate__(calls: Array) → felt252` external
-
+
Validates a transaction before execution.
Returns the short string `'VALID'` if valid, otherwise it reverts.
+
-#### [](#ISRC6-is_valid_signature)`is_valid_signature(hash: felt252, signature: Array) → felt252` external
-
+
Validates whether a signature is valid or not for the given message hash.
Returns the short string `'VALID'` if valid, otherwise it reverts.
+
-### [](#ISRC9_V2)`ISRC9_V2`[](https://github.com/OpenZeppelin/cairo-contracts/blob/release-v3.0.0-alpha.1/packages/interfaces/src/account/src9.cairo)
+### `ISRC9_V2` [toc] [#ISRC9_V2]
+
```rust
use openzeppelin_interfaces::src9::ISRC9_V2;
@@ -56,17 +83,22 @@ Interface of the SRC9 Standard as defined in the [SNIP-9](https://github.com/sta
[SRC5 ID](introspection#ISRC5)
+```text
0x1d1144bb2138366ff28d8e9ab57456b1d332ac42196230c3a602003c89872
+```
Functions
- [`execute_from_outside_v2(outside_execution, signature)`](#ISRC9_V2-execute_from_outside_v2)
- [`is_valid_outside_execution_nonce(nonce)`](#ISRC9_V2-is_valid_outside_execution_nonce)
-#### [](#ISRC9_V2-Functions)Functions
-
-#### [](#ISRC9_V2-execute_from_outside_v2)`execute_from_outside_v2(outside_execution: OutsideExecution, signature: Span,) → Array>` external
+#### Functions [!toc] [#ISRC9_V2-Functions]
+
Allows anyone to submit a transaction on behalf of the account as long as they have the relevant signatures.
This method allows reentrancy. A call to `__execute__` or `execute_from_outside_v2` can trigger another nested transaction to `execute_from_outside_v2` thus the implementation MUST verify that the provided `signature` matches the hash of `outside_execution` and that `nonce` was not already used.
@@ -77,14 +109,23 @@ Arguments:
- `outside_execution` - The parameters of the transaction to execute.
- `signature` - A valid signature on the [SNIP-12](https://github.com/starknet-io/SNIPs/blob/main/SNIPS/snip-12.md) message encoding of `outside_execution`.
+
-#### [](#ISRC9_V2-is_valid_outside_execution_nonce)`is_valid_outside_execution_nonce(nonce: felt252) → bool` external
-
+
Get the status of a given nonce. `true` if the nonce is available to use.
+
-## [](#core)Core
+## Core
-### [](#AccountComponent)`AccountComponent`[](https://github.com/OpenZeppelin/cairo-contracts/blob/release-v3.0.0-alpha.1/packages/account/src/account.cairo)
+### `AccountComponent` [toc] [#AccountComponent]
+
```rust
use openzeppelin_account::AccountComponent;
@@ -96,7 +137,7 @@ Implementing [SRC5Component](introspection#SRC5Component) is a requirement for t
[Embeddable Mixin Implementations](../components#mixins)
-AccountMixinImpl
+#### AccountMixinImpl [!toc] [#AccountComponent-Embeddable-Impls-AccountMixinImpl]
- [`SRC6Impl`](#AccountComponent-Embeddable-Impls-SRC6Impl)
- [`DeclarerImpl`](#AccountComponent-Embeddable-Impls-DeclarerImpl)
@@ -108,41 +149,41 @@ AccountMixinImpl
Embeddable Implementations
-SRC6Impl
+#### SRC6Impl [!toc] [#AccountComponent-Embeddable-Impls-SRC6Impl]
- [`__execute__(self, calls)`](#AccountComponent-__execute__)
- [`__validate__(self, calls)`](#AccountComponent-__validate__)
- [`is_valid_signature(self, hash, signature)`](#AccountComponent-is_valid_signature)
-DeclarerImpl
+#### DeclarerImpl [!toc] [#AccountComponent-Embeddable-Impls-DeclarerImpl]
- [`__validate_declare__(self, class_hash)`](#AccountComponent-__validate_declare__)
-DeployableImpl
+#### DeployableImpl [!toc] [#AccountComponent-Embeddable-Impls-DeployableImpl]
- [`__validate_deploy__(self, hash, signature)`](#AccountComponent-__validate_deploy__)
-PublicKeyImpl
+#### PublicKeyImpl [!toc] [#AccountComponent-Embeddable-Impls-PublicKeyImpl]
- [`get_public_key(self)`](#AccountComponent-get_public_key)
- [`set_public_key(self, new_public_key, signature)`](#AccountComponent-set_public_key)
-SRC6CamelOnlyImpl
+#### SRC6CamelOnlyImpl [!toc] [#AccountComponent-Embeddable-Impls-SRC6CamelOnlyImpl]
- [`isValidSignature(self, hash, signature)`](#AccountComponent-isValidSignature)
-PublicKeyCamelImpl
+#### PublicKeyCamelImpl [!toc] [#AccountComponent-Embeddable-Impls-PublicKeyCamelImpl]
- [`getPublicKey(self)`](#AccountComponent-getPublicKey)
- [`setPublicKey(self, newPublicKey, signature)`](#AccountComponent-setPublicKey)
-SRC5Impl
+#### SRC5Impl [!toc] [#AccountComponent-Embeddable-Impls-SRC5Impl]
- [`supports_interface(self, interface_id: felt252)`](introspection#ISRC5-supports_interface)
Internal Implementations
-InternalImpl
+#### InternalImpl [!toc] [#AccountComponent-InternalImpl]
- [`initializer(self, public_key)`](#AccountComponent-initializer)
- [`assert_only_self(self)`](#AccountComponent-assert_only_self)
@@ -156,38 +197,65 @@ Events
- [`OwnerAdded(new_owner_guid)`](#AccountComponent-OwnerAdded)
- [`OwnerRemoved(removed_owner_guid)`](#AccountComponent-OwnerRemoved)
-#### [](#AccountComponent-Embeddable-Functions)Embeddable functions
-
-#### [](#AccountComponent-__execute__)`__execute__(self: @ContractState, calls: Array)` external
+#### Embeddable functions [!toc] [#AccountComponent-Embeddable-Functions]
+
See [ISRC6::\_\_execute\_\_](#ISRC6-__execute__).
+
-#### [](#AccountComponent-__validate__)`__validate__(self: @ContractState, calls: Array) → felt252` external
-
+
See [ISRC6::\_\_validate\_\_](#ISRC6-__validate__).
+
-#### [](#AccountComponent-is_valid_signature)`is_valid_signature(self: @ContractState, hash: felt252, signature: Array) → felt252` external
-
+
See [ISRC6::is\_valid\_signature](#ISRC6-is_valid_signature).
+
-#### [](#AccountComponent-__validate_declare__)`__validate_declare__(self: @ContractState, class_hash: felt252) → felt252` external
-
+
Validates a [`Declare` transaction](https://docs.starknet.io/architecture-and-concepts/network-architecture/transactions/#declare-transaction).
Returns the short string `'VALID'` if valid, otherwise it reverts.
+
-#### [](#AccountComponent-__validate_deploy__)`__validate_deploy__(self: @ContractState, class_hash: felt252, contract_address_salt: felt252, public_key: felt252) → felt252` external
-
+
Validates a [`DeployAccount` transaction](https://docs.starknet.io/architecture-and-concepts/network-architecture/transactions/#deploy_account_transaction). See [Counterfactual Deployments](../guides/deployment).
Returns the short string `'VALID'` if valid, otherwise it reverts.
+
-#### [](#AccountComponent-get_public_key)`get_public_key(self: @ContractState) → felt252` external
-
+
Returns the current public key of the account.
+
-#### [](#AccountComponent-set_public_key)`set_public_key(ref self: ContractState, new_public_key: felt252, signature: Span)` external
-
+
Sets a new public key for the account. Only accessible by the account calling itself through `__execute__`.
Requirements:
@@ -207,33 +275,57 @@ let message_hash = PoseidonTrait::new()
.update_with(current_owner)
.finalize();
```
+
-#### [](#AccountComponent-isValidSignature)`isValidSignature(self: @ContractState, hash: felt252, signature: Array) → felt252` external
-
+
See [ISRC6::is\_valid\_signature](#ISRC6-is_valid_signature).
+
-#### [](#AccountComponent-getPublicKey)`getPublicKey(self: @ContractState) → felt252` external
-
+
See [get\_public\_key](#AccountComponent-get_public_key).
+
-#### [](#AccountComponent-setPublicKey)`setPublicKey(ref self: ContractState, newPublicKey: felt252, signature: Span)` external
-
+
See [set\_public\_key](#AccountComponent-set_public_key).
+
-#### [](#AccountComponent-Internal-Functions)Internal functions
-
-#### [](#AccountComponent-initializer)`initializer(ref self: ComponentState, public_key: felt252)` internal
+#### Internal functions [!toc] [#AccountComponent-Internal-Functions]
+
Initializes the account with the given public key, and registers the `ISRC6` interface ID.
Emits an [OwnerAdded](#AccountComponent-OwnerAdded) event.
+
-#### [](#AccountComponent-assert_only_self)`assert_only_self(self: @ComponentState)` internal
-
+
Validates that the caller is the account itself. Otherwise it reverts.
+
-#### [](#AccountComponent-assert_valid_new_owner)`assert_valid_new_owner(self: @ComponentState, current_owner: felt252, new_owner: felt252, signature: Span)` internal
-
+
Validates that `new_owner` accepted the ownership of the contract through a signature.
Requirements:
@@ -241,36 +333,61 @@ Requirements:
- `signature` must be valid for the new owner.
This function assumes that `current_owner` is the current owner of the contract, and does not validate this assumption.
+
-#### [](#AccountComponent-validate_transaction)`validate_transaction(self: @ComponentState) → felt252` internal
-
+
Validates a transaction signature from the [global context](https://github.com/starkware-libs/cairo/blob/main/corelib/src/starknet/info.cairo#L61).
Returns the short string `'VALID'` if valid, otherwise it reverts.
+
-#### [](#AccountComponent-_set_public_key)`_set_public_key(ref self: ComponentState, new_public_key: felt252)` internal
-
+
Set the public key without validating the caller.
Emits an [OwnerAdded](#AccountComponent-OwnerAdded) event.
The usage of this method outside the `set_public_key` function is discouraged.
-
-#### [](#AccountComponent-_is_valid_signature)`_is_valid_signature(self: @ComponentState, hash: felt252, signature: Span) → bool` internal
-
-Validates the provided `signature` for the `hash`, using the account’s current public key.
-
-#### [](#AccountComponent-Events)Events
-
-#### [](#AccountComponent-OwnerAdded)`OwnerAdded(new_owner_guid: felt252)` event
-
+
+
+
+Validates the provided `signature` for the `hash`, using the account's current public key.
+
+
+#### Events [!toc] [#AccountComponent-Events]
+
+
Emitted when a `public_key` is added.
+
-#### [](#AccountComponent-OwnerRemoved)`OwnerRemoved(removed_owner_guid: felt252)` event
-
+
Emitted when a `public_key` is removed.
+
-### [](#EthAccountComponent)`EthAccountComponent`[](https://github.com/OpenZeppelin/cairo-contracts/blob/release-v3.0.0-alpha.1/packages/account/src/eth_account.cairo)
+### `EthAccountComponent` [toc] [#EthAccountComponent]
+
```rust
use openzeppelin_account::eth_account::EthAccountComponent;
@@ -284,7 +401,7 @@ The `EthPublicKey` type is an alias for `starknet::secp256k1::Secp256k1Point`.
[Embeddable Mixin Implementations](../components#mixins)
-EthAccountMixinImpl
+#### EthAccountMixinImpl [!toc] [#EthAccountComponent-Embeddable-Impls-EthAccountMixinImpl]
- [`SRC6Impl`](#EthAccountComponent-Embeddable-Impls-SRC6Impl)
- [`DeclarerImpl`](#EthAccountComponent-Embeddable-Impls-DeclarerImpl)
@@ -296,41 +413,41 @@ EthAccountMixinImpl
Embeddable Implementations
-SRC6Impl
+#### SRC6Impl [!toc] [#EthAccountComponent-Embeddable-Impls-SRC6Impl]
- [`__execute__(self, calls)`](#EthAccountComponent-__execute__)
- [`__validate__(self, calls)`](#EthAccountComponent-__validate__)
- [`is_valid_signature(self, hash, signature)`](#EthAccountComponent-is_valid_signature)
-DeclarerImpl
+#### DeclarerImpl [!toc] [#EthAccountComponent-Embeddable-Impls-DeclarerImpl]
- [`__validate_declare__(self, class_hash)`](#EthAccountComponent-__validate_declare__)
-DeployableImpl
+#### DeployableImpl [!toc] [#EthAccountComponent-Embeddable-Impls-DeployableImpl]
- [`__validate_deploy__(self, hash, signature)`](#EthAccountComponent-__validate_deploy__)
-PublicKeyImpl
+#### PublicKeyImpl [!toc] [#EthAccountComponent-Embeddable-Impls-PublicKeyImpl]
- [`get_public_key(self)`](#EthAccountComponent-get_public_key)
- [`set_public_key(self, new_public_key, signature)`](#EthAccountComponent-set_public_key)
-SRC6CamelOnlyImpl
+#### SRC6CamelOnlyImpl [!toc] [#EthAccountComponent-Embeddable-Impls-SRC6CamelOnlyImpl]
- [`isValidSignature(self, hash, signature)`](#EthAccountComponent-isValidSignature)
-PublicKeyCamelImpl
+#### PublicKeyCamelImpl [!toc] [#EthAccountComponent-Embeddable-Impls-PublicKeyCamelImpl]
- [`getPublicKey(self)`](#EthAccountComponent-getPublicKey)
- [`setPublicKey(self, newPublicKey, signature)`](#EthAccountComponent-setPublicKey)
-SRC5Impl
+#### SRC5Impl [!toc] [#EthAccountComponent-Embeddable-Impls-SRC5Impl]
- [`supports_interface(self, interface_id: felt252)`](introspection#ISRC5-supports_interface)
Internal Implementations
-InternalImpl
+#### InternalImpl [!toc] [#EthAccountComponent-InternalImpl]
- [`initializer(self, public_key)`](#EthAccountComponent-initializer)
- [`assert_only_self(self)`](#EthAccountComponent-assert_only_self)
@@ -344,38 +461,65 @@ Events
- [`OwnerAdded(new_owner_guid)`](#EthAccountComponent-OwnerAdded)
- [`OwnerRemoved(removed_owner_guid)`](#EthAccountComponent-OwnerRemoved)
-#### [](#EthAccountComponent-Embeddable-Functions)Embeddable functions
-
-#### [](#EthAccountComponent-__execute__)`__execute__(self: @ContractState, calls: Array)` external
+#### Embeddable functions [!toc] [#EthAccountComponent-Embeddable-Functions]
+
See [ISRC6::\_\_execute\_\_](#ISRC6-__execute__).
+
-#### [](#EthAccountComponent-__validate__)`__validate__(self: @ContractState, calls: Array) → felt252` external
-
+
See [ISRC6::\_\_validate\_\_](#ISRC6-__validate__).
+
-#### [](#EthAccountComponent-is_valid_signature)`is_valid_signature(self: @ContractState, hash: felt252, signature: Array) → felt252` external
-
+
See [ISRC6::is\_valid\_signature](#ISRC6-is_valid_signature).
+
-#### [](#EthAccountComponent-__validate_declare__)`__validate_declare__(self: @ContractState, class_hash: felt252) → felt252` external
-
+
Validates a [`Declare` transaction](https://docs.starknet.io/architecture-and-concepts/network-architecture/transactions/#declare-transaction).
Returns the short string `'VALID'` if valid, otherwise it reverts.
+
-#### [](#EthAccountComponent-__validate_deploy__)`__validate_deploy__(self: @ContractState, class_hash: felt252, contract_address_salt: felt252, public_key: EthPublicKey) → felt252` external
-
+
Validates a [`DeployAccount` transaction](https://docs.starknet.io/architecture-and-concepts/network-architecture/transactions/#deploy_account_transaction). See [Counterfactual Deployments](../guides/deployment).
Returns the short string `'VALID'` if valid, otherwise it reverts.
+
-#### [](#EthAccountComponent-get_public_key)`get_public_key(self: @ContractState) → EthPublicKey` external
-
+
Returns the current public key of the account.
+
-#### [](#EthAccountComponent-set_public_key)`set_public_key(ref self: ContractState, new_public_key: EthPublicKey, signature: Span)` external
-
+
Sets a new public key for the account. Only accessible by the account calling itself through `__execute__`.
Requirements:
@@ -395,33 +539,57 @@ let message_hash = PoseidonTrait::new()
.update_with(current_owner.get_coordinates().unwrap_syscall())
.finalize();
```
+
-#### [](#EthAccountComponent-isValidSignature)`isValidSignature(self: @ContractState, hash: felt252, signature: Array) → felt252` external
-
+
See [ISRC6::is\_valid\_signature](#ISRC6-is_valid_signature).
+
-#### [](#EthAccountComponent-getPublicKey)`getPublicKey(self: @ContractState) → EthPublicKey` external
-
+
See [get\_public\_key](#EthAccountComponent-get_public_key).
+
-#### [](#EthAccountComponent-setPublicKey)`setPublicKey(ref self: ContractState, newPublicKey: EthPublicKey, signature: Span)` external
-
+
See [set\_public\_key](#EthAccountComponent-set_public_key).
+
-#### [](#EthAccountComponent-Internal-Functions)Internal functions
-
-#### [](#EthAccountComponent-initializer)`initializer(ref self: ComponentState, public_key: EthPublicKey)` internal
+#### Internal functions [!toc] [#EthAccountComponent-Internal-Functions]
+
Initializes the account with the given public key, and registers the `ISRC6` interface ID.
Emits an [OwnerAdded](#EthAccountComponent-OwnerAdded) event.
+
-#### [](#EthAccountComponent-assert_only_self)`assert_only_self(self: @ComponentState)` internal
-
+
Validates that the caller is the account itself. Otherwise it reverts.
+
-#### [](#EthAccountComponent-assert_valid_new_owner)`assert_valid_new_owner(self: @ComponentState, current_owner: EthPublicKey, new_owner: EthPublicKey, signature: Span)` internal
-
+
Validates that `new_owner` accepted the ownership of the contract through a signature.
Requirements:
@@ -429,40 +597,65 @@ Requirements:
- The signature must be valid for the `new_owner`.
This function assumes that `current_owner` is the current owner of the contract, and does not validate this assumption.
+
-#### [](#EthAccountComponent-validate_transaction)`validate_transaction(self: @ComponentState) → felt252` internal
-
+
Validates a transaction signature from the [global context](https://github.com/starkware-libs/cairo/blob/main/corelib/src/starknet/info.cairo#L61).
Returns the short string `'VALID'` if valid, otherwise it reverts.
+
-#### [](#EthAccountComponent-_set_public_key)`_set_public_key(ref self: ComponentState, new_public_key: EthPublicKey)` internal
-
+
Set the public key without validating the caller.
Emits an [OwnerAdded](#EthAccountComponent-OwnerAdded) event.
The usage of this method outside the `set_public_key` function is discouraged.
+
-#### [](#EthAccountComponent-_is_valid_signature)`_is_valid_signature(self: @ComponentState, hash: felt252, signature: Span) → bool` internal
+
+Validates the provided `signature` for the `hash`, using the account's current public key.
+
-Validates the provided `signature` for the `hash`, using the account’s current public key.
-
-#### [](#EthAccountComponent-Events)Events
+#### Events [!toc] [#EthAccountComponent-Events]
The `guid` is computed as the hash of the public key, using the poseidon hash function.
-#### [](#EthAccountComponent-OwnerAdded)`OwnerAdded(new_owner_guid: felt252)` event
-
+
Emitted when a `public_key` is added.
+
-#### [](#EthAccountComponent-OwnerRemoved)`OwnerRemoved(removed_owner_guid: felt252)` event
-
+
Emitted when a `public_key` is removed.
+
-## [](#extensions)Extensions
+## Extensions
-### [](#SRC9Component)`SRC9Component`[](https://github.com/OpenZeppelin/cairo-contracts/blob/release-v3.0.0-alpha.1/packages/account/src/extensions/src9/src9.cairo)
+### `SRC9Component` [toc] [#SRC9Component]
+
```rust
use openzeppelin_account::extensions::SRC9Component;
@@ -474,21 +667,24 @@ This component is signature-agnostic, meaning it can be integrated into any acco
Embeddable Implementations
-OutsideExecutionV2Impl
+#### OutsideExecutionV2Impl [!toc] [#SRC9Component-Embeddable-Impls-OutsideExecutionV2Impl]
- [`execute_from_outside_v2(self, outside_execution, signature)`](#SRC9Component-execute_from_outside_v2)
- [`is_valid_outside_execution_nonce(self, nonce)`](#SRC9Component-is_valid_outside_execution_nonce)
Internal Implementations
-InternalImpl
+#### InternalImpl [!toc] [#SRC9Component-InternalImpl]
- [`initializer(self)`](#SRC9Component-initializer)
-#### [](#SRC9Component-Embeddable-Functions)Embeddable functions
-
-#### [](#SRC9Component-execute_from_outside_v2)`execute_from_outside_v2(ref self: ContractState, outside_execution: OutsideExecution, signature: Span) → Array>` external
+#### Embeddable functions [!toc] [#SRC9Component-Embeddable-Functions]
+
Allows anyone to submit a transaction on behalf of the account as long as they have the relevant signatures.
This method allows reentrancy. A call to `__execute__` or `execute_from_outside_v2` can trigger another nested transaction to `execute_from_outside_v2`. This implementation verifies that the provided `signature` matches the hash of `outside_execution` and that `nonce` was not already used.
@@ -504,20 +700,33 @@ Requirements:
- The current time must be within the `outside_execution.execute_after` and `outside_execution.execute_before` span.
- The `outside_execution.nonce` must not be used before.
- The `signature` must be valid.
+
-#### [](#SRC9Component-is_valid_outside_execution_nonce)`is_valid_outside_execution_nonce(self: @ContractState, nonce: felt252) → bool` external
-
+
Returns the status of a given nonce. `true` if the nonce is available to use.
+
-#### [](#SRC9Component-Internal-Functions)Internal functions
-
-#### [](#SRC9Component-initializer)`initializer(ref self: ComponentState)` internal
+#### Internal functions [!toc] [#SRC9Component-Internal-Functions]
+
Initializes the account by registering the `ISRC9_V2` interface ID.
+
-## [](#presets)Presets
+## Presets
-### [](#AccountUpgradeable)`AccountUpgradeable`[](https://github.com/OpenZeppelin/cairo-contracts/blob/release-v3.0.0-alpha.1/packages/presets/src/account.cairo)
+### `AccountUpgradeable` [toc] [#AccountUpgradeable]
+
```rust
use openzeppelin_presets::AccountUpgradeable;
@@ -527,7 +736,9 @@ Upgradeable account which can change its public key and declare, deploy, or call
[Sierra class hash](../presets)
-0x002de258cce5b9e160bf83956b09f982059582469f7e6fad07b438128317d029
+```text
+{{AccountUpgradeableClassHash}}
+```
Constructor
@@ -547,24 +758,36 @@ External Functions
- [`upgrade(self, new_class_hash)`](#AccountUpgradeable-upgrade)
-#### [](#AccountUpgradeable-constructor-section)Constructor
-
-#### [](#AccountUpgradeable-constructor)`constructor(ref self: ContractState, public_key: felt252)` constructor
+#### Constructor [!toc] [#AccountUpgradeable-Constructor]
+
Sets the account `public_key` and registers the interfaces the contract supports.
+
-#### [](#AccountUpgradeable-external-functions)External functions
-
-#### [](#AccountUpgradeable-upgrade)`upgrade(ref self: ContractState, new_class_hash: ClassHash)` external
+#### External functions [!toc] [#AccountUpgradeable-External-Functions]
+
Upgrades the contract to a new implementation given by `new_class_hash`.
Requirements:
- The caller is the account contract itself.
- `new_class_hash` cannot be zero.
+
-### [](#EthAccountUpgradeable)`EthAccountUpgradeable`[](https://github.com/OpenZeppelin/cairo-contracts/blob/release-v3.0.0-alpha.1/packages/presets/src/eth_account.cairo)
+### `EthAccountUpgradeable` [toc] [#EthAccountUpgradeable]
+
```rust
use openzeppelin_presets::EthAccountUpgradeable;
@@ -576,7 +799,9 @@ The `EthPublicKey` type is an alias for `starknet::secp256k1::Secp256k1Point`.
[Sierra class hash](../presets)
-0x07f54a43da3f7beb5099c87f5627b7fba5f31c7a704cce57f8fb73287c1ea3be
+```text
+{{EthAccountUpgradeableClassHash}}
+```
Constructor
@@ -596,19 +821,27 @@ External Functions
- [`upgrade(self, new_class_hash)`](#EthAccountUpgradeable-upgrade)
-#### [](#EthAccountUpgradeable-constructor-section)Constructor
-
-#### [](#EthAccountUpgradeable-constructor)`constructor(ref self: ContractState, public_key: EthPublicKey)` constructor
+#### Constructor [!toc] [#EthAccountUpgradeable-Constructor]
+
Sets the account `public_key` and registers the interfaces the contract supports.
+
-#### [](#EthAccountUpgradeable-external-functions)External functions
-
-#### [](#EthAccountUpgradeable-upgrade)`upgrade(ref self: ContractState, new_class_hash: ClassHash)` external
+#### External functions [!toc] [#EthAccountUpgradeable-External-Functions]
+
Upgrades the contract to a new implementation given by `new_class_hash`.
Requirements:
- The caller is the account contract itself.
- `new_class_hash` cannot be zero.
+
diff --git a/content/contracts-cairo/api/erc1155.mdx b/content/contracts-cairo/api/erc1155.mdx
index dd1284e..0a86b43 100644
--- a/content/contracts-cairo/api/erc1155.mdx
+++ b/content/contracts-cairo/api/erc1155.mdx
@@ -2,15 +2,25 @@
title: ERC1155
---
+import { UMBRELLA_VERSION } from "../utils/constants.js";
+
This module provides interfaces, presets, and utilities related to ERC1155 contracts.
For an overview of ERC1155, read our [ERC1155 guide](../erc1155).
## [](#interfaces)Interfaces
-Starting from version `3.x.x`, the interfaces are no longer part of the `openzeppelin_token` package. The references documented here are contained in the `openzeppelin_interfaces` package version `v2.1.0`.
+
+Starting from version `3.x.x`, the interfaces are no longer part of the `openzeppelin_access` package. The references
+documented here are contained in the `openzeppelin_interfaces` package version `{{openzeppelin_interfaces_version}}`.
+
+
+### `IERC1155` [toc] [#IERC1155]
-### [](#IERC1155)`IERC1155`[](https://github.com/OpenZeppelin/cairo-contracts/blob/release-v3.0.0-alpha.1/packages/interfaces/src/token/erc1155.cairo)
+
```rust
use openzeppelin_interfaces::erc1155::IERC1155;
@@ -20,7 +30,9 @@ Interface of the IERC1155 standard as defined in [EIP1155](https://eips.ethereum
[SRC5 ID](introspection#ISRC5)
+```text
0x6114a8f75559e1b39fcba08ce02961a1aa082d9256a158dd3e64964e4b1b52
+```
Functions
@@ -38,61 +50,106 @@ Events
- [`ApprovalForAll(owner, operator, approved)`](#IERC1155-ApprovalForAll)
- [`URI(value, id)`](#IERC1155-URI)
-#### [](#functions)Functions
-
-#### [](#IERC1155-balance_of)`balance_of(account: ContractAddress, token_id: u256) → u256` external
+#### Functions [!toc] [#functions]
+
Returns the amount of `token_id` tokens owned by `account`.
+
-#### [](#IERC1155-balance_of_batch)`balance_of_batch(accounts: Span, token_ids: Span) → Span` external
-
+
Returns a list of balances derived from the `accounts` and `token_ids` pairs.
+
-#### [](#IERC1155-safe_transfer_from)`safe_transfer_from(from: ContractAddress, to: ContractAddress, token_id: u256, value: u256, data: Span)` external
-
+
Transfers ownership of `value` amount of `token_id` from `from` if `to` is either `IERC1155Receiver` or an account.
`data` is additional data, it has no specified format and it is passed to `to`.
Emits a [TransferSingle](#IERC1155-TransferSingle) event.
+
-#### [](#IERC1155-safe_batch_transfer_from)`safe_batch_transfer_from(from: ContractAddress, to: ContractAddress, token_ids: Span, values: Span, data: Span)` external
-
+
Transfers ownership of `token_ids` and `values` pairs from `from` if `to` is either `IERC1155Receiver` or an account.
`data` is additional data, it has no specified format and it is passed to `to`.
Emits a [TransferBatch](#IERC1155-TransferBatch) event.
+
-#### [](#IERC1155-set_approval_for_all)`set_approval_for_all(operator: ContractAddress, approved: bool)` external
-
-Enables or disables approval for `operator` to manage all of the caller’s assets.
+
+Enables or disables approval for `operator` to manage all of the caller's assets.
Emits an [ApprovalForAll](#IERC1155-ApprovalForAll) event.
+
-#### [](#IERC1155-is_approved_for_all)`is_approved_for_all(owner: ContractAddress, operator: ContractAddress) -> bool` external
-
+
Queries if `operator` is an authorized operator for `owner`.
+
-#### [](#events)Events
-
-#### [](#IERC1155-TransferSingle)`TransferSingle(operator: ContractAddress, from: ContractAddress, to: ContractAddress, id: u256, value: u256)` event
+#### Events [!toc] [#events]
+
Emitted when `value` amount of `id` token is transferred from `from` to `to` through `operator`.
+
-#### [](#IERC1155-TransferBatch)`TransferBatch(operator: ContractAddress, from: ContractAddress, to: ContractAddress, ids: Span, values: Span)` event
-
+
Emitted when a batch of `values` amount of `ids` tokens are transferred from `from` to `to` through `operator`.
-
-#### [](#IERC1155-ApprovalForAll)`ApprovalForAll(owner: ContractAddress, operator: ContractAddress, approved: bool)` event
-
-Emitted when `owner` enables or disables `operator` to manage all of the owner’s assets.
-
-#### [](#IERC1155-URI)`URI(value: ByteArray, id: u256)` event
-
+
+
+
+Emitted when `owner` enables or disables `operator` to manage all of the owner's assets.
+
+
+
Emitted when the token URI is updated to `value` for the `id` token.
+
-### [](#IERC1155MetadataURI)`IERC1155MetadataURI`[](https://github.com/OpenZeppelin/cairo-contracts/blob/release-v3.0.0-alpha.1/packages/interfaces/src/token/erc1155.cairo)
+### `IERC1155MetadataURI` [toc] [#IERC1155MetadataURI]
+
+
```rust
use openzeppelin_interfaces::erc1155::IERC1155MetadataURI;
@@ -102,19 +159,30 @@ Interface for the optional metadata function in [EIP1155](https://eips.ethereum.
[SRC5 ID](introspection#ISRC5)
+```text
0xcabe2400d5fe509e1735ba9bad205ba5f3ca6e062da406f72f113feb889ef7
+```
Functions
- [`uri(token_id)`](#IERC1155MetadataURI-uri)
-#### [](#functions_2)Functions
-
-#### [](#IERC1155MetadataURI-uri)`uri(token_id: u256) -> ByteArray` external
+#### Functions [!toc] [#functions_2]
+
Returns the Uniform Resource Identifier (URI) for the `token_id` token.
+
+
+### `IERC1155Receiver` [toc] [#IERC1155Receiver]
-### [](#IERC1155Receiver)`IERC1155Receiver`[](https://github.com/OpenZeppelin/cairo-contracts/blob/release-v3.0.0-alpha.1/packages/interfaces/src/token/erc1155.cairo)
+
```rust
use openzeppelin_interfaces::erc1155::IERC1155Receiver;
@@ -124,26 +192,41 @@ Interface for contracts that support receiving token transfers from `ERC1155` co
[SRC5 ID](introspection#ISRC5)
+```text
0x15e8665b5af20040c3af1670509df02eb916375cdf7d8cbaf7bd553a257515e
+```
Functions
- [`on_erc1155_received(operator, from, token_id, value, data)`](#IERC1155Receiver-on_erc1155_received)
- [`on_erc1155_batch_received(operator, from, token_ids, values, data)`](#IERC1155Receiver-on_erc1155_batch_received)
-#### [](#functions_3)Functions
-
-#### [](#IERC1155Receiver-on_erc1155_received)`on_erc1155_received(operator: ContractAddress, from: ContractAddress, token_id: u256, value: u256, data Span) -> felt252` external
+#### Functions [!toc] [#functions_3]
+
This function is called whenever an ERC1155 `token_id` token is transferred to this `IERC1155Receiver` implementer via [IERC1155::safe\_transfer\_from](#IERC1155-safe_transfer_from) by `operator` from `from`.
+
-#### [](#IERC1155Receiver-on_erc1155_batch_received)`on_erc1155_batch_received(operator: ContractAddress, from: ContractAddress, token_ids: Span, values: Span, data Span) -> felt252` external
-
+
This function is called whenever multiple ERC1155 `token_ids` tokens are transferred to this `IERC1155Receiver` implementer via [IERC1155::safe\_batch\_transfer\_from](#IERC1155-safe_batch_transfer_from) by `operator` from `from`.
+
## [](#core)Core
-### [](#ERC1155Component)`ERC1155Component`[](https://github.com/OpenZeppelin/cairo-contracts/blob/release-v3.0.0-alpha.1/packages/token/src/erc1155/erc1155.cairo)
+### `ERC1155Component` [toc] [#ERC1155Component]
+
+
```rust
use openzeppelin_token::erc1155::ERC1155Component;
@@ -155,16 +238,16 @@ Implementing [SRC5Component](introspection#SRC5Component) is a requirement for t
See [Hooks](#ERC1155Component-Hooks) to understand how are hooks used.
-Hooks
+#### Hooks [!toc] [#ERC1155Component-Hooks]
-ERC1155HooksTrait
+#### ERC1155HooksTrait [!toc] [#ERC1155Component-ERC1155HooksTrait]
- [`before_update(self, from, to, token_ids, values)`](#ERC1155Component-before_update)
- [`after_update(self, from, to, token_ids, values)`](#ERC1155Component-after_update)
[Embeddable Mixin Implementations](../components#mixins)
-ERC1155MixinImpl
+#### ERC1155MixinImpl [!toc] [#ERC1155Component-Embeddable-Impls-ERC1155MixinImpl]
- [`ERC1155Impl`](#ERC1155Component-Embeddable-Impls-ERC1155Impl)
- [`ERC1155MetadataURIImpl`](#ERC1155Component-Embeddable-Impls-ERC1155MetadataURIImpl)
@@ -173,7 +256,7 @@ ERC1155MixinImpl
Embeddable Implementations
-ERC1155Impl
+#### ERC1155Impl [!toc] [#ERC1155Component-Embeddable-Impls-ERC1155Impl]
- [`balance_of(self, account, token_id)`](#ERC1155Component-balance_of)
- [`balance_of_batch(self, accounts, token_ids)`](#ERC1155Component-balance_of_batch)
@@ -182,11 +265,11 @@ ERC1155Impl
- [`set_approval_for_all(self, operator, approved)`](#ERC1155Component-set_approval_for_all)
- [`is_approved_for_all(self, owner, operator)`](#ERC1155Component-is_approved_for_all)
-ERC1155MetadataURIImpl
+#### ERC1155MetadataURIImpl [!toc] [#ERC1155Component-Embeddable-Impls-ERC1155MetadataURIImpl]
- [`uri(self, token_id)`](#ERC1155Component-uri)
-ERC1155CamelImpl
+#### ERC1155CamelImpl [!toc] [#ERC1155Component-Embeddable-Impls-ERC1155CamelImpl]
- [`balanceOf(self, account, tokenId)`](#ERC1155Component-balanceOf)
- [`balanceOfBatch(self, accounts, tokenIds)`](#ERC1155Component-balanceOfBatch)
@@ -197,7 +280,7 @@ ERC1155CamelImpl
Internal Functions
-InternalImpl
+#### InternalImpl [!toc] [#ERC1155Component-InternalImpl]
- [`initializer(self, base_uri)`](#ERC1155Component-initializer)
- [`initializer_no_metadata(self)`](#ERC1155Component-initializer_no_metadata)
@@ -218,36 +301,53 @@ IERC1155
- [`ApprovalForAll(owner, operator, approved)`](#ERC1155Component-ApprovalForAll)
- [`URI(value, id)`](#ERC1155Component-URI)
-#### [](#ERC1155Component-Hooks)Hooks
-
Hooks are functions which implementations can extend the functionality of the component source code. Every contract using ERC1155Component is expected to provide an implementation of the ERC1155HooksTrait. For basic token contracts, an empty implementation with no logic must be provided.
You can use `openzeppelin_token::erc1155::ERC1155HooksEmptyImpl` which is already available as part of the library for this purpose.
-#### [](#ERC1155Component-before_update)`before_update(ref self: ContractState, from: ContractAddress, to: ContractAddress, token_ids: Span, values: Span)` hook
-
+
Function executed at the beginning of the [update](#ERC1155Component-update) function prior to any other logic.
+
-#### [](#ERC1155Component-after_update)`after_update(ref self: ContractState, from: ContractAddress, to: ContractAddress, token_ids: Span, values: Span)` hook
-
+
Function executed at the end of the [update](#ERC1155Component-update) function.
+
-#### [](#embeddable_functions)Embeddable functions
-
-#### [](#ERC1155Component-balance_of)`balance_of(self: @ContractState, account: ContractAddress, token_id: u256) → u256` external
+#### Embeddable functions [!toc] [#embeddable_functions]
+
Returns the amount of `token_id` tokens owned by `account`.
+
-#### [](#ERC1155Component-balance_of_batch)`balance_of_batch(self: @ContractState, accounts: Span, token_ids: Span) → Span` external
-
+
Returns a list of balances derived from the `accounts` and `token_ids` pairs.
Requirements:
- `token_ids` and `accounts` must have the same length.
+
-#### [](#ERC1155Component-safe_transfer_from)`safe_transfer_from(ref self: ContractState, from: ContractAddress, to: ContractAddress, token_id: u256, value: u256, data: Span)` external
-
+
Transfers ownership of `value` amount of `token_id` from `from` if `to` is either an account or `IERC1155Receiver`.
`data` is additional data, it has no specified format and it is passed to `to`.
@@ -262,9 +362,13 @@ Requirements:
- If `to` refers to a non-account contract, it must implement `IERC1155Receiver::on_ERC1155_received` and return the required magic value.
Emits a [TransferSingle](#ERC1155Component-TransferSingle) event.
+
-#### [](#ERC1155Component-safe_batch_transfer_from)`safe_batch_transfer_from(ref self: ContractState, from: ContractAddress, to: ContractAddress, token_ids: Span, values: Span, data: Span)` external
-
+
Transfers ownership of `values` and `token_ids` pairs from `from` if `to` is either an account or `IERC1155Receiver`.
`data` is additional data, it has no specified format and it is passed to `to`.
@@ -280,9 +384,13 @@ Requirements:
- If `to` refers to a non-account contract, it must implement `IERC1155Receiver::on_ERC1155_batch_received` and return the acceptance magic value.
Emits a [TransferSingle](#ERC1155Component-TransferSingle) event if the arrays contain one element, and [TransferBatch](#ERC1155Component-TransferBatch) otherwise.
+
-#### [](#ERC1155Component-set_approval_for_all)`set_approval_for_all(ref self: ContractState, operator: ContractAddress, approved: bool)` external
-
+
Enables or disables approval for `operator` to manage all of the callers assets.
Requirements:
@@ -290,57 +398,102 @@ Requirements:
- `operator` cannot be the caller.
Emits an [ApprovalForAll](#ERC1155Component-ApprovalForAll) event.
+
-#### [](#ERC1155Component-is_approved_for_all)`is_approved_for_all(self: @ContractState, owner: ContractAddress, operator: ContractAddress) -> bool` external
-
+
Queries if `operator` is an authorized operator for `owner`.
+
-#### [](#ERC1155Component-uri)`uri(self: @ContractState, token_id: u256) -> ByteArray` external
+
This implementation returns the same URI for **all** token types. It relies on the token type ID substitution mechanism [specified in the EIP](https://eips.ethereum.org/EIPS/eip-1155#metadata).
Clients calling this function must replace the `id` substring with the actual token type ID.
+
-#### [](#ERC1155Component-balanceOf)`balanceOf(self: @ContractState, account: ContractAddress, tokenId: u256) → u256` external
-
+
See [ERC1155Component::balance\_of](#ERC1155Component-balance_of).
+
-#### [](#ERC1155Component-balanceOfBatch)`balanceOfBatch(self: @ContractState, accounts: Span, tokenIds: Span) → Span` external
-
+
See [ERC1155Component::balance\_of\_batch](#ERC1155Component-balance_of_batch).
+
-#### [](#ERC1155Component-safeTransferFrom)`safeTransferFrom(ref self: ContractState, from: ContractAddress, to: ContractAddress, tokenId: u256, value: u256, data: Span)` external
-
+
See [ERC1155Component::safe\_transfer\_from](#ERC1155Component-safe_transfer_from).
+
-#### [](#ERC1155Component-safeBatchTransferFrom)`safeBatchTransferFrom(ref self: ContractState, from: ContractAddress, to: ContractAddress, tokenIds: Span, values: Span, data: Span)` external
-
+
See [ERC1155Component::safe\_batch\_transfer\_from](#ERC1155Component-safe_batch_transfer_from).
+
-#### [](#ERC1155Component-setApprovalForAll)`setApprovalForAll(ref self: ContractState, operator: ContractAddress, approved: bool)` external
-
+
See [ERC1155Component::set\_approval\_for\_all](#ERC1155Component-set_approval_for_all).
+
-#### [](#ERC1155Component-isApprovedForAll)`isApprovedForAll(self: @ContractState, owner: ContractAddress, operator: ContractAddress) -> bool` external
-
+
See [ERC1155Component::is\_approved\_for\_all](#ERC1155Component-is_approved_for_all).
+
-#### [](#internal_functions)Internal functions
+#### Internal functions [!toc] [#internal_functions]
-#### [](#ERC1155Component-initializer)`initializer(ref self: ContractState, base_uri: ByteArray)` internal
-
-Initializes the contract by setting the token’s base URI as `base_uri`, and registering the supported interfaces. This should only be used inside the contract’s constructor.
+
+Initializes the contract by setting the token's base URI as `base_uri`, and registering the supported interfaces. This should only be used inside the contract's constructor.
Most ERC1155 contracts expose the [IERC1155MetadataURI](#IERC1155MetadataURI) interface which is what this initializer is meant to support. If the contract DOES NOT expose the [IERC1155MetadataURI](#IERC1155MetadataURI) interface, meaning tokens do not have a URI, the contract must instead use [initializer\_no\_metadata](#ERC1155Component-initializer_no_metadata) in the constructor. Failure to abide by these instructions can lead to unexpected issues especially with UIs.
+
-#### [](#ERC1155Component-initializer_no_metadata)`initializer_no_metadata(ref self: ContractState)` internal
-
+
Initializes the contract with no metadata by registering only the IERC1155 interface.
This initializer should ONLY be used during construction in the very specific instance when the contract does NOT expose the [IERC1155MetadataURI](#IERC1155MetadataURI) interface. Initializing a contract with this initializer means that tokens will not have a URI.
+
-#### [](#ERC1155Component-mint_with_acceptance_check)`mint_with_acceptance_check(ref self: ContractState, to: ContractAddress, token_id: u256, value: u256, data: Span)` internal
-
+
Creates a `value` amount of tokens of type `token_id`, and assigns them to `to`.
Requirements:
@@ -349,9 +502,13 @@ Requirements:
- If `to` refers to a smart contract, it must implement `IERC1155Receiver::on_ERC1155_received` and return the acceptance magic value.
Emits a [TransferSingle](#ERC1155Component-TransferSingle) event.
+
-#### [](#ERC1155Component-batch_mint_with_acceptance_check)`batch_mint_with_acceptance_check(ref self: ContractState, to: ContractAddress, token_ids: Span, values: Span, data: Span)` internal
-
+
Batched version of [mint\_with\_acceptance\_check](#ERC1155Component-mint_with_acceptance_check).
Requirements:
@@ -361,9 +518,13 @@ Requirements:
- If `to` refers to a smart contract, it must implement `IERC1155Receiver::on_ERC1155_batch_received` and return the acceptance magic value.
Emits a [TransferBatch](#ERC1155Component-TransferBatch) event.
+
-#### [](#ERC1155Component-burn)`burn(ref self: ContractState, from: ContractAddress, token_id: u256, value: u256)` internal
-
+
Destroys a `value` amount of tokens of type `token_id` from `from`.
Requirements:
@@ -372,9 +533,13 @@ Requirements:
- `from` must have at least `value` amount of tokens of type `token_id`.
Emits a [TransferSingle](#ERC1155Component-TransferSingle) event.
+
-#### [](#ERC1155Component-batch_burn)`batch_burn(ref self: ContractState, from: ContractAddress, token_ids: Span, values: Span)` internal
-
+
Batched version of [burn](#ERC1155Component-burn).
Requirements:
@@ -384,9 +549,13 @@ Requirements:
- `token_ids` and `values` must have the same length.
Emits a [TransferBatch](#ERC1155Component-TransferBatch) event.
+
-#### [](#ERC1155Component-update_with_acceptance_check)`update_with_acceptance_check(ref self: ContractState, from: ContractAddress, to: ContractAddress, token_ids: Span, values: Span, data: Span)` internal
-
+
Version of `update` that performs the token acceptance check by calling `onERC1155Received` or `onERC1155BatchReceived` in the receiver if it implements `IERC1155Receiver`, otherwise by checking if it is an account.
Requirements:
@@ -395,9 +564,13 @@ Requirements:
- `token_ids` and `values` must have the same length.
Emits a [TransferSingle](#ERC1155Component-TransferSingle) event if the arrays contain one element, and [TransferBatch](#ERC1155Component-TransferBatch) otherwise.
+
-#### [](#ERC1155Component-update)`update(ref self: ContractState, from: ContractAddress, to: ContractAddress, token_ids: Span, values: Span)` internal
-
+
Transfers a `value` amount of tokens of type `id` from `from` to `to`. Will mint (or burn) if `from` (or `to`) is the zero address.
Requirements:
@@ -409,9 +582,13 @@ Emits a [TransferSingle](#ERC1155Component-TransferSingle) event if the arrays c
This function can be extended using the [ERC1155HooksTrait](#ERC1155Component-ERC1155HooksTrait), to add functionality before and/or after the transfer, mint, or burn.
The ERC1155 acceptance check is not performed in this function. See [update\_with\_acceptance\_check](#ERC1155Component-update_with_acceptance_check) instead.
+
-#### [](#ERC1155Component-_set_base_uri)`_set_base_uri(ref self: ContractState, base_uri: ByteArray)` internal
-
+
Sets a new URI for all token types, by relying on the token type ID substitution mechanism [specified in the EIP](https://eips.ethereum.org/EIPS/eip-1155#metadata).
By this mechanism, any occurrence of the `id` substring in either the URI or any of the values in the JSON file at said URI will be replaced by clients with the token type ID.
@@ -419,26 +596,49 @@ By this mechanism, any occurrence of the `id` substring in either the URI or any
For example, the `https://token-cdn-domain/\id\.json` URI would be interpreted by clients as `https://token-cdn-domain/000000000000...000000000000004cce0.json` for token type ID `0x4cce0`.
Because these URIs cannot be meaningfully represented by the `URI` event, this function emits no events.
+
-#### [](#events_2)Events
-
-#### [](#ERC1155Component-TransferSingle)`TransferSingle(operator: ContractAddress, from: ContractAddress, to: ContractAddress, id: u256, value: u256)` event
+#### Events [!toc] [#events_2]
+
See [IERC1155::TransferSingle](#IERC1155-TransferSingle).
+
-#### [](#ERC1155Component-TransferBatch)`TransferBatch(operator: ContractAddress, from: ContractAddress, to: ContractAddress, ids: Span, values: Span)` event
-
+
See [IERC1155::TransferBatch](#IERC1155-TransferBatch).
+
-#### [](#ERC1155Component-ApprovalForAll)`ApprovalForAll(owner: ContractAddress, operator: ContractAddress, approved: bool)` event
-
+
See [IERC1155::ApprovalForAll](#IERC1155-ApprovalForAll).
+
-#### [](#ERC1155Component-URI)`URI(value: ByteArray, id: u256)` event
+
See [IERC1155::URI](#IERC1155-URI).
+
+
+### `ERC1155ReceiverComponent` [toc] [#ERC1155ReceiverComponent]
-### [](#ERC1155ReceiverComponent)`ERC1155ReceiverComponent`[](https://github.com/OpenZeppelin/cairo-contracts/blob/release-v3.0.0-alpha.1/packages/token/src/erc1155/erc1155_receiver.cairo)
+
```rust
use openzeppelin_token::erc1155::ERC1155ReceiverComponent;
@@ -450,7 +650,7 @@ Implementing [SRC5Component](introspection#SRC5Component) is a requirement for t
[Embeddable Mixin Implementations](../components#mixins)
-ERC1155MixinImpl
+#### ERC1155MixinImpl [!toc] [#ERC1155ReceiverComponent-Embeddable-Impls-ERC1155MixinImpl]
- [`ERC1155ReceiverImpl`](#ERC1155ReceiverComponent-Embeddable-Impls-ERC1155ReceiverImpl)
- [`ERC1155ReceiverCamelImpl`](#ERC1155ReceiverComponent-Embeddable-Impls-ERC1155ReceiverCamelImpl)
@@ -458,49 +658,74 @@ ERC1155MixinImpl
Embeddable Implementations
-ERC1155ReceiverImpl
+#### ERC1155ReceiverImpl [!toc] [#ERC1155ReceiverComponent-Embeddable-Impls-ERC1155ReceiverImpl]
- [`on_erc1155_received(self, operator, from, token_id, value, data)`](#ERC1155ReceiverComponent-on_erc1155_received)
- [`on_erc1155_batch_received(self, operator, from, token_ids, values, data)`](#ERC1155ReceiverComponent-on_erc1155_batch_received)
-ERC1155ReceiverCamelImpl
+#### ERC1155ReceiverCamelImpl [!toc] [#ERC1155ReceiverComponent-Embeddable-Impls-ERC1155ReceiverCamelImpl]
- [`onERC1155Received(self, operator, from, tokenId, value, data)`](#ERC1155ReceiverComponent-onERC1155Received)
- [`onERC1155BatchReceived(self, operator, from, tokenIds, values, data)`](#ERC1155ReceiverComponent-onERC1155BatchReceived)
Internal Functions
-InternalImpl
+#### InternalImpl [!toc] [#ERC1155ReceiverComponent-InternalImpl]
- [`initializer(self)`](#ERC1155ReceiverComponent-initializer)
-#### [](#embeddable_functions_2)Embeddable functions
-
-#### [](#ERC1155ReceiverComponent-on_erc1155_received)`on_erc1155_received(self: @ContractState, operator: ContractAddress, from: ContractAddress, token_id: u256, value: u256, data Span) -> felt252` external
+#### Embeddable functions [!toc] [#embeddable_functions_2]
+
Returns the `IERC1155Receiver` interface ID.
+
-#### [](#ERC1155ReceiverComponent-on_erc1155_batch_received)`on_erc1155_batch_received(self: @ContractState, operator: ContractAddress, from: ContractAddress, token_ids: Span, values: Span, data Span) -> felt252` external
-
+
Returns the `IERC1155Receiver` interface ID.
+
-#### [](#ERC1155ReceiverComponent-onERC1155Received)`onERC1155Received(self: @ContractState, operator: ContractAddress, from: ContractAddress, tokenId: u256, value: u256, data Span) -> felt252` external
-
+
See [ERC1155ReceiverComponent::on\_erc1155\_received](#ERC1155ReceiverComponent-on_erc1155_received).
+
-#### [](#ERC1155ReceiverComponent-onERC1155BatchReceived)`onERC1155BatchReceived(self: @ContractState, operator: ContractAddress, from: ContractAddress, tokenIds: Span, values: Span, data Span) -> felt252` external
-
+
See [ERC1155ReceiverComponent::on\_erc1155\_batch\_received](#ERC1155ReceiverComponent-on_erc1155_batch_received).
+
-#### [](#internal_functions_2)Internal functions
-
-#### [](#ERC1155ReceiverComponent-initializer)`initializer(ref self: ContractState)` internal
+#### Internal functions [!toc] [#internal_functions_2]
+
Registers the `IERC1155Receiver` interface ID as supported through introspection.
+
## [](#presets)Presets
-### [](#ERC1155Upgradeable)`ERC1155Upgradeable`[](https://github.com/OpenZeppelin/cairo-contracts/blob/release-v3.0.0-alpha.1/packages/presets/src/erc1155.cairo)
+### `ERC1155Upgradeable` [toc] [#ERC1155Upgradeable]
+
+
```rust
use openzeppelin_presets::ERC1155;
@@ -510,7 +735,9 @@ Upgradeable ERC1155 contract leveraging [ERC1155Component](#ERC1155Component).
[Sierra class hash](../presets)
-0x06c8912d4397bb25c73a571bced14cedb959a7caa40b76fb0ce19a57d4a7a9c0
+```text
+{{ERC1155UpgradeableClassHash}}
+```
Constructor
@@ -530,24 +757,32 @@ External Functions
- [`upgrade(self, new_class_hash)`](#ERC1155Upgradeable-upgrade)
-#### [](#ERC1155Upgradeable-constructor-section)Constructor
-
-#### [](#ERC1155Upgradeable-constructor)`constructor(ref self: ContractState, base_uri: ByteArray, recipient: ContractAddress, token_ids: Span, values: Span, owner: ContractAddress)` constructor
+#### Constructor [!toc] [#ERC1155Upgradeable-constructor-section]
+
Sets the `base_uri` for all tokens and registers the supported interfaces. Mints the `values` for `token_ids` tokens to `recipient`. Assigns `owner` as the contract owner with permissions to upgrade.
Requirements:
- `to` is either an account contract (supporting ISRC6) or supports the `IERC1155Receiver` interface.
- `token_ids` and `values` must have the same length.
+
-#### [](#ERC1155Upgradeable-external-functions)External Functions
-
-#### [](#ERC1155Upgradeable-upgrade)`upgrade(ref self: ContractState, new_class_hash: ClassHash)` external
+#### External Functions [!toc] [#ERC1155Upgradeable-external-functions]
+
Upgrades the contract to a new implementation given by `new_class_hash`.
Requirements:
- The caller is the contract owner.
- `new_class_hash` cannot be zero.
+
diff --git a/content/contracts-cairo/api/erc20.mdx b/content/contracts-cairo/api/erc20.mdx
index a62efc6..539c38c 100644
--- a/content/contracts-cairo/api/erc20.mdx
+++ b/content/contracts-cairo/api/erc20.mdx
@@ -8,9 +8,18 @@ For an overview of ERC20, read our [ERC20 guide](../erc20).
## [](#interfaces)Interfaces
-Starting from version `3.x.x`, the interfaces are no longer part of the `openzeppelin_token` package. The references documented here are contained in the `openzeppelin_interfaces` package version `v2.1.0`.
+
+Starting from version `3.x.x`, the interfaces are no longer part of the `openzeppelin_access` package. The references
+documented here are contained in the `openzeppelin_interfaces` package version `{{openzeppelin_interfaces_version}}`.
+
-### [](#IERC20)`IERC20`[](https://github.com/OpenZeppelin/cairo-contracts/blob/release-v3.0.0-alpha.1/packages/interfaces/src/token/erc20.cairo)
+import { UMBRELLA_VERSION } from "../utils/constants.js";
+
+### `IERC20` [toc] [#IERC20]
+
```rust
use openzeppelin_interfaces::erc20::IERC20;
@@ -32,53 +41,89 @@ Events
- [`Transfer(from, to, value)`](#IERC20-Transfer)
- [`Approval(owner, spender, value)`](#IERC20-Approval)
-#### [](#IERC20-Functions)Functions
-
-#### [](#IERC20-total_supply)`total_supply() → u256` external
+#### Functions [!toc] [#IERC20-Functions]
+
Returns the amount of tokens in existence.
+
-#### [](#IERC20-balance_of)`balance_of(account: ContractAddress) → u256` external
-
+
Returns the amount of tokens owned by `account`.
+
-#### [](#IERC20-allowance)`allowance(owner: ContractAddress, spender: ContractAddress) → u256` external
-
+
Returns the remaining number of tokens that `spender` is allowed to spend on behalf of `owner` through [transfer\_from](#transfer_from). This is zero by default.
This value changes when [approve](#IERC20-approve) or [transfer\_from](#IERC20-transfer_from) are called.
+
-#### [](#IERC20-transfer)`transfer(recipient: ContractAddress, amount: u256) → bool` external
-
-Moves `amount` tokens from the caller’s token balance to `to`. Returns `true` on success, reverts otherwise.
+
+Moves `amount` tokens from the caller's token balance to `to`. Returns `true` on success, reverts otherwise.
Emits a [Transfer](#IERC20-Transfer) event.
+
-#### [](#IERC20-transfer_from)`transfer_from(sender: ContractAddress, recipient: ContractAddress, amount: u256) → bool` external
-
-Moves `amount` tokens from `sender` to `recipient` using the allowance mechanism. `amount` is then deducted from the caller’s allowance. Returns `true` on success, reverts otherwise.
+
+Moves `amount` tokens from `sender` to `recipient` using the allowance mechanism. `amount` is then deducted from the caller's allowance. Returns `true` on success, reverts otherwise.
Emits a [Transfer](#IERC20-Transfer) event.
+
-#### [](#IERC20-approve)`approve(spender: ContractAddress, amount: u256) → bool` external
-
-Sets `amount` as the allowance of `spender` over the caller’s tokens. Returns `true` on success, reverts otherwise.
+
+Sets `amount` as the allowance of `spender` over the caller's tokens. Returns `true` on success, reverts otherwise.
Emits an [Approval](#ERC20-Approval) event.
+
-#### [](#IERC20-Events)Events
-
-#### [](#IERC20-Transfer)`Transfer(from: ContractAddress, to: ContractAddress, value: u256)` event
+#### Events [!toc] [#IERC20-Events]
+
Emitted when `value` tokens are moved from one address (`from`) to another (`to`).
Note that `value` may be zero.
+
-#### [](#IERC20-Approval)`Approval(owner: ContractAddress, spender: ContractAddress, value: u256)` event
-
+
Emitted when the allowance of a `spender` for an `owner` is set. `value` is the new allowance.
+
-### [](#IERC20Metadata)`IERC20Metadata`[](https://github.com/OpenZeppelin/cairo-contracts/blob/release-v3.0.0-alpha.1/packages/interfaces/src/token/erc20.cairo)
+### `IERC20Metadata` [toc] [#IERC20Metadata]
+
```rust
use openzeppelin_interfaces::erc20::IERC20Metadata;
@@ -92,18 +137,29 @@ Functions
- [`symbol()`](#IERC20Metadata-symbol)
- [`decimals()`](#IERC20Metadata-decimals)
-#### [](#IERC20Metadata-Functions)Functions
-
-#### [](#IERC20Metadata-name)`name() → ByteArray` external
+#### Functions [!toc] [#IERC20Metadata-Functions]
+
Returns the name of the token.
+
-#### [](#IERC20Metadata-symbol)`symbol() → ByteArray` external
-
+
Returns the ticker symbol of the token.
+
-#### [](#IERC20Metadata-decimals)`decimals() → u8` external
-
+
Returns the number of decimals the token uses - e.g. `8` means to divide the token amount by `100000000` to get its user-readable representation.
For example, if `decimals` equals `2`, a balance of `505` tokens should be displayed to a user as `5.05` (`505 / 10 ** 2`).
@@ -111,8 +167,13 @@ For example, if `decimals` equals `2`, a balance of `505` tokens should be displ
Tokens usually opt for a value of `18`, imitating the relationship between Ether and Wei. This is the default value returned by this function. To create a custom decimals implementation, see [Customizing decimals](../erc20#customizing_decimals).
This information is only used for *display* purposes: it in no way affects any of the arithmetic of the contract.
+
-### [](#IERC20Permit)`IERC20Permit`[](https://github.com/OpenZeppelin/cairo-contracts/blob/release-v3.0.0-alpha.1/packages/interfaces/src/token/erc20.cairo)
+### `IERC20Permit` [toc] [#IERC20Permit]
+
```rust
use openzeppelin_interfaces::erc20::IERC20Permit;
@@ -126,21 +187,37 @@ Functions
- [`nonces(owner)`](#IERC20Permit-nonces)
- [`DOMAIN_SEPARATOR()`](#IERC20Permit-DOMAIN_SEPARATOR)
-#### [](#IERC20Permit-Functions)Functions
-
-#### [](#IERC20Permit-permit)`permit(owner: ContractAddress, spender: ContractAddress, amount: u256, deadline: u64, signature: Span)` external
+#### Functions [!toc] [#IERC20Permit-Functions]
+
Sets `amount` as the allowance of `spender` over `owner`'s tokens after validating the signature.
+
-#### [](#IERC20Permit-nonces)`nonces(owner: ContractAddress) → felt252` external
-
+
Returns the current nonce of `owner`. A nonce value must be included whenever a signature for `permit` call is generated.
+
-#### [](#IERC20Permit-DOMAIN_SEPARATOR)`DOMAIN_SEPARATOR() → felt252` external
-
+
Returns the domain separator used in generating a message hash for `permit` signature. The domain hashing logic follows the [SNIP12](https://github.com/starknet-io/SNIPs/blob/main/SNIPS/snip-12.md) standard.
+
-### [](#IERC4626)`IERC4626`[](https://github.com/OpenZeppelin/cairo-contracts/blob/release-v3.0.0-alpha.1/packages/interfaces/src/token/erc4626.cairo)
+### `IERC4626` [toc] [#IERC4626]
+
```rust
use openzeppelin_interfaces::erc4626::IERC4626;
@@ -172,29 +249,40 @@ Events
- [`Deposit(sender, owner, assets, shares)`](#IERC4626-Deposit)
- [`Withdraw(sender, receiver, owner, assets, shares)`](#IERC4626-Withdraw)
-#### [](#IERC4626-Functions)Functions
-
-#### [](#IERC4626-asset)`asset() → ContractAddress` external
+#### Functions [!toc] [#IERC4626-Functions]
+
Returns the address of the underlying token used for the Vault for accounting, depositing, and withdrawing.
Requirements:
- MUST be an ERC20 token contract.
- MUST NOT panic.
+
-#### [](#IERC4626-total_assets)`total_assets() → u256` external
-
-Returns the total amount of the underlying asset that is “managed” by Vault.
+
+Returns the total amount of the underlying asset that is "managed" by Vault.
Requirements:
- SHOULD include any compounding that occurs from yield.
- MUST be inclusive of any fees that are charged against assets in the Vault.
- MUST NOT panic.
+
-#### [](#IERC4626-convert_to_shares)`convert_to_shares(assets: u256) → u256` external
-
+
Returns the amount of shares that the Vault would exchange for the amount of `assets` provided irrespective of slippage or fees.
Requirements:
@@ -205,10 +293,14 @@ Requirements:
- MUST NOT panic unless due to integer overflow caused by an unreasonably large input.
- MUST round down towards 0.
-This calculation MAY NOT reflect the "per-user" price-per-share, and instead should reflect the "average-user’s" price-per-share, meaning what the average user should expect to see when exchanging to and from.
-
-#### [](#IERC4626-convert_to_assets)`convert_to_assets(shares: u256) → u256` external
+This calculation MAY NOT reflect the "per-user" price-per-share, and instead should reflect the "average-user's" price-per-share, meaning what the average user should expect to see when exchanging to and from.
+
+
Returns the amount of assets that the Vault would exchange for the amount of `shares` provided irrespective of slippage or fees.
Requirements:
@@ -219,10 +311,14 @@ Requirements:
- MUST NOT panic unless due to integer overflow caused by an unreasonably large input.
- MUST round down towards 0.
-This calculation MAY NOT reflect the “per-user” price-per-share, and instead should reflect the “average-user’s” price-per-share, meaning what the average user should expect to see when exchanging to and from.
-
-#### [](#IERC4626-max_deposit)`max_deposit(receiver: ContractAddress) → u256` external
+This calculation MAY NOT reflect the "per-user" price-per-share, and instead should reflect the "average-user's" price-per-share, meaning what the average user should expect to see when exchanging to and from.
+
+
Returns the maximum amount of the underlying asset that can be deposited into the Vault for `receiver`, through a deposit call.
Requirements:
@@ -230,9 +326,13 @@ Requirements:
- MUST return a limited value if receiver is subject to some deposit limit.
- MUST return 2 \** 256 - 1 if there is no limit on the maximum amount of assets that may be deposited.
- MUST NOT panic.
+
-#### [](#IERC4626-preview_deposit)`preview_deposit(assets: u256) → u256` external
-
+
Allows an on-chain or off-chain user to simulate the effects of their deposit at the current block, given current on-chain conditions.
Requirements:
@@ -243,9 +343,13 @@ Requirements:
- MUST NOT panic.
Any unfavorable discrepancy between [IERC4626::convert\_to\_shares](#IERC4626-convert_to_shares) and `preview_deposit` SHOULD be considered slippage in share price or some other type of condition, meaning the depositor will lose assets by depositing.
+
-#### [](#IERC4626-deposit)`deposit(assets: u256, receiver: ContractAddress) → u256` external
-
+
Mints Vault shares to `receiver` by depositing exactly amount of `assets`.
Requirements:
@@ -254,10 +358,14 @@ Requirements:
- MAY support an additional flow in which the underlying tokens are owned by the Vault contract before the deposit execution, and are accounted for during deposit.
- MUST panic if all of assets cannot be deposited (due to deposit limit being reached, slippage, the user not approving enough underlying tokens to the Vault contract, etc).
-Most implementations will require pre-approval of the Vault with the Vault’s underlying asset token.
-
-#### [](#IERC4626-max_mint)`max_mint(receiver: ContractAddress) → u256` external
+Most implementations will require pre-approval of the Vault with the Vault's underlying asset token.
+
+
Returns the maximum amount of the Vault shares that can be minted for the receiver, through a mint call.
Requirements:
@@ -265,9 +373,13 @@ Requirements:
- MUST return a limited value if receiver is subject to some mint limit.
- MUST return 2 \** 256 - 1 if there is no limit on the maximum amount of shares that may be minted.
- MUST NOT panic.
+
-#### [](#IERC4626-preview_mint)`preview_mint(shares: u256) → u256` external
-
+
Allows an on-chain or off-chain user to simulate the effects of their mint at the current block, given current on-chain conditions.
Requirements:
@@ -278,9 +390,13 @@ Requirements:
- MUST NOT panic.
Any unfavorable discrepancy between [IERC4626::convert\_to\_assets](#IERC4626-convert_to_assets) and `preview_mint` SHOULD be considered slippage in share price or some other type of condition, meaning the depositor will lose assets by minting.
+
-#### [](#IERC4626-mint)`mint(shares: u256, receiver: ContractAddress) → u256` external
-
+
Mints exactly shares Vault shares to receiver by depositing amount of underlying tokens.
Requirements:
@@ -289,19 +405,27 @@ Requirements:
- MAY support an additional flow in which the underlying tokens are owned by the Vault contract before the mint execution, and are accounted for during mint.
- MUST panic if all of shares cannot be minted (due to deposit limit being reached, slippage, the user not approving enough underlying tokens to the Vault contract, etc).
-Most implementations will require pre-approval of the Vault with the Vault’s underlying asset token.
-
-#### [](#IERC4626-max_withdraw)`max_withdraw(owner: ContractAddress) → u256` external
+Most implementations will require pre-approval of the Vault with the Vault's underlying asset token.
+
+
Returns the maximum amount of the underlying asset that can be withdrawn from the owner balance in the Vault, through a withdraw call.
Requirements:
- MUST return a limited value if owner is subject to some withdrawal limit or timelock.
- MUST NOT panic.
+
-#### [](#IERC4626-preview_withdraw)`preview_withdraw(assets: u256) → u256` external
-
+
Allows an on-chain or off-chain user to simulate the effects of their withdrawal at the current block, given current on-chain conditions.
Requirements:
@@ -312,9 +436,13 @@ Requirements:
- MUST NOT panic.
Any unfavorable discrepancy between [IERC4626::convert\_to\_shares](#IERC4626-convert_to_shares) and `preview_withdraw` SHOULD be considered slippage in share price or some other type of condition, meaning the depositor will lose assets by depositing.
+
-#### [](#IERC4626-withdraw)`withdraw(assets: u256, receiver: ContractAddress, owner: ContractAddress) → u256` external
-
+
Burns shares from owner and sends exactly assets of underlying tokens to receiver.
Requirements:
@@ -324,9 +452,13 @@ Requirements:
- MUST revert if all of assets cannot be withdrawn (due to withdrawal limit being reached, slippage, the owner not having enough shares, etc).
Some implementations will require pre-requesting to the Vault before a withdrawal may be performed. Those methods should be performed separately.
+
-#### [](#IERC4626-max_redeem)`max_redeem(owner: ContractAddress) → u256` external
-
+
Returns the maximum amount of Vault shares that can be redeemed from the owner balance in the Vault, through a redeem call.
Requirements:
@@ -334,9 +466,13 @@ Requirements:
- MUST return a limited value if owner is subject to some withdrawal limit or timelock.
- MUST return `ERC20::balance_of(owner)` if `owner` is not subject to any withdrawal limit or timelock.
- MUST NOT panic.
+
-#### [](#IERC4626-preview_redeem)`preview_redeem(shares: u256) → u256` external
-
+
Allows an on-chain or off-chain user to simulate the effects of their redeemption at the current block, given current on-chain conditions.
Requirements:
@@ -347,9 +483,13 @@ Requirements:
- MUST NOT panic.
Any unfavorable discrepancy between [IERC4626::convert\_to\_assets](#IERC4626-convert_to_assets) and `preview_redeem` SHOULD be considered slippage in share price or some other type of condition, meaning the depositor will lose assets by redeeming.
+
-#### [](#IERC4626-redeem)`redeem(shares: u256, receiver: ContractAddress, owner: ContractAddress) → u256` external
-
+
Burns exactly shares from owner and sends assets of underlying tokens to receiver.
Requirements:
@@ -359,20 +499,33 @@ Requirements:
- MUST revert if all of shares cannot be redeemed (due to withdrawal limit being reached, slippage, the owner not having enough shares, etc).
Some implementations will require pre-requesting to the Vault before a withdrawal may be performed. Those methods should be performed separately.
+
-#### [](#IERC4626-Events)Events
-
-#### [](#IERC4626-Deposit)`Deposit(sender: ContractAddress, owner: ContractAddress, assets: u256, shares: u256)` event
+#### Events [!toc] [#IERC4626-Events]
+
Emitted when `sender` exchanges `assets` for `shares` and transfers those `shares` to `owner`.
+
-#### [](#IERC4626-Withdraw)`Withdraw(sender: ContractAddress, receiver: ContractAddress, owner: ContractAddress, assets: u256, shares: u256)` event
-
+
Emitted when `sender` exchanges `shares`, owned by `owner`, for `assets` and transfers those `assets` to `receiver`.
+
-## [](#core)Core
+## Core
-### [](#ERC20Component)`ERC20Component`[](https://github.com/OpenZeppelin/cairo-contracts/blob/release-v3.0.0-alpha.1/packages/token/src/erc20/erc20.cairo)
+### `ERC20Component` [toc] [#ERC20Component]
+
```rust
use openzeppelin_token::erc20::ERC20Component;
@@ -384,14 +537,14 @@ See [Hooks](#ERC20Component-Hooks) to understand how are hooks used.
Hooks
-ERC20HooksTrait
+#### ERC20HooksTrait [!toc] [#ERC20Component-ERC20HooksTrait]
- [`before_update(self, from, recipient, amount)`](#ERC20Component-before_update)
- [`after_update(self, from, recipient, amount)`](#ERC20Component-after_update)
[Embeddable Mixin Implementations](../components#mixins)
-ERC20MixinImpl
+#### ERC20MixinImpl [!toc] [#ERC20Component-Embeddable-Impls-ERC20MixinImpl]
- [`ERC20Impl`](#ERC20Component-Embeddable-Impls-ERC20Impl)
- [`ERC20MetadataImpl`](#ERC20Component-Embeddable-Impls-ERC20MetadataImpl)
@@ -399,7 +552,7 @@ ERC20MixinImpl
Embeddable Implementations
-ERC20Impl
+#### ERC20Impl [!toc] [#ERC20Component-Embeddable-Impls-ERC20Impl]
- [`total_supply(self)`](#ERC20Component-total_supply)
- [`balance_of(self, account)`](#ERC20Component-balance_of)
@@ -408,31 +561,31 @@ ERC20Impl
- [`transfer_from(self, sender, recipient, amount)`](#ERC20Component-transfer_from)
- [`approve(self, spender, amount)`](#ERC20Component-approve)
-ERC20MetadataImpl
+#### ERC20MetadataImpl [!toc] [#ERC20Component-Embeddable-Impls-ERC20MetadataImpl]
- [`name(self)`](#ERC20Component-name)
- [`symbol(self)`](#ERC20Component-symbol)
- [`decimals(self)`](#ERC20Component-decimals)
-ERC20CamelOnlyImpl
+#### ERC20CamelOnlyImpl [!toc] [#ERC20Component-Embeddable-Impls-ERC20CamelOnlyImpl]
- [`totalSupply(self)`](#ERC20Component-totalSupply)
- [`balanceOf(self, account)`](#ERC20Component-balanceOf)
- [`transferFrom(self, sender, recipient, amount)`](#ERC20Component-transferFrom)
-ERC20PermitImpl
+#### ERC20PermitImpl [!toc] [#ERC20Component-Embeddable-Impls-ERC20PermitImpl]
- [`permit(self, owner, spender, amount, deadline, signature)`](#ERC20Component-permit)
- [`nonces(self, owner)`](#ERC20Component-nonces)
- [`DOMAIN_SEPARATOR(self)`](#ERC20Component-DOMAIN_SEPARATOR)
-SNIP12MetadataExternalImpl
+#### SNIP12MetadataExternalImpl [!toc] [#ERC20Component-Embeddable-Impls-SNIP12MetadataExternalImpl]
- [`snip12_metadata(self)`](#ERC20Component-snip12_metadata)
Internal implementations
-InternalImpl
+#### InternalImpl [!toc] [#ERC20Component-InternalImpl]
- [`initializer(self, name, symbol)`](#ERC20Component-initializer)
- [`mint(self, recipient, amount)`](#ERC20Component-mint)
@@ -447,45 +600,72 @@ Events
- [`Transfer(from, to, value)`](#ERC20Component-Transfer)
- [`Approval(owner, spender, value)`](#ERC20Component-Approval)
-#### [](#ERC20Component-Hooks)Hooks
+#### Hooks [!toc] [#ERC20Component-Hooks]
Hooks are functions which implementations can extend the functionality of the component source code. Every contract using ERC20Component is expected to provide an implementation of the ERC20HooksTrait. For basic token contracts, an empty implementation with no logic must be provided.
You can use `openzeppelin_token::erc20::ERC20HooksEmptyImpl` which is already available as part of the library for this purpose.
-#### [](#ERC20Component-before_update)`before_update(ref self: ContractState, from: ContractAddress, recipient: ContractAddress, amount: u256)` hook
-
+
Function executed at the beginning of the [update](#ERC20Component-update) function prior to any other logic.
+
-#### [](#ERC20Component-after_update)`after_update(ref self: ContractState, from: ContractAddress, recipient: ContractAddress, amount: u256)` hook
-
+
Function executed at the end of the [update](#ERC20Component-update) function.
+
-#### [](#ERC20Component-Embeddable-functions)Embeddable functions
-
-#### [](#ERC20Component-total_supply)`total_supply(@self: ContractState) → u256` external
+#### Embeddable functions [!toc] [#ERC20Component-Embeddable-Functions]
+
See [IERC20::total\_supply](#IERC20-total_supply).
+
-#### [](#ERC20Component-balance_of)`balance_of(@self: ContractState, account: ContractAddress) → u256` external
-
+
See [IERC20::balance\_of](#IERC20-balance_of).
+
-#### [](#ERC20Component-allowance)`allowance(@self: ContractState, owner: ContractAddress, spender: ContractAddress) → u256` external
-
+
See [IERC20::allowance](#IERC20-allowance).
+
-#### [](#ERC20Component-transfer)`transfer(ref self: ContractState, recipient: ContractAddress, amount: u256) → bool` external
-
+
See [IERC20::transfer](#IERC20-transfer).
Requirements:
- `recipient` cannot be the zero address.
- The caller must have a balance of at least `amount`.
+
-#### [](#ERC20Component-transfer_from)`transfer_from(ref self: ContractState, sender: ContractAddress, recipient: ContractAddress, amount: u256) → bool` external
-
+
See [IERC20::transfer\_from](#IERC20-transfer_from).
Requirements:
@@ -494,47 +674,79 @@ Requirements:
- `sender` must have a balance of at least `amount`.
- `recipient` cannot be the zero address.
- The caller must have allowance for `sender`'s tokens of at least `amount`.
+
-#### [](#ERC20Component-approve)`approve(ref self: ContractState, spender: ContractAddress, amount: u256) → bool` external
-
+
See [IERC20::approve](#IERC20-approve).
Requirements:
- `spender` cannot be the zero address.
+
-#### [](#ERC20Component-name)`name() → ByteArray` external
-
+
See [IERC20Metadata::name](#IERC20Metadata-name).
+
-#### [](#ERC20Component-symbol)`symbol() → ByteArray` external
-
+
See [IERC20Metadata::symbol](#IERC20Metadata-symbol).
+
-#### [](#ERC20Component-decimals)`decimals() → u8` external
-
+
See [IERC20Metadata::decimals](#IERC20Metadata-decimals).
+
-#### [](#ERC20Component-totalSupply)`totalSupply(self: @ContractState) → u256` external
-
+
See [IERC20::total\_supply](#IERC20-total_supply).
Supports the Cairo v0 convention of writing external methods in camelCase as discussed [here](https://github.com/OpenZeppelin/cairo-contracts/discussions/34).
+
-#### [](#ERC20Component-balanceOf)`balanceOf(self: @ContractState, account: ContractAddress) → u256` external
-
+
See [IERC20::balance\_of](#IERC20-balance_of).
Supports the Cairo v0 convention of writing external methods in camelCase as discussed [here](https://github.com/OpenZeppelin/cairo-contracts/discussions/34).
+
-#### [](#ERC20Component-transferFrom)`transferFrom(ref self: ContractState, sender: ContractAddress, recipient: ContractAddress) → bool` external
-
+
See [IERC20::transfer\_from](#IERC20-transfer_from).
Supports the Cairo v0 convention of writing external methods in camelCase as discussed [here](https://github.com/OpenZeppelin/cairo-contracts/discussions/34).
+
-#### [](#ERC20Component-permit)`permit(ref self: ContractState, owner: ContractAddress, spender: ContractAddress, amount: u256, deadline: u64, signature: Span) → bool` external
-
+
Sets `amount` as the allowance of `spender` over `owner`'s tokens after validating the signature.
Requirements:
@@ -545,33 +757,53 @@ Requirements:
- `signature` is a valid signature that can be validated with a call to `owner` account.
- `signature` must use the current nonce of the `owner`.
-Emits an [Approval](#ERC20-Approval) event. Every successful call increases \`owner’s nonce by one.
-
-#### [](#ERC20Component-nonces)`nonces(self: @ContractState, owner: ContractAddress) → felt252` external
+Emits an [Approval](#ERC20-Approval) event. Every successful call increases \`owner's nonce by one.
+
+
Returns the current nonce of `owner`. A nonce value must be included whenever a signature for `permit` call is generated.
+
-#### [](#ERC20Component-DOMAIN_SEPARATOR)`DOMAIN_SEPARATOR(self: @ContractState) → felt252` external
-
+
Returns the domain separator used in generating a message hash for `permit` signature. The domain hashing logic follows the [SNIP12](https://github.com/starknet-io/SNIPs/blob/main/SNIPS/snip-12.md) standard.
+
-#### [](#ERC20Component-snip12_metadata)`snip12_metadata(self: @ContractState) → (felt252, felt252)` external
-
+
Returns the domain name and version used to generate the message hash for permit signature.
The returned tuple contains:
- `t.0`: The name used in the [SNIP12Metadata](utilities#snip12) implementation.
- `t.1`: The version used in the [SNIP12Metadata](utilities#snip12) implementation.
-
-#### [](#ERC20Component-Internal-functions)Internal functions
-
-#### [](#ERC20Component-initializer)`initializer(ref self: ContractState, name: ByteArray, symbol: ByteArray)` internal
-
-Initializes the contract by setting the token name and symbol. This should be used inside of the contract’s constructor.
-
-#### [](#ERC20Component-mint)`mint(ref self: ContractState, recipient: ContractAddress, amount: u256)` internal
-
+
+
+#### Internal functions [!toc] [#ERC20Component-Internal-Functions]
+
+
+Initializes the contract by setting the token name and symbol. This should be used inside of the contract's constructor.
+
+
+
Creates an `amount` number of tokens and assigns them to `recipient`.
Emits a [Transfer](#ERC20Component-Transfer) event with `from` being the zero address.
@@ -579,9 +811,13 @@ Emits a [Transfer](#ERC20Component-Transfer) event with `from` being the zero ad
Requirements:
- `recipient` cannot be the zero address.
+
-#### [](#ERC20Component-burn)`burn(ref self: ContractState, account: ContractAddress, amount: u256)` internal
-
+
Destroys `amount` number of tokens from `account`.
Emits a [Transfer](#ERC20Component-Transfer) event with `to` set to the zero address.
@@ -589,17 +825,25 @@ Emits a [Transfer](#ERC20Component-Transfer) event with `to` set to the zero add
Requirements:
- `account` cannot be the zero address.
+
-#### [](#ERC20Component-update)`update(ref self: ContractState, from: ContractAddress, to: ContractAddress, amount: u256)` internal
-
+
Transfers an `amount` of tokens from `from` to `to`, or alternatively mints (or burns) if `from` (or `to`) is the zero address.
This function can be extended using the [ERC20HooksTrait](#ERC20Component-ERC20HooksTrait), to add functionality before and/or after the transfer, mint, or burn.
Emits a [Transfer](#ERC20Component-Transfer) event.
+
-#### [](#ERC20Component-_transfer)`_transfer(ref self: ContractState, sender: ContractAddress, recipient: ContractAddress, amount: u256)` internal
-
+
Moves `amount` of tokens from `from` to `to`.
This internal function does not check for access permissions but can be useful as a building block, for example to implement automatic token fees, slashing mechanisms, etc.
@@ -611,9 +855,13 @@ Requirements:
- `from` cannot be the zero address.
- `to` cannot be the zero address.
- `from` must have a balance of at least `amount`.
+
-#### [](#ERC20Component-_approve)`_approve(ref self: ContractState, owner: ContractAddress, spender: ContractAddress, amount: u256)` internal
-
+
Sets `amount` as the allowance of `spender` over `owner`'s tokens.
This internal function does not check for access permissions but can be useful as a building block, for example to implement automatic allowances on behalf of other addresses.
@@ -624,28 +872,45 @@ Requirements:
- `owner` cannot be the zero address.
- `spender` cannot be the zero address.
+
-#### [](#ERC20Component-_spend_allowance)`_spend_allowance(ref self: ContractState, owner: ContractAddress, spender: ContractAddress, amount: u256)` internal
-
+
Updates `owner`'s allowance for `spender` based on spent `amount`.
This internal function does not update the allowance value in the case of infinite allowance.
Possibly emits an [Approval](#ERC20Component-Approval) event.
+
-#### [](#ERC20Component-Events)Events
-
-#### [](#ERC20Component-Transfer)`Transfer(from: ContractAddress, to: ContractAddress, value: u256)` event
+#### Events [!toc] [#ERC20Component-Events]
+
See [IERC20::Transfer](#IERC20-Transfer).
+
-#### [](#ERC20Component-Approval)`Approval(owner: ContractAddress, spender: ContractAddress, value: u256)` event
-
+
See [IERC20::Approval](#IERC20-Approval).
+
-## [](#extensions)Extensions
+## Extensions
-### [](#ERC4626Component)`ERC4626Component`[](https://github.com/OpenZeppelin/cairo-contracts/blob/release-v3.0.0-alpha.1/packages/token/src/erc20/extensions/erc4626/interface.cairo#L19)
+### `ERC4626Component` [toc] [#ERC4626Component]
+
```rust
use openzeppelin_token::erc20::extensions::erc4626::ERC4626Component;
@@ -653,41 +918,41 @@ use openzeppelin_token::erc20::extensions::erc4626::ERC4626Component;
Extension of ERC20 that implements the [IERC4626](#IERC4626) interface which allows the minting and burning of "shares" in exchange for an underlying "asset." The component leverages traits to configure fees, limits, and decimals.
-[Immutable Component Config](../components#immutable_config)
+[Immutable Component Config](../components#immutable-config)
-constants
+#### constants [!toc] [#ERC4626Component-constants]
- [`UNDERLYING_DECIMALS`](#ERC4626Component-IC-UNDERLYING_DECIMALS)
- [`DECIMALS_OFFSET`](#ERC4626Component-IC-DECIMALS_OFFSET)
-functions
+#### functions [!toc] [#ERC4626Component-functions]
- [`validate()`](#ERC4626Component-IC-validate)
Hooks
-FeeConfigTrait
+#### FeeConfigTrait [!toc] [#ERC4626Component-FeeConfigTrait]
- [`calculate_deposit_fee(self, assets, shares)`](#ERC4626Component-calculate_deposit_fee)
- [`calculate_mint_fee(self, assets, shares)`](#ERC4626Component-calculate_mint_fee)
- [`calculate_withdraw_fee(self, assets, shares)`](#ERC4626Component-calculate_withdraw_fee)
- [`calculate_redeem_fee(self, assets, shares)`](#ERC4626Component-calculate_redeem_fee)
-LimitConfigTrait
+#### LimitConfigTrait [!toc] [#ERC4626Component-LimitConfigTrait]
- [`deposit_limit(self, receiver)`](#ERC4626Component-deposit_limit)
- [`mint_limit(self, receiver)`](#ERC4626Component-mint_limit)
- [`withdraw_limit(self, owner)`](#ERC4626Component-withdraw_limit)
- [`redeem_limit(self, owner)`](#ERC4626Component-redeem_limit)
-ERC4626HooksTrait
+#### ERC4626HooksTrait [!toc] [#ERC4626Component-ERC4626HooksTrait]
- [`before_deposit(self, caller, receiver, assets, shares, fee)`](#ERC4626Component-before_deposit)
- [`after_deposit(self, caller, receiver, assets, shares, fee)`](#ERC4626Component-after_deposit)
- [`before_withdraw(self, caller, receiver, owner, assets, shares, fee)`](#ERC4626Component-before_withdraw)
- [`after_withdraw(self, caller, receiver, owner, assets, shares, fee)`](#ERC4626Component-after_withdraw)
-AssetsManagementTrait
+#### AssetsManagementTrait [!toc] [#ERC4626Component-AssetsManagementTrait]
- [`get_total_assets(self)`](#ERC4626Component-get_total_assets)
- [`transfer_assets_in(self, from, assets)`](#ERC4626Component-transfer_assets_in)
@@ -695,7 +960,7 @@ AssetsManagementTrait
Embeddable Implementations
-ERC4626Impl
+#### ERC4626Impl [!toc] [#ERC4626Component-Embeddable-Impls-ERC4626Impl]
- [`asset(self)`](#ERC4626Component-asset)
- [`total_assets(self)`](#ERC4626Component-total_assets)
@@ -714,7 +979,7 @@ ERC4626Impl
- [`preview_redeem(self, shares)`](#ERC4626Component-preview_redeem)
- [`redeem(self, shares, receiver, owner)`](#ERC4626Component-redeem)
-ERC20Impl
+#### ERC20Impl [!toc] [#ERC4626Component-Embeddable-Impls-ERC20Impl]
- [`total_supply(self)`](#ERC20Component-total_supply)
- [`balance_of(self, account)`](#ERC20Component-balance_of)
@@ -723,7 +988,7 @@ ERC20Impl
- [`transfer_from(self, sender, recipient, amount)`](#ERC20Component-transfer_from)
- [`approve(self, spender, amount)`](#ERC20Component-approve)
-ERC4626MetadataImpl
+#### ERC4626MetadataImpl [!toc] [#ERC4626Component-Embeddable-Impls-ERC4626MetadataImpl]
- [`name(self)`](#ERC4626Component-name)
- [`symbol(self)`](#ERC4626Component-symbol)
@@ -731,7 +996,7 @@ ERC4626MetadataImpl
Internal functions
-InternalImpl
+#### InternalImpl [!toc] [#ERC4626Component-InternalImpl]
- [`initializer(self, asset_address)`](#ERC4626Component-initializer)
- [`_deposit(self, caller, receiver, assets, shares)`](#ERC4626Component-_deposit)
@@ -739,33 +1004,45 @@ InternalImpl
- [`_convert_to_shares(self, assets, rounding)`](#ERC4626Component-_convert_to_shares)
- [`_convert_to_assets(self, shares, rounding)`](#ERC4626Component-_convert_to_assets)
-#### [](#ERC4626Component-Immutable-Config)Immutable Config
-
-#### [](#ERC4626Component-IC-UNDERLYING_DECIMALS)`UNDERLYING_DECIMALS: u128` constant
-
-Should match the underlying asset’s decimals. The default value is `18`.
-
-#### [](#ERC4626Component-IC-DECIMALS_OFFSET)`DECIMALS_OFFSET: u128` constant
-
+#### Immutable Config [!toc] [#ERC4626Component-Immutable-Config]
+
+
+Should match the underlying asset's decimals. The default value is `18`.
+
+
+
Corresponds to the representational offset between `UNDERLYING_DECIMALS` and the vault decimals. The greater the offset, the more expensive it is for attackers to execute an inflation attack.
+
-#### [](#ERC4626Component-IC-validate)`validate()` internal
-
-Validates the given implementation of the contract’s configuration.
+
+Validates the given implementation of the contract's configuration.
Requirements:
- `UNDERLYING_DECIMALS` + `DECIMALS_OFFSET` cannot exceed 255 (max u8).
-This function is called by the contract’s initializer.
+This function is called by the contract's initializer.
+
-#### [](#ERC4626Component-Hooks)Hooks
+#### Hooks [!toc] [#ERC4626Component-Hooks]
Hooks are functions which implementations can extend the functionality of the component source code. Every contract using ERC4626Component is expected to provide an implementation of the ERC4626HooksTrait. For basic token contracts, an empty implementation with no logic must be provided.
You can use `openzeppelin_token::erc20::extensions::erc4626::ERC4626EmptyHooks` which is already available as part of the library for this purpose.
-#### [](#feeconfigtrait)FeeConfigTrait
+#### FeeConfigTrait [!toc] [#ERC4626Component-FeeConfigTrait]
The logic for calculating entry and exit fees is expected to be defined at the contract level. Defaults to no entry or exit fees.
@@ -778,94 +1055,142 @@ See implementation examples:
- Contract charging fees in assets: [ERC4626AssetsFeesMock](https://github.com/OpenZeppelin/cairo-contracts/tree/main/packages/test_common/src/mocks/erc4626.cairo#L253)
- Contract charging fees in shares: [ERC4626SharesFeesMock](https://github.com/OpenZeppelin/cairo-contracts/tree/main/packages/test_common/src/mocks/erc4626.cairo#L426)
-#### [](#ERC4626Component-calculate_deposit_fee)`calculate_deposit_fee(self: @ContractState, assets: u256, shares: u256) → Option` hook
-
-Calculates the entry fee for a deposit during [preview\_deposit](#ERC4626Component-preview_deposit). The returned fee affects the final asset and share amounts. Fees are not transferred automatically and must be handled in the [after\_deposit](#ERC4626Component-after_deposit) hook: asset fees should be transferred from the vault’s management to the fee recipient, while share fees should be minted to the fee recipient.
-
-#### [](#ERC4626Component-calculate_mint_fee)`calculate_mint_fee(self: @ContractState, assets: u256, shares: u256) → Option` hook
-
-Calculates the entry fee for a mint during [preview\_mint](#ERC4626Component-preview_mint). The returned fee affects the final asset and share amounts. Fees are not transferred automatically and must be handled in the [after\_deposit](#ERC4626Component-after_deposit) hook: asset fees should be transferred from the vault’s management to the fee recipient, while share fees should be minted to the fee recipient.
-
-#### [](#ERC4626Component-calculate_withdraw_fee)`calculate_withdraw_fee(self: @ContractState, assets: u256, shares: u256) → Option` hook
-
-Calculates the exit fee for a withdraw during [preview\_withdraw](#ERC4626Component-preview_withdraw). The returned fee affects the final asset and share amounts. Fees are not transferred automatically and must be handled in the [before\_withdraw](#ERC4626Component-before_withdraw) hook: asset fees should be transferred from the vault’s management to the fee recipient, while share fees should be transferred from the owner to the fee recipient.
-
-#### [](#ERC4626Component-calculate_redeem_fee)`calculate_redeem_fee(self: @ContractState, assets: u256, shares: u256) → Option` hook
-
-Calculates the exit fee for a redeem during [preview\_redeem](#ERC4626Component-preview_redeem). The returned fee affects the final asset and share amounts. Fees are not transferred automatically and must be handled in the [before\_withdraw](#ERC4626Component-before_withdraw) hook: asset fees should be transferred from the vault’s management to the fee recipient, while share fees should be transferred from the owner to the fee recipient.
-
-#### [](#limitconfigtrait)LimitConfigTrait
+
+Calculates the entry fee for a deposit during [preview\_deposit](#ERC4626Component-preview_deposit). The returned fee affects the final asset and share amounts. Fees are not transferred automatically and must be handled in the [after\_deposit](#ERC4626Component-after_deposit) hook: asset fees should be transferred from the vault's management to the fee recipient, while share fees should be minted to the fee recipient.
+
+
+
+Calculates the entry fee for a mint during [preview\_mint](#ERC4626Component-preview_mint). The returned fee affects the final asset and share amounts. Fees are not transferred automatically and must be handled in the [after\_deposit](#ERC4626Component-after_deposit) hook: asset fees should be transferred from the vault's management to the fee recipient, while share fees should be minted to the fee recipient.
+
+
+
+Calculates the exit fee for a withdraw during [preview\_withdraw](#ERC4626Component-preview_withdraw). The returned fee affects the final asset and share amounts. Fees are not transferred automatically and must be handled in the [before\_withdraw](#ERC4626Component-before_withdraw) hook: asset fees should be transferred from the vault's management to the fee recipient, while share fees should be transferred from the owner to the fee recipient.
+
+
+
+Calculates the exit fee for a redeem during [preview\_redeem](#ERC4626Component-preview_redeem). The returned fee affects the final asset and share amounts. Fees are not transferred automatically and must be handled in the [before\_withdraw](#ERC4626Component-before_withdraw) hook: asset fees should be transferred from the vault's management to the fee recipient, while share fees should be transferred from the owner to the fee recipient.
+
+
+#### LimitConfigTrait [!toc] [#ERC4626Component-LimitConfigTrait]
Sets limits to the target exchange type and is expected to be defined at the contract level. These limits correspond directly to the `max_` i.e. `deposit_limit` → `max_deposit`.
The [EIP-4626](https://eips.ethereum.org/EIPS/eip-4626) spec states that the `max_` methods must take into account all global and user-specific limits. If an operation is disabled (even temporarily), the corresponding limit MUST be `0` and MUST NOT panic.
-#### [](#ERC4626Component-deposit_limit)`deposit_limit(ref self: ContractState, receiver: ContractAddress) → Option` hook
-
+
The max deposit allowed.
Defaults (`Option::None`) to 2 \** 256 - 1.
+
-#### [](#ERC4626Component-mint_limit)`mint_limit(ref self: ContractState, receiver: ContractAddress) → Option` hook
-
+
The max mint allowed.
Defaults (`Option::None`) to 2 \** 256 - 1.
+
-#### [](#ERC4626Component-withdraw_limit)`withdraw_limit(ref self: ContractState, owner: ContractAddress) → Option` hook
-
+
The max withdraw allowed.
Defaults (`Option::None`) to the full asset balance of `owner` converted from shares.
+
-#### [](#ERC4626Component-redeem_limit)`redeem_limit(ref self: ContractState, owner: ContractAddress) → Option` hook
-
+
The max redeem allowed.
Defaults (`Option::None`) to the full asset balance of `owner`.
+
-#### [](#erc4626hookstrait)ERC4626HooksTrait
+#### ERC4626HooksTrait [!toc] [#ERC4626Component-ERC4626HooksTrait]
Allows contracts to hook logic into deposit and withdraw transactions. This is where contracts can transfer fees.
ERC4626 preview methods must be inclusive of any entry or exit fees. Fees are calculated using [FeeConfigTrait](#ERC4626Component-FeeConfigTrait) methods and automatically adjust the final asset and share amounts. Fee transfers are handled in `ERC4626HooksTrait` methods.
-Special care must be taken when calling external contracts in these hooks. In that case, consider implementing reentrancy protections. For example, in the `withdraw` flow, the `withdraw_limit` is checked **before** the `before_withdraw` hook is invoked. If this hook performs a reentrant call that invokes `withdraw` again, the subsequent check on `withdraw_limit` will be done before the first withdrawal’s core logic (e.g., burning shares and transferring assets) is executed. This could lead to bypassing withdrawal constraints or draining funds.
+Special care must be taken when calling external contracts in these hooks. In that case, consider implementing reentrancy protections. For example, in the `withdraw` flow, the `withdraw_limit` is checked **before** the `before_withdraw` hook is invoked. If this hook performs a reentrant call that invokes `withdraw` again, the subsequent check on `withdraw_limit` will be done before the first withdrawal's core logic (e.g., burning shares and transferring assets) is executed. This could lead to bypassing withdrawal constraints or draining funds.
See the [ERC4626AssetsFeesMock](https://github.com/OpenZeppelin/cairo-contracts/tree/main/packages/test_common/src/mocks/erc4626.cairo#L253) and [ERC4626SharesFeesMock](https://github.com/OpenZeppelin/cairo-contracts/tree/main/packages/test_common/src/mocks/erc4626.cairo#L426) examples.
-#### [](#ERC4626Component-before_deposit)`before_deposit(ref self: ContractState, caller: ContractAddress, receiver: ContractAddress, assets: u256, shares: u256, fee: Option)` hook
-
+
Hooks into [\_deposit](#ERC4626Component-_deposit).
Executes logic before transferring assets and minting shares. The fee is calculated via [FeeConfigTrait](#ERC4626Component-FeeConfigTrait). Assets and shares represent the actual amounts the user will spend and receive, respectively. Asset fees are included in assets; share fees are excluded from shares.
+
-#### [](#ERC4626Component-after_deposit)`after_deposit(ref self: ContractState, caller: ContractAddress, receiver: ContractAddress, assets: u256, shares: u256, fee: Option)` hook
-
+
Hooks into [\_deposit](#ERC4626Component-_deposit).
Executes logic after transferring assets and minting shares. The fee is calculated via [FeeConfigTrait](#ERC4626Component-FeeConfigTrait). Assets and shares represent the actual amounts the user will spend and receive, respectively. Asset fees are included in assets; share fees are excluded from shares.
+
-#### [](#ERC4626Component-before_withdraw)`before_withdraw(ref self: ContractState, caller: ContractAddress, receiver: ContractAddress, owner: ContractAddress, assets: u256, shares: u256, fee: Option)` hook
-
+
Hooks into [\_withdraw](#ERC4626Component-_withdraw).
Executes logic before burning shares and transferring assets. The fee is calculated via [FeeConfigTrait](#ERC4626Component-FeeConfigTrait). Assets and shares represent the actual amounts the user will receive and spend, respectively. Asset fees are excluded from assets; share fees are included in shares.
+
-#### [](#ERC4626Component-after_withdraw)`after_withdraw(ref self: ContractState, caller: ContractAddress, receiver: ContractAddress, owner: ContractAddress, assets: u256, shares: u256, fee: Option)` hook
-
+
Hooks into [\_withdraw](#ERC4626Component-_withdraw).
Executes logic after burning shares and transferring assets. The fee is calculated via [FeeConfigTrait](#ERC4626Component-FeeConfigTrait). Assets and shares represent the actual amounts the user will receive and spend, respectively. Asset fees are excluded from assets; share fees are included in shares.
+
-#### [](#assetsmanagementtrait)AssetsManagementTrait
+#### AssetsManagementTrait [!toc] [#ERC4626Component-AssetsManagementTrait]
Defines how the ERC4626 vault manages its underlying assets. This trait provides the core asset management functionality for the vault, abstracting the actual storage and transfer mechanisms. It enables two primary implementation patterns:
1. **Self-managed assets**: The vault contract holds assets directly on its own address. This is the default behavior provided by `ERC4626SelfAssetsManagement` implementation.
2. **External vault**: Assets are managed by an external contract, allowing for more complex asset management strategies. The exact implementation is expected to be defined by the contract implementing the ERC4626 component.
-The trait methods are called during deposit, withdrawal, and total assets calculations, ensuring that the vault’s share pricing remains accurate regardless of the underlying asset management strategy.
+The trait methods are called during deposit, withdrawal, and total assets calculations, ensuring that the vault's share pricing remains accurate regardless of the underlying asset management strategy.
Implementations must ensure that `get_total_assets` returns the actual amount of assets that can be withdrawn by users. Inaccurate reporting can lead to incorrect share valuations and potential economic attacks.
@@ -874,76 +1199,115 @@ See implementation examples:
- Self-managed vault: [ERC4626SelfAssetsManagement](https://github.com/OpenZeppelin/cairo-contracts/tree/main/packages/token/src/erc20/extensions/erc4626/erc4626.cairo#L760).
- External vault: [ERC4626ExternalAssetsManagement](https://github.com/OpenZeppelin/cairo-contracts/tree/main/packages/test_common/src/mocks/erc4626.cairo#L92).
-#### [](#ERC4626Component-get_total_assets)`get_total_assets(self: @ContractState) → u256` hook
+
+Returns the total amount of underlying assets under the vault's management. Used for share price calculations and determining the vault's total value.
-Returns the total amount of underlying assets under the vault’s management. Used for share price calculations and determining the vault’s total value.
-
-This method should return the actual amount of assets that the vault controls and that can be used to satisfy withdrawal requests. For self-managed vaults, this is typically the vault contract’s token balance. For external vaults, this should include any assets deposited in external protocols, minus any that are locked or unredeemable.
+This method should return the actual amount of assets that the vault controls and that can be used to satisfy withdrawal requests. For self-managed vaults, this is typically the vault contract's token balance. For external vaults, this should include any assets deposited in external protocols, minus any that are locked or unredeemable.
The accuracy of this method is critical for proper vault operation: - Overreporting can lead to share dilution and user losses. - Underreporting can lead to share inflation and potential economic attacks.
+
-#### [](#ERC4626Component-transfer_assets_in)`transfer_assets_in(ref self: ContractState, from: ContractAddress, assets: u256)` hook
-
-Transfers assets from an external address into the vault’s management. Called during `deposit` and `mint` operations.
+
+Transfers assets from an external address into the vault's management. Called during `deposit` and `mint` operations.
-This method should handle the actual transfer of underlying assets from the `from` address into the vault’s control. For self-managed vaults, this typically means transferring tokens to the vault contract’s address. For external vaults, this might involve transferring into an external contract.
+This method should handle the actual transfer of underlying assets from the `from` address into the vault's control. For self-managed vaults, this typically means transferring tokens to the vault contract's address. For external vaults, this might involve transferring into an external contract.
Requirements:
- MUST transfer exactly `assets` amount of the underlying token.
- SHOULD revert if the transfer fails or insufficient allowance/balance.
+
-#### [](#ERC4626Component-transfer_assets_out)`transfer_assets_out(ref self: ContractState, to: ContractAddress, assets: u256)` hook
-
-Transfers assets from the vault’s management to an external address. Called during withdraw and redeem operations.
+
+Transfers assets from the vault's management to an external address. Called during withdraw and redeem operations.
-This method should handle the actual transfer of underlying assets from the vault’s control to the `to` address. For self-managed vaults, this typically means transferring tokens from the vault contract’s address. For external vaults, this might involve withdrawing from an external contract first.
+This method should handle the actual transfer of underlying assets from the vault's control to the `to` address. For self-managed vaults, this typically means transferring tokens from the vault contract's address. For external vaults, this might involve withdrawing from an external contract first.
Requirements:
- MUST transfer exactly `assets` amount of the underlying token.
- SHOULD revert if insufficient assets are available or transfer fails.
+
-#### [](#embeddable_functions)Embeddable functions
-
-#### [](#ERC4626Component-asset)`asset(self: @ContractState) → ContractAddress` external
+#### Embeddable functions [!toc] [#ERC4626Component-Embeddable-Functions]
+
Returns the address of the underlying token used for the Vault for accounting, depositing, and withdrawing.
-
-#### [](#ERC4626Component-total_assets)`total_assets(self: @ContractState) → u256` external
-
-Returns the total amount of the underlying asset that is “managed” by Vault.
-
-#### [](#ERC4626Component-convert_to_shares)`convert_to_shares(self: @ContractState, assets: u256) → u256` external
-
+
+
+
+Returns the total amount of the underlying asset that is "managed" by Vault.
+
+
+
Returns the amount of shares that the Vault would exchange for the amount of assets provided irrespective of slippage or fees.
-As per the [EIP-4626](https://eips.ethereum.org/EIPS/eip-4626) spec, this may panic *only* if there’s an overflow from an unreasonably large input.
-
-#### [](#ERC4626Component-convert_to_assets)`convert_to_assets(self: @ContractState, shares: u256) → u256` external
+As per the [EIP-4626](https://eips.ethereum.org/EIPS/eip-4626) spec, this may panic *only* if there's an overflow from an unreasonably large input.
+
+
Returns the amount of assets that the Vault would exchange for the amount of shares provided irrespective of slippage or fees.
-As per the [EIP-4626](https://eips.ethereum.org/EIPS/eip-4626) spec, this may panic *only* if there’s an overflow from an unreasonably large input.
-
-#### [](#ERC4626Component-max_deposit)`max_deposit(self: @ContractState, receiver: ContractAddress) → u256` external
+As per the [EIP-4626](https://eips.ethereum.org/EIPS/eip-4626) spec, this may panic *only* if there's an overflow from an unreasonably large input.
+
+
Returns the maximum amount of the underlying asset that can be deposited into the Vault for the `receiver`, through a [deposit](#ERC4626Component-deposit) call.
The default max deposit value is 2 \** 256 - 1.
This can be changed in the implementing contract by defining custom logic in [LimitConfigTrait::deposit\_limit](#ERC4626Component-deposit_limit).
+
-#### [](#ERC4626Component-preview_deposit)`preview_deposit(self: @ContractState, assets: u256) → u256` external
-
+
Allows an on-chain or off-chain user to simulate the effects of their deposit at the current block, given current on-chain conditions.
The default deposit preview value is the full amount of shares. This can be changed to account for fees, for example, in the implementing contract by defining custom logic in [FeeConfigTrait::calculate\_deposit\_fee](#ERC4626Component-calculate_deposit_fee).
This method must be inclusive of entry fees to be compliant with the [EIP-4626](https://eips.ethereum.org/EIPS/eip-4626) spec.
+
-#### [](#ERC4626Component-deposit)`deposit(ref self: ContractState, assets: u256, receiver: ContractAddress) → u256` external
-
+
Mints Vault shares to `receiver` by depositing exactly `assets` of underlying tokens. Returns the amount of newly-minted shares.
Requirements:
@@ -951,25 +1315,37 @@ Requirements:
- `assets` is less than or equal to the max deposit amount for `receiver`.
Emits a [Deposit](#IERC4626-Deposit) event.
+
-#### [](#ERC4626Component-max_mint)`max_mint(self: @ContractState, receiver: ContractAddress) → u256` external
-
+
Returns the maximum amount of the Vault shares that can be minted for `receiver` through a [mint](#ERC4626Component-mint) call.
The default max mint value is 2 \** 256 - 1.
This can be changed in the implementing contract by defining custom logic in [LimitConfigTrait::mint\_limit](#ERC4626Component-mint_limit).
+
-#### [](#ERC4626Component-preview_mint)`preview_mint(self: @ContractState, shares: u256) → u256` external
-
+
Allows an on-chain or off-chain user to simulate the effects of their mint at the current block, given current on-chain conditions.
The default mint preview value is the full amount of assets. This can be changed to account for fees, for example, in the implementing contract by defining custom logic in [FeeConfigTrait::calculate\_mint\_fee](#ERC4626Component-calculate_mint_fee).
This method must be inclusive of entry fees to be compliant with the [EIP-4626](https://eips.ethereum.org/EIPS/eip-4626) spec.
+
-#### [](#ERC4626Component-mint)`mint(self: @ContractState, shares: u256, receiver: ContractAddress) → u256` external
-
+
Mints exactly Vault `shares` to `receiver` by depositing amount of underlying tokens. Returns the amount deposited assets.
Requirements:
@@ -977,25 +1353,37 @@ Requirements:
- `shares` is less than or equal to the max shares amount for `receiver`.
Emits a [Deposit](#IERC4626-Deposit) event.
+
-#### [](#ERC4626Component-max_withdraw)`max_withdraw(self: @ContractState, owner: ContractAddress) → u256` external
-
+
Returns the maximum amount of the underlying asset that can be withdrawn from the owner balance in the Vault, through a [withdraw](#ERC4626Component-withdraw) call.
The default max withdraw value is the full balance of assets for `owner` (converted from shares). This can be changed in the implementing contract by defining custom logic in [LimitConfigTrait::withdraw\_limit](#ERC4626Component-withdraw_limit).
With customized limits, the maximum withdraw amount will either be the custom limit itself or `owner`'s total asset balance, whichever value is less.
+
-#### [](#ERC4626Component-preview_withdraw)`preview_withdraw(self: @ContractState, assets: u256) → u256` external
-
+
Allows an on-chain or off-chain user to simulate the effects of their withdrawal at the current block, given current on-chain conditions.
The default withdraw preview value is the full amount of shares. This can be changed to account for fees, for example, in the implementing contract by defining custom logic in [FeeConfigTrait::calculate\_withdraw\_fee](#ERC4626Component-calculate_withdraw_fee).
This method must be inclusive of exit fees to be compliant with the [EIP-4626](https://eips.ethereum.org/EIPS/eip-4626) spec.
+
-#### [](#ERC4626Component-withdraw)`withdraw(self: @ContractState, assets: u256, receiver: ContractAddress, owner: ContractAddress) → u256` external
-
+
Burns shares from `owner` and sends exactly `assets` of underlying tokens to `receiver`.
Requirements:
@@ -1003,25 +1391,37 @@ Requirements:
- `assets` is less than or equal to the max withdraw amount of `owner`.
Emits a [Withdraw](#IERC4626-Withdraw) event.
+
-#### [](#ERC4626Component-max_redeem)`max_redeem(self: @ContractState, owner: ContractAddress) → u256` external
-
+
Returns the maximum amount of Vault shares that can be redeemed from the owner balance in the Vault, through a [redeem](#ERC4626Component-redeem) call.
The default max redeem value is the full balance of assets for `owner`. This can be changed in the implementing contract by defining custom logic in [LimitConfigTrait::redeem\_limit](#ERC4626Component-redeem_limit).
With customized limits, the maximum redeem amount will either be the custom limit itself or `owner`'s total asset balance, whichever value is less.
+
-#### [](#ERC4626Component-preview_redeem)`preview_redeem(self: @ContractState, shares: u256) → u256` external
-
+
Allows an on-chain or off-chain user to simulate the effects of their redeemption at the current block, given current on-chain conditions.
The default redeem preview value is the full amount of assets. This can be changed to account for fees, for example, in the implementing contract by defining custom logic in [FeeConfigTrait::calculate\_redeem\_fee](#ERC4626Component-calculate_redeem_fee).
This method must be inclusive of exit fees to be compliant with the [EIP-4626](https://eips.ethereum.org/EIPS/eip-4626) spec.
+
-#### [](#ERC4626Component-redeem)`redeem(self: @ContractState, shares: u256, receiver: ContractAddress, owner: ContractAddress) → u256` external
-
+
Burns exactly `shares` from `owner` and sends assets of underlying tokens to `receiver`.
Requirements:
@@ -1029,31 +1429,51 @@ Requirements:
- `shares` is less than or equal to the max redeem amount of `owner`.
Emits a [Withdraw](#IERC4626-Withdraw) event.
+
-#### [](#ERC4626Component-name)`name(self: @ContractState) → ByteArray` external
-
+
Returns the name of the token.
+
-#### [](#ERC4626Component-symbol)`symbol(self: @ContractState) → ByteArray` external
-
+
Returns the ticker symbol of the token, usually a shorter version of the name.
+
-#### [](#ERC4626Component-decimals)`decimals(self: @ContractState) → u8` external
-
+
Returns the cumulative number of decimals which includes both `UNDERLYING_DECIMALS` and `OFFSET_DECIMALS`. Both of which must be defined in the [ImmutableConfig](#ERC4626Component-Immutable-Config) inside the implementing contract.
+
-#### [](#internal_functions)Internal functions
-
-#### [](#ERC4626Component-initializer)`initializer(ref self: ContractState, asset_address: ContractAddress)` internal
+#### Internal functions [!toc] [#ERC4626Component-Internal-Functions]
-Validates the [ImmutableConfig](#ERC4626Component-Immutable-Config) constants and sets the `asset_address` to the vault. This should be set in the contract’s constructor.
+
+Validates the [ImmutableConfig](#ERC4626Component-Immutable-Config) constants and sets the `asset_address` to the vault. This should be set in the contract's constructor.
Requirements:
- `asset_address` cannot be the zero address.
+
-#### [](#ERC4626Component-_deposit)`_deposit(ref self: ContractState, caller: ContractAddress, receiver: ContractAddress, assets: u256, shares: u256)` internal
-
+
Internal logic for [deposit](#ERC4626Component-deposit) and [mint](#ERC4626Component-mint).
Transfers `assets` from `caller` to the Vault contract then mints `shares` to `receiver`. Fees can be transferred in the `ERC4626Hooks::after_deposit` hook which is executed after assets are transferred and shares are minted.
@@ -1065,9 +1485,13 @@ Requirements:
Emits two [ERC20::Transfer](#ERC20Component-Transfer) events (`ERC20::mint` and `ERC20::transfer_from`).
Emits a [Deposit](#IERC4626-Deposit) event.
+
-#### [](#ERC4626Component-_withdraw)`_withdraw(ref self: ContractState, caller: ContractAddress, receiver: ContractAddress, owner: ContractAddress, assets: u256, shares: u256)` internal
-
+
Internal logic for [withdraw](#ERC4626Component-withdraw) and [redeem](#ERC4626Component-redeem).
Burns `shares` from `owner` and then transfers `assets` to `receiver`. Fees can be transferred in the `ERC4626Hooks::before_withdraw` hook which is executed before shares are burned and assets are transferred.
@@ -1079,18 +1503,31 @@ Requirements:
Emits two [ERC20::Transfer](#ERC20Component-Transfer) events (`ERC20::burn` and `ERC20::transfer`).
Emits a [Withdraw](#IERC4626-Withdraw) event.
+
-#### [](#ERC4626Component-_convert_to_shares)`_convert_to_shares(self: @ContractState, assets: u256, rounding: Rounding) -> u256` internal
-
+
Internal conversion function (from assets to shares) with support for `rounding` direction.
+
-#### [](#ERC4626Component-_convert_to_assets)`_convert_to_assets(self: @ContractState, shares: u256, rounding: Rounding) -> u256` internal
-
+
Internal conversion function (from shares to assets) with support for `rounding` direction.
+
-## [](#presets)Presets
+## Presets
-### [](#ERC20Upgradeable)`ERC20Upgradeable`[](https://github.com/OpenZeppelin/cairo-contracts/blob/release-v3.0.0-alpha.1/packages/presets/src/erc20.cairo)
+### `ERC20Upgradeable` [toc] [#ERC20Upgradeable]
+
```rust
use openzeppelin_presets::ERC20Upgradeable;
@@ -1100,7 +1537,9 @@ Upgradeable ERC20 contract leveraging [ERC20Component](#ERC20Component) with a f
[Sierra class hash](../presets)
-0x07802658d99373a4002434cbdc8897d1936c6b1beea48af0cc3b5574707f8d92
+```text
+{{ERC20UpgradeableClassHash}}
+```
Constructor
@@ -1108,11 +1547,11 @@ Constructor
Embedded Implementations
-ERC20MixinImpl
+#### ERC20MixinImpl [!toc] [#ERC20Upgradeable-Embedded-Impls-ERC20MixinImpl]
- [`ERC20MixinImpl`](#ERC20Component-Embeddable-Mixin-Impl)
-OwnableMixinImpl
+#### OwnableMixinImpl [!toc] [#ERC20Upgradeable-Embedded-Impls-OwnableMixinImpl]
- [`OwnableMixinImpl`](access#OwnableComponent-Mixin-Impl)
@@ -1120,19 +1559,27 @@ External Functions
- [`upgrade(self, new_class_hash)`](#ERC20Upgradeable-upgrade)
-#### [](#ERC20Upgradeable-constructor-section)Constructor
-
-#### [](#ERC20Upgradeable-constructor)`constructor(ref self: ContractState, name: ByteArray, symbol: ByteArray, fixed_supply: u256, recipient: ContractAddress, owner: ContractAddress)` constructor
+#### Constructor [!toc] [#ERC20Upgradeable-Constructor]
+
Sets the `name` and `symbol` and mints `fixed_supply` tokens to `recipient`. Assigns `owner` as the contract owner with permissions to upgrade.
+
-#### [](#ERC20Upgradeable-external-functions)External functions
-
-#### [](#ERC20Upgradeable-upgrade)`upgrade(ref self: ContractState, new_class_hash: ClassHash)` external
+#### External functions [!toc] [#ERC20Upgradeable-External-Functions]
+
Upgrades the contract to a new implementation given by `new_class_hash`.
Requirements:
- The caller is the contract owner.
- `new_class_hash` cannot be zero.
+
diff --git a/content/contracts-cairo/api/erc721.mdx b/content/contracts-cairo/api/erc721.mdx
index 47a9b79..7c4fa2f 100644
--- a/content/contracts-cairo/api/erc721.mdx
+++ b/content/contracts-cairo/api/erc721.mdx
@@ -8,9 +8,18 @@ For an overview of ERC721, read our [ERC721 guide](../erc721).
## [](#interfaces)Interfaces
-Starting from version `3.x.x`, the interfaces are no longer part of the `openzeppelin_token` package. The references documented here are contained in the `openzeppelin_interfaces` package version `v2.1.0`.
+
+Starting from version `3.x.x`, the interfaces are no longer part of the `openzeppelin_access` package. The references
+documented here are contained in the `openzeppelin_interfaces` package version `{{openzeppelin_interfaces_version}}`.
+
-### [](#IERC721)`IERC721`[](https://github.com/OpenZeppelin/cairo-contracts/blob/release-v3.0.0-alpha.1/packages/interfaces/src/token/erc721.cairo)
+import { UMBRELLA_VERSION } from "../utils/constants.js";
+
+### `IERC721` [toc] [#IERC721]
+
```rust
use openzeppelin_interfaces::erc721::IERC721;
@@ -20,7 +29,9 @@ Interface of the IERC721 standard as defined in [EIP721](https://eips.ethereum.o
[SRC5 ID](introspection#ISRC5)
+```text
0x33eb2f84c309543403fd69f0d0f363781ef06ef6faeb0131ff16ea3175bd943
+```
Functions
@@ -39,65 +50,113 @@ Events
- [`ApprovalForAll(owner, operator, approved)`](#IERC721-ApprovalForAll)
- [`Transfer(from, to, token_id)`](#IERC721-Transfer)
-#### [](#functions)Functions
-
-#### [](#IERC721-balance_of)`balance_of(account: ContractAddress) → u256` external
+#### Functions [!toc] [#IERC721-Functions]
+
Returns the number of NFTs owned by `account`.
+
-#### [](#IERC721-owner_of)`owner_of(token_id: u256) → ContractAddress` external
-
+
Returns the owner address of `token_id`.
+
-#### [](#IERC721-safe_transfer_from)`safe_transfer_from(from: ContractAddress, to: ContractAddress, token_id: u256, data: Span)` external
-
+
Transfer ownership of `token_id` from `from` to `to`, checking first that `to` is aware of the ERC721 protocol to prevent tokens being locked forever. For information regarding how contracts communicate their awareness of the ERC721 protocol, see [Receiving Tokens](../erc721#receiving_tokens).
Emits a [Transfer](#IERC721-Transfer) event.
+
-#### [](#IERC721-transfer_from)`transfer_from(from: ContractAddress, to: ContractAddress, token_id: u256)` external
-
+
Transfer ownership of `token_id` from `from` to `to`.
Note that the caller is responsible to confirm that the recipient is capable of receiving ERC721 transfers or else they may be permanently lost. Usage of [IERC721::safe\_transfer\_from](#IERC721-safe_transfer_from) prevents loss, though the caller must understand this adds an external call which potentially creates a reentrancy vulnerability.
Emits a [Transfer](#IERC721-Transfer) event.
+
-#### [](#IERC721-approve)`approve(to: ContractAddress, token_id: u256)` external
-
+
Change or reaffirm the approved address for an NFT.
Emits an [Approval](#IERC721-Approval) event.
+
-#### [](#IERC721-set_approval_for_all)`set_approval_for_all(operator: ContractAddress, approved: bool)` external
-
-Enable or disable approval for `operator` to manage all of the caller’s assets.
+
+Enable or disable approval for `operator` to manage all of the caller's assets.
Emits an [ApprovalForAll](#IERC721-ApprovalForAll) event.
+
-#### [](#IERC721-get_approved)`get_approved(token_id: u256) -> u256` external
-
+
Returns the address approved for `token_id`.
+
-#### [](#IERC721-is_approved_for_all)`is_approved_for_all(owner: ContractAddress, operator: ContractAddress) -> bool` external
-
+
Query if `operator` is an authorized operator for `owner`.
+
-#### [](#events)Events
-
-#### [](#IERC721-Approval)`Approval(owner: ContractAddress, approved: ContractAddress, token_id: u256)` event
+#### Events [!toc] [#IERC721-Events]
+
Emitted when `owner` enables `approved` to manage the `token_id` token.
+
-#### [](#IERC721-ApprovalForAll)`ApprovalForAll(owner: ContractAddress, operator: ContractAddress, approved: bool)` event
-
+
Emitted when `owner` enables or disables `operator` to manage the `token_id` token.
+
-#### [](#IERC721-Transfer)`Transfer(from: ContractAddress, to: ContractAddress, token_id: u256)` event
-
+
Emitted when `token_id` token is transferred from `from` to `to`.
+
-### [](#IERC721Metadata)`IERC721Metadata`[](https://github.com/OpenZeppelin/cairo-contracts/blob/release-v3.0.0-alpha.1/packages/interfaces/src/token/erc721.cairo)
+### `IERC721Metadata` [toc] [#IERC721Metadata]
+
```rust
use openzeppelin_interfaces::erc721::IERC721Metadata;
@@ -107,7 +166,9 @@ Interface for the optional metadata functions in [EIP721](https://eips.ethereum.
[SRC5 ID](introspection#ISRC5)
+```text
0xabbcd595a567dce909050a1038e055daccb3c42af06f0add544fa90ee91f25
+```
Functions
@@ -115,21 +176,37 @@ Functions
- [`symbol()`](#IERC721Metadata-symbol)
- [`token_uri(token_id)`](#IERC721Metadata-token_uri)
-#### [](#functions_2)Functions
-
-#### [](#IERC721Metadata-name)`name() -> ByteArray` external
+#### Functions [!toc] [#IERC721Metadata-Functions]
+
Returns the NFT name.
+
-#### [](#IERC721Metadata-symbol)`symbol() -> ByteArray` external
-
+
Returns the NFT ticker symbol.
+
-#### [](#IERC721Metadata-token_uri)`token_uri(token_id: u256) -> ByteArray` external
-
+
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`.
+
-### [](#IERC721Receiver)`IERC721Receiver`[](https://github.com/OpenZeppelin/cairo-contracts/blob/release-v3.0.0-alpha.1/packages/interfaces/src/token/erc721.cairo)
+### `IERC721Receiver` [toc] [#IERC721Receiver]
+
```rust
use openzeppelin_interfaces::erc721::IERC721Receiver;
@@ -139,25 +216,37 @@ Interface for contracts that support receiving `safe_transfer_from` transfers.
[SRC5 ID](introspection#ISRC5)
+```text
0x3a0dff5f70d80458ad14ae37bb182a728e3c8cdda0402a5daa86620bdf910bc
+```
Functions
- [`on_erc721_received(operator, from, token_id, data)`](#IERC721Receiver-on_erc721_received)
-#### [](#functions_3)Functions
-
-#### [](#IERC721Receiver-on_erc721_received)`on_erc721_received(operator: ContractAddress, from: ContractAddress, token_id: u256, data: Span) -> felt252` external
+#### Functions [!toc] [#IERC721Receiver-Functions]
+
Whenever an IERC721 `token_id` token is transferred to this non-account contract via [IERC721::safe\_transfer\_from](#IERC721-safe_transfer_from) by `operator` from `from`, this function is called.
+
-### [](#IERC721Enumerable)`IERC721Enumerable`[](https://github.com/OpenZeppelin/cairo-contracts/blob/release-v3.0.0-alpha.1/packages/interfaces/src/token/erc721.cairo)
+### `IERC721Enumerable` [toc] [#IERC721Enumerable]
+
Interface for the optional enumerable functions in [EIP721](https://eips.ethereum.org/EIPS/eip-721).
[SRC5 ID](introspection#ISRC5)
+```text
0x16bc0f502eeaf65ce0b3acb5eea656e2f26979ce6750e8502a82f377e538c87
+```
Functions
@@ -165,23 +254,39 @@ Functions
- [`token_by_index(index)`](#IERC721Enumerable-token_by_index)
- [`token_of_owner_by_index(owner, index)`](#IERC721Enumerable-token_of_owner_by_index)
-#### [](#functions_4)Functions
-
-#### [](#IERC721Enumerable-total_supply)`total_supply() -> u256` external
+#### Functions [!toc] [#IERC721Enumerable-Functions]
+
Returns the total amount of tokens stored by the contract.
+
-#### [](#IERC721Enumerable-token_by_index)`token_by_index(index: u256) -> u256` external
-
+
Returns a token id at a given `index` of all the tokens stored by the contract. Use along with [IERC721Enumerable::total\_supply](#IERC721Enumerable-total_supply) to enumerate all tokens.
+
-#### [](#IERC721Enumerable-token_of_owner_by_index)`token_of_owner_by_index(owner: ContractAddress, index: u256) -> u256` external
-
+
Returns the token id owned by `owner` at a given `index` of its token list. Use along with [IERC721::balance\_of](#IERC721-balance_of) to enumerate all of `owner`'s tokens.
+
-## [](#core)Core
+## Core
-### [](#ERC721Component)`ERC721Component`[](https://github.com/OpenZeppelin/cairo-contracts/blob/release-v3.0.0-alpha.1/packages/token/src/erc721/erc721.cairo)
+### `ERC721Component` [toc] [#ERC721Component]
+
```rust
use openzeppelin_token::erc721::ERC721Component;
@@ -195,14 +300,14 @@ See [Hooks](#ERC721Component-Hooks) to understand how are hooks used.
Hooks
-ERC721HooksTrait
+#### ERC721HooksTrait [!toc] [#ERC721Component-ERC721HooksTrait]
- [`before_update(self, to, token_id, auth)`](#ERC721Component-before_update)
- [`after_update(self, to, token_id, auth)`](#ERC721Component-after_update)
[Embeddable Mixin Implementations](../components#mixins)
-ERC721MixinImpl
+#### ERC721MixinImpl [!toc] [#ERC721Component-Embeddable-Impls-ERC721MixinImpl]
- [`ERC721Impl`](#ERC721Component-Embeddable-Impls-ERC721Impl)
- [`ERC721MetadataImpl`](#ERC721Component-Embeddable-Impls-ERC721MetadataImpl)
@@ -212,7 +317,7 @@ ERC721MixinImpl
Embeddable Implementations
-ERC721Impl
+#### ERC721Impl [!toc] [#ERC721Component-Embeddable-Impls-ERC721Impl]
- [`balance_of(self, account)`](#ERC721Component-balance_of)
- [`owner_of(self, token_id)`](#ERC721Component-owner_of)
@@ -223,13 +328,13 @@ ERC721Impl
- [`get_approved(self, token_id)`](#ERC721Component-get_approved)
- [`is_approved_for_all(self, owner, operator)`](#ERC721Component-is_approved_for_all)
-ERC721MetadataImpl
+#### ERC721MetadataImpl [!toc] [#ERC721Component-Embeddable-Impls-ERC721MetadataImpl]
- [`name(self)`](#ERC721Component-name)
- [`symbol(self)`](#ERC721Component-symbol)
- [`token_uri(self, token_id)`](#ERC721Component-token_uri)
-ERC721CamelOnlyImpl
+#### ERC721CamelOnlyImpl [!toc] [#ERC721Component-Embeddable-Impls-ERC721CamelOnlyImpl]
- [`balanceOf(self, account)`](#ERC721Component-balanceOf)
- [`ownerOf(self, tokenId)`](#ERC721Component-ownerOf)
@@ -239,17 +344,17 @@ ERC721CamelOnlyImpl
- [`getApproved(self, tokenId)`](#ERC721Component-getApproved)
- [`isApprovedForAll(self, owner, operator)`](#ERC721Component-isApprovedForAll)
-ERC721MetadataCamelOnlyImpl
+#### ERC721MetadataCamelOnlyImpl [!toc] [#ERC721Component-Embeddable-Impls-ERC721MetadataCamelOnlyImpl]
- [`tokenURI(self, tokenId)`](#ERC721Component-tokenURI)
-SRC5Impl
+#### SRC5Impl [!toc] [#ERC721Component-Embeddable-Impls-SRC5Impl]
- [`supports_interface(self, interface_id: felt252)`](introspection#ISRC5-supports_interface)
Internal functions
-InternalImpl
+#### InternalImpl [!toc] [#ERC721Component-InternalImpl]
- [`initializer(self, name, symbol, base_uri)`](#ERC721Component-initializer)
- [`initializer_no_metadata(self)`](#ERC721Component-initializer_no_metadata)
@@ -278,36 +383,55 @@ IERC721
- [`ApprovalForAll(owner, operator, approved)`](#ERC721Component-ApprovalForAll)
- [`Transfer(from, to, token_id)`](#ERC721Component-Transfer)
-#### [](#ERC721Component-Hooks)Hooks
+#### Hooks [!toc] [#ERC721Component-Hooks]
Hooks are functions which implementations can extend the functionality of the component source code. Every contract using ERC721Component is expected to provide an implementation of the ERC721HooksTrait. For basic token contracts, an empty implementation with no logic must be provided.
You can use `openzeppelin_token::erc721::ERC721HooksEmptyImpl` which is already available as part of the library for this purpose.
-#### [](#ERC721Component-before_update)`before_update(ref self: ContractState, to: ContractAddress, token_id: u256, auth: ContractAddress)` hook
-
+
Function executed at the beginning of the [update](#ERC721Component-update) function prior to any other logic.
+
-#### [](#ERC721Component-after_update)`after_update(ref self: ContractState, to: ContractAddress, token_id: u256, auth: ContractAddress)` hook
-
+
Function executed at the end of the [update](#ERC721Component-update) function.
+
-#### [](#embeddable_functions)Embeddable functions
-
-#### [](#ERC721Component-balance_of)`balance_of(self: @ContractState, account: ContractAddress) → u256` external
+#### [](#embeddable_functions)Embeddable functions [!toc] [#embeddable_functions]
+
See [IERC721::balance\_of](#IERC721-balance_of).
+
-#### [](#ERC721Component-owner_of)`owner_of(self: @ContractState, token_id: u256) → ContractAddress` external
-
+
See [IERC721::owner\_of](#IERC721-owner_of).
Requirements:
- `token_id` exists.
+
-#### [](#ERC721Component-safe_transfer_from)`safe_transfer_from(ref self: ContractState, from: ContractAddress, to: ContractAddress, token_id: u256, data: Span)` external
-
+
See [IERC721::safe\_transfer\_from](#IERC721-safe_transfer_from).
Requirements:
@@ -317,9 +441,13 @@ Requirements:
- `from` is not the zero address.
- `token_id` exists.
- `to` is either an account contract or supports the [IERC721Receiver](#IERC721Receiver) interface.
+
-#### [](#ERC721Component-transfer_from)`transfer_from(ref self: ContractState, from: ContractAddress, to: ContractAddress, token_id: u256)` external
-
+
See [IERC721::transfer\_from](#IERC721-transfer_from).
Requirements:
@@ -328,9 +456,13 @@ Requirements:
- `to` is not the zero address.
- `from` is not the zero address.
- `token_id` exists.
+
-#### [](#ERC721Component-approve)`approve(ref self: ContractState, to: ContractAddress, token_id: u256)` external
-
+
See [IERC721::approve](#IERC721-approve).
Requirements:
@@ -338,95 +470,167 @@ Requirements:
- The caller is either an approved operator or the `token_id` owner.
- `to` cannot be the token owner or the zero address.
- `token_id` exists.
+
-#### [](#ERC721Component-set_approval_for_all)`set_approval_for_all(ref self: ContractState, operator: ContractAddress, approved: bool)` external
-
+
See [IERC721::set\_approval\_for\_all](#IERC721-set_approval_for_all).
Requirements:
- `operator` is not the zero address.
+
-#### [](#ERC721Component-get_approved)`get_approved(self: @ContractState, token_id: u256) -> u256` external
-
+
See [IERC721::get\_approved](#IERC721-get_approved).
Requirements:
- `token_id` exists.
+
-#### [](#ERC721Component-is_approved_for_all)`is_approved_for_all(self: @ContractState, owner: ContractAddress, operator: ContractAddress) -> bool` external
-
+
See [IERC721::is\_approved\_for\_all](#IERC721-is_approved_for_all).
+
-#### [](#ERC721Component-name)`name(self: @ContractState) -> ByteArray` external
-
+
See [IERC721Metadata::name](#IERC721Metadata-name).
+
-#### [](#ERC721Component-symbol)`symbol(self: @ContractState) -> ByteArray` external
-
+
See [IERC721Metadata::symbol](#IERC721Metadata-symbol).
+
-#### [](#ERC721Component-token_uri)`token_uri(self: @ContractState, token_id: u256) -> ByteArray` external
-
+
Returns the Uniform Resource Identifier (URI) for the `token_id` token. If a base URI is set, the resulting URI for each token will be the concatenation of the base URI and the token ID. For example, the base URI `https://token-cdn-domain/` would be returned as `https://token-cdn-domain/123` for token ID `123`.
If the URI is not set for `token_id`, the return value will be an empty `ByteArray`.
+
-#### [](#ERC721Component-balanceOf)`balanceOf(self: @ContractState, account: ContractAddress) -> u256` external
-
+
See [ERC721Component::balance\_of](#ERC721Component-balance_of).
+
-#### [](#ERC721Component-ownerOf)`ownerOf(self: @ContractState, tokenId: u256) -> ContractAddress` external
-
+
See [ERC721Component::owner\_of](#ERC721Component-owner_of).
+
-#### [](#ERC721Component-safeTransferFrom)`safeTransferFrom(ref self: ContractState, from: ContractAddress, to: ContractAddress, tokenId: u256, data: Span)` external
-
+
See [ERC721Component::safe\_transfer\_from](#ERC721Component-safe_transfer_from).
+
-#### [](#ERC721Component-transferFrom)`transferFrom(ref self: ContractState, from: ContractAddress, to: ContractAddress, tokenId: u256)` external
-
+
See [ERC721Component::transfer\_from](#ERC721Component-transfer_from).
+
-#### [](#ERC721Component-setApprovalForAll)`setApprovalForAll(ref self: ContractState, operator: ContractAddress, approved: bool)` external
-
+
See [ERC721Component::set\_approval\_for\_all](#ERC721Component-set_approval_for_all).
+
-#### [](#ERC721Component-getApproved)`getApproved(self: @ContractState, tokenId: u256) -> ContractAddress` external
-
+
See [ERC721Component::get\_approved](#ERC721Component-get_approved).
+
-#### [](#ERC721Component-isApprovedForAll)`isApprovedForAll(self: @ContractState, owner: ContractAddress, operator: ContractAddress) -> bool` external
-
+
See [ERC721Component::is\_approved\_for\_all](#ERC721Component-is_approved_for_all).
+
-#### [](#ERC721Component-tokenURI)`tokenURI(self: @ContractState, tokenId: u256) -> ByteArray` external
-
+
See [ERC721Component::token\_uri](#ERC721Component-token_uri).
+
-#### [](#internal_functions)Internal functions
-
-#### [](#ERC721Component-initializer)`initializer(ref self: ContractState, name: ByteArray, symbol: ByteArray, base_uri: ByteArray)` internal
+#### [](#internal_functions)Internal functions [!toc] [#internal_functions]
-Initializes the contract by setting the token name and symbol. This should be used inside the contract’s constructor.
+
+Initializes the contract by setting the token name and symbol. This should be used inside the contract's constructor.
Most ERC721 contracts expose the [IERC721Metadata](#IERC721Metadata) interface which is what this initializer is meant to support. If the contract DOES NOT expose the [IERC721Metadata](#IERC721Metadata) interface, meaning the token does not have a name, symbol, or URI, the contract must instead use [initializer\_no\_metadata](#ERC721Component-initializer_no_metadata) in the constructor. Failure to abide by these instructions can lead to unexpected issues especially with UIs.
+
-#### [](#ERC721Component-initializer_no_metadata)`initializer_no_metadata(ref self: ContractState)` internal
-
+
Initializes the contract with no metadata by registering only the IERC721 interface.
This initializer should ONLY be used during construction in the very specific instance when the contract does NOT expose the [IERC721Metadata](#IERC721Metadata) interface. Initializing a contract with this initializer means that tokens will not have a name, symbol, or URI.
+
-#### [](#ERC721Component-exists)`exists(self: @ContractState, token_id: u256) -> bool` internal
-
+
Internal function that returns whether `token_id` exists.
Tokens start existing when they are minted ([mint](#ERC721-mint)), and stop existing when they are burned ([burn](#ERC721-burn)).
+
-#### [](#ERC721Component-transfer)`transfer(ref self: ContractState, from: ContractAddress, to: ContractAddress, token_id: u256)` internal
-
+
Transfers `token_id` from `from` to `to`.
Internal function without access restriction.
@@ -440,9 +644,13 @@ Requirements:
- `token_id` exists.
Emits a [Transfer](#IERC721-Transfer) event.
+
-#### [](#ERC721Component-mint)`mint(ref self: ContractState, to: ContractAddress, token_id: u256)` internal
-
+
Mints `token_id` and transfers it to `to`. Internal function without access restriction.
This method may lead to the loss of tokens if `to` is not aware of the ERC721 protocol.
@@ -453,9 +661,13 @@ Requirements:
- `token_id` does not exist.
Emits a [Transfer](#IERC721-Transfer) event.
+
-#### [](#ERC721Component-safe_transfer)`safe_transfer(ref self: ContractState, from: ContractAddress, to: ContractAddress, token_id: u256, data: Span)` internal
-
+
Transfers ownership of `token_id` from `from` if `to` is either an account or `IERC721Receiver`.
`data` is additional data, it has no specified format and is forwarded in `IERC721Receiver::on_erc721_received` to `to`.
@@ -470,9 +682,13 @@ Requirements:
- `to` is either an account contract or supports the `IERC721Receiver` interface.
Emits a [Transfer](#IERC721-Transfer) event.
+
-#### [](#ERC721Component-safe_mint)`safe_mint(ref self: ContractState, to: ContractAddress, token_id: u256, data: Span)` internal
-
+
Mints `token_id` if `to` is either an account or `IERC721Receiver`.
`data` is additional data, it has no specified format and is forwarded in `IERC721Receiver::on_erc721_received` to `to`.
@@ -485,9 +701,13 @@ Requirements:
- `to` is either an account contract or supports the `IERC721Receiver` interface.
Emits a [Transfer](#IERC721-Transfer) event.
+
-#### [](#ERC721Component-burn)`burn(ref self: ContractState, token_id: u256)` internal
-
+
Destroys `token_id`. The approval is cleared when the token is burned.
This internal function does not check if the caller is authorized to operate on the token.
@@ -497,9 +717,13 @@ Requirements:
- `token_id` exists.
Emits a [Transfer](#IERC721-Transfer) event.
+
-#### [](#ERC721Component-update)`update(ref self: ContractState, to: ContractAddress, token_id: u256, auth: ContractAddress)` internal
-
+
Transfers `token_id` from its current owner to `to`, or alternatively mints (or burns) if the current owner (or `to`) is the zero address. Returns the owner of the `token_id` before the update.
The `auth` argument is optional. If the value passed is non-zero, then this function will check that `auth` is either the owner of the token, or approved to operate on the token (by the owner).
@@ -507,25 +731,41 @@ The `auth` argument is optional. If the value passed is non-zero, then this func
Emits a [Transfer](#IERC721-Transfer) event.
This function can be extended using the `ERC721HooksTrait`, to add functionality before and/or after the transfer, mint, or burn.
+
-#### [](#ERC721Component-_owner_of)`_owner_of(self: @ContractState, token_id: felt252) -> ContractAddress` internal
-
+
Internal function that returns the owner address of `token_id`.
+
-#### [](#ERC721Component-_require_owned)`_require_owned(self: @ContractState, token_id: felt252) -> ContractAddress` internal
-
+
Version of [\_owner\_of](#ERC721Component-_owner_of) that panics if owner is the zero address.
+
-#### [](#ERC721Component-_approve)`_approve(ref self: ContractState, to: ContractAddress, token_id: u256, auth: ContractAddress)` internal
-
+
Approve `to` to operate on `token_id`
The `auth` argument is optional. If the value passed is non-zero, then this function will check that `auth` is either the owner of the token, or approved to operate on all tokens held by this owner.
Emits an [Approval](#IERC721-Approval) event.
+
-#### [](#ERC721Component-_approve_with_optional_event)`_approve_with_optional_event(ref self: ContractState, to: ContractAddress, token_id: u256, auth: ContractAddress, emit_event: bool)` internal
-
+
Variant of [\_approve](#ERC721Component-_approve) with an optional flag to enable or disable the `Approval` event. The event is not emitted in the context of transfers.
If `auth` is zero and `emit_event` is false, this function will not check that the token exists.
@@ -535,9 +775,13 @@ Requirements:
- if `auth` is non-zero, it must be either the owner of the token or approved to operate on all of its tokens.
May emit an [Approval](#IERC721-Approval) event.
+
-#### [](#ERC721Component-_set_approval_for_all)`_set_approval_for_all(ref self: ContractState, owner: ContractAddress, operator: ContractAddress, approved: bool)` internal
-
+
Enables or disables approval for `operator` to manage all of the `owner` assets.
Requirements:
@@ -545,25 +789,41 @@ Requirements:
- `operator` is not the zero address.
Emits an [Approval](#IERC721-Approval) event.
+
-#### [](#ERC721Component-_set_base_uri)`_set_base_uri(ref self: ContractState, base_uri: ByteArray)` internal
-
+
Internal function that sets the `base_uri`.
+
-#### [](#ERC721Component-_base_uri)`_base_uri(self: @ContractState) -> ByteArray` internal
-
+
Base URI for computing [token\_uri](#IERC721Metadata-token_uri).
If set, the resulting URI for each token will be the concatenation of the base URI and the token ID. Returns an empty `ByteArray` if not set.
+
-#### [](#ERC721Component-_is_authorized)`_is_authorized(self: @ContractState, owner: ContractAddress, spender: ContractAddress, token_id: u256) -> bool` internal
-
+
Returns whether `spender` is allowed to manage `owner`'s tokens, or `token_id` in particular (ignoring whether it is owned by `owner`).
This function assumes that `owner` is the actual owner of `token_id` and does not verify this assumption.
+
-#### [](#ERC721Component-_check_authorized)`_check_authorized(self: @ContractState, owner: ContractAddress, spender: ContractAddress, token_id: u256) -> bool` internal
-
+
Checks if `spender` can operate on `token_id`, assuming the provided `owner` is the actual owner.
Requirements:
@@ -573,22 +833,39 @@ Requirements:
- `spender` must be the owner of `token_id` or be approved to operate on it.
This function assumes that `owner` is the actual owner of `token_id` and does not verify this assumption.
+
-#### [](#events_2)Events
-
-#### [](#ERC721Component-Approval)`Approval(owner: ContractAddress, approved: ContractAddress, token_id: u256)` event
+#### [](#events_2)Events [!toc] [#events_2]
+
See [IERC721::Approval](#IERC721-Approval).
+
-#### [](#ERC721Component-ApprovalForAll)`ApprovalForAll(owner: ContractAddress, operator: ContractAddress, approved: bool)` event
-
+
See [IERC721::ApprovalForAll](#IERC721-ApprovalForAll).
+
-#### [](#ERC721Component-Transfer)`Transfer(from: ContractAddress, to: ContractAddress, token_id: u256)` event
-
+
See [IERC721::Transfer](#IERC721-Transfer).
+
-### [](#ERC721ReceiverComponent)`ERC721ReceiverComponent`[](https://github.com/OpenZeppelin/cairo-contracts/blob/release-v3.0.0-alpha.1/packages/token/src/erc721/erc721_receiver.cairo)
+### `ERC721ReceiverComponent` [toc] [#ERC721ReceiverComponent]
+
```rust
use openzeppelin_token::erc721::ERC721ReceiverComponent;
@@ -600,7 +877,7 @@ Implementing [SRC5Component](introspection#SRC5Component) is a requirement for t
[Embeddable Mixin Implementations](../components#mixins)
-ERCReceiverMixinImpl
+#### ERCReceiverMixinImpl [!toc] [#ERC721ReceiverComponent-Embeddable-Impls-ERCReceiverMixinImpl]
- [`ERC721ReceiverImpl`](#ERC721ReceiverComponent-Embeddable-Impls-ERC721ReceiverImpl)
- [`ERC721ReceiverCamelImpl`](#ERC721ReceiverComponent-Embeddable-Impls-ERC721ReceiverCamelImpl)
@@ -608,39 +885,55 @@ ERCReceiverMixinImpl
Embeddable Implementations
-ERC721ReceiverImpl
+#### ERC721ReceiverImpl [!toc] [#ERC721ReceiverComponent-Embeddable-Impls-ERC721ReceiverImpl]
- [`on_erc721_received(self, operator, from, token_id, data)`](#ERC721ReceiverComponent-on_erc721_received)
-ERC721ReceiverCamelImpl
+#### ERC721ReceiverCamelImpl [!toc] [#ERC721ReceiverComponent-Embeddable-Impls-ERC721ReceiverCamelImpl]
- [`onERC721Received(self, operator, from, tokenId, data)`](#ERC721ReceiverComponent-onERC721Received)
Internal Functions
-InternalImpl
+#### InternalImpl [!toc] [#ERC721ReceiverComponent-InternalImpl]
- [`initializer(self)`](#ERC721ReceiverComponent-initializer)
-#### [](#embeddable_functions_2)Embeddable functions
-
-#### [](#ERC721ReceiverComponent-on_erc721_received)`on_erc721_received(self: @ContractState, operator: ContractAddress, from: ContractAddress, token_id: u256, data Span) -> felt252` external
+#### [](#embeddable_functions_2)Embeddable functions [!toc] [#embeddable_functions_2]
+
Returns the `IERC721Receiver` interface ID.
+
-#### [](#ERC721ReceiverComponent-onERC721Received)`onERC721Received(self: @ContractState, operator: ContractAddress, from: ContractAddress, token_id: u256, data Span) -> felt252` external
-
+
See [ERC721ReceiverComponent::on\_erc721\_received](#ERC721ReceiverComponent-on_erc721_received).
+
-#### [](#internal_functions_2)Internal functions
-
-#### [](#ERC721ReceiverComponent-initializer)`initializer(ref self: ContractState)` internal
+#### [](#internal_functions_2)Internal functions [!toc] [#internal_functions_2]
+
Registers the `IERC721Receiver` interface ID as supported through introspection.
+
-## [](#extensions)Extensions
+## Extensions
-### [](#ERC721EnumerableComponent)`ERC721EnumerableComponent`[](https://github.com/OpenZeppelin/cairo-contracts/blob/release-v3.0.0-alpha.1/packages/token/src/erc721/extensions/erc721_enumerable.cairo)
+### `ERC721EnumerableComponent` [toc] [#ERC721EnumerableComponent]
+
```rust
use openzeppelin_token::erc721::extensions::ERC721EnumerableComponent;
@@ -650,7 +943,7 @@ Extension of ERC721 as defined in the EIP that adds enumerability of all the tok
Implementing [ERC721Component](#ERC721Component) is a requirement for this component to be implemented.
-To properly track token ids, this extension requires that the [ERC721EnumerableComponent::before\_update](#ERC721EnumerableComponent-before_update) function is called before every transfer, mint, or burn operation. For this, the [ERC721HooksTrait::before\_update](#ERC721Component-before_update) hook must be used. Here’s how the hook should be implemented in a contract:
+To properly track token ids, this extension requires that the [ERC721EnumerableComponent::before\_update](#ERC721EnumerableComponent-before_update) function is called before every transfer, mint, or burn operation. For this, the [ERC721HooksTrait::before\_update](#ERC721Component-before_update) hook must be used. Here's how the hook should be implemented in a contract:
```[
#[starknet::contract]
@@ -677,7 +970,7 @@ mod ERC721EnumerableContract {
Embeddable Implementations
-ERC721EnumerableImpl
+#### ERC721EnumerableImpl [!toc] [#ERC721EnumerableComponent-Embeddable-Impls-ERC721EnumerableImpl]
- [`total_supply(self)`](#ERC721EnumerableComponent-total_supply)
- [`token_by_index(self, index)`](#ERC721EnumerableComponent-token_by_index)
@@ -685,7 +978,7 @@ ERC721EnumerableImpl
Internal functions
-InternalImpl
+#### InternalImpl [!toc] [#ERC721EnumerableComponent-InternalImpl]
- [`initializer(self)`](#ERC721EnumerableComponent-initializer)
- [`before_update(self, to, token_id)`](#ERC721EnumerableComponent-before_update)
@@ -695,76 +988,120 @@ InternalImpl
- [`_remove_token_from_owner_enumeration(self, from, token_id)`](#ERC721EnumerableComponent-_remove_token_from_owner_enumeration)
- [`_remove_token_from_all_tokens_enumeration(self, token_id)`](#ERC721EnumerableComponent-_remove_token_from_all_tokens_enumeration)
-#### [](#ERC721EnumerableComponent-Embeddable-functions)Embeddable functions
-
-#### [](#ERC721EnumerableComponent-total_supply)`total_supply(self: @ContractState) → u256` external
+#### [](#ERC721EnumerableComponent-Embeddable-functions)Embeddable functions [!toc] [#ERC721EnumerableComponent-Embeddable-functions]
+
Returns the current amount of votes that `account` has.
+
-#### [](#ERC721EnumerableComponent-token_by_index)`token_by_index(self: @ContractState, index: u256) → u256` external
-
+
See [IERC721Enumerable::token\_by\_index](#IERC721Enumerable-token_by_index).
Requirements:
- `index` is less than the total token supply.
+
-#### [](#ERC721EnumerableComponent-token_of_owner_by_index)`token_of_owner_by_index(self: @ContractState, owner: ContractAddress, index: u256) → u256` external
-
+
See [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
-
-#### [](#ERC721EnumerableComponent-initializer)`initializer(ref self: ContractState)` internal
+#### [](#ERC721EnumerableComponent-Internal-functions)Internal functions [!toc] [#ERC721EnumerableComponent-Internal-functions]
+
Registers the `IERC721Enumerable` interface ID as supported through introspection.
+
-#### [](#ERC721EnumerableComponent-before_update)`before_update(ref self: ContractState, to: ContractAddress, token_id: u256)` 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 [ERC721HooksTrait::before\_update](#ERC721Component-before_update) hook.
-
-#### [](#ERC721EnumerableComponent-all_tokens_of_owner)`all_tokens_of_owner(self: @ContractState, owner: ContractAddress) → Span` internal
+This must be added to the implementing contract's [ERC721HooksTrait::before\_update](#ERC721Component-before_update) hook.
+
+
Returns a list of all token ids owned by the specified `owner`. This function provides a more efficient alternative to calling `ERC721::balance_of` and iterating through tokens with `ERC721Enumerable::token_of_owner_by_index`.
Requirements:
- `owner` is not the zero address.
-
-#### [](#ERC721EnumerableComponent-_add_token_to_owner_enumeration)`_add_token_to_owner_enumeration(ref self: ContractState, to: ContractAddress, token_id: u256)` internal
-
-Adds token to this extension’s ownership-tracking data structures.
-
-#### [](#ERC721EnumerableComponent-_add_token_to_all_tokens_enumeration)`_add_token_to_all_tokens_enumeration(ref self: ContractState, token_id: u256)` internal
-
-Adds token to this extension’s token-tracking data structures.
-
-#### [](#ERC721EnumerableComponent-_remove_token_from_owner_enumeration)`_remove_token_from_owner_enumeration(ref self: ContractState, from: ContractAddress, token_id: u256)` internal
-
-Removes a token from this extension’s ownership-tracking data structures.
+
+
+
+Adds token to this extension's ownership-tracking data structures.
+
+
+
+Adds token to this extension's token-tracking data structures.
+
+
+
+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]`.
+
-#### [](#ERC721EnumerableComponent-_remove_token_from_all_tokens_enumeration)`_remove_token_from_all_tokens_enumeration(ref self: ContractState, token_id: u256)` internal
-
-Removes `token_id` from this extension’s token-tracking data structures.
+
+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]`.
+
-## [](#presets)Presets
+## Presets
-### [](#ERC721Upgradeable)`ERC721Upgradeable`[](https://github.com/OpenZeppelin/cairo-contracts/blob/release-v3.0.0-alpha.1/packages/presets/src/erc721.cairo)
+### `ERC721Upgradeable` [toc] [#ERC721Upgradeable]
+
```rust
use openzeppelin_presets::ERC721Upgradeable;
@@ -774,7 +1111,9 @@ Upgradeable ERC721 contract leveraging [ERC721Component](#ERC721Component).
[Sierra class hash](../presets)
-0x04080084ac1ba5a26b4638ac7ca2ff009a9a9b86bf6db5df05e96c90aa143df5
+```text
+{{ERC721UpgradeableClassHash}}
+```
Constructor
@@ -794,19 +1133,27 @@ External Functions
- [`upgrade(self, new_class_hash)`](#ERC721Upgradeable-upgrade)
-#### [](#ERC721Upgradeable-constructor-section)Constructor
-
-#### [](#ERC721Upgradeable-constructor)`constructor(ref self: ContractState, name: ByteArray, symbol: ByteArray, recipient: ContractAddress, token_ids: Span, base_uri: ByteArray, owner: ContractAddress)` constructor
+#### [](#ERC721Upgradeable-constructor-section)Constructor [!toc] [#ERC721Upgradeable-constructor-section]
+
Sets the `name` and `symbol`. Mints `token_ids` tokens to `recipient` and sets the `base_uri`. Assigns `owner` as the contract owner with permissions to upgrade.
+
-#### [](#ERC721Upgradeable-external-functions)External functions
-
-#### [](#ERC721Upgradeable-upgrade)`upgrade(ref self: ContractState, new_class_hash: ClassHash)` external
+#### [](#ERC721Upgradeable-external-functions)External functions [!toc] [#ERC721Upgradeable-external-functions]
+
Upgrades the contract to a new implementation given by `new_class_hash`.
Requirements:
- The caller is the contract owner.
- `new_class_hash` cannot be zero.
+
diff --git a/content/contracts-cairo/api/finance.mdx b/content/contracts-cairo/api/finance.mdx
index 6779c9c..29d0213 100644
--- a/content/contracts-cairo/api/finance.mdx
+++ b/content/contracts-cairo/api/finance.mdx
@@ -2,13 +2,23 @@
title: Finance
---
+import { UMBRELLA_VERSION } from "../utils/constants.js";
+
This crate includes primitives for financial systems.
## [](#interfaces)Interfaces
-Starting from version `3.x.x`, the interfaces are no longer part of the `openzeppelin_finance` package. The references documented here are contained in the `openzeppelin_interfaces` package version `v2.1.0`.
+
+Starting from version `3.x.x`, the interfaces are no longer part of the `openzeppelin_access` package. The references
+documented here are contained in the `openzeppelin_interfaces` package version `{{openzeppelin_interfaces_version}}`.
+
+
+### `IVesting` [toc] [#IVesting]
-### [](#IVesting)`IVesting`[](https://github.com/OpenZeppelin/cairo-contracts/blob/release-v3.0.0-alpha.1/packages/interfaces/src/finance/vesting.cairo)
+
```rust
use openzeppelin_interfaces::vesting::IVesting;
@@ -31,51 +41,92 @@ Events
- [`AmountReleased(token, amount)`](#IVesting-AmountReleased)
-#### [](#IVesting-Functions)Functions
-
-#### [](#IVesting-start)`start() → u64` external
+#### Functions [!toc] [#IVesting-Functions]
+
Returns the timestamp marking the beginning of the vesting period.
+
-#### [](#IVesting-cliff)`cliff() → u64` external
-
+
Returns the timestamp marking the end of the cliff period.
+
-#### [](#IVesting-duration)`duration() → u64` external
-
+
Returns the total duration of the vesting period.
+
-#### [](#IVesting-end)`end() → u64` external
-
+
Returns the timestamp marking the end of the vesting period.
+
-#### [](#IVesting-released)`released(token: ContractAddress) → u256` external
-
+
Returns the already released amount for a given `token`.
+
-#### [](#IVesting-releasable)`releasable(token: ContractAddress) → u256` external
-
+
Returns the amount of a given `token` that can be released at the time of the call.
+
-#### [](#IVesting-vested_amount)`vested_amount(token: ContractAddress, timestamp: u64) → u256` external
-
+
Returns the total vested amount of a specified `token` at a given `timestamp`.
+
-#### [](#IVesting-release)`release(token: ContractAddress) → u256` external
-
+
Releases the amount of a given `token` that has already vested and returns that amount.
May emit an [AmountReleased](#IVesting-AmountReleased) event.
+
-#### [](#IVesting-Events)Events
-
-#### [](#IVesting-AmountReleased)`AmountReleased(token: ContractAddress, amount: u256)` event
+#### Events [!toc] [#IVesting-Events]
+
Emitted when vested tokens are released to the beneficiary.
+
## [](#vesting)Vesting
-### [](#VestingComponent)`VestingComponent`[](https://github.com/OpenZeppelin/cairo-contracts/blob/release-v3.0.0-alpha.1/packages/finance/src/vesting/vesting.cairo)
+### `VestingComponent` [toc] [#VestingComponent]
+
+
```rust
use openzeppelin_finance::vesting::VestingComponent;
@@ -85,13 +136,13 @@ Vesting component implementing the [`IVesting`](#IVesting) interface.
Vesting Schedule Trait Implementations
-functions
+#### functions [!toc] [#VestingComponent-Vesting-Schedule-functions]
- [`calculate_vested_amount(self, token, total_allocation, timestamp, start, duration, cliff)`](#VestingComponent-calculate_vested_amount)
Embeddable Implementations
-VestingImpl
+#### VestingImpl [!toc] [#VestingComponent-Embeddable-Impls-VestingImpl]
- [`start(self)`](#VestingComponent-start)
- [`cliff(self)`](#VestingComponent-cliff)
@@ -104,78 +155,125 @@ VestingImpl
Internal implementations
-InternalImpl
+#### InternalImpl [!toc] [#VestingComponent-InternalImpl]
- [`initializer(self, start, duration, cliff_duration)`](#VestingComponent-initializer)
- [`resolve_vested_amount(self, token, timestamp)`](#VestingComponent-resolve_vested_amount)
-#### [](#VestingComponent-Vesting-Schedule)VestingSchedule trait
-
A trait that defines the logic for calculating the vested amount based on a given timestamp.
-You can read more about the trait’s purpose and how to use it [here](../finance#vesting_schedule).
-
-#### [](#VestingComponent-calculate_vested_amount)`calculate_vested_amount(self: @ContractState, token: ContractAddress, total_allocation: u256, timestamp: u64, start: u64, duration: u64, cliff: u64) → u256` internal
+You can read more about the trait's purpose and how to use it [here](../finance#vesting_schedule).
+
Calculates and returns the vested amount at a given `timestamp` based on the core vesting parameters.
+
-#### [](#VestingComponent-Functions)Functions
-
-#### [](#VestingComponent-start)`start(self: @ContractState) → u64` external
+#### Functions [!toc] [#VestingComponent-Functions]
+
Returns the timestamp marking the beginning of the vesting period.
+
-#### [](#VestingComponent-cliff)`cliff(self: @ContractState) → u64` external
-
+
Returns the timestamp marking the end of the cliff period.
+
-#### [](#VestingComponent-duration)`duration(self: @ContractState) → u64` external
-
+
Returns the total duration of the vesting period.
+
-#### [](#VestingComponent-end)`end(self: @ContractState) → u64` external
-
+
Returns the timestamp marking the end of the vesting period.
+
-#### [](#VestingComponent-released)`released(self: @ContractState, token: ContractAddress) → u256` external
-
+
Returns the already released amount for a given `token`.
+
-#### [](#VestingComponent-releasable)`releasable(self: @ContractState, token: ContractAddress) → u256` external
-
+
Returns the amount of a given `token` that can be released at the time of the call.
+
-#### [](#VestingComponent-vested_amount)`vested_amount(self: @ContractState, token: ContractAddress, timestamp: u64) → u256` external
-
+
Returns the total vested amount of a specified `token` at a given `timestamp`.
+
-#### [](#VestingComponent-release)`release(ref self: ContractState, token: ContractAddress) → u256` external
-
+
Releases the amount of a given `token` that has already vested and returns that amount.
-If the releasable amount is zero, this function won’t emit the event or attempt to transfer the tokens.
+If the releasable amount is zero, this function won't emit the event or attempt to transfer the tokens.
Requirements:
- `transfer` call to the `token` must return `true` indicating a successful transfer.
May emit an [AmountReleased](#IVesting-AmountReleased) event.
+
-#### [](#VestingComponent-Internal-Functions)Internal functions
-
-#### [](#VestingComponent-initializer)`initializer(ref self: ContractState, start: u64, duration: u64, cliff_duration: u64)` internal
+#### Internal functions [!toc] [#VestingComponent-Internal-Functions]
-Initializes the component by setting the vesting `start`, `duration` and `cliff_duration`. To prevent reinitialization, this should only be used inside of a contract’s constructor.
+
+Initializes the component by setting the vesting `start`, `duration` and `cliff_duration`. To prevent reinitialization, this should only be used inside of a contract's constructor.
Requirements:
- `cliff_duration` must be less than or equal to `duration`.
+
-#### [](#VestingComponent-resolve_vested_amount)`resolve_vested_amount(self: @ContractState, token: ContractAddress, timestamp: u64) → u256` internal
+
+Returns the vested amount that's calculated using the [VestingSchedule](#VestingComponent-Vesting-Schedule) trait implementation.
+
-Returns the vested amount that’s calculated using the [VestingSchedule](#VestingComponent-Vesting-Schedule) trait implementation.
+### `LinearVestingSchedule` [toc] [#LinearVestingSchedule]
-### [](#LinearVestingSchedule)`LinearVestingSchedule`[](https://github.com/OpenZeppelin/cairo-contracts/blob/release-v3.0.0-alpha.1/packages/finance/src/vesting/vesting.cairo)
+
```rust
use openzeppelin_finance::vesting::LinearVestingSchedule;
@@ -185,7 +283,12 @@ Defines the logic for calculating the vested amount, incorporating a cliff perio
## [](#presets)Presets
-### [](#VestingWallet)`VestingWallet`[](https://github.com/OpenZeppelin/cairo-contracts/blob/release-v3.0.0-alpha.1/packages/presets/src/vesting.cairo)
+### `VestingWallet` [toc] [#VestingWallet]
+
+
```rust
use openzeppelin::presets::VestingWallet;
@@ -197,7 +300,9 @@ The contract is intentionally designed to be non-upgradable to ensure that neith
[Sierra class hash](../presets)
-0x062050f8eb6942d067d9d6fc6c2d01aaedbee284f339e58196d5a3bd3d4d6c6f
+```text
+{{VestingWalletClassHash}}
+```
Constructor
@@ -213,12 +318,16 @@ OwnableComponent
- [`OwnableMixinImpl`](access#OwnableComponent-Mixin-Impl)
-#### [](#VestingWallet-constructor-section)Constructor
-
-#### [](#VestingWallet-constructor)`constructor(ref self: ContractState, beneficiary: ContractAddress, start: u64, duration: u64, cliff_duration: u64)` constructor
+#### Constructor [!toc] [#VestingWallet-constructor-section]
+
Initializes the vesting component by setting the vesting `start`, `duration` and `cliff_duration`. Assigns `beneficiary` as the contract owner and the vesting beneficiary.
Requirements:
- `cliff_duration` must be less than or equal to `duration`.
+
diff --git a/content/contracts-cairo/api/governance.mdx b/content/contracts-cairo/api/governance.mdx
index 89e87b4..36db139 100644
--- a/content/contracts-cairo/api/governance.mdx
+++ b/content/contracts-cairo/api/governance.mdx
@@ -2,13 +2,23 @@
title: Governance
---
+import { UMBRELLA_VERSION } from "../utils/constants.js";
+
This crate includes primitives for on-chain governance.
## [](#interfaces)Interfaces
-Starting from version `3.x.x`, the interfaces are no longer part of the `openzeppelin_governance` package. The references documented here are contained in the `openzeppelin_interfaces` package version `v2.1.0`.
+
+Starting from version `3.x.x`, the interfaces are no longer part of the `openzeppelin_access` package. The references
+documented here are contained in the `openzeppelin_interfaces` package version `{{openzeppelin_interfaces_version}}`.
+
+
+### `IGovernor` [toc] [#IGovernor]
-### [](#IGovernor)`IGovernor`[](https://github.com/OpenZeppelin/cairo-contracts/blob/release-v3.0.0-alpha.1/packages/interfaces/src/governance/governor.cairo)
+
```rust
use openzeppelin_interfaces::governor::IGovernor;
@@ -18,7 +28,9 @@ Interface of a governor contract.
[SRC5 ID](introspection#ISRC5)
+```text
0x1100a1f8546595b5bd75a6cd8fcc5b015370655e66f275963321c5cd0357ac9
+```
Functions
@@ -60,18 +72,29 @@ Events
- [`VoteCast(voter, proposal_id, support, weight, reason)`](#IGovernor-VoteCast)
- [`VoteCastWithParams(voter, proposal_id, support, weight, reason, params)`](#IGovernor-VoteCastWithParams)
-#### [](#IGovernor-Functions)Functions
-
-#### [](#IGovernor-name)`name() → felt252` external
+#### Functions [!toc] [#IGovernor-Functions]
+
Name of the governor instance (used in building the [SNIP-12](https://github.com/starknet-io/SNIPs/blob/main/SNIPS/snip-12.md) domain separator).
+
-#### [](#IGovernor-version)`version() → felt252` external
-
+
Version of the governor instance (used in building [SNIP-12](https://github.com/starknet-io/SNIPs/blob/main/SNIPS/snip-12.md) domain separator).
+
-#### [](#IGovernor-COUNTING_MODE)`COUNTING_MODE() → ByteArray` external
-
+
A description of the possible `support` values for `cast_vote` and the way these votes are counted, meant to be consumed by UIs to show correct vote options and interpret the results. The string is a URL-encoded sequence of key-value pairs that each describe one aspect, for example `support=bravo&quorum=for,abstain`.
There are 2 standard keys: `support` and `quorum`.
@@ -85,173 +108,305 @@ If a counting module makes use of encoded `params`, it should include this under
- `params=fractional` might refer to a scheme where votes are divided fractionally between for/against/abstain.
- `params=erc721` might refer to a scheme where specific NFTs are delegated to vote.
+
The string can be decoded by the standard [`URLSearchParams`](https://developer.mozilla.org/en-US/docs/Web/API/URLSearchParams) JavaScript class.
-
-#### [](#IGovernor-hash_proposal)`hash_proposal(calls: Span, description_hash: felt252) → felt252` external
-
+
+
+
+
Hashing function used to (re)build the proposal id from the proposal details.
+
-#### [](#IGovernor-state)`state(proposal_id: felt252) → ProposalState` external
-
+
Returns the state of a proposal, given its id.
+
-#### [](#IGovernor-proposal_threshold)`proposal_threshold() → u256` external
-
+
The number of votes required in order for a voter to become a proposer.
-
-#### [](#IGovernor-proposal_snapshot)`proposal_snapshot(proposal_id: felt252) → u64` external
-
-Timepoint used to retrieve user’s votes and quorum. If using block number, the snapshot is performed at the end of this block. Hence, voting for this proposal starts at the beginning of the following block.
-
-#### [](#IGovernor-proposal_deadline)`proposal_deadline(proposal_id: felt252) → u64` external
-
+
+
+
+Timepoint used to retrieve user's votes and quorum. If using block number, the snapshot is performed at the end of this block. Hence, voting for this proposal starts at the beginning of the following block.
+
+
+
Timepoint at which votes close. If using block number, votes close at the end of this block, so it is possible to cast a vote during this block.
+
-#### [](#IGovernor-proposal_proposer)`proposal_proposer(proposal_id: felt252) → ContractAddress` external
-
+
The account that created a proposal.
-
-#### [](#IGovernor-proposal_eta)`proposal_eta(proposal_id: felt252) → u64` external
-
-The time when a queued proposal becomes executable ("ETA"). Unlike `proposal_snapshot` and `proposal_deadline`, this doesn’t use the governor clock, and instead relies on the executor’s clock which may be different. In most cases this will be a timestamp.
-
-#### [](#IGovernor-proposal_needs_queuing)`proposal_needs_queuing(proposal_id: felt252) → bool` external
-
+
+
+
+The time when a queued proposal becomes executable ("ETA"). Unlike `proposal_snapshot` and `proposal_deadline`, this doesn't use the governor clock, and instead relies on the executor's clock which may be different. In most cases this will be a timestamp.
+
+
+
Whether a proposal needs to be queued before execution. This indicates if the proposal needs to go through a timelock.
+
-#### [](#IGovernor-voting_delay)`voting_delay() → u64` external
-
+
Delay between when a proposal is created and when the vote starts. The unit this duration is expressed in depends on the clock (see [ERC-6372](https://eips.ethereum.org/EIPS/eip-6372)) this contract uses.
This can be increased to leave time for users to buy voting power, or delegate it, before the voting of a proposal starts.
+
-#### [](#IGovernor-voting_period)`voting_period() → u64` external
-
+
Delay between when a vote starts and when it ends. The unit this duration is expressed in depends on the clock (see [ERC-6372](https://eips.ethereum.org/EIPS/eip-6372)) this contract uses.
The `voting_delay` can delay the start of the vote. This must be considered when setting the voting duration compared to the voting delay.
This value is stored when the proposal is submitted so that possible changes to the value do not affect proposals that have already been submitted.
+
-#### [](#IGovernor-quorum)`quorum(timepoint: u64) → u256` external
-
+
Minimum number of votes required for a proposal to be successful.
The `timepoint` parameter corresponds to the snapshot used for counting vote. This allows the quorum to scale depending on values such as the total supply of a token at this timepoint.
+
-#### [](#IGovernor-get_votes)`get_votes(account: ContractAddress, timepoint: u64) → u256` external
-
+
Returns the voting power of an `account` at a specific `timepoint`.
This can be implemented in a number of ways, for example by reading the delegated balance from one (or multiple) `ERC20Votes` tokens.
+
-#### [](#IGovernor-get_votes_with_params)`get_votes_with_params(account: ContractAddress, timepoint: u64, params: Span) → u256` external
-
+
Returns the voting power of an `account` at a specific `timepoint`, given additional encoded parameters.
+
-#### [](#IGovernor-has_voted)`has_voted(proposal_id: felt252, account: ContractAddress) → bool` external
-
+
Returns whether an `account` has cast a vote on a proposal.
+
-#### [](#IGovernor-propose)`propose(calls: Span, description: ByteArray) → felt252` external
-
+
Creates a new proposal. Vote starts after a delay specified by `voting_delay` and lasts for a duration specified by `voting_period`.
-The state of the Governor and targets may change between the proposal creation and its execution. This may be the result of third party actions on the targeted contracts, or other governor proposals. For example, the balance of this contract could be updated or its access control permissions may be modified, possibly compromising the proposal’s ability to execute successfully (e.g. the governor doesn’t have enough value to cover a proposal with multiple transfers).
+The state of the Governor and targets may change between the proposal creation and its execution. This may be the result of third party actions on the targeted contracts, or other governor proposals. For example, the balance of this contract could be updated or its access control permissions may be modified, possibly compromising the proposal's ability to execute successfully (e.g. the governor doesn't have enough value to cover a proposal with multiple transfers).
Returns the id of the proposal.
+
-#### [](#IGovernor-queue)`queue(calls: Span, description_hash: felt252) → felt252` external
-
+
Queue a proposal. Some governors require this step to be performed before execution can happen. If queuing is not necessary, this function may revert.
Queuing a proposal requires the quorum to be reached, the vote to be successful, and the deadline to be reached.
Returns the id of the proposal.
+
-#### [](#IGovernor-execute)`execute(calls: span, description_hash: felt252) → felt252` external
-
+
Execute a successful proposal. This requires the quorum to be reached, the vote to be successful, and the deadline to be reached. Depending on the governor it might also be required that the proposal was queued and that some delay passed.
Some modules can modify the requirements for execution, for example by adding an additional timelock (See `timelock_controller`).
Returns the id of the proposal.
+
-#### [](#IGovernor-cancel)`cancel(calls: Span, description_hash: felt252) → felt252` external
-
+
Cancel a proposal. A proposal is cancellable by the proposer, but only while it is Pending state, i.e. before the vote starts.
Returns the id of the proposal.
+
-#### [](#IGovernor-cast_vote)`cast_vote(proposal_id: felt252, support: u8) → u256` external
-
+
Cast a vote on a proposal.
Returns the weight of the vote.
+
-#### [](#IGovernor-cast_vote_with_reason)`cast_vote_with_reason(proposal_id: felt252, support: u8, reason: ByteArray) → u256` external
-
+
Cast a vote on a proposal with a `reason`.
Returns the weight of the vote.
+
-#### [](#IGovernor-cast_vote_with_reason_and_params)`cast_vote_with_reason_and_params(proposal_id: felt252, support: u8, reason: ByteArray, params: Span) → u256` external
-
+
Cast a vote on a proposal with a reason and additional encoded parameters.
Returns the weight of the vote.
+
-#### [](#IGovernor-cast_vote_by_sig)`cast_vote_by_sig(proposal_id: felt252, support: u8, voter: ContractAddress, signature: Span) → u256` external
-
-Cast a vote on a proposal using the voter’s signature.
+
+Cast a vote on a proposal using the voter's signature.
Returns the weight of the vote.
+
-#### [](#IGovernor-cast_vote_with_reason_and_params_by_sig)`cast_vote_with_reason_and_params_by_sig(proposal_id: felt252, support: u8, voter: ContractAddress, reason: ByteArray, params: Span, signature: Span) → u256` external
-
+
Cast a vote on a proposal with a reason and additional encoded parameters using the `voter`'s signature.
Returns the weight of the vote.
+
-#### [](#IGovernor-nonces)`nonces(voter: ContractAddress) → felt252` external
-
+
Returns the next unused nonce for an address.
+
-#### [](#IGovernor-relay)`relay(call: Call)` external
-
+
Relays a transaction or function call to an arbitrary target.
In cases where the governance executor is some contract other than the governor itself, like when using a timelock, this function can be invoked in a governance proposal to recover tokens that were sent to the governor contract by mistake.
If the executor is simply the governor itself, use of `relay` is redundant.
+
-#### [](#IGovernor-Events)Events
-
-#### [](#IGovernor-ProposalCreated)`ProposalCreated(proposal_id: felt252, proposer: ContractAddress, calls: Span, signatures: Span>, vote_start: u64, vote_end: u64, description: ByteArray)` event
+#### Events [!toc] [#IGovernor-Events]
+
Emitted when a proposal is created.
+
-#### [](#IGovernor-ProposalQueued)`ProposalQueued(proposal_id: felt252, eta_seconds: u64)` event
-
+
Emitted when a proposal is queued.
+
-#### [](#IGovernor-ProposalExecuted)`ProposalExecuted(proposal_id: felt252)` event
-
+
Emitted when a proposal is executed.
+
-#### [](#IGovernor-ProposalCanceled)`ProposalCanceled(proposal_id: felt252)` event
-
+
Emitted when a proposal is canceled.
+
-#### [](#IGovernor-VoteCast)`VoteCast(voter: ContractAddress, proposal_id: felt252, support: u8, weight: u256, reason: ByteArray)` event
-
+
Emitted when a vote is cast.
+
-#### [](#IGovernor-VoteCastWithParams)`VoteCastWithParams(voter: ContractAddress, proposal_id: felt252, support: u8, weight: u256, reason: ByteArray, params: Span)` event
-
+
Emitted when a vote is cast with params.
+
+
+### `IMultisig` [toc] [#IMultisig]
-### [](#IMultisig)`IMultisig`[](https://github.com/OpenZeppelin/cairo-contracts/blob/release-v3.0.0-alpha.1/packages/interfaces/src/governance/multisig.cairo)
+
```rust
use openzeppelin_interfaces::multisig::IMultisig;
@@ -294,54 +449,101 @@ Events
- [`TransactionExecuted(id)`](#IMultisig-TransactionExecuted)
- [`CallSalt(id, salt)`](#IMultisig-CallSalt)
-#### [](#IMultisig-Functions)Functions
-
-#### [](#IMultisig-get_quorum)`get_quorum() → u32` external
+#### Functions [!toc] [#IMultisig-Functions]
+
Returns the current quorum value. The quorum is the minimum number of confirmations required to approve a transaction.
+
-#### [](#IMultisig-is_signer)`is_signer(signer: ContractAddress) → bool` external
-
+
Returns whether the given `signer` is registered. Only registered signers can submit, confirm, or execute transactions.
+
-#### [](#IMultisig-get_signers)`get_signers() → Span` external
-
+
Returns the list of all current signers.
+
-#### [](#IMultisig-is_confirmed)`is_confirmed(id: TransactionID) → bool` external
-
+
Returns whether the transaction with the given `id` has been confirmed.
+
-#### [](#IMultisig-is_confirmed_by)`is_confirmed_by(id: TransactionID, signer: ContractAddress) → bool` external
-
+
Returns whether the transaction with the given `id` has been confirmed by the specified `signer`.
+
-#### [](#IMultisig-is_executed)`is_executed(id: TransactionID) → bool` external
-
+
Returns whether the transaction with the given `id` has been executed.
+
-#### [](#IMultisig-get_submitted_block)`get_submitted_block(id: TransactionID) → u64` external
-
+
Returns the block number when the transaction with the given `id` was submitted.
+
-#### [](#IMultisig-get_transaction_state)`get_transaction_state(id: TransactionID) → TransactionState` external
-
+
Returns the current state of the transaction with the given `id`.
+
-#### [](#IMultisig-get_transaction_confirmations)`get_transaction_confirmations(id: TransactionID) → u32` external
-
+
Returns the number of confirmations from registered signers for the transaction with the specified `id`.
+
-#### [](#IMultisig-hash_transaction)`hash_transaction(to: ContractAddress, selector: felt252, calldata: Span, salt: felt252) → TransactionID` external
-
+
Returns the computed identifier of a transaction containing a single call.
+
-#### [](#IMultisig-hash_transaction_batch)`hash_transaction_batch(calls: Span, salt: felt252) → TransactionID` external
-
+
Returns the computed identifier of a transaction containing a batch of calls.
+
-#### [](#IMultisig-add_signers)`add_signers(new_quorum: u32, signers_to_add: Span)` external
-
+
Adds new signers and updates the quorum.
Requirements:
@@ -352,9 +554,13 @@ Requirements:
Emits a [SignerAdded](#IMultisig-SignerAdded) event for each signer added.
Emits a [QuorumUpdated](#IMultisig-QuorumUpdated) event if the quorum changes.
+
-#### [](#IMultisig-remove_signers)`remove_signers(new_quorum: u32, signers_to_remove: Span)` external
-
+
Removes signers and updates the quorum.
Requirements:
@@ -365,9 +571,13 @@ Requirements:
Emits a [SignerRemoved](#IMultisig-SignerRemoved) event for each signer removed.
Emits a [QuorumUpdated](#IMultisig-QuorumUpdated) event if the quorum changes.
+
-#### [](#IMultisig-replace_signer)`replace_signer(signer_to_remove: ContractAddress, signer_to_add: ContractAddress)` external
-
+
Replaces an existing signer with a new signer.
Requirements:
@@ -379,9 +589,13 @@ Requirements:
Emits a [SignerRemoved](#IMultisig-SignerRemoved) event for the removed signer.
Emits a [SignerAdded](#IMultisig-SignerAdded) event for the new signer.
+
-#### [](#IMultisig-change_quorum)`change_quorum(new_quorum: u32)` external
-
+
Updates the quorum value to `new_quorum` if it differs from the current quorum.
Requirements:
@@ -391,9 +605,13 @@ Requirements:
- `new_quorum` must be less than or equal to the total number of signers.
Emits a [QuorumUpdated](#IMultisig-QuorumUpdated) event if the quorum changes.
+
-#### [](#IMultisig-submit_transaction)`submit_transaction(to: ContractAddress, selector: felt252, calldata: Span, salt: felt252) → TransactionID` external
-
+
Submits a new transaction for confirmation.
Requirements:
@@ -404,8 +622,13 @@ Requirements:
Emits a [TransactionSubmitted](#IMultisig-TransactionSubmitted) event.
Emits a [CallSalt](#IMultisig-CallSalt) event if `salt` is not zero.
+
-#### [](#IMultisig-submit_transaction_batch)`submit_transaction_batch(calls: Span, salt: felt252) → TransactionID` external
+
Submits a new batch transaction for confirmation.
@@ -417,9 +640,13 @@ Requirements:
Emits a [TransactionSubmitted](#IMultisig-TransactionSubmitted) event.
Emits a [CallSalt](#IMultisig-CallSalt) event if `salt` is not zero.
+
-#### [](#IMultisig-confirm_transaction)`confirm_transaction(id: TransactionID)` external
-
+
Confirms a transaction with the given `id`.
Requirements:
@@ -429,9 +656,13 @@ Requirements:
- The caller must not have already confirmed the transaction.
Emits a [TransactionConfirmed](#IMultisig-TransactionConfirmed) event.
+
-#### [](#IMultisig-revoke_confirmation)`revoke_confirmation(id: TransactionID)` external
-
+
Revokes a previous confirmation for a transaction with the given `id`.
Requirements:
@@ -440,9 +671,13 @@ Requirements:
- The caller must have previously confirmed the transaction.
Emits a [ConfirmationRevoked](#IMultisig-ConfirmationRevoked) event.
+
-#### [](#IMultisig-execute_transaction)`execute_transaction(to: ContractAddress, selector: felt252, calldata: Span, salt: felt252)` external
-
+
Executes a confirmed transaction.
Requirements:
@@ -451,9 +686,13 @@ Requirements:
- The transaction must be confirmed and not yet executed.
Emits a [TransactionExecuted](#IMultisig-TransactionExecuted) event.
+
-#### [](#IMultisig-execute_transaction_batch)`execute_transaction_batch(calls: Span, salt: felt252)` external
-
+
Executes a confirmed batch transaction.
Requirements:
@@ -462,42 +701,80 @@ Requirements:
- The transaction must be confirmed and not yet executed.
Emits a [TransactionExecuted](#IMultisig-TransactionExecuted) event.
+
-#### [](#IMultisig-Events)Events
-
-#### [](#IMultisig-SignerAdded)`SignerAdded(signer: ContractAddress)` event
+#### Events [!toc] [#IMultisig-Events]
+
Emitted when a new `signer` is added.
+
-#### [](#IMultisig-SignerRemoved)`SignerRemoved(signer: ContractAddress)` event
-
+
Emitted when a `signer` is removed.
+
-#### [](#IMultisig-QuorumUpdated)`QuorumUpdated(old_quorum: u32, new_quorum: u32)` event
-
+
Emitted when the `quorum` value is updated.
+
-#### [](#IMultisig-TransactionSubmitted)`TransactionSubmitted(id: TransactionID, signer: ContractAddress)` event
-
+
Emitted when a new transaction is submitted by a `signer`.
+
-#### [](#IMultisig-TransactionConfirmed)`TransactionConfirmed(id: TransactionID, signer: ContractAddress)` event
-
+
Emitted when a transaction is confirmed by a `signer`.
+
-#### [](#IMultisig-ConfirmationRevoked)`ConfirmationRevoked(id: TransactionID, signer: ContractAddress)` event
-
+
Emitted when a `signer` revokes his confirmation.
+
-#### [](#IMultisig-TransactionExecuted)`TransactionExecuted(id: TransactionID)` event
-
+
Emitted when a transaction is executed.
+
-#### [](#IMultisig-CallSalt)`CallSalt(id: felt252, salt: felt252)` event
-
+
Emitted when a new transaction is submitted with non-zero salt.
+
+
+### `ITimelock` [toc] [#ITimelock]
-### [](#ITimelock)`ITimelock`[](https://github.com/OpenZeppelin/cairo-contracts/blob/release-v3.0.0-alpha.1/packages/interfaces/src/governance/timelock.cairo)
+
```rust
use openzeppelin_interfaces::timelock::ITimelock;
@@ -531,31 +808,55 @@ Events
- [`CallCancelled(id)`](#ITimelock-CallCancelled)
- [`MinDelayChanged(old_duration, new_duration)`](#ITimelock-MinDelayChanged)
-#### [](#ITimelock-Functions)Functions
-
-#### [](#ITimelock-is_operation)`is_operation(id: felt252) → bool` external
+#### Functions [!toc] [#ITimelock-Functions]
+
Returns whether `id` corresponds to a registered operation. This includes the OperationStates: `Waiting`, `Ready`, and `Done`.
+
-#### [](#ITimelock-is_operation_pending)`is_operation_pending(id: felt252) → bool` external
-
+
Returns whether the `id` OperationState is pending or not. Note that a pending operation may be either `Waiting` or `Ready`.
+
-#### [](#ITimelock-is_operation_ready)`is_operation_ready(id: felt252) → bool` external
-
+
Returns whether the `id` OperationState is `Ready` or not.
+
-#### [](#ITimelock-is_operation_done)`is_operation_done(id: felt252) → bool` external
-
+
Returns whether the `id` OperationState is `Done` or not.
+
-#### [](#ITimelock-get_timestamp)`get_timestamp(id: felt252) → u64` external
-
+
Returns the timestamp at which `id` becomes `Ready`.
`0` means the OperationState is `Unset` and `1` means the OperationState is `Done`.
+
-#### [](#ITimelock-get_operation_state)`get_operation_state(id: felt252) → OperationState` external
+
Returns the current state of the operation with the given `id`.
@@ -565,21 +866,37 @@ The possible states are:
- `Waiting`: the operation has been scheduled and is pending the scheduled delay.
- `Ready`: the timer has expired, and the operation is eligible for execution.
- `Done`: the operation has been executed.
+
-#### [](#ITimelock-get_min_delay)`get_min_delay() → u64` external
-
+
Returns the minimum delay in seconds for an operation to become valid. This value can be changed by executing an operation that calls `update_delay`.
+
-#### [](#ITimelock-hash_operation)`hash_operation(call: Call, predecessor: felt252, salt: felt252)` external
-
+
Returns the identifier of an operation containing a single transaction.
+
-#### [](#ITimelock-hash_operation_batch)`hash_operation_batch(calls: Span, predecessor: felt252, salt: felt252)` external
-
+
Returns the identifier of an operation containing a batch of transactions.
+
-#### [](#ITimelock-schedule)`schedule(call: Call, predecessor: felt252, salt: felt252, delay: u64)` external
-
+
Schedule an operation containing a single transaction.
Requirements:
@@ -587,9 +904,13 @@ Requirements:
- The caller must have the `PROPOSER_ROLE` role.
Emits [CallScheduled](#ITimelock-CallScheduled) event. Emits [CallSalt](#ITimelock-CallSalt) event if `salt` is not zero.
+
-#### [](#ITimelock-schedule_batch)`schedule_batch(calls: Span, predecessor: felt252, salt: felt252, delay: u64)` external
-
+
Schedule an operation containing a batch of transactions.
Requirements:
@@ -597,9 +918,13 @@ Requirements:
- The caller must have the `PROPOSER_ROLE` role.
Emits one [CallScheduled](#ITimelock-CallScheduled) event for each transaction in the batch. Emits [CallSalt](#ITimelock-CallSalt) event if `salt` is not zero.
+
-#### [](#ITimelock-cancel)`cancel(id: felt252)` external
-
+
Cancels an operation. A canceled operation returns to `Unset` OperationState.
Requirements:
@@ -608,9 +933,13 @@ Requirements:
- `id` must be a pending operation.
Emits a [CallCancelled](#ITimelock-CallCancelled) event.
+
-#### [](#ITimelock-execute)`execute(call: Call, predecessor: felt252, salt: felt252)` external
-
+
Execute a (Ready) operation containing a single Call.
Requirements:
@@ -621,10 +950,14 @@ Requirements:
Emits a [CallExecuted](#ITimelock-CallExecuted) event.
-This function can reenter, but it doesn’t pose a risk because [`_after_call(self: @ContractState, id: felt252)` internal](#TimelockControllerComponent-_after_call) checks that the proposal is pending, thus any modifications to the operation during reentrancy should be caught.
-
-#### [](#ITimelock-execute_batch)`execute_batch(calls: Span, predecessor: felt252, salt: felt252)` external
+This function can reenter, but it doesn't pose a risk because [`_after_call(self: @ContractState, id: felt252)` internal](#TimelockControllerComponent-_after_call) checks that the proposal is pending, thus any modifications to the operation during reentrancy should be caught.
+
+
Execute a (Ready) operation containing a batch of Calls.
Requirements:
@@ -635,10 +968,14 @@ Requirements:
Emits a [CallExecuted](#ITimelock-CallExecuted) event for each Call.
-This function can reenter, but it doesn’t pose a risk because `_after_call` checks that the proposal is pending, thus any modifications to the operation during reentrancy should be caught.
-
-#### [](#ITimelock-update_delay)`update_delay(new_delay: u64)` external
+This function can reenter, but it doesn't pose a risk because `_after_call` checks that the proposal is pending, thus any modifications to the operation during reentrancy should be caught.
+
+
Changes the minimum timelock duration for future operations.
Requirements:
@@ -646,30 +983,56 @@ Requirements:
- The caller must be the timelock itself. This can only be achieved by scheduling and later executing an operation where the timelock is the target and the data is the serialized call to this function.
Emits a [MinDelayChanged](#ITimelock-MinDelayChanged) event.
+
-#### [](#ITimelock-Events)Events
-
-#### [](#ITimelock-CallScheduled)`CallScheduled(id: felt252, index: felt252, call: Call, predecessor: felt252, delay: u64)` event
+#### Events [!toc] [#ITimelock-Events]
+
Emitted when `call` is scheduled as part of operation `id`.
+
-#### [](#ITimelock-CallExecuted)`CallExecuted(id: felt252, index: felt252, call: Call)` event
-
+
Emitted when `call` is performed as part of operation `id`.
+
-#### [](#ITimelock-CallSalt)`CallSalt(id: felt252, salt: felt252)` event
-
+
Emitted when a new proposal is scheduled with non-zero salt.
+
-#### [](#ITimelock-CallCancelled)`CallCancelled(id: felt252)` event
-
+
Emitted when operation `id` is cancelled.
+
-#### [](#ITimelock-MinDelayChanged)`MinDelayChanged(old_duration: u64, new_duration: u64)` event
-
+
Emitted when the minimum delay for future operations is modified.
+
-### [](#IVotes)`IVotes`[](https://github.com/OpenZeppelin/cairo-contracts/blob/release-v3.0.0-alpha.1/packages/interfaces/src/governance/votes.cairo)
+### `IVotes` [toc] [#IVotes]
+
+
```rust
use openzeppelin_interfaces::votes::IVotes;
@@ -688,49 +1051,81 @@ Functions
- [`clock()`](#IVotes-clock)
- [`CLOCK_MODE()`](#IVotes-CLOCK_MODE)
-#### [](#IVotes-Functions)Functions
-
-#### [](#IVotes-get_votes)`get_votes(account: ContractAddress) → u256` external
+#### Functions [!toc] [#IVotes-Functions]
+
Returns the current amount of votes that `account` has.
+
-#### [](#IVotes-get_past_votes)`get_past_votes(account: ContractAddress, timepoint: u64) → u256` external
-
+
Returns the amount of votes that `account` had at a specific moment in the past.
+
-#### [](#IVotes-get_past_total_supply)`get_past_total_supply(timepoint: u64) → u256` external
-
+
Returns the total supply of votes available at a specific moment in the past.
This value is the sum of all available votes, which is not necessarily the sum of all delegated votes. Votes that have not been delegated are still part of total supply, even though they would not participate in a vote.
+
-#### [](#IVotes-delegates)`delegates(account: ContractAddress) → ContractAddress` external
-
+
Returns the delegate that `account` has chosen.
+
-#### [](#IVotes-delegate)`delegate(delegatee: ContractAddress)` external
-
+
Delegates votes from the sender to `delegatee`.
+
-#### [](#IVotes-delegate_by_sig)`delegate_by_sig(delegator: ContractAddress, delegatee: ContractAddress, nonce: felt252, expiry: u64, signature: Span)` external
-
+
Delegates votes from `delegator` to `delegatee` through a [SNIP-12](https://github.com/starknet-io/SNIPs/blob/main/SNIPS/snip-12.md) message signature validation.
+
-#### [](#IVotes-clock)`clock() → u64` external
-
-Returns the current timepoint determined by the contract’s operational mode, intended for use in time-sensitive logic. See [ERC-6372#clock](https://eips.ethereum.org/EIPS/eip-6372#clock).
+
+Returns the current timepoint determined by the contract's operational mode, intended for use in time-sensitive logic. See [ERC-6372#clock](https://eips.ethereum.org/EIPS/eip-6372#clock).
Requirements:
- This function MUST always be non-decreasing.
+
-#### [](#IVotes-CLOCK_MODE)`CLOCK_MODE() → u64` external
-
+
Returns a description of the clock the contract is operating in. See [ERC-6372#CLOCK\_MODE](https://eips.ethereum.org/EIPS/eip-6372#clock_mode).
Requirements:
- The output MUST be formatted like a URL query string, decodable in standard JavaScript.
+
## [](#governor)Governor
@@ -738,7 +1133,12 @@ This modular system of Governor components allows the deployment of easily custo
For a walkthrough of how to implement a Governor, check the [Governor](../governance/governor) page.
-### [](#GovernorComponent)`GovernorComponent`[](https://github.com/OpenZeppelin/cairo-contracts/blob/release-v3.0.0-alpha.1/packages/governance/src/governor/governor.cairo)
+### `GovernorComponent` [toc] [#GovernorComponent]
+
+
```rust
use openzeppelin_governance::governor::GovernorComponent;
@@ -752,17 +1152,17 @@ Implementing [SRC5Component](introspection#SRC5Component) is a requirement for t
Extensions traits
-GovernorSettingsTrait
+#### GovernorSettingsTrait [!toc] [#GovernorComponent-GovernorSettingsTrait]
- [`voting_delay(self)`](#GovernorComponent-GovernorSettingsTrait-voting_delay)
- [`voting_period(self)`](#GovernorComponent-GovernorSettingsTrait-voting_period)
- [`proposal_threshold(self)`](#GovernorComponent-GovernorSettingsTrait-proposal_threshold)
-GovernorQuorumTrait
+#### GovernorQuorumTrait [!toc] [#GovernorComponent-GovernorQuorumTrait]
- [`quorum(self, timepoint)`](#GovernorComponent-GovernorQuorumTrait-quorum)
-GovernorCountingTrait
+#### GovernorCountingTrait [!toc] [#GovernorComponent-GovernorCountingTrait]
- [`counting_mode(self)`](#GovernorComponent-GovernorCountingTrait-counting_mode)
- [`count_vote(self, proposal_id, account, support, total_weight, params)`](#GovernorComponent-GovernorCountingTrait-count_vote)
@@ -770,13 +1170,13 @@ GovernorCountingTrait
- [`quorum_reached(self, proposal_id)`](#GovernorComponent-GovernorCountingTrait-quorum_reached)
- [`vote_succeeded(self, proposal_id)`](#GovernorComponent-GovernorCountingTrait-vote_succeeded)
-GovernorVotesTrait
+#### GovernorVotesTrait [!toc] [#GovernorComponent-GovernorVotesTrait]
- [`clock(self)`](#GovernorComponent-GovernorVotesTrait-clock)
- [`CLOCK_MODE(self)`](#GovernorComponent-GovernorVotesTrait-CLOCK_MODE)
- [`get_votes(self, account, timepoint, params)`](#GovernorComponent-GovernorVotesTrait-get_votes)
-GovernorExecutionTrait
+#### GovernorExecutionTrait [!toc] [#GovernorComponent-GovernorExecutionTrait]
- [`state(self, proposal_id)`](#GovernorComponent-GovernorExecutionTrait-state)
- [`executor(self)`](#GovernorComponent-GovernorExecutionTrait-executor)
@@ -787,7 +1187,7 @@ GovernorExecutionTrait
Embeddable Implementations
-GovernorImpl
+#### GovernorImpl [!toc] [#GovernorComponent-GovernorImpl]
- [`name(self)`](#GovernorComponent-name)
- [`version(self)`](#GovernorComponent-version)
@@ -820,7 +1220,7 @@ GovernorImpl
Internal Implementations
-InternalImpl
+#### InternalImpl [!toc] [#GovernorComponent-InternalImpl]
- [`initializer(self)`](#GovernorComponent-initializer)
- [`get_proposal(self, proposal_id)`](#GovernorComponent-get_proposal)
@@ -831,7 +1231,7 @@ InternalImpl
- [`_proposal_proposer(self, proposal_id)`](#GovernorComponent-_proposal_proposer)
- [`_proposal_eta(self, proposal_id)`](#GovernorComponent-_proposal_eta)
-InternalExtendedImpl
+#### InternalExtendedImpl [!toc] [#GovernorComponent-InternalExtendedImpl]
- [`assert_only_governance(self)`](#GovernorComponent-assert_only_governance)
- [`validate_state(self, proposal_id, allowed_states)`](#GovernorComponent-validate_state)
@@ -853,68 +1253,119 @@ Events
- [`VoteCast(voter, proposal_id, support, weight, reason)`](#GovernorComponent-VoteCast)
- [`VoteCastWithParams(voter, proposal_id, support, weight, reason, params)`](#GovernorComponent-VoteCastWithParams)
-#### [](#GovernorComponent-Extensions-Traits)Extensions traits functions
-
-#### [](#GovernorComponent-GovernorSettingsTrait-voting_delay)`voting_delay(self: @ContractState) → u64` extension
+#### Extensions traits functions [!toc] [#GovernorComponent-Extensions-Traits]
+
Must return the delay, in number of timepoints, between when the proposal is created and when the vote starts. This can be increased to leave time for users to buy voting power, or delegate it, before the voting of a proposal starts.
+
-#### [](#GovernorComponent-GovernorSettingsTrait-voting_period)`voting_period(self: @ContractState) → u64` extension
-
+
Must return the delay, in number of timepoints, between the vote start and vote end.
+
-#### [](#GovernorComponent-GovernorSettingsTrait-proposal_threshold)`proposal_threshold(self: @ContractState) → u256` extension
-
+
Must return the minimum number of votes that an account must have to create a proposal.
+
-#### [](#GovernorComponent-GovernorQuorumTrait-quorum)`quorum(self: @ContractState, timepoint: u64) → u256` extension
-
+
Must return the minimum number of votes required for a proposal to succeed.
+
-#### [](#GovernorComponent-GovernorCountingTrait-counting_mode)`counting_mode(self: @ContractState) → ByteArray` extension
-
+
Must return a description of the possible `support` values for `cast_vote` and the way these votes are counted, meant to be consumed by UIs to show correct vote options and interpret the results. See [COUNTING\_MODE](#GovernorComponent-COUNTING_MODE) for more details.
+
-#### [](#GovernorComponent-GovernorCountingTrait-count_vote)`count_vote(ref self: ContractState, proposal_id: felt252, account: ContractAddress, support: u8, total_weight: u256, params: Span) → u256` extension
-
+
Must register a vote for `proposal_id` by `account` with a given `support`, voting `weight` and voting `params`.
Support is generic and can represent various things depending on the voting system used.
+
-#### [](#GovernorComponent-GovernorCountingTrait-has_voted)`has_voted(self: @ContractState, proposal_id: felt252, account: ContractAddress) → bool` extension
-
+
Must return whether an account has cast a vote on a proposal.
+
-#### [](#GovernorComponent-GovernorCountingTrait-quorum_reached)`quorum_reached(self: @ContractState, proposal_id: felt252) → bool` extension
-
+
Must return whether the minimum quorum has been reached for a proposal.
+
-#### [](#GovernorComponent-GovernorCountingTrait-vote_succeeded)`vote_succeeded(self: @ContractState, proposal_id: felt252) → bool` extension
-
+
Must return whether a proposal has succeeded or not.
+
-#### [](#GovernorComponent-GovernorVotesTrait-clock)`clock(self: @ContractState) → u64` extension
-
-Returns the current timepoint determined by the governor’s operational mode, intended for use in time-sensitive logic. See [ERC-6372#clock](https://eips.ethereum.org/EIPS/eip-6372#clock).
+
+Returns the current timepoint determined by the governor's operational mode, intended for use in time-sensitive logic. See [ERC-6372#clock](https://eips.ethereum.org/EIPS/eip-6372#clock).
Requirements:
- This function MUST always be non-decreasing.
+
-#### [](#GovernorComponent-GovernorVotesTrait-CLOCK_MODE)`CLOCK_MODE(self: @ContractState) → ByteArray` extension
-
+
Returns a description of the clock the governor is operating in. See [ERC-6372#CLOCK\_MODE](https://eips.ethereum.org/EIPS/eip-6372#clock_mode).
Requirements:
- The output MUST be formatted like a URL query string, decodable in standard JavaScript.
+
-#### [](#GovernorComponent-GovernorVotesTrait-get_votes)`get_votes(self: @ContractState, account: ContractAddress, timepoint: u64, params: Span) → u256` extension
-
+
Must return the voting power of an account at a specific timepoint with the given parameters.
+
-#### [](#GovernorComponent-GovernorExecutionTrait-state)`state(self: @ContractState, proposal_id: felt252) → ProposalState` extension
-
+
Must return the state of a proposal at the current time.
The state can be either:
@@ -926,47 +1377,80 @@ The state can be either:
- `Succeeded`: The proposal has succeeded.
- `Queued`: The proposal has been queued.
- `Executed`: The proposal has been executed.
+
-#### [](#GovernorComponent-GovernorExecutionTrait-executor)`executor(self: @ContractState) → ContractAddress` internal
-
+
Must return the address through which the governor executes action. Should be used to specify whether the module execute actions through another contract such as a timelock.
MUST be the governor itself, or an instance of TimelockController with the governor as the only proposer, canceller, and executor.
When the executor is not the governor itself (i.e. a timelock), it can call functions that are restricted with the `assert_only_governance` guard, and also potentially execute transactions on behalf of the governor. Because of this, this module is designed to work with the TimelockController as the unique potential external executor.
+
-#### [](#GovernorComponent-GovernorExecutionTrait-execute_operations)`execute_operations(ref self: ContractState, proposal_id: felt252, calls: Span)` internal
+
Execution mechanism. Can be used to modify the way operations are executed (for example adding a vault/timelock).
+
-#### [](#GovernorComponent-GovernorExecutionTrait-queue_operations)`queue_operations(ref self: ContractState, proposal_id: felt252, calls: Span)` internal
-
+
Queuing mechanism. Can be used to modify the way queuing is performed (for example adding a vault/timelock).
Requirements:
- Must return a timestamp that describes the expected ETA for execution. If the returned value is 0, the core will consider queueing did not succeed, and the public `queue` function will revert.
+
-#### [](#GovernorComponent-GovernorExecutionTrait-proposal_needs_queuing)`proposal_needs_queuing(self: @ContractState) → bool` internal
-
+
Must return whether proposals need to be queued before execution. This usually indicates if the proposal needs to go through a timelock.
+
-#### [](#GovernorComponent-GovernorExecutionTrait-cancel_operations)`cancel_operations(ref self: ContractState, proposal_id: felt252, calls: Span)` internal
-
+
Cancel mechanism. Can be used to modify the way canceling is performed (for example adding a vault/timelock).
+
-#### [](#GovernorComponent-Embeddable-Functions)Embeddable functions
-
-#### [](#GovernorComponent-name)`name() → felt252` external
+#### Embeddable functions [!toc] [#GovernorComponent-Embeddable-Functions]
+
Name of the governor instance (used in building the [SNIP-12](https://github.com/starknet-io/SNIPs/blob/main/SNIPS/snip-12.md) domain separator).
+
-#### [](#GovernorComponent-version)`version() → felt252` external
-
+
Version of the governor instance (used in building [SNIP-12](https://github.com/starknet-io/SNIPs/blob/main/SNIPS/snip-12.md) domain separator).
+
-#### [](#GovernorComponent-COUNTING_MODE)`COUNTING_MODE() → ByteArray` external
-
+
A description of the possible `support` values for `cast_vote` and the way these votes are counted, meant to be consumed by UIs to show correct vote options and interpret the results. The string is a URL-encoded sequence of key-value pairs that each describe one aspect, for example `support=bravo&quorum=for,abstain`.
There are 2 standard keys: `support` and `quorum`.
@@ -981,80 +1465,142 @@ If a counting module makes use of encoded `params`, it should include this under
- `params=erc721` might refer to a scheme where specific NFTs are delegated to vote.
The string can be decoded by the standard [`URLSearchParams`](https://developer.mozilla.org/en-US/docs/Web/API/URLSearchParams) JavaScript class.
+
-#### [](#GovernorComponent-hash_proposal)`hash_proposal(calls: Span, description_hash: felt252) → felt252` external
+
Hashing function used to (re)build the proposal id from the proposal details.
+
-#### [](#GovernorComponent-state)`state(proposal_id: felt252) → ProposalState` external
-
+
Returns the state of a proposal, given its id.
+
-#### [](#GovernorComponent-proposal_threshold)`proposal_threshold() → u256` external
-
+
The number of votes required in order for a voter to become a proposer.
-
-#### [](#GovernorComponent-proposal_snapshot)`proposal_snapshot(proposal_id: felt252) → u64` external
-
-Timepoint used to retrieve user’s votes and quorum. If using block number, the snapshot is performed at the end of this block. Hence, voting for this proposal starts at the beginning of the following block.
-
-#### [](#GovernorComponent-proposal_deadline)`proposal_deadline(proposal_id: felt252) → u64` external
-
+
+
+
+Timepoint used to retrieve user's votes and quorum. If using block number, the snapshot is performed at the end of this block. Hence, voting for this proposal starts at the beginning of the following block.
+
+
+
Timepoint at which votes close. If using block number, votes close at the end of this block, so it is possible to cast a vote during this block.
+
-#### [](#GovernorComponent-proposal_proposer)`proposal_proposer(proposal_id: felt252) → ContractAddress` external
-
+
The account that created a proposal.
-
-#### [](#GovernorComponent-proposal_eta)`proposal_eta(proposal_id: felt252) → u64` external
-
-The time when a queued proposal becomes executable ("ETA"). Unlike `proposal_snapshot` and `proposal_deadline`, this doesn’t use the governor clock, and instead relies on the executor’s clock which may be different. In most cases this will be a timestamp.
-
-#### [](#GovernorComponent-proposal_needs_queuing)`proposal_needs_queuing(proposal_id: felt252) → bool` external
-
+
+
+
+The time when a queued proposal becomes executable ("ETA"). Unlike `proposal_snapshot` and `proposal_deadline`, this doesn't use the governor clock, and instead relies on the executor's clock which may be different. In most cases this will be a timestamp.
+
+
+
Whether a proposal needs to be queued before execution. This indicates if the proposal needs to go through a timelock.
+
-#### [](#GovernorComponent-voting_delay)`voting_delay() → u64` external
-
+
Delay between when a proposal is created and when the vote starts. The unit this duration is expressed in depends on the clock (see [ERC-6372](https://eips.ethereum.org/EIPS/eip-6372)) this contract uses.
This can be increased to leave time for users to buy voting power, or delegate it, before the voting of a proposal starts.
+
-#### [](#GovernorComponent-voting_period)`voting_period() → u64` external
-
+
Delay between the vote start and vote end. The unit this duration is expressed in depends on the clock (see [ERC-6372](https://eips.ethereum.org/EIPS/eip-6372)) this contract uses.
The `voting_delay` can delay the start of the vote. This must be considered when setting the voting duration compared to the voting delay.
This value is stored when the proposal is submitted so that possible changes to the value do not affect proposals that have already been submitted.
+
-#### [](#GovernorComponent-quorum)`quorum(timepoint: u64) → u256` external
+
Minimum number of votes required for a proposal to be successful.
The `timepoint` parameter corresponds to the snapshot used for counting vote. This allows the quorum to scale depending on values such as the total supply of a token at this timepoint.
+
-#### [](#GovernorComponent-get_votes)`get_votes(account: ContractAddress, timepoint: u64) → u256` external
-
+
Returns the voting power of an `account` at a specific `timepoint`.
This can be implemented in a number of ways, for example by reading the delegated balance from one (or multiple) `ERC20Votes` tokens.
+
-#### [](#GovernorComponent-get_votes_with_params)`get_votes_with_params(account: ContractAddress, timepoint: u64, params: Span) → u256` external
-
+
Returns the voting power of an account at a specific timepoint, given additional encoded parameters.
+
-#### [](#GovernorComponent-has_voted)`has_voted(proposal_id: felt252, account: ContractAddress) → bool` external
-
+
Returns whether an account has cast a vote on a proposal.
+
-#### [](#GovernorComponent-propose)`propose(calls: Span, description: ByteArray) → felt252` external
-
+
Creates a new proposal. Voting starts after the delay specified by `voting_delay` and lasts for a duration specified by `voting_period`. Returns the id of the proposal.
This function has opt-in frontrunning protection, described in `is_valid_description_for_proposer`.
-The state of the Governor and targets may change between the proposal creation and its execution. This may be the result of third party actions on the targeted contracts, or other governor proposals. For example, the balance of this contract could be updated or its access control permissions may be modified, possibly compromising the proposal’s ability to execute successfully (e.g. the governor doesn’t have enough value to cover a proposal with multiple transfers).
+The state of the Governor and targets may change between the proposal creation and its execution. This may be the result of third party actions on the targeted contracts, or other governor proposals. For example, the balance of this contract could be updated or its access control permissions may be modified, possibly compromising the proposal's ability to execute successfully (e.g. the governor doesn't have enough value to cover a proposal with multiple transfers).
Requirements:
@@ -1063,9 +1609,13 @@ Requirements:
- The proposal must not already exist.
Emits a [ProposalCreated](#GovernorComponent-ProposalCreated) event.
+
-#### [](#GovernorComponent-queue)`queue(calls: Span, description_hash: felt252) → felt252` external
-
+
Queues a proposal. Some governors require this step to be performed before execution can happen. If queuing is not necessary, this function may revert. Queuing a proposal requires the quorum to be reached, the vote to be successful, and the deadline to be reached.
Returns the id of the proposal.
@@ -1076,8 +1626,13 @@ Requirements:
- The queue operation must return a non-zero ETA.
Emits a [ProposalQueued](#GovernorComponent-ProposalQueued) event.
+
-#### [](#GovernorComponent-execute)`execute(calls: span, description_hash: felt252) → felt252` external
+
Executes a successful proposal. This requires the quorum to be reached, the vote to be successful, and the deadline to be reached. Depending on the governor it might also be required that the proposal was queued and that some delay passed.
@@ -1090,9 +1645,13 @@ Requirements:
- The proposal must be in the `Succeeded` or `Queued` state.
Emits a [ProposalExecuted](#GovernorComponent-ProposalExecuted) event.
+
-#### [](#GovernorComponent-cancel)`cancel(calls: Span, description_hash: felt252) → felt252` external
-
+
Cancels a proposal. A proposal is cancellable by the proposer, but only while it is Pending state, i.e. before the vote starts.
Returns the id of the proposal.
@@ -1103,9 +1662,13 @@ Requirements:
- The caller must be the proposer of the proposal.
Emits a [ProposalCanceled](#GovernorComponent-ProposalCanceled) event.
+
-#### [](#GovernorComponent-cast_vote)`cast_vote(proposal_id: felt252, support: u8) → u256` external
-
+
Cast a vote.
Requirements:
@@ -1113,9 +1676,13 @@ Requirements:
- The proposal must be active.
Emits a [VoteCast](#GovernorComponent-VoteCast) event.
+
-#### [](#GovernorComponent-cast_vote_with_reason)`cast_vote_with_reason(proposal_id: felt252, support: u8, reason: ByteArray) → u256` external
-
+
Cast a vote with a `reason`.
Requirements:
@@ -1123,9 +1690,13 @@ Requirements:
- The proposal must be active.
Emits a [VoteCast](#GovernorComponent-VoteCast) event.
+
-#### [](#GovernorComponent-cast_vote_with_reason_and_params)`cast_vote_with_reason_and_params(proposal_id: felt252, support: u8, reason: ByteArray, params: Span) → u256` external
-
+
Cast a vote with a `reason` and additional serialized `params`.
Requirements:
@@ -1136,28 +1707,36 @@ Emits either:
- [VoteCast](#GovernorComponent-VoteCast) event if no params are provided.
- [VoteCastWithParams](#GovernorComponent-VoteCastWithParams) event otherwise.
+
-#### [](#GovernorComponent-cast_vote_by_sig)`cast_vote_by_sig(proposal_id: felt252, support: u8, voter: ContractAddress, signature: Span) → u256` external
-
+
Cast a vote using the `voter`'s signature.
Requirements:
- The proposal must be active.
-- The nonce in the signed message must match the account’s current nonce.
+- The nonce in the signed message must match the account's current nonce.
- `voter` must implement `SRC6::is_valid_signature`.
- `signature` must be valid for the message hash.
Emits a [VoteCast](#GovernorComponent-VoteCast) event.
+
-#### [](#GovernorComponent-cast_vote_with_reason_and_params_by_sig)`cast_vote_with_reason_and_params_by_sig(proposal_id: felt252, support: u8, voter: ContractAddress, reason: ByteArray, params: Span, signature: Span) → u256` external
-
+
Cast a vote with a `reason` and additional serialized `params` using the `voter`'s signature.
Requirements:
- The proposal must be active.
-- The nonce in the signed message must match the account’s current nonce.
+- The nonce in the signed message must match the account's current nonce.
- `voter` must implement `SRC6::is_valid_signature`.
- `signature` must be valid for the message hash.
@@ -1165,31 +1744,51 @@ Emits either:
- [VoteCast](#GovernorComponent-VoteCast) event if no params are provided.
- [VoteCastWithParams](#GovernorComponent-VoteCastWithParams) event otherwise.
+
-#### [](#GovernorComponent-nonces)`nonces(voter: ContractAddress) → felt252` external
-
+
Returns the next unused nonce for an address.
+
-#### [](#GovernorComponent-relay)`relay(call: Call)` external
-
+
Relays a transaction or function call to an arbitrary target.
In cases where the governance executor is some contract other than the governor itself, like when using a timelock, this function can be invoked in a governance proposal to recover tokens that were sent to the governor contract by mistake.
If the executor is simply the governor itself, use of `relay` is redundant.
+
-#### [](#GovernorComponent-Internal-Functions)Internal functions
-
-#### [](#GovernorComponent-initializer)`initializer(ref self: ContractState)` internal
+#### Internal functions [!toc] [#GovernorComponent-Internal-Functions]
+
Initializes the contract by registering the supported interface id.
+
-#### [](#GovernorComponent-get_proposal)`get_proposal(self: @ContractState, proposal_id: felt252) → ProposalCore` internal
-
+
Returns the proposal object given its id.
+
-#### [](#GovernorComponent-is_valid_description_for_proposer)`is_valid_description_for_proposer(self: @ContractState, proposer: ContractAddress, description: ByteArray) → bool` internal
-
+
Checks if the proposer is authorized to submit a proposal with the given description.
If the proposal description ends with `#proposer=0x???`, where `0x???` is an address written as a hex string (case insensitive), then the submission of this proposal will only be authorized to said address.
@@ -1205,64 +1804,112 @@ If the description does not match this pattern, it is unrestricted and anyone ca
- If it ends with the expected suffix followed by newlines or other whitespace.
- If it ends with some other similar suffix, e.g. `#other=abc`.
- If it does not end with any such suffix.
+
-#### [](#GovernorComponent-_hash_proposal)`_hash_proposal(self: @ContractState, calls: Span, description_hash: felt252) → felt252` internal
-
+
Returns the proposal id computed from the given parameters.
The proposal id is computed as a Pedersen hash of:
- The array of calls being proposed
- The description hash
-
-#### [](#GovernorComponent-_proposal_snapshot)`_proposal_snapshot(self: @ContractState, proposal_id: felt252) → u64` internal
-
-Timepoint used to retrieve user’s votes and quorum. If using block number, the snapshot is performed at the end of this block. Hence, voting for this proposal starts at the beginning of the following block.
-
-#### [](#GovernorComponent-_proposal_deadline)`_proposal_deadline(self: @ContractState, proposal_id: felt252) → u64` internal
-
+
+
+
+Timepoint used to retrieve user's votes and quorum. If using block number, the snapshot is performed at the end of this block. Hence, voting for this proposal starts at the beginning of the following block.
+
+
+
Timepoint at which votes close. If using block number, votes close at the end of this block, so it is possible to cast a vote during this block.
+
-#### [](#GovernorComponent-_proposal_proposer)`_proposal_proposer(self: @ContractState, proposal_id: felt252) → ContractAddress` internal
-
+
The account that created a proposal.
-
-#### [](#GovernorComponent-_proposal_eta)`_proposal_eta(self: @ContractState, proposal_id: felt252) → u64` internal
-
-The time when a queued proposal becomes executable ("ETA"). Unlike `proposal_snapshot` and `proposal_deadline`, this doesn’t use the governor clock, and instead relies on the executor’s clock which may be different. In most cases this will be a timestamp.
-
-#### [](#GovernorComponent-assert_only_governance)`assert_only_governance(self: @ContractState)` internal
-
+
+
+
+The time when a queued proposal becomes executable ("ETA"). Unlike `proposal_snapshot` and `proposal_deadline`, this doesn't use the governor clock, and instead relies on the executor's clock which may be different. In most cases this will be a timestamp.
+
+
+
Asserts that the caller is the governance executor.
When the executor is not the governor itself (i.e. a timelock), it can call functions that are restricted with this modifier, and also potentially execute transactions on behalf of the governor. Because of this, this module is designed to work with the TimelockController as the unique potential external executor. The timelock MUST have the governor as the only proposer, canceller, and executor.
+
-#### [](#GovernorComponent-validate_state)`validate_state(self: @ContractState, proposal_id: felt252, state: ProposalState)` internal
-
+
Validates that a proposal is in the expected state. Otherwise it panics.
+
-#### [](#GovernorComponent-use_nonce)`use_nonce(ref self: ContractState) → felt252` internal
-
+
Consumes a nonce, returns the current value, and increments nonce.
+
-#### [](#GovernorComponent-_get_votes)`_get_votes(self: @ContractState, account: ContractAddress, timepoint: u64, params: Span) → u256` internal
-
+
Internal wrapper for `GovernorVotesTrait::get_votes`.
+
-#### [](#GovernorComponent-_proposal_threshold)`_proposal_threshold(self: @ContractState) → u256` internal
-
+
Internal wrapper for `GovernorProposeTrait::proposal_threshold`.
+
-#### [](#GovernorComponent-_state)`_state(self: @ContractState, proposal_id: felt252) → ProposalState` internal
-
+
Returns the state of a proposal, given its id.
Requirements:
- The proposal must exist.
+
-#### [](#GovernorComponent-_propose)`_propose(ref self: ContractState, calls: Span, description_hash: felt252) → felt252` internal
-
+
Internal propose mechanism. Returns the proposal id.
Requirements:
@@ -1270,21 +1917,33 @@ Requirements:
- The proposal must not already exist.
Emits a [ProposalCreated](#GovernorComponent-ProposalCreated) event.
+
-#### [](#GovernorComponent-_cancel)`_cancel(ref self: ContractState, proposal_id: felt252)` internal
-
+
Internal cancel mechanism with minimal restrictions.
A proposal can be cancelled in any state other than Canceled or Executed.
-Once cancelled, a proposal can’t be re-submitted.
-
-#### [](#GovernorComponent-_count_vote)`_count_vote(ref self: ContractState, proposal_id: felt252, account: ContractAddress, support: u8, weight: u256, params: Span)` internal
+Once cancelled, a proposal can't be re-submitted.
+
+
Internal wrapper for `GovernorCountingTrait::count_vote`.
+
-#### [](#GovernorComponent-_cast_vote)`_cast_vote(ref self: ContractState, proposal_id: felt252, account: ContractAddress, support: u8, reason: ByteArray, params: Span) → u256` internal
-
+
Internal vote-casting mechanism.
Checks that the vote is pending and that it has not been cast yet. This function retrieves the voting weight using `get_votes` and then calls the `_count_vote` internal function.
@@ -1293,38 +1952,68 @@ Emits either:
- [VoteCast](#GovernorComponent-VoteCast) event if no params are provided.
- [VoteCastWithParams](#GovernorComponent-VoteCastWithParams) event otherwise.
+
-#### [](#GovernorComponent-Events)Events
-
-#### [](#GovernorComponent-ProposalCreated)`ProposalCreated(proposal_id: felt252, proposer: ContractAddress, calls: Span, signatures: Span>, vote_start: u64, vote_end: u64, description: ByteArray)` event
+#### Events [!toc] [#GovernorComponent-Events]
+
Emitted when a proposal is created.
+
-#### [](#GovernorComponent-ProposalQueued)`ProposalQueued(proposal_id: felt252, eta_seconds: u64)` event
-
+
Emitted when a proposal is queued.
+
-#### [](#GovernorComponent-ProposalExecuted)`ProposalExecuted(proposal_id: felt252)` event
-
+
Emitted when a proposal is executed.
+
-#### [](#GovernorComponent-ProposalCanceled)`ProposalCanceled(proposal_id: felt252)` event
-
+
Emitted when a proposal is canceled.
+
-#### [](#GovernorComponent-VoteCast)`VoteCast(voter: ContractAddress, proposal_id: felt252, support: u8, weight: u256, reason: ByteArray)` event
-
+
Emitted when a vote is cast.
+
-#### [](#GovernorComponent-VoteCastWithParams)`VoteCastWithParams(voter: ContractAddress, proposal_id: felt252, support: u8, weight: u256, reason: ByteArray, params: Span)` event
-
+
Emitted when a vote is cast with params.
+
## [](#governor_extensions)Governor extensions
The Governor component can (and must) be extended by implementing the [extensions traits](#GovernorComponent-Extensions-Traits-Traits) to add the desired functionality. This can be achieved by directly implementing the traits on your contract, or by using a set of ready-to-use extensions provided by the library, which are presented below.
-### [](#GovernorCoreExecutionComponent)`GovernorCoreExecutionComponent`[](https://github.com/OpenZeppelin/cairo-contracts/blob/release-v3.0.0-alpha.1/packages/governance/src/governor/extensions/governor_core_execution.cairo)
+### `GovernorCoreExecutionComponent` [toc] [#GovernorCoreExecutionComponent]
+
+
```rust
use openzeppelin_governance::governor::extensions::GovernorCoreExecutionComponent;
@@ -1334,7 +2023,7 @@ Extension of [GovernorComponent](#GovernorComponent) providing an execution mech
Extension traits implementations
-GovernorExecution
+#### GovernorExecution [!toc] [#GovernorCoreExecutionComponent-GovernorExecution]
- [`state(self, proposal_id)`](#GovernorCoreExecutionComponent-state)
- [`executor(self)`](#GovernorCoreExecutionComponent-executor)
@@ -1343,39 +2032,68 @@ GovernorExecution
- [`proposal_needs_queuing(self, proposal_id)`](#GovernorCoreExecutionComponent-proposal_needs_queuing)
- [`cancel_operations(self, proposal_id, description_hash)`](#GovernorCoreExecutionComponent-cancel_operations)
-#### [](#GovernorCoreExecutionComponent-Extension-Traits-Functions)Extension traits functions
-
-#### [](#GovernorCoreExecutionComponent-state)`state(self: @ContractState, proposal_id: felt252) → ProposalState` internal
+#### Extension traits functions [!toc] [#GovernorCoreExecutionComponent-Extension-Traits-Functions]
+
Returns the state of a proposal given its id.
Requirements:
- The proposal must exist.
+
-#### [](#GovernorCoreExecutionComponent-executor)`executor(self: @ContractState) → ContractAddress` internal
-
+
Returns the executor address.
In this case, it returns the governor contract address since execution is performed directly through it.
-
-#### [](#GovernorCoreExecutionComponent-execute_operations)`execute_operations(ref self: ContractState, proposal_id: felt252, calls: Span, description_hash: felt252)` internal
-
-Executes the proposal’s operations directly through the governor contract.
-
-#### [](#GovernorCoreExecutionComponent-queue_operations)`queue_operations(ref self: ContractState, proposal_id: felt252, calls: Span, description_hash: felt252) → u64` internal
-
+
+
+
+Executes the proposal's operations directly through the governor contract.
+
+
+
In this implementation, queuing is not required so it returns 0.
+
-#### [](#GovernorCoreExecutionComponent-proposal_needs_queuing)`proposal_needs_queuing(self: @ContractState, proposal_id: felt252) → bool` internal
-
+
In this implementation, it always returns false.
+
-#### [](#GovernorCoreExecutionComponent-cancel_operations)`cancel_operations(ref self: ContractState, proposal_id: felt252, description_hash: felt252)` internal
+
+Cancels a proposal's operations.
+
-Cancels a proposal’s operations.
+### `GovernorCountingSimpleComponent` [toc] [#GovernorCountingSimpleComponent]
-### [](#GovernorCountingSimpleComponent)`GovernorCountingSimpleComponent`[](https://github.com/OpenZeppelin/cairo-contracts/blob/release-v3.0.0-alpha.1/packages/governance/src/governor/extensions/governor_counting_simple.cairo)
+
```rust
use openzeppelin_governance::governor::extensions::GovernorCountingSimpleComponent;
@@ -1385,7 +2103,7 @@ Extension of [GovernorComponent](#GovernorComponent) for simple vote counting wi
Extension traits implementations
-GovernorCounting
+#### GovernorCounting [!toc] [#GovernorCountingSimpleComponent-GovernorCounting]
- [`counting_mode(self)`](#GovernorCountingSimpleComponent-counting_mode)
- [`count_vote(self, proposal_id, account, support, total_weight, params)`](#GovernorCountingSimpleComponent-count_vote)
@@ -1393,40 +2111,66 @@ GovernorCounting
- [`quorum_reached(self, proposal_id)`](#GovernorCountingSimpleComponent-quorum_reached)
- [`vote_succeeded(self, proposal_id)`](#GovernorCountingSimpleComponent-vote_succeeded)
-#### [](#GovernorCountingSimpleComponent-Extension-Traits-Functions)Extension traits functions
-
-#### [](#GovernorCountingSimpleComponent-counting_mode)`counting_mode(self: @ContractState) → ByteArray` internal
+#### Extension traits functions [!toc] [#GovernorCountingSimpleComponent-Extension-Traits-Functions]
+
Returns `"support=bravo&quorum=for,abstain"`.
- `support=bravo` indicates that the support follows the Governor Bravo format where voters can vote For, Against, or Abstain
- `quorum=for,abstain` indicates that both For and Abstain votes count toward quorum
+
-#### [](#GovernorCountingSimpleComponent-count_vote)`count_vote(ref self: ContractState, proposal_id: felt252, account: ContractAddress, support: u8, total_weight: u256, params: Span) → u256` internal
-
+
Records a vote for a proposal.
The support value follows the `VoteType` enum (0=Against, 1=For, 2=Abstain).
Returns the weight that was counted.
+
-#### [](#GovernorCountingSimpleComponent-has_voted)`has_voted(self: @ContractState, proposal_id: felt252, account: ContractAddress) → bool` internal
-
+
Returns whether an account has cast a vote on a proposal.
+
-#### [](#GovernorCountingSimpleComponent-quorum_reached)`quorum_reached(self: @ContractState, proposal_id: felt252) → bool` internal
+
Returns whether a proposal has reached quorum.
In this implementation, both For and Abstain votes count toward quorum.
+
-#### [](#GovernorCountingSimpleComponent-vote_succeeded)`vote_succeeded(self: @ContractState, proposal_id: felt252) → bool` internal
-
+
Returns whether a proposal has succeeded.
In this implementation, the For votes must be strictly greater than Against votes.
+
+
+### `GovernorSettingsComponent` [toc] [#GovernorSettingsComponent]
-### [](#GovernorSettingsComponent)`GovernorSettingsComponent`[](https://github.com/OpenZeppelin/cairo-contracts/blob/release-v3.0.0-alpha.1/packages/governance/src/governor/extensions/governor_settings.cairo)
+
```rust
use openzeppelin_governance::governor::extensions::GovernorSettingsComponent;
@@ -1436,7 +2180,7 @@ Extension of [GovernorComponent](#GovernorComponent) for settings that are updat
Extension traits implementations
-GovernorSettings
+#### GovernorSettings [!toc] [#GovernorSettingsComponent-GovernorSettings]
- [`voting_delay(self)`](#GovernorSettingsComponent-voting_delay)
- [`voting_period(self)`](#GovernorSettingsComponent-voting_period)
@@ -1444,7 +2188,7 @@ GovernorSettings
Embeddable implementations
-GovernorSettingsAdminImpl
+#### GovernorSettingsAdminImpl [!toc] [#GovernorSettingsComponent-GovernorSettingsAdminImpl]
- [`set_voting_delay(self, new_voting_delay)`](#GovernorSettingsComponent-set_voting_delay)
- [`set_voting_period(self, new_voting_period)`](#GovernorSettingsComponent-set_voting_period)
@@ -1452,7 +2196,7 @@ GovernorSettingsAdminImpl
Internal implementations
-InternalImpl
+#### InternalImpl [!toc] [#GovernorSettingsComponent-InternalImpl]
- [`initializer(self, new_voting_delay, new_voting_period, new_proposal_threshold)`](#GovernorSettingsComponent-initializer)
- [`assert_only_governance(self)`](#GovernorSettingsComponent-assert_only_governance)
@@ -1466,24 +2210,39 @@ Events
- [`VotingPeriodUpdated(old_voting_period, new_voting_period)`](#GovernorSettingsComponent-VotingPeriodUpdated)
- [`ProposalThresholdUpdated(old_proposal_threshold, new_proposal_threshold)`](#GovernorSettingsComponent-ProposalThresholdUpdated)
-#### [](#GovernorSettings-Extension-Traits-Functions)Extension traits functions
-
-#### [](#GovernorSettingsComponent-voting_delay)`voting_delay(self: @ContractState) → u64` internal
+#### Extension traits functions [!toc] [#GovernorSettingsComponent-ExtensionTraitsFunctions]
+
Returns the delay, between when a proposal is created and when voting starts.
+
-#### [](#GovernorSettingsComponent-voting_period)`voting_period(self: @ContractState) → u64` internal
-
+
Returns the time period, during which votes can be cast.
+
-#### [](#GovernorSettingsComponent-proposal_threshold)`proposal_threshold(self: @ContractState) → u256` internal
-
+
Returns the minimum number of votes required for an account to create a proposal.
+
-#### [](#GovernorSettings-Embeddable-Functions)Embeddable functions
-
-#### [](#GovernorSettingsComponent-set_voting_delay)`set_voting_delay(ref self: ContractState, new_voting_delay: u64)` external
+#### Embeddable functions [!toc] [#GovernorSettingsComponent-EmbeddableFunctions]
+
Sets the voting delay.
Requirements:
@@ -1493,9 +2252,13 @@ Requirements:
This function does not emit an event if the new voting delay is the same as the old one.
May emit a [VotingDelayUpdated](#GovernorSettingsComponent-VotingDelayUpdated) event.
+
-#### [](#GovernorSettingsComponent-set_voting_period)`set_voting_period(ref self: ContractState, new_voting_period: u64)` external
-
+
Sets the voting period.
This function does not emit an event if the new voting period is the same as the old one.
@@ -1506,9 +2269,13 @@ Requirements:
- `new_voting_period` must be greater than 0.
May emit a [VotingPeriodUpdated](#GovernorSettingsComponent-VotingPeriodUpdated) event.
+
-#### [](#GovernorSettingsComponent-set_proposal_threshold)`set_proposal_threshold(ref self: ContractState, new_proposal_threshold: u256)` external
-
+
Sets the proposal threshold.
This function does not emit an event if the new proposal threshold is the same as the old one.
@@ -1518,11 +2285,15 @@ Requirements:
- Caller must be the governance executor.
May emit a [ProposalThresholdUpdated](#GovernorSettingsComponent-ProposalThresholdUpdated) event.
+
-#### [](#GovernorSettingsComponent-Internal-Functions)Internal functions
-
-#### [](#GovernorSettingsComponent-initializer)`initializer(ref self: ContractState, initial_voting_delay: u64, initial_voting_period: u64, initial_proposal_threshold: u256)` internal
+#### Internal functions [!toc] [#GovernorSettingsComponent-InternalFunctions]
+
Initializes the component by setting the default values.
Requirements:
@@ -1530,21 +2301,33 @@ Requirements:
- `new_voting_period` must be greater than 0.
Emits a [VotingDelayUpdated](#GovernorSettingsComponent-VotingDelayUpdated), [VotingPeriodUpdated](#GovernorSettingsComponent-VotingPeriodUpdated), and [ProposalThresholdUpdated](#GovernorSettingsComponent-ProposalThresholdUpdated) event.
+
-#### [](#GovernorSettingsComponent-assert_only_governance)`assert_only_governance(ref self: ContractState)` internal
-
+
Asserts that the caller is the governance executor.
+
-#### [](#GovernorSettingsComponent-_set_voting_delay)`_set_voting_delay(ref self: ContractState, new_voting_delay: u64)` internal
-
+
Internal function to update the voting delay.
This function does not emit an event if the new voting delay is the same as the old one.
May emit a [VotingDelayUpdated](#GovernorSettingsComponent-VotingDelayUpdated) event.
+
-#### [](#GovernorSettingsComponent-_set_voting_period)`_set_voting_period(ref self: ContractState, new_voting_period: u64)` internal
-
+
Internal function to update the voting period.
Requirements:
@@ -1554,30 +2337,52 @@ Requirements:
This function does not emit an event if the new voting period is the same as the old one.
May emit a [VotingPeriodUpdated](#GovernorSettingsComponent-VotingPeriodUpdated) event.
+
-#### [](#GovernorSettingsComponent-_set_proposal_threshold)`_set_proposal_threshold(ref self: ContractState, new_proposal_threshold: u256)` internal
-
+
Internal function to update the proposal threshold.
This function does not emit an event if the new proposal threshold is the same as the old one.
May emit a [ProposalThresholdUpdated](#GovernorSettingsComponent-ProposalThresholdUpdated) event.
+
-#### [](#GovernorSettings-Events)Events
-
-#### [](#GovernorSettingsComponent-VotingDelayUpdated)`VotingDelayUpdated(old_voting_delay: u64, new_voting_delay: u64)` event
+#### Events [!toc] [#GovernorSettingsComponent-Events]
+
Emitted when the voting delay is updated.
+
-#### [](#GovernorSettingsComponent-VotingPeriodUpdated)`VotingPeriodUpdated(old_voting_period: u64, new_voting_period: u64)` event
-
+
Emitted when the voting period is updated.
+
-#### [](#GovernorSettingsComponent-ProposalThresholdUpdated)`ProposalThresholdUpdated(old_proposal_threshold: u256, new_proposal_threshold: u256)` event
-
+
Emitted when the proposal threshold is updated.
+
+
+### `GovernorVotesComponent` [toc] [#GovernorVotesComponent]
-### [](#GovernorVotesComponent)`GovernorVotesComponent`[](https://github.com/OpenZeppelin/cairo-contracts/blob/release-v3.0.0-alpha.1/packages/governance/src/governor/extensions/governor_votes.cairo)
+
```rust
use openzeppelin_governance::governor::extensions::GovernorVotesComponent;
@@ -1587,7 +2392,7 @@ Extension of [GovernorComponent](#GovernorComponent) for voting weight extractio
Extension traits implementations
-GovernorVotes
+#### GovernorVotes [!toc] [#GovernorVotesComponent-GovernorVotes]
- [`clock(self)`](#GovernorVotesComponent-clock)
- [`CLOCK_MODE(self)`](#GovernorVotesComponent-CLOCK_MODE)
@@ -1595,55 +2400,80 @@ GovernorVotes
Embeddable implementations
-VotesTokenImpl
+#### VotesTokenImpl [!toc] [#GovernorVotesComponent-VotesTokenImpl]
- [`token(self)`](#GovernorVotesComponent-token)
Internal implementations
-InternalImpl
+#### InternalImpl [!toc] [#GovernorVotesComponent-InternalImpl]
- [`initializer(self, votes_token)`](#GovernorVotesComponent-initializer)
-#### [](#GovernorVotes-Extension-Traits-Functions)Extension traits functions
+#### Extension traits functions [!toc] [#GovernorVotesComponent-ExtensionTraitsFunctions]
-#### [](#GovernorVotesComponent-clock)`clock(self: @ContractState) → u64` internal
-
-Returns the current timepoint determined by the governor’s operational mode, intended for use in time-sensitive logic. See [ERC-6372#clock](https://eips.ethereum.org/EIPS/eip-6372#clock).
+
+Returns the current timepoint determined by the governor's operational mode, intended for use in time-sensitive logic. See [ERC-6372#clock](https://eips.ethereum.org/EIPS/eip-6372#clock).
Requirements:
- This function MUST always be non-decreasing.
+
-#### [](#GovernorVotesComponent-CLOCK_MODE)`CLOCK_MODE(self: @ContractState) → ByteArray` internal
-
+
Returns a description of the clock the governor is operating in. See [ERC-6372#CLOCK\_MODE](https://eips.ethereum.org/EIPS/eip-6372#clock_mode).
Requirements:
- The output MUST be formatted like a URL query string, decodable in standard JavaScript.
+
-#### [](#GovernorVotesComponent-get_votes)`get_votes(self: @ContractState, account: ContractAddress, timepoint: u64, params: Span) → u256` internal
-
+
Returns the voting power of `account` at a specific `timepoint` using the votes token.
+
-#### [](#GovernorVotesComponent-Embeddable-Functions)Embeddable functions
-
-#### [](#GovernorVotesComponent-token)`token(self: @ContractState) → ContractAddress` external
+#### Embeddable functions [!toc] [#GovernorVotesComponent-EmbeddableFunctions]
+
Returns the votes token that voting power is sourced from.
+
-#### [](#GovernorVotesComponent-Internal-Functions)Internal functions
-
-#### [](#GovernorVotesComponent-initializer)`initializer(ref self: ContractState, votes_token: ContractAddress)` internal
+#### Internal functions [!toc] [#GovernorVotesComponent-InternalFunctions]
+
Initializes the component by setting the votes token.
Requirements:
- `votes_token` must not be zero.
+
-### [](#GovernorVotesQuorumFractionComponent)`GovernorVotesQuorumFractionComponent`[](https://github.com/OpenZeppelin/cairo-contracts/blob/release-v3.0.0-alpha.1/packages/governance/src/governor/extensions/governor_votes_quorum_fraction.cairo)
+### `GovernorVotesQuorumFractionComponent` [toc] [#GovernorVotesQuorumFractionComponent]
+
+
```rust
use openzeppelin_governance::governor::extensions::GovernorVotesQuorumFractionComponent;
@@ -1653,11 +2483,11 @@ Extension of [GovernorComponent](#GovernorComponent) for voting weight extractio
Extension traits implementations
-GovernorQuorum
+#### GovernorQuorum [!toc] [#GovernorVotesQuorumFractionComponent-GovernorQuorum]
- [`quorum(self, timepoint)`](#GovernorVotesQuorumFractionComponent-quorum)
-GovernorVotes
+#### GovernorVotes [!toc] [#GovernorVotesQuorumFractionComponent-GovernorVotes]
- [`clock(self)`](#GovernorVotesQuorumFractionComponent-clock)
- [`CLOCK_MODE(self)`](#GovernorVotesQuorumFractionComponent-CLOCK_MODE)
@@ -1665,7 +2495,7 @@ GovernorVotes
Embeddable implementations
-QuorumFractionImpl
+#### QuorumFractionImpl [!toc] [#GovernorVotesQuorumFractionComponent-QuorumFractionImpl]
- [`token(self)`](#GovernorVotesQuorumFractionComponent-token)
- [`current_quorum_numerator(self)`](#GovernorVotesQuorumFractionComponent-current_quorum_numerator)
@@ -1674,7 +2504,7 @@ QuorumFractionImpl
Internal implementations
-InternalImpl
+#### InternalImpl [!toc] [#GovernorVotesQuorumFractionComponent-InternalImpl]
- [`initializer(self, votes_token, quorum_numerator)`](#GovernorVotesQuorumFractionComponent-initializer)
- [`update_quorum_numerator(self, new_quorum_numerator)`](#GovernorVotesQuorumFractionComponent-update_quorum_numerator)
@@ -1683,54 +2513,89 @@ Events
- [`QuorumNumeratorUpdated(old_quorum_numerator, new_quorum_numerator)`](#GovernorVotesQuorumFractionComponent-QuorumNumeratorUpdated)
-#### [](#GovernorVotesQuorumFractionComponent-Extension-Traits-Functions)Extension traits functions
-
-#### [](#GovernorVotesQuorumFractionComponent-quorum)`quorum(self: @ContractState, timepoint: u64) → u256` internal
+#### Extension traits functions [!toc] [#GovernorVotesQuorumFractionComponent-ExtensionTraitsFunctions]
+
It is computed as a percentage of the votes token total supply at a given `timepoint` in the past.
+
-#### [](#GovernorVotesQuorumFractionComponent-clock)`clock(self: @ContractState) → u64` internal
-
-Returns the current timepoint determined by the governor’s operational mode, intended for use in time-sensitive logic. See [ERC-6372#clock](https://eips.ethereum.org/EIPS/eip-6372#clock).
+
+Returns the current timepoint determined by the governor's operational mode, intended for use in time-sensitive logic. See [ERC-6372#clock](https://eips.ethereum.org/EIPS/eip-6372#clock).
Requirements:
- This function MUST always be non-decreasing.
+
-#### [](#GovernorVotesQuorumFractionComponent-CLOCK_MODE)`CLOCK_MODE(self: @ContractState) → ByteArray` internal
-
+
Returns a description of the clock the governor is operating in. See [ERC-6372#CLOCK\_MODE](https://eips.ethereum.org/EIPS/eip-6372#clock_mode).
Requirements:
- The output MUST be formatted like a URL query string, decodable in standard JavaScript.
+
-#### [](#GovernorVotesQuorumFractionComponent-get_votes)`get_votes(self: @ContractState, account: ContractAddress, timepoint: u64, params: Span) → u256` internal
-
+
Returns the voting power of `account` at a specific `timepoint` using the votes token.
+
-#### [](#GovernorVotesQuorumFractionComponent-Embeddable-Functions)Embeddable functions
-
-#### [](#GovernorVotesQuorumFractionComponent-token)`token(self: @ContractState) → ContractAddress` external
+#### Embeddable functions [!toc] [#GovernorVotesQuorumFractionComponent-EmbeddableFunctions]
+
Returns the address of the votes token used for voting power extraction.
+
-#### [](#GovernorVotesQuorumFractionComponent-current_quorum_numerator)`current_quorum_numerator(self: @ContractState) → u256` external
-
+
Returns the current quorum numerator value.
+
-#### [](#GovernorVotesQuorumFractionComponent-quorum_numerator)`quorum_numerator(self: @ContractState, timepoint: u64) → u256` external
-
+
Returns the quorum numerator value at a specific `timepoint` in the past.
+
-#### [](#GovernorVotesQuorumFractionComponent-quorum_denominator)`quorum_denominator(self: @ContractState) → u256` external
-
+
Returns the quorum denominator value.
+
-#### [](#GovernorVotesQuorumFractionComponent-Internal-Functions)Internal functions
-
-#### [](#GovernorVotesQuorumFractionComponent-initializer)`initializer(self: @ComponentState, votes_token: ContractAddress, quorum_numerator: u256)` internal
+#### Internal functions [!toc] [#GovernorVotesQuorumFractionComponent-InternalFunctions]
+
Initializes the component by setting the votes token and the initial quorum numerator value.
Requirements:
@@ -1739,9 +2604,13 @@ Requirements:
- `quorum_numerator` must be less than `quorum_denominator`.
Emits a [QuorumNumeratorUpdated](#GovernorVotesQuorumFractionComponent-QuorumNumeratorUpdated) event.
+
-#### [](#GovernorVotesQuorumFractionComponent-update_quorum_numerator)`update_quorum_numerator(self: @ComponentState, new_quorum_numerator: u256)` internal
-
+
Updates the quorum numerator.
This function does not emit an event if the new quorum numerator is the same as the old one.
@@ -1751,14 +2620,24 @@ Requirements:
- `new_quorum_numerator` must be less than `quorum_denominator`.
May emit a [QuorumNumeratorUpdated](#GovernorVotesQuorumFractionComponent-QuorumNumeratorUpdated) event.
+
-#### [](#GovernorVotesQuorumFractionComponent-Events)Events
-
-#### [](#GovernorVotesQuorumFractionComponent-QuorumNumeratorUpdated)`QuorumNumeratorUpdated(old_quorum_numerator: u256, new_quorum_numerator: u256)` event
+#### Events [!toc] [#GovernorVotesQuorumFractionComponent-Events]
+
Emitted when the quorum numerator is updated.
+
+
+### `GovernorTimelockExecutionComponent` [toc] [#GovernorTimelockExecutionComponent]
-### [](#GovernorTimelockExecutionComponent)`GovernorTimelockExecutionComponent`[](https://github.com/OpenZeppelin/cairo-contracts/blob/release-v3.0.0-alpha.1/packages/governance/src/governor/extensions/governor_timelock_execution.cairo)
+
```rust
use openzeppelin_governance::governor::extensions::GovernorTimelockExecutionComponent;
@@ -1774,7 +2653,7 @@ Setting up the timelock to have additional proposers or cancellers besides the g
Extension traits implementations
-GovernorExecution
+#### GovernorExecution [!toc] [#GovernorTimelockExecutionComponent-GovernorExecution]
- [`state(self, proposal_id)`](#GovernorTimelockExecutionComponent-state)
- [`executor(self)`](#GovernorTimelockExecutionComponent-executor)
@@ -1785,7 +2664,7 @@ GovernorExecution
Embeddable implementations
-TimelockedImpl
+#### TimelockedImpl [!toc] [#GovernorTimelockExecutionComponent-TimelockedImpl]
- [`timelock(self)`](#GovernorTimelockExecutionComponent-timelock)
- [`get_timelock_id(self, proposal_id)`](#GovernorTimelockExecutionComponent-get_timelock_id)
@@ -1793,7 +2672,7 @@ TimelockedImpl
Internal implementations
-InternalImpl
+#### InternalImpl [!toc] [#GovernorTimelockExecutionComponent-InternalImpl]
- [`initializer(self, timelock_controller)`](#GovernorTimelockExecutionComponent-initializer)
- [`assert_only_governance(self)`](#GovernorTimelockExecutionComponent-assert_only_governance)
@@ -1805,52 +2684,87 @@ Events
- [`TimelockUpdated(old_timelock, new_timelock)`](#GovernorTimelockExecutionComponent-TimelockUpdated)
-#### [](#GovernorTimelockExecutionComponent-Extension-Traits-Functions)Extension traits functions
-
-#### [](#GovernorTimelockExecutionComponent-state)`state(self: @ContractState, proposal_id: felt252) → ProposalState` internal
+#### Extension traits functions [!toc] [#GovernorTimelockExecutionComponent-ExtensionTraitsFunctions]
+
Returns the state of a proposal given its id.
Requirements:
- The proposal must exist.
+
-#### [](#GovernorTimelockExecutionComponent-executor)`executor(self: @ContractState) → ContractAddress` internal
-
+
Returns the executor address.
In this module, the executor is the timelock controller.
+
-#### [](#GovernorTimelockExecutionComponent-execute_operations)`execute_operations(ref self: ContractState, proposal_id: felt252, calls: Span, description_hash: felt252)` internal
-
+
Runs the already queued proposal through the timelock.
+
-#### [](#GovernorTimelockExecutionComponent-queue_operations)`queue_operations(ref self: ContractState, proposal_id: felt252, calls: Span, description_hash: felt252) → u64` internal
-
+
Queue a proposal to the timelock.
Returns the eta for the execution of the queued proposal.
+
-#### [](#GovernorTimelockExecutionComponent-proposal_needs_queuing)`proposal_needs_queuing(self: @ContractState, proposal_id: felt252) → bool` internal
-
+
In this implementation, it always returns true.
+
-#### [](#GovernorTimelockExecutionComponent-cancel_operations)`cancel_operations(ref self: ContractState, proposal_id: felt252, description_hash: felt252)` internal
-
+
Cancels the timelocked proposal if it has already been queued.
+
-#### [](#GovernorTimelockExecutionComponent-Embeddable-Functions)Embeddable functions
-
-#### [](#GovernorTimelockExecutionComponent-timelock)`timelock(self: @ContractState) → ContractAddress` external
+#### Embeddable functions [!toc] [#GovernorTimelockExecutionComponent-EmbeddableFunctions]
+
Returns the timelock controller address.
+
-#### [](#GovernorTimelockExecutionComponent-get_timelock_id)`get_timelock_id(self: @ContractState) → felt252` external
-
+
Returns the timelock proposal id for a given proposal id.
+
-#### [](#GovernorTimelockExecutionComponent-update_timelock)`update_timelock(ref self: ContractState, new_timelock: ContractAddress)` external
-
+
Updates the associated timelock.
Requirements:
@@ -1858,48 +2772,78 @@ Requirements:
- The caller must be the governance.
Emits a [TimelockUpdated](#GovernorTimelockExecutionComponent-TimelockUpdated) event.
+
-#### [](#GovernorTimelockExecutionComponent-Internal-Functions)Internal functions
-
-#### [](#GovernorTimelockExecutionComponent-initializer)`initializer(ref self: ContractState, timelock: ContractAddress)` internal
+#### Internal functions [!toc] [#GovernorTimelockExecutionComponent-InternalFunctions]
+
Initializes the timelock controller.
Requirements:
- The timelock must not be the zero address.
+
-#### [](#GovernorTimelockExecutionComponent-assert_only_governance)`assert_only_governance(self: @ContractState)` internal
-
+
Ensures the caller is the executor (the timelock controller in this case).
+
-#### [](#GovernorTimelockExecutionComponent-timelock_salt)`timelock_salt(self: @ContractState, description_hash: felt252) → felt252` internal
-
+
Computes the `TimelockController` operation salt as the XOR of the governor address and `description_hash`.
It is computed with the governor address itself to avoid collisions across governor instances using the same timelock.
+
-#### [](#GovernorTimelockExecutionComponent-get_timelock_dispatcher)`get_timelock_dispatcher(self: @ContractState) → ITimelockDispatcher` internal
-
+
Returns a dispatcher for interacting with the timelock controller.
+
-#### [](#GovernorTimelockExecutionComponent-_update_timelock)`_update_timelock(ref self: ContractState, new_timelock: ContractAddress)` internal
-
+
Internal function to update the timelock controller address.
Emits a [TimelockUpdated](#GovernorTimelockExecutionComponent-TimelockUpdated) event.
+
-#### [](#GovernorTimelockExecutionComponent-Events)Events
-
-#### [](#GovernorTimelockExecutionComponent-TimelockUpdated)`TimelockUpdated(old_timelock: ContractAddress, new_timelock: ContractAddress)` event
+#### Events [!toc] [#GovernorTimelockExecutionComponent-Events]
+
Emitted when the timelock controller is updated.
+
## [](#multisig)Multisig
A Multisig module enhances security and decentralization by requiring multiple signers to approve and execute transactions. Features include configurable quorum, signer management, and self-administration, ensuring collective decision-making and transparency for critical operations.
-### [](#MultisigComponent)`MultisigComponent`
+### `MultisigComponent` [toc] [#MultisigComponent]
+
+
```rust
use openzeppelin_governance::multisig::MultisigComponent;
@@ -1909,7 +2853,7 @@ Component that implements [IMultisig](#IMultisig) and provides functionality for
Embeddable Implementations
-MultisigImpl
+#### MultisigImpl [!toc] [#MultisigComponent-MultisigImpl]
- [`get_quorum(self)`](#MultisigComponent-get_quorum)
- [`is_signer(self, signer)`](#MultisigComponent-is_signer)
@@ -1935,7 +2879,7 @@ MultisigImpl
Internal Implementations
-InternalImpl
+#### InternalImpl [!toc] [#MultisigComponent-InternalImpl]
- [`initializer(ref self, quorum, signers)`](#MultisigComponent-initializer)
- [`resolve_tx_state(self, id)`](#MultisigComponent-resolve_tx_state)
@@ -1958,61 +2902,108 @@ Events
- [`TransactionExecuted(id)`](#MultisigComponent-TransactionExecuted)
- [`CallSalt(id, salt)`](#MultisigComponent-CallSalt)
-#### [](#MultisigComponent-Functions)Embeddable functions
-
-#### [](#MultisigComponent-get_quorum)`get_quorum(self: @ContractState) → u32` external
+#### Embeddable functions [!toc] [#MultisigComponent-EmbeddableFunctions]
+
Returns the current quorum value.
+
-#### [](#MultisigComponent-is_signer)`is_signer(self: @ContractState, signer: ContractAddress) → bool` external
-
+
Checks if a given `signer` is registered.
+
-#### [](#MultisigComponent-get_signers)`get_signers(self: @ContractState) → Span` external
-
+
Returns a list of all current signers.
+
-#### [](#MultisigComponent-is_confirmed)`is_confirmed(self: @ContractState, id: TransactionID) → bool` external
-
+
Returns whether the transaction with the given `id` has been confirmed. A confirmed transaction has received the required number of confirmations (quorum).
+
-#### [](#MultisigComponent-is_confirmed_by)`is_confirmed_by(self: @ContractState, id: TransactionID, signer: ContractAddress) → bool` external
-
+
Returns whether the transaction with the given `id` has been confirmed by the specified `signer`.
+
-#### [](#MultisigComponent-is_executed)`is_executed(self: @ContractState, id: TransactionID) → bool` external
-
+
Returns whether the transaction with the given `id` has been executed.
+
-#### [](#MultisigComponent-get_submitted_block)`get_submitted_block(self: @ContractState, id: TransactionID) → u64` external
-
+
Returns the block number when the transaction with the given `id` was submitted.
+
-#### [](#MultisigComponent-get_transaction_state)`get_transaction_state(self: @ContractState, id: TransactionID) → TransactionState` external
-
+
Returns the current state of the transaction with the given `id`.
The possible states are:
- `NotFound`: the transaction does not exist.
-- `Pending`: the transaction exists but hasn’t reached the required confirmations.
-- `Confirmed`: the transaction has reached the required confirmations but hasn’t been executed.
+- `Pending`: the transaction exists but hasn't reached the required confirmations.
+- `Confirmed`: the transaction has reached the required confirmations but hasn't been executed.
- `Executed`: the transaction has been executed.
+
-#### [](#MultisigComponent-get_transaction_confirmations)`get_transaction_confirmations(self: @ContractState, id: TransactionID) → u32` external
-
+
Returns the number of confirmations from registered signers for the transaction with the specified `id`.
+
-#### [](#MultisigComponent-hash_transaction)`hash_transaction(self: @ContractState, to: ContractAddress, selector: felt252, calldata: Span, salt: felt252)` external
-
+
Returns the computed identifier of a transaction containing a single call.
+
-#### [](#MultisigComponent-hash_transaction_batch)`hash_transaction_batch(self: @ContractState, calls: Span, salt: felt252)` external
-
+
Returns the computed identifier of a transaction containing a batch of calls.
+
-#### [](#MultisigComponent-add_signers)`add_signers(ref self: ContractState, new_quorum: u32, signers_to_add: Span)` external
-
+
Adds new signers and updates the quorum.
Requirements:
@@ -2023,9 +3014,13 @@ Requirements:
Emits a [SignerAdded](#MultisigComponent-SignerAdded) event for each signer added.
Emits a [QuorumUpdated](#MultisigComponent-QuorumUpdated) event if the quorum changes.
+
-#### [](#MultisigComponent-remove_signers)`remove_signers(ref self: ContractState, new_quorum: u32, signers_to_remove: Span)` external
-
+
Removes signers and updates the quorum.
Requirements:
@@ -2036,9 +3031,13 @@ Requirements:
Emits a [SignerRemoved](#MultisigComponent-SignerRemoved) event for each signer removed.
Emits a [QuorumUpdated](#MultisigComponent-QuorumUpdated) event if the quorum changes.
+
-#### [](#MultisigComponent-replace_signer)`replace_signer(ref self: ContractState, signer_to_remove: ContractAddress, signer_to_add: ContractAddress)` external
-
+
Replaces an existing signer with a new signer.
Requirements:
@@ -2050,9 +3049,13 @@ Requirements:
Emits a [SignerRemoved](#MultisigComponent-SignerRemoved) event for the removed signer.
Emits a [SignerAdded](#MultisigComponent-SignerAdded) event for the new signer.
+
-#### [](#MultisigComponent-change_quorum)`change_quorum(ref self: ContractState, new_quorum: u32)` external
-
+
Updates the quorum value to `new_quorum`.
Requirements:
@@ -2062,9 +3065,13 @@ Requirements:
- `new_quorum` must be less than or equal to the total number of signers.
Emits a [QuorumUpdated](#MultisigComponent-QuorumUpdated) event if the quorum changes.
+
-#### [](#MultisigComponent-submit_transaction)`submit_transaction(ref self: ContractState, to: ContractAddress, selector: felt252, calldata: Span, salt: felt252)` external
-
+
Submits a new transaction for confirmation.
Requirements:
@@ -2075,9 +3082,13 @@ Requirements:
Emits a [TransactionSubmitted](#MultisigComponent-TransactionSubmitted) event.
Emits a [CallSalt](#MultisigComponent-CallSalt) event if `salt` is not zero.
+
-#### [](#MultisigComponent-submit_transaction_batch)`submit_transaction_batch(ref self: ContractState, calls: Span, salt: felt252)` external
-
+
Submits a new batch transaction for confirmation.
Requirements:
@@ -2088,9 +3099,13 @@ Requirements:
Emits a [TransactionSubmitted](#MultisigComponent-TransactionSubmitted) event.
Emits a [CallSalt](#MultisigComponent-CallSalt) event if `salt` is not zero.
+
-#### [](#MultisigComponent-confirm_transaction)`confirm_transaction(ref self: ContractState, id: TransactionID)` external
-
+
Confirms a transaction with the given `id`.
Requirements:
@@ -2100,9 +3115,13 @@ Requirements:
- The caller must not have already confirmed the transaction.
Emits a [TransactionConfirmed](#MultisigComponent-TransactionConfirmed) event.
+
-#### [](#MultisigComponent-revoke_confirmation)`revoke_confirmation(ref self: ContractState, id: TransactionID)` external
-
+
Revokes a previous confirmation for a transaction with the given `id`.
Requirements:
@@ -2111,9 +3130,13 @@ Requirements:
- The caller must have previously confirmed the transaction.
Emits a [ConfirmationRevoked](#MultisigComponent-ConfirmationRevoked) event.
+
-#### [](#MultisigComponent-execute_transaction)`execute_transaction(ref self: ContractState, to: ContractAddress, selector: felt252, calldata: Span, salt: felt252)` external
-
+
Executes a confirmed transaction.
Requirements:
@@ -2122,9 +3145,13 @@ Requirements:
- The transaction must be confirmed and not yet executed.
Emits a [TransactionExecuted](#MultisigComponent-TransactionExecuted) event.
+
-#### [](#MultisigComponent-execute_transaction_batch)`execute_transaction_batch(ref self: ContractState, calls: Span, salt: felt252)` external
-
+
Executes a confirmed batch transaction.
Requirements:
@@ -2133,11 +3160,15 @@ Requirements:
- The transaction must be confirmed and not yet executed.
Emits a [TransactionExecuted](#MultisigComponent-TransactionExecuted) event.
+
-#### [](#MultisigComponent-Internal-Functions)Internal functions
-
-#### [](#MultisigComponent-initializer)`initializer(ref self: ContractState, quorum: u32, signers: Span)` internal
+#### Internal functions [!toc] [#MultisigComponent-InternalFunctions]
+
Initializes the Multisig component with the initial `quorum` and `signers`. This function must be called during contract initialization to set up the initial state.
Requirements:
@@ -2147,44 +3178,64 @@ Requirements:
Emits a [SignerAdded](#MultisigComponent-SignerAdded) event for each signer added.
Emits a [QuorumUpdated](#MultisigComponent-QuorumUpdated) event.
+
-#### [](#MultisigComponent-resolve_tx_state)`resolve_tx_state(self: @ContractState, id: TransactionID) → TransactionState` internal
-
+
Resolves and returns the current state of the transaction with the given `id`.
The possible states are:
- `NotFound`: the transaction does not exist.
-- `Pending`: the transaction exists but hasn’t reached the required confirmations.
-- `Confirmed`: the transaction has reached the required confirmations but hasn’t been executed.
+- `Pending`: the transaction exists but hasn't reached the required confirmations.
+- `Confirmed`: the transaction has reached the required confirmations but hasn't been executed.
- `Executed`: the transaction has been executed.
+
-#### [](#MultisigComponent-assert_one_of_signers)`assert_one_of_signers(self: @ContractState, caller: ContractAddress)` internal
-
+
Asserts that the `caller` is one of the registered signers.
Requirements:
- The `caller` must be a registered signer.
+
-#### [](#MultisigComponent-assert_tx_exists)`assert_tx_exists(self: @ContractState, id: TransactionID)` internal
-
+
Asserts that a transaction with the given `id` exists.
Requirements:
- The transaction with the given `id` must have been submitted.
+
-#### [](#MultisigComponent-assert_only_self)`assert_only_self(self: @ContractState)` internal
-
+
Asserts that the caller is the contract itself.
Requirements:
-- The caller must be the contract’s own address.
-
-#### [](#MultisigComponent-_add_signers)`_add_signers(ref self: ContractState, new_quorum: u32, signers_to_add: Span)` internal
+- The caller must be the contract's own address.
+
+
Adds new signers and updates the quorum.
Requirements:
@@ -2195,9 +3246,13 @@ Requirements:
Emits a [SignerAdded](#MultisigComponent-SignerAdded) event for each new signer added.
Emits a [QuorumUpdated](#MultisigComponent-QuorumUpdated) event if the quorum changes.
+
-#### [](#MultisigComponent-_remove_signers)`_remove_signers(ref self: ContractState, new_quorum: u32, signers_to_remove: Span)` internal
-
+
Removes existing signers and updates the quorum.
Requirements:
@@ -2207,9 +3262,13 @@ Requirements:
Emits a [SignerRemoved](#MultisigComponent-SignerRemoved) event for each signer removed.
Emits a [QuorumUpdated](#MultisigComponent-QuorumUpdated) event if the quorum changes.
+
-#### [](#MultisigComponent-_replace_signer)`_replace_signer(ref self: ContractState, signer_to_remove: ContractAddress, signer_to_add: ContractAddress)` internal
-
+
Replaces an existing signer with a new signer.
Requirements:
@@ -2221,9 +3280,13 @@ Requirements:
Emits a [SignerRemoved](#MultisigComponent-SignerRemoved) event for the removed signer.
Emits a [SignerAdded](#MultisigComponent-SignerAdded) event for the new signer.
+
-#### [](#MultisigComponent-_change_quorum)`_change_quorum(ref self: ContractState, new_quorum: u32)` internal
-
+
Updates the quorum value to `new_quorum` if it differs from the current quorum.
Requirements:
@@ -2232,46 +3295,84 @@ Requirements:
- `new_quorum` must be less than or equal to the total number of signers.
Emits a [QuorumUpdated](#MultisigComponent-QuorumUpdated) event if the quorum changes.
+
-#### [](#MultisigComponent-Events)Events
-
-#### [](#MultisigComponent-SignerAdded)`SignerAdded(signer: ContractAddress)` event
+#### Events [!toc] [#MultisigComponent-Events]
+
Emitted when a new `signer` is added.
+
-#### [](#MultisigComponent-SignerRemoved)`SignerRemoved(signer: ContractAddress)` event
-
+
Emitted when a `signer` is removed.
+
-#### [](#MultisigComponent-QuorumUpdated)`QuorumUpdated(old_quorum: u32, new_quorum: u32)` event
-
+
Emitted when the `quorum` value is updated.
+
-#### [](#MultisigComponent-TransactionSubmitted)`TransactionSubmitted(id: TransactionID, signer: ContractAddress)` event
-
+
Emitted when a new transaction is submitted by a `signer`.
+
-#### [](#MultisigComponent-TransactionConfirmed)`TransactionConfirmed(id: TransactionID, signer: ContractAddress)` event
-
+
Emitted when a transaction is confirmed by a `signer`.
+
-#### [](#MultisigComponent-ConfirmationRevoked)`ConfirmationRevoked(id: TransactionID, signer: ContractAddress)` event
-
+
Emitted when a `signer` revokes his confirmation.
+
-#### [](#MultisigComponent-TransactionExecuted)`TransactionExecuted(id: TransactionID)` event
-
+
Emitted when a transaction is executed.
+
-#### [](#MultisigComponent-CallSalt)`CallSalt(id: felt252, salt: felt252)` event
-
+
Emitted when a new transaction is submitted with non-zero salt.
+
## [](#timelock)Timelock
In a governance system, `TimelockControllerComponent` is in charge of introducing a delay between a proposal and its execution.
-### [](#TimelockControllerComponent)`TimelockControllerComponent`[](https://github.com/OpenZeppelin/cairo-contracts/blob/release-v3.0.0-alpha.1/packages/governance/src/timelock/timelock_controller.cairo)
+### `TimelockControllerComponent` [toc] [#TimelockControllerComponent]
+
+
```rust
use openzeppelin_governance::timelock::TimelockControllerComponent;
@@ -2281,7 +3382,7 @@ Component that implements [ITimelock](#ITimelock) and enables the implementing c
[Embeddable Mixin Implementations](../components#mixins)
-TimelockMixinImpl
+#### TimelockMixinImpl [!toc] [#TimelockControllerComponent-TimelockMixinImpl]
- [`TimelockImpl`](#TimelockControllerComponent-Embeddable-Impls-TimelockImpl)
- [`SRC5Impl`](introspection#SRC5Component-Embeddable-Impls)
@@ -2290,7 +3391,7 @@ TimelockMixinImpl
Embeddable Implementations
-TimelockImpl
+#### TimelockImpl [!toc] [#TimelockControllerComponent-TimelockImpl]
- [`is_operation(self, id)`](#TimelockControllerComponent-is_operation)
- [`is_operation_pending(self, id)`](#TimelockControllerComponent-is_operation_pending)
@@ -2308,11 +3409,11 @@ TimelockImpl
- [`execute_batch(self, calls, predecessor, salt)`](#TimelockControllerComponent-execute_batch)
- [`update_delay(self, new_delay)`](#TimelockControllerComponent-update_delay)
-SRC5Impl
+#### SRC5Impl [!toc] [#TimelockControllerComponent-SRC5Impl]
- [`supports_interface(self, interface_id: felt252)`](introspection#ISRC5-supports_interface)
-AccessControlImpl
+#### AccessControlImpl [!toc] [#TimelockControllerComponent-AccessControlImpl]
- [`has_role(self, role, account)`](access#IAccessControl-has_role)
- [`get_role_admin(self, role)`](access#IAccessControl-get_role_admin)
@@ -2320,7 +3421,7 @@ AccessControlImpl
- [`revoke_role(self, role, account)`](access#IAccessControl-revoke_role)
- [`renounce_role(self, role, account)`](access#IAccessControl-renounce_role)
-AccessControlCamelImpl
+#### AccessControlCamelImpl [!toc] [#TimelockControllerComponent-AccessControlCamelImpl]
- [`hasRole(self, role, account)`](access#IAccessControl-hasRole)
- [`getRoleAdmin(self, role)`](access#IAccessControl-getRoleAdmin)
@@ -2330,7 +3431,7 @@ AccessControlCamelImpl
Internal Implementations
-InternalImpl
+#### InternalImpl [!toc] [#TimelockControllerComponent-InternalImpl]
- [`initializer(self, min_delay, proposers, executors, admin)`](#TimelockControllerComponent-initializer)
- [`assert_only_role(self, role)`](#TimelockControllerComponent-assert_only_role)
@@ -2349,32 +3450,55 @@ Events
- [`CallCancelled(id)`](#TimelockControllerComponent-CallCancelled)
- [`MinDelayChanged(old_duration, new_duration)`](#TimelockControllerComponent-MinDelayChanged)
-#### [](#TimelockControllerComponent-Functions)Embeddable functions
-
-#### [](#TimelockControllerComponent-is_operation)`is_operation(self: @ContractState, id: felt252) → bool` external
+#### Embeddable functions [!toc] [#TimelockControllerComponent-EmbeddableFunctions]
+
Returns whether `id` corresponds to a registered operation. This includes the OperationStates: `Waiting`, `Ready`, and `Done`.
+
-#### [](#TimelockControllerComponent-is_operation_pending)`is_operation_pending(self: @ContractState, id: felt252) → bool` external
-
+
Returns whether the `id` OperationState is pending or not. Note that a pending operation may be either `Waiting` or `Ready`.
+
-#### [](#TimelockControllerComponent-is_operation_ready)`is_operation_ready(self: @ContractState, id: felt252) → bool` external
-
+
Returns whether the `id` OperationState is `Ready` or not.
+
-#### [](#TimelockControllerComponent-is_operation_done)`is_operation_done(self: @ContractState, id: felt252) → bool` external
-
+
Returns whether the `id` OperationState is `Done` or not.
+
-#### [](#TimelockControllerComponent-get_timestamp)`get_timestamp(self: @ContractState, id: felt252) → u64` external
-
+
Returns the timestamp at which `id` becomes `Ready`.
`0` means the OperationState is `Unset` and `1` means the OperationState is `Done`.
+
-#### [](#TimelockControllerComponent-get_operation_state)`get_operation_state(self: @ContractState, id: felt252) → OperationState` external
-
+
Returns the current state of the operation with the given `id`.
The possible states are:
@@ -2383,21 +3507,37 @@ The possible states are:
- `Waiting`: the operation has been scheduled and is pending the scheduled delay.
- `Ready`: the timer has expired, and the operation is eligible for execution.
- `Done`: the operation has been executed.
+
-#### [](#TimelockControllerComponent-get_min_delay)`get_min_delay(self: @ContractState) → u64` external
-
+
Returns the minimum delay in seconds for an operation to become valid. This value can be changed by executing an operation that calls `update_delay`.
+
-#### [](#TimelockControllerComponent-hash_operation)`hash_operation(self: @ContractState, call: Call, predecessor: felt252, salt: felt252)` external
-
+
Returns the identifier of an operation containing a single transaction.
+
-#### [](#TimelockControllerComponent-hash_operation_batch)`hash_operation_batch(self: @ContractState, calls: Span, predecessor: felt252, salt: felt252)` external
-
+
Returns the identifier of an operation containing a batch of transactions.
+
-#### [](#TimelockControllerComponent-schedule)`schedule(ref self: ContractState, call: Call, predecessor: felt252, salt: felt252, delay: u64)` external
-
+
Schedule an operation containing a single transaction.
Requirements:
@@ -2407,9 +3547,13 @@ Requirements:
- `delay` must be greater than or equal to the min delay.
Emits [CallScheduled](#TimelockControllerComponent-CallScheduled) event. Emits [CallSalt](#TimelockControllerComponent-CallSalt) event if `salt` is not zero.
+
-#### [](#TimelockControllerComponent-schedule_batch)`schedule_batch(ref self: ContractState, calls: Span, predecessor: felt252, salt: felt252, delay: u64)` external
-
+
Schedule an operation containing a batch of transactions.
Requirements:
@@ -2419,9 +3563,13 @@ Requirements:
- `delay` must be greater than or equal to the min delay.
Emits one [CallScheduled](#TimelockControllerComponent-CallScheduled) event for each transaction in the batch. Emits [CallSalt](#TimelockControllerComponent-CallSalt) event if `salt` is not zero.
+
-#### [](#TimelockControllerComponent-cancel)`cancel(ref self: ContractState, id: felt252)` external
-
+
Cancels an operation. A canceled operation returns to `Unset` OperationState.
Requirements:
@@ -2430,9 +3578,13 @@ Requirements:
- `id` must be a pending operation.
Emits a [CallCancelled](#TimelockControllerComponent-CallCancelled) event.
+
-#### [](#TimelockControllerComponent-execute)`execute(ref self: ContractState, call: Call, predecessor: felt252, salt: felt252)` external
-
+
Execute a (Ready) operation containing a single Call.
Requirements:
@@ -2443,10 +3595,14 @@ Requirements:
Emits a [CallExecuted](#TimelockControllerComponent-CallExecuted) event.
-This function can reenter, but it doesn’t pose a risk because [`_after_call(self: @ContractState, id: felt252)` internal](#TimelockControllerComponent-_after_call) checks that the proposal is pending, thus any modifications to the operation during reentrancy should be caught.
-
-#### [](#TimelockControllerComponent-execute_batch)`execute_batch(ref self: ContractState, calls: Span, predecessor: felt252, salt: felt252)` external
+This function can reenter, but it doesn't pose a risk because [`_after_call(self: @ContractState, id: felt252)` internal](#TimelockControllerComponent-_after_call) checks that the proposal is pending, thus any modifications to the operation during reentrancy should be caught.
+
+
Execute a (Ready) operation containing a batch of Calls.
Requirements:
@@ -2457,10 +3613,14 @@ Requirements:
Emits a [CallExecuted](#TimelockControllerComponent-CallExecuted) event for each Call.
-This function can reenter, but it doesn’t pose a risk because `_after_call` checks that the proposal is pending, thus any modifications to the operation during reentrancy should be caught.
-
-#### [](#TimelockControllerComponent-update_delay)`update_delay(ref self: ContractState, new_delay: u64)` external
+This function can reenter, but it doesn't pose a risk because `_after_call` checks that the proposal is pending, thus any modifications to the operation during reentrancy should be caught.
+
+
Changes the minimum timelock duration for future operations.
Requirements:
@@ -2468,11 +3628,15 @@ Requirements:
- The caller must be the timelock itself. This can only be achieved by scheduling and later executing an operation where the timelock is the target and the data is the serialized call to this function.
Emits a [MinDelayChanged](#TimelockControllerComponent-MinDelayChanged) event.
+
-#### [](#TimelockControllerComponent-Internal-Functions)Internal functions
-
-#### [](#TimelockControllerComponent-initializer)`initializer(ref self: ContractState, min_delay: u64, proposers: Span, executors: Span, admin: ContractAddress)` internal
+#### Internal functions [!toc] [#TimelockControllerComponent-InternalFunctions]
+
Initializes the contract by registering support for SRC5 and AccessControl.
This function also configures the contract with the following parameters:
@@ -2491,71 +3655,125 @@ Emits a [IAccessControl::RoleGranted](access#IAccessControl-RoleGranted) event f
May emit a [IAccessControl::RoleGranted](access#IAccessControl-RoleGranted) event for `admin` with `DEFAULT_ADMIN_ROLE` role (if `admin` is not zero).
Emits [MinDelayChanged](#TimelockControllerComponent-MinDelayChanged) event.
+
-#### [](#TimelockControllerComponent-assert_only_role)`assert_only_role(self: @ContractState, role: felt252)` internal
-
+
Validates that the caller has the given `role`. Otherwise it panics.
+
-#### [](#TimelockControllerComponent-assert_only_role_or_open_role)`assert_only_role_or_open_role(self: @ContractState, role: felt252)` internal
-
+
Validates that the caller has the given `role`. If `role` is granted to the zero address, then this is considered an open role which allows anyone to be the caller.
+
-#### [](#TimelockControllerComponent-assert_only_self)`assert_only_self(self: @ContractState)` internal
-
+
Validates that the caller is the timelock contract itself. Otherwise it panics.
+
-#### [](#TimelockControllerComponent-_before_call)`_before_call(self: @ContractState, id: felt252, predecessor: felt252)` internal
-
-Private function that checks before execution of an operation’s calls.
+
+Private function that checks before execution of an operation's calls.
Requirements:
- `id` must be in the `Ready` OperationState.
- `predecessor` must either be zero or be in the `Done` OperationState.
+
-#### [](#TimelockControllerComponent-_after_call)`_after_call(self: @ContractState, id: felt252)` internal
-
-Private function that checks after execution of an operation’s calls and sets the OperationState of `id` to `Done`.
+
+Private function that checks after execution of an operation's calls and sets the OperationState of `id` to `Done`.
Requirements:
- `id` must be in the Ready OperationState.
+
-#### [](#TimelockControllerComponent-_schedule)`_schedule(ref self: ContractState, id: felt252, delay: u64)` internal
-
+
Private function that schedules an operation that is to become valid after a given `delay`.
-
-#### [](#TimelockControllerComponent-_execute)`_execute(ref self: ContractState, call: Call)` internal
-
-Private function that executes an operation’s calls.
-
-#### [](#TimelockControllerComponent-Events)Events
-
-#### [](#TimelockControllerComponent-CallScheduled)`CallScheduled(id: felt252, index: felt252, call: Call, predecessor: felt252, delay: u64)` event
-
+
+
+
+Private function that executes an operation's calls.
+
+
+#### Events [!toc] [#TimelockControllerComponent-Events]
+
+
Emitted when `call` is scheduled as part of operation `id`.
+
-#### [](#TimelockControllerComponent-CallExecuted)`CallExecuted(id: felt252, index: felt252, call: Call)` event
-
+
Emitted when `call` is performed as part of operation `id`.
+
-#### [](#TimelockControllerComponent-CallSalt)`CallSalt(id: felt252, salt: felt252)` event
-
+
Emitted when a new proposal is scheduled with non-zero salt.
+
-#### [](#TimelockControllerComponent-CallCancelled)`CallCancelled(id: felt252)` event
-
+
Emitted when operation `id` is cancelled.
+
-#### [](#TimelockControllerComponent-MinDelayChanged)`MinDelayChanged(old_duration: u64, new_duration: u64)` event
-
+
Emitted when the minimum delay for future operations is modified.
+
## [](#votes)Votes
The `VotesComponent` provides a flexible system for tracking and delegating voting power. This system allows users to delegate their voting power to other addresses, enabling more active participation in governance.
-### [](#VotesComponent)`VotesComponent`[](https://github.com/OpenZeppelin/cairo-contracts/blob/release-v3.0.0-alpha.1/packages/governance/src/votes/votes.cairo)
+### `VotesComponent` [toc] [#VotesComponent]
+
+
```rust
use openzeppelin_governance::votes::VotesComponent;
@@ -2569,17 +3787,17 @@ When using this module, your contract must implement the [VotingUnitsTrait](#Vot
Voting Units Trait Implementations
-ERC20VotesImpl
+#### ERC20VotesImpl [!toc] [#VotesComponent-ERC20VotesImpl]
- [`get_voting_units(self, account)`](#VotesComponent-ERC20VotesImpl-get_voting_units)
-ERC721VotesImpl
+#### ERC721VotesImpl [!toc] [#VotesComponent-ERC721VotesImpl]
- [`get_voting_units(self, account)`](#VotesComponent-ERC721VotesImpl-get_voting_units)
Embeddable Implementations
-VotesImpl
+#### VotesImpl [!toc] [#VotesComponent-VotesImpl]
- [`get_votes(self, account)`](#VotesComponent-get_votes)
- [`get_past_votes(self, account, timepoint)`](#VotesComponent-get_past_votes)
@@ -2592,7 +3810,7 @@ VotesImpl
Internal implementations
-InternalImpl
+#### InternalImpl [!toc] [#VotesComponent-InternalImpl]
- [`get_total_supply(self)`](#VotesComponent-get_total_supply)
- [`move_delegate_votes(self, from, to, amount)`](#VotesComponent-move_delegate_votes)
@@ -2606,10 +3824,11 @@ Events
- [`DelegateChanged(delegator, from_delegate, to_delegate)`](#VotesComponent-DelegateChanged)
- [`DelegateVotesChanged(delegate, previous_votes, new_votes)`](#VotesComponent-DelegateVotesChanged)
-#### [](#VotesComponent-ERC20VotesImpl)ERC20VotesImpl
-
-#### [](#VotesComponent-ERC20VotesImpl-get_voting_units)`get_voting_units(self: @ContractState, account: ContractAddress) → u256` internal
-
+
Returns the number of voting units for a given account.
This implementation is specific to ERC20 tokens, where the balance of tokens directly represents the number of voting units.
@@ -2617,11 +3836,13 @@ This implementation is specific to ERC20 tokens, where the balance of tokens dir
This implementation will work out of the box if the ERC20 component is implemented in the final contract.
This implementation assumes tokens map to voting units 1:1. Any deviation from this formula when transferring voting units (e.g. by using hooks) may compromise the internal vote accounting.
+
-#### [](#VotesComponent-ERC721VotesImpl)ERC721VotesImpl
-
-#### [](#VotesComponent-ERC721VotesImpl-get_voting_units)`get_voting_units(self: @ContractState, account: ContractAddress) → u256` internal
-
+
Returns the number of voting units for a given account.
This implementation is specific to ERC721 tokens, where each token represents one voting unit. The function returns the balance of ERC721 tokens for the specified account.
@@ -2629,23 +3850,35 @@ This implementation is specific to ERC721 tokens, where each token represents on
This implementation will work out of the box if the ERC721 component is implemented in the final contract.
This implementation assumes tokens map to voting units 1:1. Any deviation from this formula when transferring voting units (e.g. by using hooks) may compromise the internal vote accounting.
+
-#### [](#VotesComponent-Functions)Embeddable functions
-
-#### [](#VotesComponent-get_votes)`get_votes(self: @ContractState, account: ContractAddress) → u256` external
+#### Embeddable functions [!toc] [#VotesComponent-EmbeddableFunctions]
+
Returns the current amount of votes that `account` has.
+
-#### [](#VotesComponent-get_past_votes)`get_past_votes(self: @ContractState, account: ContractAddress, timepoint: u64) → u256` external
-
+
Returns the amount of votes that `account` had at a specific moment in the past.
Requirements:
- `timepoint` must be in the past.
+
-#### [](#VotesComponent-get_past_total_supply)`get_past_total_supply(self: @ContractState, timepoint: u64) → u256` external
-
+
Returns the total supply of votes available at a specific moment in the past.
This value is the sum of all available votes, which is not necessarily the sum of all delegated votes. Votes that have not been delegated are still part of total supply, even though they would not participate in a vote.
@@ -2653,64 +3886,96 @@ This value is the sum of all available votes, which is not necessarily the sum o
Requirements:
- `timepoint` must be in the past.
+
-#### [](#VotesComponent-delegates)`delegates(self: @ContractState, account: ContractAddress) → ContractAddress` external
-
+
Returns the delegate that `account` has chosen.
+
-#### [](#VotesComponent-delegate)`delegate(ref self: ContractState, delegatee: ContractAddress)` external
-
+
Delegates votes from the sender to `delegatee`.
Emits a [DelegateChanged](#VotesComponent-DelegateChanged) event.
May emit one or two [DelegateVotesChanged](#VotesComponent-DelegateVotesChanged) events.
+
-#### [](#VotesComponent-delegate_by_sig)`delegate_by_sig(ref self: ContractState, delegator: ContractAddress, delegatee: ContractAddress, nonce: felt252, expiry: u64, signature: Span)` external
-
+
Delegates votes from `delegator` to `delegatee` through a [SNIP-12](https://github.com/starknet-io/SNIPs/blob/main/SNIPS/snip-12.md) message signature validation.
Requirements:
- `expiry` must not be in the past.
-- `nonce` must match the account’s current nonce.
+- `nonce` must match the account's current nonce.
- `delegator` must implement `SRC6::is_valid_signature`.
- `signature` should be valid for the message hash.
Emits a [DelegateChanged](#VotesComponent-DelegateChanged) event.
May emit one or two [DelegateVotesChanged](#VotesComponent-DelegateVotesChanged) events.
+
-#### [](#VotesComponent-clock)`clock(self: @ContractState) → u64` external
-
-Returns the current timepoint determined by the contract’s operational mode, intended for use in time-sensitive logic. See [ERC-6372#clock](https://eips.ethereum.org/EIPS/eip-6372#clock).
+
+Returns the current timepoint determined by the contract's operational mode, intended for use in time-sensitive logic. See [ERC-6372#clock](https://eips.ethereum.org/EIPS/eip-6372#clock).
Requirements:
- This function MUST always be non-decreasing.
+
-#### [](#VotesComponent-CLOCK_MODE)`CLOCK_MODE(self: @ContractState) → u64` external
-
+
Returns a description of the clock the contract is operating in. See [ERC-6372#CLOCK\_MODE](https://eips.ethereum.org/EIPS/eip-6372#clock_mode).
Requirements:
- The output MUST be formatted like a URL query string, decodable in standard JavaScript.
+
-#### [](#VotesComponent-Internal-functions)Internal functions
-
-#### [](#VotesComponent-get_total_supply)`get_total_supply(self: @ContractState) → u256` internal
+#### Internal functions [!toc] [#VotesComponent-InternalFunctions]
+
Returns the current total supply of votes.
+
-#### [](#VotesComponent-move_delegate_votes)`move_delegate_votes(ref self: ContractState, from: ContractAddress, to: ContractAddress, amount: u256)` internal
-
+
Moves delegated votes from one delegate to another.
May emit one or two [DelegateVotesChanged](#VotesComponent-DelegateVotesChanged) events.
+
-#### [](#VotesComponent-transfer_voting_units)`transfer_voting_units(ref self: ContractState, from: ContractAddress, to: ContractAddress, amount: u256)` internal
-
+
Transfers, mints, or burns voting units.
To register a mint, `from` should be zero. To register a burn, `to` should be zero. Total supply of voting units will be adjusted with mints and burns.
@@ -2718,34 +3983,60 @@ To register a mint, `from` should be zero. To register a burn, `to` should be ze
If voting units are based on an underlying transferable asset (like a token), you must call this function every time the asset is transferred to keep the internal voting power accounting in sync. For ERC20 and ERC721 tokens, this is typically handled using hooks.
May emit one or two [DelegateVotesChanged](#VotesComponent-DelegateVotesChanged) events.
+
-#### [](#VotesComponent-num_checkpoints)`num_checkpoints(self: @ContractState, account: ContractAddress) → u64` internal
-
+
Returns the number of checkpoints for `account`.
+
-#### [](#VotesComponent-checkpoints)`checkpoints(self: @ContractState, account: ContractAddress, pos: u64) → Checkpoint` internal
-
+
Returns the `pos`-th checkpoint for `account`.
+
-#### [](#VotesComponent-_delegate)`_delegate(ref self: ContractState, account: ContractAddress, delegatee: ContractAddress)` internal
-
+
Delegates all of `account`'s voting units to `delegatee`.
Emits a [DelegateChanged](#VotesComponent-DelegateChanged) event.
May emit one or two [DelegateVotesChanged](#VotesComponent-DelegateVotesChanged) events.
+
-#### [](#VotesComponent-Events)Events
-
-#### [](#VotesComponent-DelegateChanged)`DelegateChanged(delegator: ContractAddress, from_delegate: ContractAddress, to_delegate: ContractAddress)` event
+#### Events [!toc] [#VotesComponent-Events]
+
Emitted when an account changes their delegate.
+
-#### [](#VotesComponent-DelegateVotesChanged)`DelegateVotesChanged(delegate: ContractAddress, previous_votes: u256, new_votes: u256)` event
+
+Emitted when a token transfer or delegate change results in changes to a delegate's number of votes.
+
-Emitted when a token transfer or delegate change results in changes to a delegate’s number of votes.
+### `VotingUnitsTrait` [toc] [#VotingUnitsTrait]
-### [](#VotingUnitsTrait)`VotingUnitsTrait`[](https://github.com/OpenZeppelin/cairo-contracts/blob/release-v3.0.0-alpha.1/packages/governance/src/votes/votes.cairo)
+
```rust
pub trait VotingUnitsTrait {
@@ -2759,11 +4050,15 @@ Functions
- [`get_voting_units(self, account)`](#VotingUnitsTrait-get_voting_units)
-#### [](#VotingUnitsTrait-Functions)Functions
-
-#### [](#VotingUnitsTrait-get_voting_units)`get_voting_units(self: @TState, account: ContractAddress) → u256` external
+#### Functions [!toc] [#VotingUnitsTrait-Functions]
+
Returns the number of voting units for a given account. For ERC20, this is typically the token balance. For ERC721, this is typically the number of tokens owned.
While any formula can be used as a measure of voting units, the internal vote accounting of the contract may be compromised if voting units are transferred in any external flow by following a different formula.
For example, when implementing the hook for ERC20, the number of voting units transferred should match the formula given by the `get_voting_units` implementation.
+
diff --git a/content/contracts-cairo/api/introspection.mdx b/content/contracts-cairo/api/introspection.mdx
index 78db9d0..32a0450 100644
--- a/content/contracts-cairo/api/introspection.mdx
+++ b/content/contracts-cairo/api/introspection.mdx
@@ -2,13 +2,23 @@
title: Introspection
---
-This crate handles [type introspection](https://en.wikipedia.org/wiki/Type_introspection) of contracts. In other words, it examines which functions can be called on a given contract. This is referred to as the contract’s interface.
+import { UMBRELLA_VERSION } from "../utils/constants.js";
+
+This crate handles [type introspection](https://en.wikipedia.org/wiki/Type_introspection) of contracts. In other words, it examines which functions can be called on a given contract. This is referred to as the contract's interface.
## [](#interfaces)Interfaces
-Starting from version `3.x.x`, the interfaces are no longer part of the `openzeppelin_introspection` package. The references documented here are contained in the `openzeppelin_interfaces` package version `v2.1.0`.
+
+Starting from version `3.x.x`, the interfaces are no longer part of the `openzeppelin_access` package. The references
+documented here are contained in the `openzeppelin_interfaces` package version `{{openzeppelin_interfaces_version}}`.
+
+
+### `ISRC5` [toc] [#ISRC5]
-### [](#ISRC5)`ISRC5`[](https://github.com/OpenZeppelin/cairo-contracts/blob/release-v3.0.0-alpha.1/packages/interfaces/src/introspection.cairo)
+
```rust
use openzeppelin_interfaces::introspection::ISRC5;
@@ -18,23 +28,34 @@ Interface of the SRC5 Introspection Standard as defined in [SNIP-5](https://gith
[SRC5 ID](#ISRC5)
+```text
0x3f918d17e5ee77373b56385708f855659a07f75997f365cf87748628532a055
+```
Functions
- [`supports_interface(interface_id)`](#ISRC5-supports_interface)
-#### [](#ISRC5-Functions)Functions
-
-#### [](#ISRC5-supports_interface)`supports_interface(interface_id: felt252) → bool` external
+#### Functions [!toc] [#ISRC5-Functions]
+
Checks whether the contract implements the given interface.
-Check [Computing the Interface ID](../introspection#computing_the_interface_id) for more information on how to compute this ID.
+Check [Computing the Interface ID](../introspection#computing-the-interface-id) for more information on how to compute this ID.
+
## [](#core)Core
-### [](#SRC5Component)`SRC5Component`[](https://github.com/OpenZeppelin/cairo-contracts/blob/release-v3.0.0-alpha.1/packages/introspection/src/src5.cairo)
+### `SRC5Component` [toc] [#SRC5Component]
+
+
```rust
use openzeppelin_introspection::src5::SRC5Component;
@@ -44,29 +65,41 @@ SRC5 component extending [`ISRC5`](#ISRC5).
Embeddable Implementations
-SRC5Impl
+#### SRC5Impl [!toc] [#SRC5Component-SRC5Impl]
- [`supports_interface(self, interface_id)`](#SRC5Component-supports_interface)
Internal Implementations
-InternalImpl
+#### InternalImpl [!toc] [#SRC5Component-InternalImpl]
- [`register_interface(self, interface_id)`](#SRC5Component-register_interface)
- [`deregister_interface(self, interface_id)`](#SRC5Component-deregister_interface)
-#### [](#SRC5Component-Embeddable-Functions)Embeddable functions
-
-#### [](#SRC5Component-supports_interface)`supports_interface(self: @ContractState, interface_id: felt252) → bool` external
+#### Embeddable functions [!toc] [#SRC5Component-EmbeddableFunctions]
+
See [`ISRC5::supports_interface`](#ISRC5-supports_interface).
+
-#### [](#SRC5Component-Internal-Functions)Internal functions
-
-#### [](#SRC5Component-register_interface)`register_interface(ref self: ComponentState, interface_id: felt252)` internal
+#### Internal functions [!toc] [#SRC5Component-InternalFunctions]
+
Registers support for the given `interface_id`.
+
-#### [](#SRC5Component-deregister_interface)`deregister_interface(ref self: ComponentState, interface_id: felt252)` internal
-
+
Deregisters support for the given `interface_id`.
+
diff --git a/content/contracts-cairo/api/merkle-tree.mdx b/content/contracts-cairo/api/merkle-tree.mdx
index 0c1fbfe..5772e07 100644
--- a/content/contracts-cairo/api/merkle-tree.mdx
+++ b/content/contracts-cairo/api/merkle-tree.mdx
@@ -2,6 +2,8 @@
title: Merkle Tree
---
+import { UMBRELLA_VERSION } from "../utils/constants.js";
+
This crate provides a set of utilities for verifying Merkle Tree proofs on-chain. The tree and the proofs can be generated using this [JavaScript library](https://github.com/ericnordelo/strk-merkle-tree).
This module provides:
@@ -17,7 +19,9 @@ To use it as a standalone package, you can add it in your `Scarb.toml` as follow
## [](#modules)Modules
-### [](#merkle_proof)`merkle_proof`[](https://github.com/OpenZeppelin/cairo-contracts/blob/release-v3.0.0-alpha.1/packages/merkle_tree/src/merkle_proof.cairo)
+### [](#merkle_proof)`merkle_proof` [toc] [#merkle_proof]
+
+
```rust
use openzeppelin_merkle_tree::merkle_proof;
@@ -38,10 +42,13 @@ Functions
- [`verify_multi_proof(proof, proof_flags, root, leaves)`](#merkle_proof-verify_multi_proof)
- [`process_multi_proof(proof, proof_flags, leaf)`](#merkle_proof-process_multi_proof)
-#### [](#merkle_proof-Functions)Functions
-
-#### [](#merkle_proof-verify)`verify<+CommutativeHasher>(proof: Span, root: felt252, leaf: felt252) → bool` public
+#### [](#merkle_proof-Functions)Functions [!toc]
+
Returns true if a `leaf` can be proved to be a part of a Merkle tree defined by `root`.
For this, a `proof` must be provided, containing sibling hashes on the branch from the leaf to the root of the tree.
@@ -51,17 +58,29 @@ Each pair of leaves and each pair of pre-images are assumed to be sorted.
This function expects a `CommutativeHasher` implementation. See [hashes::CommutativeHasher](#hashes-CommutativeHasher) for more information.
`verify_pedersen` and `verify_poseidon` already include the corresponding `Hasher` implementations.
+
-#### [](#merkle_proof-verify_pedersen)`verify_pedersen(proof: Span, root: felt252, leaf: felt252) → bool` public
-
+
Version of `verify` using Pedersen as the hashing function.
+
-#### [](#merkle_proof-verify_poseidon)`verify_poseidon(proof: Span, root: felt252, leaf: felt252) → bool` public
-
+
Version of `verify` using Poseidon as the hashing function.
+
-#### [](#merkle_proof-process_proof)`process_proof<+CommutativeHasher>(proof: Span, leaf: felt252) → felt252` public
-
+
Returns the rebuilt hash obtained by traversing a Merkle tree up from `leaf` using `proof`.
A `proof` is valid if and only if the rebuilt hash matches the root of the tree.
@@ -69,9 +88,13 @@ A `proof` is valid if and only if the rebuilt hash matches the root of the tree.
When processing the proof, the pairs of leaves & pre-images are assumed to be sorted.
This function expects a `CommutativeHasher` implementation. See [hashes::CommutativeHasher](#hashes-CommutativeHasher) for more information.
+
-#### [](#merkle_proof-verify_multi_proof)`verify_multi_proof<+CommutativeHasher>(proof: Span, proof_flags: Span, root: felt252, leaves: Span) → bool` public
-
+
Returns true if the `leaves` can be simultaneously proven to be a part of a Merkle tree defined by `root`, according to `proof` and `proof_flags` as described in `process_multi_proof`.
The `leaves` must be validated independently.
@@ -81,9 +104,13 @@ Not all Merkle trees admit multiproofs. See `process_multi_proof` for details.
Consider the case where `root == proof.at(0) && leaves.len() == 0` as it will return `true`.
This function expects a `CommutativeHasher` implementation. See [hashes::CommutativeHasher](#hashes-CommutativeHasher) for more information.
+
-#### [](#merkle_proof-process_multi_proof)`process_multi_proof<+CommutativeHasher>(proof: Span, proof_flags: Span, leaves: Span) → felt252` public
-
+
Returns the root of a tree reconstructed from `leaves` and sibling nodes in `proof`.
The reconstruction proceeds by incrementally reconstructing all inner nodes by combining a leaf/inner node with either another leaf/inner node or a proof sibling node, depending on whether each `proof_flags` item is true or false respectively.
@@ -93,11 +120,14 @@ Not all Merkle trees admit multiproofs. To use multiproofs, it is sufficient to
1. The tree is complete (but not necessarily perfect).
2. The leaves to be proven are in the opposite order than they are in the tree. (i.e., as seen from right to left starting at the deepest layer and continuing at the next layer).
-The *empty set* (i.e. the case where `proof.len() == 1 && leaves.len() == 0`) is considered a no-op, and therefore a valid multiproof (i.e. it returns `proof.at(0)`). Consider disallowing this case if you’re not validating the leaves elsewhere.
+The *empty set* (i.e. the case where `proof.len() == 1 && leaves.len() == 0`) is considered a no-op, and therefore a valid multiproof (i.e. it returns `proof.at(0)`). Consider disallowing this case if you're not validating the leaves elsewhere.
This function expects a `CommutativeHasher` implementation. See [hashes::CommutativeHasher](#hashes-CommutativeHasher) for more information.
+
+
+### [](#hashes)`hashes` [toc] [#hashes]
-### [](#hashes)`hashes`[](https://github.com/OpenZeppelin/cairo-contracts/blob/release-v3.0.0-alpha.1/packages/merkle_tree/src/hashes.cairo)
+
```rust
use openzeppelin_merkle_tree::hashes;
@@ -116,10 +146,13 @@ Impls
- [`PedersenCHasher`](#hashes-PedersenCHasher)
- [`PoseidonCHasher`](#hashes-PoseidonCHasher)
-#### [](#hashes-Traits)Traits
-
-#### [](#hashes-CommutativeHasher)`CommutativeHasher` trait
+#### [](#hashes-Traits)Traits [!toc]
+
Declares a commutative hash function with the following signature:
`commutative_hash(a: felt252, b: felt252) → felt252;`
@@ -131,13 +164,22 @@ This is usually implemented as an extension of a non-commutative hash function,
Frequently used when working with merkle proofs.
The `commutative_hash` function MUST follow the invariant that `commutative_hash(a, b) == commutative_hash(b, a)`.
+
-#### [](#hashes-Impls)Impls
-
-#### [](#hashes-PedersenCHasher)`PedersenCHasher` impl
+#### [](#hashes-Impls)Impls [!toc]
+
Implementation of the `CommutativeHasher` trait which computes the Pedersen hash of chaining the two input values with the len (2), sorting the pair first.
+
-#### [](#hashes-PoseidonCHasher)`PoseidonCHasher` impl
-
+
Implementation of the `CommutativeHasher` trait which computes the Poseidon hash of the concatenation of two values, sorting the pair first.
+
diff --git a/content/contracts-cairo/api/security.mdx b/content/contracts-cairo/api/security.mdx
index f074c67..12e3a01 100644
--- a/content/contracts-cairo/api/security.mdx
+++ b/content/contracts-cairo/api/security.mdx
@@ -2,11 +2,15 @@
title: Security
---
+import { UMBRELLA_VERSION } from "../utils/constants.js";
+
This crate provides components to handle common security-related tasks.
## [](#initializable)Initializable
-### [](#InitializableComponent)`InitializableComponent`[](https://github.com/OpenZeppelin/cairo-contracts/blob/release-v3.0.0-alpha.1/packages/security/src/initializable.cairo)
+### [](#InitializableComponent)`InitializableComponent` [toc] [#InitializableComponent]
+
+
```rust
use openzeppelin_security::InitializableComponent;
@@ -26,25 +30,35 @@ InternalImpl
- [`initialize(self)`](#InitializableComponent-initialize)
-#### [](#InitializableComponent-Embeddable-Functions)Embeddable functions
-
-#### [](#InitializableComponent-is_initialized)`is_initialized(self: @ComponentState) → bool` external
+#### [](#InitializableComponent-Embeddable-Functions)Embeddable functions [!toc]
+
Returns whether the contract has been initialized.
+
-#### [](#InitializableComponent-Internal-Functions)Internal functions
-
-#### [](#InitializableComponent-initialize)`initialize(ref self: ComponentState)` internal
+#### [](#InitializableComponent-Internal-Functions)Internal functions [!toc]
+
Initializes the contract. Can only be called once.
Requirements:
- the contract must not have been initialized before.
+
## [](#pausable)Pausable
-### [](#PausableComponent)`PausableComponent`[](https://github.com/OpenZeppelin/cairo-contracts/blob/release-v3.0.0-alpha.1/packages/security/src/pausable.cairo)
+### [](#PausableComponent)`PausableComponent` [toc] [#PausableComponent]
+
+
```rust
use openzeppelin_security::PausableComponent;
@@ -72,24 +86,39 @@ Events
- [`Paused(account)`](#PausableComponent-Paused)
- [`Unpaused(account)`](#PausableComponent-Unpaused)
-#### [](#PausableComponent-Embeddable-Functions)Embeddable functions
-
-#### [](#PausableComponent-is_paused)`is_paused(self: @ComponentState) → bool` external
+#### [](#PausableComponent-Embeddable-Functions)Embeddable functions [!toc]
+
Returns whether the contract is currently paused.
+
-#### [](#PausableComponent-Internal-Functions)Internal functions
-
-#### [](#PausableComponent-assert_not_paused)`assert_not_paused(self: @ComponentState)` internal
+#### [](#PausableComponent-Internal-Functions)Internal functions [!toc]
+
Panics if the contract is paused.
+
-#### [](#PausableComponent-assert_paused)`assert_paused(self: @ComponentState)` internal
-
+
Panics if the contract is not paused.
+
-#### [](#PausableComponent-pause)`pause(ref self: ComponentState)` internal
-
+
Pauses the contract.
Requirements:
@@ -97,9 +126,13 @@ Requirements:
- the contract must not be paused.
Emits a [Paused](#PausableComponent-Paused) event.
+
-#### [](#PausableComponent-unpause)`unpause(ref self: ComponentState)` internal
-
+
Unpauses the contract.
Requirements:
@@ -107,20 +140,31 @@ Requirements:
- the contract must be paused.
Emits an [Unpaused](#PausableComponent-Unpaused) event.
+
-#### [](#PausableComponent-Events)Events
-
-#### [](#PausableComponent-Paused)`Paused(account: ContractAddress)` event
+#### [](#PausableComponent-Events)Events [!toc]
+
Emitted when the contract is paused by `account`.
+
-#### [](#PausableComponent-Unpaused)`Unpaused(account: ContractAddress)` event
-
+
Emitted when the contract is unpaused by `account`.
+
## [](#reentrancyguard)ReentrancyGuard
-### [](#ReentrancyGuardComponent)`ReentrancyGuardComponent`[](https://github.com/OpenZeppelin/cairo-contracts/blob/release-v3.0.0-alpha.1/packages/security/src/reentrancyguard.cairo)
+### [](#ReentrancyGuardComponent)`ReentrancyGuardComponent` [toc] [#ReentrancyGuardComponent]
+
+
```rust
use openzeppelin_security::ReentrancyGuardComponent;
@@ -135,16 +179,24 @@ InternalImpl
- [`start(self)`](#ReentrancyGuardComponent-start)
- [`end(self)`](#ReentrancyGuardComponent-end)
-#### [](#ReentrancyGuardComponent-Internal-Functions)Internal functions
-
-#### [](#ReentrancyGuardComponent-start)`start(ref self: ComponentState)` internal
+#### [](#ReentrancyGuardComponent-Internal-Functions)Internal functions [!toc]
-Prevents a contract’s function from calling itself or another protected function, directly or indirectly.
+
+Prevents a contract's function from calling itself or another protected function, directly or indirectly.
Requirements:
- the guard must not be currently enabled.
+
-#### [](#ReentrancyGuardComponent-end)`end(ref self: ComponentState)` internal
-
+
Removes the reentrant guard.
+
diff --git a/content/contracts-cairo/api/testing.mdx b/content/contracts-cairo/api/testing.mdx
new file mode 100644
index 0000000..7a9b3cc
--- /dev/null
+++ b/content/contracts-cairo/api/testing.mdx
@@ -0,0 +1,10 @@
+---
+title: Testing
+---
+
+
+The `openzeppelin_testing` package version is now decoupled from the `cairo-contracts` version.
+
+
+You can find the documentation for the `openzeppelin_testing` package in the README for the corresponding version in the
+[scarb registry](https://scarbs.xyz/packages/openzeppelin_testing).
diff --git a/content/contracts-cairo/api/token_common.mdx b/content/contracts-cairo/api/token_common.mdx
index b41abae..08fad2c 100644
--- a/content/contracts-cairo/api/token_common.mdx
+++ b/content/contracts-cairo/api/token_common.mdx
@@ -2,13 +2,20 @@
title: Common (Token)
---
+import { UMBRELLA_VERSION } from "../utils/constants.js";
+
This module provides extensions and utilities that are common to multiple token standards.
## [](#interfaces)Interfaces
-Starting from version `3.x.x`, the interfaces are no longer part of the `openzeppelin_token` package. The references documented here are contained in the `openzeppelin_interfaces` package version `v2.1.0`.
+
+Starting from version `3.x.x`, the interfaces are no longer part of the `openzeppelin_access` package. The references
+documented here are contained in the `openzeppelin_interfaces` package version `{{openzeppelin_interfaces_version}}`.
+
+
+### [](#IERC2981)`IERC2981` [toc] [#IERC2981]
-### [](#IERC2981)`IERC2981`[](https://github.com/OpenZeppelin/cairo-contracts/blob/release-v3.0.0-alpha.1/packages/interfaces/src/token/erc2981.cairo)
+
```rust
use openzeppelin_interfaces::erc2981::IERC2981;
@@ -16,7 +23,9 @@ use openzeppelin_interfaces::erc2981::IERC2981;
[SRC5 ID](introspection#ISRC5)
+```text
0x2d3414e45a8700c29f119a54b9f11dca0e29e06ddcb214018fc37340e165ed6
+```
Interface of the ERC2981 standard as defined in [EIP-2981](https://eips.ethereum.org/EIPS/eip-2981).
@@ -24,13 +33,19 @@ Functions
- [`royalty_info(token_id, sale_price)`](#IERC2981-royalty_info)
-#### [](#IERC2981-Functions)Functions
-
-#### [](#IERC2981-royalty_info)`royalty_info(token_id: u256, sale_price: u256) → (ContractAddress, u256)` external
+#### [](#IERC2981-Functions)Functions [!toc]
+
Returns how much royalty is owed and to whom, based on a sale price that may be denominated in any unit of exchange. The royalty amount is denominated and must be paid in that same unit of exchange.
+
+
+### [](#IERC2981Info)`IERC2981Info` [toc] [#IERC2981Info]
-### [](#IERC2981Info)`IERC2981Info`[](https://github.com/OpenZeppelin/cairo-contracts/blob/release-v3.0.0-alpha.1/packages/interfaces/src/token/erc2981.cairo)
+
```rust
use openzeppelin_interfaces::erc2981::IERC2981Info;
@@ -43,10 +58,13 @@ Functions
- [`default_royalty()`](#IERC2981Info-default_royalty)
- [`token_royalty(token_id)`](#IERC2981Info-token_royalty)
-#### [](#IERC2981Info-Functions)Functions
-
-#### [](#IERC2981Info-default_royalty)`default_royalty() → (ContractAddress, u128, u128)` external
+#### [](#IERC2981Info-Functions)Functions [!toc]
+
Returns the royalty information that all ids in this contract will default to.
The returned tuple contains:
@@ -54,9 +72,13 @@ The returned tuple contains:
- `t.0`: The receiver of the royalty payment.
- `t.1`: The numerator of the royalty fraction.
- `t.2`: The denominator of the royalty fraction.
+
-#### [](#IERC2981Info-token_royalty)`token_royalty(token_id: u256) → (ContractAddress, u128, u128)` external
-
+
Returns the royalty information specific to a token.
The returned tuple contains:
@@ -64,8 +86,11 @@ The returned tuple contains:
- `t.0`: The receiver of the royalty payment.
- `t.1`: The numerator of the royalty fraction.
- `t.2`: The denominator of the royalty fraction.
+
-### [](#IERC2981Admin)`IERC2981Admin`[](https://github.com/OpenZeppelin/cairo-contracts/blob/release-v3.0.0-alpha.1/packages/interfaces/src/token/erc2981.cairo)
+### [](#IERC2981Admin)`IERC2981Admin` [toc] [#IERC2981Admin]
+
+
```rust
use openzeppelin_interfaces::erc2981::IERC2981Admin;
@@ -80,27 +105,45 @@ Functions
- [`set_token_royalty(token_id, receiver, fee_numerator)`](#IERC2981Admin-set_token_royalty)
- [`reset_token_royalty(token_id)`](#IERC2981Admin-reset_token_royalty)
-#### [](#IERC2981Admin-Functions)Functions
-
-#### [](#IERC2981Admin-set_default_royalty)`set_default_royalty(receiver: ContractAddress, fee_numerator: u128)` external
+#### [](#IERC2981Admin-Functions)Functions [!toc]
+
Sets the royalty information that all ids in this contract will default to.
+
-#### [](#IERC2981Admin-delete_default_royalty)`delete_default_royalty()` external
-
+
Sets the default royalty percentage and receiver to zero.
+
-#### [](#IERC2981Admin-set_token_royalty)`set_token_royalty(token_id: u256, receiver: ContractAddress, fee_numerator: u128)` external
-
+
Sets the royalty information for a specific token id that takes precedence over the global default.
+
-#### [](#IERC2981Admin-reset_token_royalty)`reset_token_royalty(token_id: u256)` external
-
+
Resets royalty information for the token id back to unset.
+
## [](#erc2981)ERC2981
-### [](#ERC2981Component)`ERC2981Component`[](https://github.com/OpenZeppelin/cairo-contracts/blob/release-v3.0.0-alpha.1/packages/token/src/common/erc2981/erc2981.cairo)
+### [](#ERC2981Component)`ERC2981Component` [toc] [#ERC2981Component]
+
+
```rust
use openzeppelin_token::common::erc2981::ERC2981Component;
@@ -108,7 +151,7 @@ use openzeppelin_token::common::erc2981::ERC2981Component;
ERC2981 component extending [IERC2981](#IERC2981).
-[Immutable Component Config](../components#immutable_config)
+[Immutable Component Config](../components#immutable-config)
constants
@@ -155,35 +198,50 @@ InternalImpl
- [`_set_token_royalty(self, token_id, receiver, fee_numerator)`](#ERC2981Component-_set_token_royalty)
- [`_reset_token_royalty(self, token_id)`](#ERC2981Component-_reset_token_royalty)
-#### [](#ERC2981Component-Immutable-Config)Immutable Config constants
-
-#### [](#ERC2981Component-IC-FEE_DENOMINATOR)`FEE_DENOMINATOR: u128` constant
+#### [](#ERC2981Component-Immutable-Config)Immutable Config constants [!toc]
+
The denominator with which to interpret the fee set in `_set_token_royalty` and `_set_default_royalty` as a fraction of the sale price.
+
-#### [](#ERC2981Component-IC-validate)`validate()` internal
-
-Validates the given implementation of the contract’s configuration.
+
+Validates the given implementation of the contract's configuration.
Requirements:
- `FEE_DENOMINATOR` must be greater than 0.
-This function is called by the contract’s initializer.
+This function is called by the contract's initializer.
+
-#### [](#ERC2981Component-Embeddable-functions)Embeddable functions
-
-#### [](#ERC2981Component-royalty_info)`royalty_info(@self: ContractState, token_id: u256, sale_price: u256) → (ContractAddress, u256)` external
+#### [](#ERC2981Component-Embeddable-functions)Embeddable functions [!toc]
+
Returns how much royalty is owed and to whom, based on a sale price that may be denominated in any unit of exchange. The royalty amount is denominated and should be paid in that same unit of exchange.
The returned tuple contains:
- `t.0`: The receiver of the royalty payment.
- `t.1`: The amount of royalty payment.
+
-#### [](#ERC2981InfoImpl-default_royalty)`default_royalty(@self: ContractState) → (ContractAddress, u128, u128)` external
-
+
Returns the royalty information that all ids in this contract will default to.
The returned tuple contains:
@@ -191,9 +249,13 @@ The returned tuple contains:
- `t.0`: The receiver of the royalty payment.
- `t.1`: The numerator of the royalty fraction.
- `t.2`: The denominator of the royalty fraction.
+
-#### [](#ERC2981InfoImpl-token_royalty)`token_royalty(self: @ContractState, token_id: u256) → (ContractAddress, u128, u128)` external
-
+
Returns the royalty information specific to a token. If no specific royalty information is set for the token, the default is returned.
The returned tuple contains:
@@ -201,13 +263,17 @@ The returned tuple contains:
- `t.0`: The receiver of the royalty payment.
- `t.1`: The numerator of the royalty fraction.
- `t.2`: The denominator of the royalty fraction.
+
-#### [](#ERC2981Component-ERC2981AdminOwnableImpl)ERC2981AdminOwnableImpl
-
-Provides admin functions for managing royalty settings that are restricted to be called only by the contract’s owner. Requires the contract to implement [OwnableComponent](access#OwnableComponent).
+#### [](#ERC2981Component-ERC2981AdminOwnableImpl)ERC2981AdminOwnableImpl [!toc]
-#### [](#ERC2981AdminOwnableImpl-set_default_royalty)`set_default_royalty(ref self: ContractState, receiver: ContractAddress, fee_numerator: u128)` external
+Provides admin functions for managing royalty settings that are restricted to be called only by the contract's owner. Requires the contract to implement [OwnableComponent](access#OwnableComponent).
+
Sets the royalty information that all ids in this contract will default to.
Requirements:
@@ -215,17 +281,25 @@ Requirements:
- The caller is the contract owner.
- `receiver` cannot be the zero address.
- `fee_numerator` cannot be greater than the fee denominator.
+
-#### [](#ERC2981AdminOwnableImpl-delete_default_royalty)`delete_default_royalty(ref self: ContractState)` external
-
+
Sets the default royalty percentage and receiver to zero.
Requirements:
- The caller is the contract owner.
+
-#### [](#ERC2981AdminOwnableImpl-set_token_royalty)`set_token_royalty(ref self: ContractState, token_id: u256, receiver: ContractAddress, fee_numerator: u128)` external
-
+
Sets the royalty information for a specific token id that takes precedence over the global default.
Requirements:
@@ -233,25 +307,37 @@ Requirements:
- The caller is the contract owner.
- `receiver` cannot be the zero address.
- `fee_numerator` cannot be greater than the fee denominator.
+
-#### [](#ERC2981AdminOwnableImpl-reset_token_royalty)`reset_token_royalty(ref self: ContractState, token_id: u256)` external
-
+
Resets royalty information for the token id back to unset.
Requirements:
- The caller is the contract owner.
+
-#### [](#ERC2981Component-ERC2981AdminAccessControlImpl)ERC2981AdminAccessControlImpl
+#### [](#ERC2981Component-ERC2981AdminAccessControlImpl)ERC2981AdminAccessControlImpl [!toc]
Provides admin functions for managing royalty settings that require `ROYALTY_ADMIN_ROLE` to be granted to the caller. Requires the contract to implement [AccessControlComponent](access#AccessControlComponent).
-#### [](#ERC2981AdminAccessControlImpl-ROYALTY_ADMIN_ROLE)`ROYALTY_ADMIN_ROLE: felt252` constant
-
+
Role for the admin responsible for managing royalty settings.
+
-#### [](#ERC2981AdminAccessControlImpl-set_default_royalty)`set_default_royalty(ref self: ContractState, receiver: ContractAddress, fee_numerator: u128)` external
-
+
Sets the royalty information that all ids in this contract will default to.
Requirements:
@@ -259,17 +345,25 @@ Requirements:
- The caller must have `ROYALTY_ADMIN_ROLE` role.
- `receiver` cannot be the zero address.
- `fee_numerator` cannot be greater than the fee denominator.
+
-#### [](#ERC2981AdminAccessControlImpl-delete_default_royalty)`delete_default_royalty(ref self: ContractState)` external
-
+
Sets the default royalty percentage and receiver to zero.
Requirements:
- The caller must have `ROYALTY_ADMIN_ROLE` role.
+
-#### [](#ERC2981AdminAccessControlImpl-set_token_royalty)`set_token_royalty(ref self: ContractState, token_id: u256, receiver: ContractAddress, fee_numerator: u128)` external
-
+
Sets the royalty information for a specific token id that takes precedence over the global default.
Requirements:
@@ -277,19 +371,27 @@ Requirements:
- The caller must have `ROYALTY_ADMIN_ROLE` role.
- `receiver` cannot be the zero address.
- `fee_numerator` cannot be greater than the fee denominator.
+
-#### [](#ERC2981AdminAccessControlImpl-reset_token_royalty)`reset_token_royalty(ref self: ContractState, token_id: u256)` external
-
+
Resets royalty information for the token id back to unset.
Requirements:
- The caller must have `ROYALTY_ADMIN_ROLE` role.
+
-#### [](#ERC2981Component-Internal-functions)Internal functions
-
-#### [](#ERC2981Component-initializer)`initializer(ref self: ContractState, default_receiver: ContractAddress, default_royalty_fraction: u128)` internal
+#### [](#ERC2981Component-Internal-functions)Internal functions [!toc]
+
Initializes the contract by setting the default royalty and registering the supported interface.
Requirements:
@@ -298,10 +400,14 @@ Requirements:
- `default_royalty_fraction` cannot be greater than the fee denominator.
- The fee denominator must be greater than 0.
-The fee denominator is set by the contract using the [Immutable Component Config](../components#immutable_config).
-
-#### [](#ERC2981Component-_default_royalty)`_default_royalty(self: @ContractState) → (ContractAddress, u128, u128)` internal
+The fee denominator is set by the contract using the [Immutable Component Config](../components#immutable-config).
+
+
Returns the royalty information that all ids in this contract will default to.
The returned tuple contains:
@@ -309,22 +415,34 @@ The returned tuple contains:
- `t.0`: The receiver of the royalty payment.
- `t.1`: The numerator of the royalty fraction.
- `t.2`: The denominator of the royalty fraction.
+
-#### [](#ERC2981Component-_set_default_royalty)`_set_default_royalty(ref self: ContractState, receiver: ContractAddress, fee_numerator: u128)` internal
-
+
Sets the royalty information that all ids in this contract will default to.
Requirements:
- `receiver` cannot be the zero address.
- `fee_numerator` cannot be greater than the fee denominator.
+
-#### [](#ERC2981Component-_delete_default_royalty)`_delete_default_royalty(ref self: ContractState)` internal
-
+
Sets the default royalty percentage and receiver to zero.
+
-#### [](#ERC2981Component-_token_royalty)`_token_royalty(self: @ContractState, token_id: u256) → (ContractAddress, u256, u256)` internal
-
+
Returns the royalty information that all ids in this contract will default to.
The returned tuple contains:
@@ -332,16 +450,25 @@ The returned tuple contains:
- `t.0`: The receiver of the royalty payment.
- `t.1`: The numerator of the royalty fraction.
- `t.2`: The denominator of the royalty fraction.
+
-#### [](#ERC2981Component-_set_token_royalty)`_set_token_royalty(ref self: ContractState, token_id: u256, receiver: ContractAddress, fee_numerator: u128)` internal
-
+
Sets the royalty information for a specific token id that takes precedence over the global default.
Requirements:
- `receiver` cannot be the zero address.
- `fee_numerator` cannot be greater than the fee denominator.
+
-#### [](#ERC2981Component-_reset_token_royalty)`_reset_token_royalty(ref self: ContractState, token_id: u256)` internal
-
+
Resets royalty information for the token id back to unset.
+
diff --git a/content/contracts-cairo/api/udc.mdx b/content/contracts-cairo/api/udc.mdx
index fe52b23..742fd90 100644
--- a/content/contracts-cairo/api/udc.mdx
+++ b/content/contracts-cairo/api/udc.mdx
@@ -2,13 +2,20 @@
title: Universal Deployer
---
+import { UMBRELLA_VERSION } from "../utils/constants.js";
+
Reference of the Universal Deployer Contract (UDC) interface and preset.
## [](#interfaces)Interfaces
-Starting from version `3.x.x`, the interfaces are no longer part of the `openzeppelin_utils` package. The references documented here are contained in the `openzeppelin_interfaces` package version `v2.1.0`.
+
+Starting from version `3.x.x`, the interfaces are no longer part of the `openzeppelin_access` package. The references
+documented here are contained in the `openzeppelin_interfaces` package version `{{openzeppelin_interfaces_version}}`.
+
+
+### [](#IUniversalDeployer)`IUniversalDeployer` [toc] [#IUniversalDeployer]
-### [](#IUniversalDeployer)`IUniversalDeployer`[](https://github.com/OpenZeppelin/cairo-contracts/blob/release-v3.0.0-alpha.1/packages/interfaces/src/utils/deployments.cairo)
+
```rust
use openzeppelin_interfaces::deployments::IUniversalDeployer;
@@ -22,21 +29,31 @@ Events
- [`ContractDeployed(address, deployer, not_from_zero, class_hash, calldata, salt)`](#IUniversalDeployer-ContractDeployed)
-#### [](#IUniversalDeployer-Functions)Functions
-
-#### [](#IUniversalDeployer-deploy_contract)`deploy_contract(class_hash: ClassHash, salt: felt252, not_from_zero: bool, calldata: Span) → ContractAddress` external
+#### [](#IUniversalDeployer-Functions)Functions [!toc]
+
Deploys a contract through the Universal Deployer Contract.
+
-#### [](#IUniversalDeployer-Events)Events
-
-#### [](#IUniversalDeployer-ContractDeployed)`ContractDeployed(address: ContractAddress, deployer: ContractAddress, not_from_zero: bool, class_hash: ClassHash, calldata: Span, salt: felt252)` event
+#### [](#IUniversalDeployer-Events)Events [!toc]
+
Emitted when `deployer` deploys a contract through the Universal Deployer Contract.
+
## [](#presets)Presets
-### [](#UniversalDeployer)`UniversalDeployer`[](https://github.com/OpenZeppelin/cairo-contracts/blob/release-v3.0.0-alpha.1/packages/presets/src/universal_deployer.cairo)
+### [](#UniversalDeployer)`UniversalDeployer` [toc] [#UniversalDeployer]
+
+
```rust
use openzeppelin_presets::UniversalDeployer;
@@ -46,7 +63,9 @@ The standard Universal Deployer Contract.
[Sierra class hash](../presets)
-0x037f5901deb2b20bf5b2ddb04f6c770a7c5581edd68aa49f199cf74dfaf03c06
+```text
+{{UniversalDeployerClassHash}}
+```
Embedded Implementations
@@ -54,12 +73,18 @@ UniversalDeployerImpl
- [`deploy_contract(self, address, deployer, not_from_zero, class_hash, calldata, salt)`](#UniversalDeployer-deploy_contract)
-#### [](#UniversalDeployer-deploy_contract)`deploy_contract(ref self: ContractState, address: ContractAddress, deployer: ContractAddress, not_from_zero: bool, class_hash: ClassHash, calldata: Span, salt: felt252) -> ContractAddress` external
+#### [](#UniversalDeployer-External-functions)External functions [!toc]
+
Deploys a contract through the Universal Deployer Contract.
-When `not_from_zero` is `true`, `salt` is hashed with the caller address and the modified salt is passed to the inner `deploy_syscall`. This type of deployment is [origin-dependent](../udc#origin_dependent).
+When `not_from_zero` is `true`, `salt` is hashed with the caller address and the modified salt is passed to the inner `deploy_syscall`. This type of deployment is [origin-dependent](../udc#origin-dependent).
-When `not_from_zero` is `false`, the deployment type is [origin-independent](../udc#origin_independent).
+When `not_from_zero` is `false`, the deployment type is [origin-independent](../udc#origin-independent).
Emits an [ContractDeployed](#IUniversalDeployer-ContractDeployed) event.
+
diff --git a/content/contracts-cairo/api/upgrades.mdx b/content/contracts-cairo/api/upgrades.mdx
index cae8445..b701356 100644
--- a/content/contracts-cairo/api/upgrades.mdx
+++ b/content/contracts-cairo/api/upgrades.mdx
@@ -2,13 +2,20 @@
title: Upgrades
---
+import { UMBRELLA_VERSION } from "../utils/constants.js";
+
This crate provides interfaces and utilities related to upgradeability.
## [](#interfaces)Interfaces
-Starting from version `3.x.x`, the interfaces are no longer part of the `openzeppelin_upgrades` package. The references documented here are contained in the `openzeppelin_interfaces` package version `v2.1.0`.
+
+Starting from version `3.x.x`, the interfaces are no longer part of the `openzeppelin_access` package. The references
+documented here are contained in the `openzeppelin_interfaces` package version `{{openzeppelin_interfaces_version}}`.
+
+
+### [](#IUpgradeable)`IUpgradeable` [toc] [#IUpgradeable]
-### [](#IUpgradeable)`IUpgradeable`[](https://github.com/OpenZeppelin/cairo-contracts/blob/release-v3.0.0-alpha.1/packages/interfaces/src/upgrades.cairo)
+
```rust
use openzeppelin_interfaces::upgrades::IUpgradeable;
@@ -20,15 +27,21 @@ Functions
- [`upgrade(new_class_hash)`](#IUpgradeable-upgrade)
-#### [](#IUpgradeable-Functions)Functions
-
-#### [](#IUpgradeable-upgrade)`upgrade(new_class_hash: ClassHash)` external
+#### [](#IUpgradeable-Functions)Functions [!toc]
+
Upgrades the contract code by updating its [class hash](https://docs.starknet.io/architecture-and-concepts/smart-contracts/class-hash/).
This function is usually protected by an [Access Control](../access) mechanism.
+
-### [](#IUpgradeAndCall)`IUpgradeAndCall`[](https://github.com/OpenZeppelin/cairo-contracts/blob/release-v3.0.0-alpha.1/packages/interfaces/src/upgrades.cairo)
+### [](#IUpgradeAndCall)`IUpgradeAndCall` [toc] [#IUpgradeAndCall]
+
+
```rust
use openzeppelin_interfaces::upgrades::IUpgradeAndCall;
@@ -40,17 +53,23 @@ Functions
- [`upgrade_and_call(new_class_hash, selector, calldata)`](#IUpgradeAndCall-upgrade_and_call)
-#### [](#IUpgradeAndCall-Functions)Functions
-
-#### [](#IUpgradeAndCall-upgrade_and_call)`upgrade_and_call(new_class_hash: ClassHash, selector: felt252, calldata: Span) → Span` external
+#### [](#IUpgradeAndCall-Functions)Functions [!toc]
+
Upgrades the contract code by updating its [class hash](https://docs.starknet.io/architecture-and-concepts/smart-contracts/class-hash/) and calls `selector` with the upgraded context.
This function is usually protected by an [Access Control](../access) mechanism.
+
## [](#core)Core
-### [](#UpgradeableComponent)`UpgradeableComponent`[](https://github.com/OpenZeppelin/cairo-contracts/blob/release-v3.0.0-alpha.1/packages/upgrades/src/upgradeable.cairo)
+### [](#UpgradeableComponent)`UpgradeableComponent` [toc] [#UpgradeableComponent]
+
+
```rust
use openzeppelin_upgrades::upgradeable::UpgradeableComponent;
@@ -69,10 +88,13 @@ Events
- [`Upgraded(class_hash)`](#UpgradeableComponent-Upgraded)
-#### [](#UpgradeableComponent-Internal-Functions)Internal Functions
-
-#### [](#UpgradeableComponent-upgrade)`upgrade(ref self: ContractState, new_class_hash: ClassHash)` internal
+#### [](#UpgradeableComponent-Internal-Functions)Internal Functions [!toc]
+
Upgrades the contract by updating the contract [class hash](https://docs.starknet.io/architecture-and-concepts/smart-contracts/class-hash/).
Requirements:
@@ -80,10 +102,14 @@ Requirements:
- `new_class_hash` must be different from zero.
Emits an [Upgraded](#UpgradeableComponent-Upgraded) event.
+
-#### [](#UpgradeableComponent-upgrade_and_call)`upgrade_and_call(ref self: ContractState, new_class_hash: ClassHash, selector: felt252, calldata: Span) → Span` internal
-
-Replaces the contract’s class hash with `new_class_hash` and then calls `selector` from the upgraded context. This function returns the unwrapped `call_contract_syscall` return value(s), if available, of the `selector` call.
+
+Replaces the contract's class hash with `new_class_hash` and then calls `selector` from the upgraded context. This function returns the unwrapped `call_contract_syscall` return value(s), if available, of the `selector` call.
Requirements:
@@ -91,12 +117,17 @@ Requirements:
The function call comes from the upgraded contract itself and not the account.
-A similar behavior to `upgrade_and_call` can also be achieved with a list of calls from an account since the [SNIP-6](https://github.com/starknet-io/SNIPs/blob/main/SNIPS/snip-6.md) account standard supports multicall. An account can execute a list of calls with [upgrade](#IUpgradeable-upgrade) being the first element in the list and the extra function call as the second. With this approach, the calls will execute from the account’s context and can’t be front-ran.
+A similar behavior to `upgrade_and_call` can also be achieved with a list of calls from an account since the [SNIP-6](https://github.com/starknet-io/SNIPs/blob/main/SNIPS/snip-6.md) account standard supports multicall. An account can execute a list of calls with [upgrade](#IUpgradeable-upgrade) being the first element in the list and the extra function call as the second. With this approach, the calls will execute from the account's context and can't be front-ran.
Emits an [Upgraded](#UpgradeableComponent-Upgraded) event.
+
-#### [](#UpgradeableComponent-Events)Events
-
-#### [](#UpgradeableComponent-Upgraded)`Upgraded(class_hash: ClassHash)` event
+#### [](#UpgradeableComponent-Events)Events [!toc]
+
Emitted when the [class hash](https://docs.starknet.io/architecture-and-concepts/smart-contracts/class-hash/) is upgraded.
+
diff --git a/content/contracts-cairo/api/utilities.mdx b/content/contracts-cairo/api/utilities.mdx
index 9cf54da..7aef39e 100644
--- a/content/contracts-cairo/api/utilities.mdx
+++ b/content/contracts-cairo/api/utilities.mdx
@@ -2,11 +2,15 @@
title: Utilities
---
+import { UMBRELLA_VERSION } from "../utils/constants.js";
+
This crate provides miscellaneous components and libraries containing utility functions to handle common tasks.
-## [](#core)Core
+## Core
+
+### `utils` [toc] [#utils]
-### [](#utils)`utils`
+
```rust
use openzeppelin_utils;
@@ -24,29 +28,51 @@ Inner modules
- [`contract_clock`](#utils-contract_clock)
- [`serde`](#utils-serde)
-#### [](#utils-Inner-Modules)Inner modules
-
-#### [](#utils-cryptography)`cryptography` module
+#### Inner modules [!toc] [#utils-Inner-Modules]
+
See [`openzeppelin_utils::cryptography`](#cryptography).
+
-#### [](#utils-deployments)`deployments` module
-
+
See [`openzeppelin_utils::deployments`](#deployments).
+
-#### [](#utils-math)`math` module
-
+
See [`openzeppelin_utils::math`](#math).
+
-#### [](#utils-contract_clock)`contract_clock` module
-
+
See [`openzeppelin_utils::contract_clock`](#contract_clock).
+
-#### [](#utils-serde)`serde` module
-
+
See [`openzeppelin_utils::serde`](#serde).
+
-### [](#cryptography)`cryptography`
+### `cryptography` [toc] [#cryptography]
+
+
```rust
use openzeppelin_utils::cryptography;
@@ -61,17 +87,27 @@ Inner modules
- [`nonces`](#cryptography-nonces)
- [`snip12`](#cryptography-snip12)
-#### [](#inner_modules)Inner modules
-
-#### [](#cryptography-nonces)`nonces` module
+#### Inner modules [!toc] [#cryptography-Inner-Modules]
+
See [`openzeppelin_utils::cryptography::nonces::NoncesComponent`](#NoncesComponent).
+
-#### [](#cryptography-snip12)`snip12` module
-
+
See [`openzeppelin_utils::cryptography::snip12`](#snip12).
+
+
+### `deployments` [toc] [#deployments]
-### [](#deployments)`deployments`
+
```rust
use openzeppelin_utils::deployments;
@@ -91,31 +127,49 @@ Functions
- [`compute_hash_on_elements(data)`](#deployments-compute_hash_on_elements)
- [`calculate_contract_address_from_udc(salt, class_hash, constructor_calldata, deployer_info)`](#deployments-calculate_contract_address_from_udc)
-#### [](#deployments-Structs)Structs
-
-#### [](#deployments-DeployerInfo)`DeployerInfo(caller_address: ContractAddress, udc_address: ContractAddress)` struct
+#### Structs [!toc] [#deployments-Structs]
+
Struct containing arguments necessary in [utils::calculate\_contract\_address\_from\_udc](#deployments-calculate_contract_address_from_udc) for origin-dependent deployment calculations.
+
-#### [](#deployments-Functions)Functions
-
-#### [](#deployments-calculate_contract_address_from_deploy_syscall)`calculate_contract_address_from_deploy_syscall(salt: felt252, class_hash: ClassHash, constructor_calldata: Span, deployer_address: ContractAddress) → ContractAddress` function
+#### Functions [!toc] [#deployments-Functions]
+
Returns the contract address when passing the given arguments to [deploy\_syscall](https://docs.starknet.io/architecture-and-concepts/smart-contracts/system-calls-cairo1/#deploy).
+
-#### [](#deployments-compute_hash_on_elements)`compute_hash_on_elements(data: Span) → felt252` function
-
+
Creates a Pedersen hash chain with the elements of `data` and returns the finalized hash.
+
-#### [](#deployments-calculate_contract_address_from_udc)`calculate_contract_address_from_udc(salt: felt252, class_hash: ClassHash, constructor_calldata: Span, deployer_info: Option) → ContractAddress` function
-
+
Returns the calculated contract address for UDC deployments.
Origin-independent deployments (deployed from zero) should pass `Option::None` as `deployer_info`.
Origin-dependent deployments hash `salt` with `caller_address` (member of [DeployerInfo](#deployments-DeployerInfo)) and pass the hashed salt to the inner [deploy\_syscall](https://docs.starknet.io/architecture-and-concepts/smart-contracts/system-calls-cairo1/#deploy) as the `contract_address_salt` argument.
+
+
+### `math` [toc] [#math]
-### [](#math)`math`
+
```rust
use openzeppelin_utils::math;
@@ -129,15 +183,20 @@ Functions
- [`average(a, b)`](#math-average)
-#### [](#math-Functions)Functions
-
-#### [](#math-average)`average(a: T, b: T) → T` function
+#### Functions [!toc] [#math-Functions]
+
Returns the average of two unsigned integers. The result is rounded down.
`T` is a generic value matching different numeric implementations.
+
-### [](#contract_clock)`contract_clock`
+### `contract_clock` [toc] [#contract_clock]
+
```rust
use openzeppelin_utils::contract_clock;
@@ -154,7 +213,8 @@ Implementations
- [`ERC6372BlockNumberClock`](#contract_clock-ERC6372BlockNumberClock)
- [`ERC6372TimestampClock`](#contract_clock-ERC6372TimestampClock)
-#### [](#ERC6372Clock)`ERC6372Clock` [github-icon](https://github.com/OpenZeppelin/cairo-contracts/blob/votes-erc6372/packages/utils/src/contract_clock.cairo)
+#### `ERC6372Clock` [toc] [#ERC6372Clock]
+
```rust
use openzeppelin_utils::contract_clock::ERC6372Clock;
@@ -167,35 +227,53 @@ Functions
- [`clock()`](#ERC6372Clock-clock)
- [`CLOCK_MODE()`](#ERC6372Clock-CLOCK_MODE)
-#### [](#ERC6372Clock-Functions)Functions
-
-#### [](#ERC6372Clock-clock)`clock() → u64` external
+#### Functions [!toc] [#ERC6372Clock-Functions]
-Returns the current timepoint determined by the contract’s operational mode, intended for use in time-sensitive logic.
+
+Returns the current timepoint determined by the contract's operational mode, intended for use in time-sensitive logic.
Requirements:
- This function MUST always be non-decreasing.
+
-#### [](#ERC6372Clock-CLOCK_MODE)`CLOCK_MODE() → ByteArray` external
-
+
Returns a description of the clock the contract is operating in.
Requirements:
- The output MUST be formatted like a URL query string, decodable in standard JavaScript.
+
-#### [](#contract_clock-Impls)Implementations
-
-#### [](#contract_clock-ERC6372BlockNumberClock)`ERC6372BlockNumberClock` impl
+#### Implementations [!toc] [#contract_clock-Impls]
+
Implementation of the `ERC6372Clock` trait that uses the block number as its clock reference.
+
-#### [](#contract_clock-ERC6372TimestampClock)`ERC6372TimestampClock` impl
-
+
Implementation of the `ERC6372Clock` trait that uses the block timestamp as its clock reference.
+
-### [](#serde)`serde`
+### `serde` [toc] [#serde]
+
+
```rust
use openzeppelin_utils::serde;
@@ -209,10 +287,13 @@ Traits
- [`SerializedAppend`](#serde-SerializedAppend)
-#### [](#serde-Traits)Traits
-
-#### [](#serde-SerializedAppend)`SerializedAppend` trait
+#### Traits [!toc] [#serde-Traits]
+
Importing this trait allows the ability to append a serialized representation of a Cairo data structure already implementing the `Serde` trait to a `felt252` buffer.
Usage example:
@@ -230,10 +311,13 @@ fn to_calldata(recipient: ContractAddress, amount: u256) -> Array {
```
Note that the `append_serde` method is automatically available for arrays of felts, and it accepts any data structure that implements the `Serde` trait.
+
-## [](#cryptography_2)Cryptography
+## Cryptography [#cryptography-toc]
-### [](#NoncesComponent)`NoncesComponent`
+### `NoncesComponent` [toc] [#NoncesComponent]
+
+
```rust
use openzeppelin_utils::cryptography::nonces::NoncesComponent;
@@ -254,25 +338,39 @@ InternalImpl
- [`use_nonce(self, owner)`](#NoncesComponent-use_nonce)
- [`use_checked_nonce(self, owner, nonce)`](#NoncesComponent-use_checked_nonce)
-#### [](#NoncesComponent-Embeddable-Functions)Embeddable functions
-
-#### [](#NoncesComponent-nonces)`nonces(self: @ContractState, owner: ContractAddress) → felt252` external
+#### Embeddable functions [!toc] [#NoncesComponent-Embeddable-Functions]
+
Returns the next unused nonce for an `owner`.
+
-#### [](#NoncesComponent-Internal-Functions)Internal functions
-
-#### [](#NoncesComponent-use_nonce)`use_nonce(ref self: ComponentState, owner: ContractAddress) → felt252` internal
+#### Internal functions [!toc] [#NoncesComponent-Internal-Functions]
+
Consumes a nonce, returns the current value, and increments nonce.
For each account, the nonce has an initial value of 0, can only be incremented by one, and cannot be decremented or reset. This guarantees that the nonce never overflows.
+
-#### [](#NoncesComponent-use_checked_nonce)`use_checked_nonce(ref self: ComponentState, owner: ContractAddress, nonce: felt252) → felt252` internal
-
+
Same as `use_nonce` but checking that `nonce` is the next valid one for `owner`.
+
+
+### `snip12` [toc] [#snip12]
-### [](#snip12)`snip12`
+
```rust
use openzeppelin_utils::snip12;
diff --git a/content/contracts-cairo/backwards-compatibility.mdx b/content/contracts-cairo/backwards-compatibility.mdx
index b2a7387..3c63bfc 100644
--- a/content/contracts-cairo/backwards-compatibility.mdx
+++ b/content/contracts-cairo/backwards-compatibility.mdx
@@ -4,7 +4,7 @@ title: Backwards Compatibility
OpenZeppelin Contracts uses semantic versioning to communicate backwards compatibility of its API and storage layout. Patch and minor updates will generally be backwards compatible, with rare exceptions as detailed below. Major updates should be assumed incompatible with previous releases. On this page, we provide details about these guarantees.
-Bear in mind that while releasing versions, we treat minors as majors and patches as minors, in accordance with semantic versioning. This means that `v2.1.0` could be adding features to `v3.0.0-alpha.2`, while `v3.0.0` would be considered a breaking release.
+Bear in mind that while releasing versions, we treat minors as majors and patches as minors, in accordance with semantic versioning. This means that `v2.1.0` could be adding features to `v2.0.0`, while `v3.0.0` would be considered a breaking release.
## API
@@ -28,7 +28,7 @@ In the case of breaking "upgrade compatibility", an entry to the changelog will
## Storage layout
-Patch updates will always preserve storage layout compatibility, and after `v3.0.0-alpha.2` minors will too. This means that a live contract can be upgraded from one minor to another without corrupting the storage layout. In some cases it may be necessary to initialize new state variables when upgrading, although we expect this to be infrequent.
+Patch updates will always preserve storage layout compatibility, and after `1.0.0` minors will too. This means that a live contract can be upgraded from one minor to another without corrupting the storage layout. In some cases it may be necessary to initialize new state variables when upgrading, although we expect this to be infrequent.
## Cairo version
diff --git a/content/contracts-cairo/components.mdx b/content/contracts-cairo/components.mdx
index f7b24b2..4846971 100644
--- a/content/contracts-cairo/components.mdx
+++ b/content/contracts-cairo/components.mdx
@@ -8,8 +8,11 @@ Starknet components are separate modules that contain storage, events, and imple
Components themselves cannot be declared or deployed.
Another way to think of components is that they are abstract modules that must be instantiated.
+[shamans_post]: https://community.starknet.io/t/cairo-components/101136#components-1
+[cairo_book]: https://book.cairo-lang.org/ch103-02-00-composability-and-components.html
+
-For more information on the construction and design of Starknet components, see the [Starknet Shamans post](https://community.starknet.io/t/cairo-components/101136#components-1) and the [Cairo book](https://book.cairo-lang.org/ch103-02-00-composability-and-components.html).
+For more information on the construction and design of Starknet components, see the [Starknet Shamans post][shamans_post] and the [Cairo book][cairo_book].
## Building a contract
@@ -29,7 +32,7 @@ mod MyContract {
}
```
-The `path` argument should be the imported component itself (in this case, [InitializableComponent](/security#initializable)).
+The `path` argument should be the imported component itself (in this case, [InitializableComponent](security#initializable)).
The `storage` and `event` arguments are the variable names that will be set in the `Storage` struct and `Event` enum, respectively.
Note that even if the component doesn’t define any events, the compiler will still create an empty event enum inside the component module.
@@ -57,7 +60,7 @@ mod MyContract {
The `#[substorage(v0)]` attribute must be included for each component in the `Storage` trait.
This allows the contract to have indirect access to the component’s storage.
-See [Accessing component storage](#accessing_component_storage) for more on this.
+See [Accessing component storage](#accessing-component-storage) for more on this.
The `#[flat]` attribute for events in the `Event` enum, however, is not required.
For component events, the first key in the event log is the component ID.
@@ -125,17 +128,17 @@ mod MyContract {
`InitializableImpl` defines the `is_initialized` method in the component.
By adding the embed attribute, `is_initialized` becomes a contract entrypoint for `MyContract`.
-
-
+
Embeddable implementations, when available in this library’s components, are segregated from the internal component implementation which makes it easier to safely expose.
-Components also separate granular implementations from [mixin](/components#mixins) implementations.
+Components also separate granular implementations from [mixin](#mixins) implementations.
The API documentation design reflects these groupings.
-See [ERC20Component](/api/erc20#ERC20Component) as an example which includes:
+See [ERC20Component](api/erc20#erc20component) as an example which includes:
* **Embeddable Mixin Implementation**
* **Embeddable Implementations**
* **Internal Implementations**
* **Events**
+
### Mixins
@@ -229,13 +232,15 @@ mod Account {
Failing to use a component’s `initializer` can result in irreparable contract deployments.
+
+Always read the API Reference documentation for each integrated component.
-Always read the API documentation for each integrated component.
+
Some components require some sort of setup upon construction.
Usually, this would be a job for a constructor; however, components themselves cannot implement constructors.
Components instead offer ``initializer``s within their `InternalImpl` to call from the contract’s constructor.
-Let’s look at how a contract would integrate [OwnableComponent](/api/access#OwnableComponent):
+Let’s look at how a contract would integrate [OwnableComponent](api/access#OwnableComponent):
```rust
#[starknet::contract]
@@ -280,7 +285,7 @@ constants declared in the component, customizing its functionality.
The Immutable Component Config standard is defined in the SRC-107.
-Here’s an example of how to use the Immutable Component Config pattern with the [ERC2981Component](/api/token_common#ERC2981Component):
+Here’s an example of how to use the Immutable Component Config pattern with the [ERC2981Component](api/token_common#erc2981component):
```rust
#[starknet::contract]
@@ -388,7 +393,7 @@ on how to use this function, refer to the [validate section of the SRC-107](http
Some components include dependencies of other components.
Contracts that integrate components with dependencies must also include the component dependency.
-For instance, [AccessControlComponent](/api/access#AccessControlComponent) depends on [SRC5Component](/api/introspection#SRC5Component).
+For instance, [AccessControlComponent](api/access#accesscontrolcomponent) depends on [SRC5Component](api/introspection#src5component).
Creating a contract with `AccessControlComponent` should look like this:
```rust
@@ -438,14 +443,16 @@ mod MyContract {
Customizing implementations and accessing component storage can potentially corrupt the state, bypass security checks, and undermine the component logic.
-
+
**Exercise extreme caution**. See [Security](#security).
+
+
### Hooks
Hooks are entrypoints to the business logic of a token component that are accessible at the contract level.
This allows contracts to insert additional behaviors before and/or after token transfers (including mints and burns).
-Prior to hooks, extending functionality required contracts to create [custom implementations](#custom_implementations).
+Prior to hooks, extending functionality required contracts to create [custom implementations](#custom-implementations).
All token components include a generic hooks trait that include empty default functions.
When creating a token contract, the using contract must create an implementation of the hooks trait.
@@ -560,7 +567,7 @@ mod ERC20Pausable {
The first thing to notice is that the contract imports the interfaces of the implementations that will be customized.
These will be used in the next code example.
-Next, the contract includes the [ERC20Component](/api/erc20#ERC20Component) implementations; however, `ERC20Impl` and `ERC20CamelOnlyImpl` are **not** embedded.
+Next, the contract includes the [ERC20Component](api/erc20#erc20component) implementations; however, `ERC20Impl` and `ERC20CamelOnlyImpl` are **not** embedded.
Instead, we want to expose our custom implementation of an interface.
The following example shows the pausable logic integrated into the ERC20 implementations:
diff --git a/content/contracts-cairo/erc1155.mdx b/content/contracts-cairo/erc1155.mdx
index 355c5b8..4fd7913 100644
--- a/content/contracts-cairo/erc1155.mdx
+++ b/content/contracts-cairo/erc1155.mdx
@@ -76,10 +76,10 @@ mod MyERC1155 {
## Interface
-The following interface represents the full ABI of the Contracts for Cairo [ERC1155Component](/api/erc1155#ERC1155Component).
-The interface includes the [IERC1155](/api/erc1155#IERC1155) standard interface and the optional [IERC1155MetadataURI](/api/erc1155#IERC1155MetadataURI) interface together with [ISRC5](/api/introspection#ISRC5).
+The following interface represents the full ABI of the Contracts for Cairo [ERC1155Component](api/erc1155#ERC1155Component).
+The interface includes the [IERC1155](api/erc1155#IERC1155) standard interface and the optional [IERC1155MetadataURI](api/erc1155#IERC1155MetadataURI) interface together with [ISRC5](api/introspection#ISRC5).
-To support older token deployments, as mentioned in [Dual interfaces](interfaces#dual_interfaces), the component also includes implementations of the interface written in camelCase.
+To support older token deployments, as mentioned in [Dual interfaces](guides/interfaces-and-dispatchers#dual-interfaces), the component also includes implementations of the interface written in camelCase.
```rust
#[starknet::interface]
@@ -148,15 +148,15 @@ Although Starknet is not EVM compatible, this implementation aims to be as close
## Batch operations
-Because all state is held in a single contract, it is possible to operate over multiple tokens in a single transaction very efficiently. The standard provides two functions, [balance_of_batch](/api/erc1155#IERC1155-balance_of_batch) and [safe_batch_transfer_from](/api/erc1155#IERC1155-safe_batch_transfer_from), that make querying multiple balances and transferring multiple tokens simpler and less gas-intensive. We also have [safe_transfer_from](/api/erc1155#IERC1155-safe_transfer_from) for non-batch operations.
+Because all state is held in a single contract, it is possible to operate over multiple tokens in a single transaction very efficiently. The standard provides two functions, [balance_of_batch](api/erc1155#IERC1155-balance_of_batch) and [safe_batch_transfer_from](api/erc1155#IERC1155-safe_batch_transfer_from), that make querying multiple balances and transferring multiple tokens simpler and less gas-intensive. We also have [safe_transfer_from](api/erc1155#IERC1155-safe_transfer_from) for non-batch operations.
In the spirit of the standard, we’ve also included batch operations in the non-standard functions, such as
-[batch_mint_with_acceptance_check](/api/erc1155#ERC1155Component-batch_mint_with_acceptance_check).
+[batch_mint_with_acceptance_check](api/erc1155#ERC1155Component-batch_mint_with_acceptance_check).
-While [safe_transfer_from](/api/erc1155#IERC1155-safe_transfer_from) and [safe_batch_transfer_from](/api/erc1155#IERC1155-safe_batch_transfer_from) prevent loss by checking the receiver can handle the
+While [safe_transfer_from](api/erc1155#IERC1155-safe_transfer_from) and [safe_batch_transfer_from](api/erc1155#IERC1155-safe_batch_transfer_from) prevent loss by checking the receiver can handle the
+tokens, this yields execution to the receiver which can result in a [reentrant call](security#reentrancy-guard).
-tokens, this yields execution to the receiver which can result in a [reentrant call](security#reentrancy_guard).
## Receiving tokens
@@ -185,12 +185,12 @@ pub trait IERC1155Receiver {
}
```
-Implementing the `IERC1155Receiver` interface exposes the [on_erc1155_received](/api/erc1155#IERC1155Receiver-on_erc1155_received) and [on_erc1155_batch_received](/api/erc1155#IERC1155Receiver-on_erc1155_batch_received) methods.
-When [safe_transfer_from](/api/erc1155#IERC1155-safe_transfer_from) and [safe_batch_transfer_from](/api/erc1155#IERC1155-safe_batch_transfer_from) are called, they invoke the recipient contract’s `on_erc1155_received` or `on_erc1155_batch_received` methods respectively which **must** return the [IERC1155Receiver interface ID](/api/erc1155#IERC1155Receiver).
+Implementing the `IERC1155Receiver` interface exposes the [on_erc1155_received](api/erc1155#IERC1155Receiver-on_erc1155_received) and [on_erc1155_batch_received](api/erc1155#IERC1155Receiver-on_erc1155_batch_received) methods.
+When [safe_transfer_from](api/erc1155#IERC1155-safe_transfer_from) and [safe_batch_transfer_from](api/erc1155#IERC1155-safe_batch_transfer_from) are called, they invoke the recipient contract’s `on_erc1155_received` or `on_erc1155_batch_received` methods respectively which **must** return the [IERC1155Receiver interface ID](api/erc1155#IERC1155Receiver).
Otherwise, the transaction will fail.
-For information on how to calculate interface IDs, see [Computing the interface ID](introspection#computing_the_interface_id).
+For information on how to calculate interface IDs, see [Computing the interface ID](introspection#computing-the-interface-id).
### Creating a token receiver contract
diff --git a/content/contracts-cairo/erc20.mdx b/content/contracts-cairo/erc20.mdx
index 6609067..9da87bf 100644
--- a/content/contracts-cairo/erc20.mdx
+++ b/content/contracts-cairo/erc20.mdx
@@ -7,9 +7,9 @@ The ERC20 token standard is a specification for [fungible tokens](https://docs.o
Prior to [Contracts v0.7.0](https://github.com/OpenZeppelin/cairo-contracts/releases/tag/v0.7.0), ERC20 contracts store and read `decimals` from storage; however, this implementation returns a static `18`.
-
If upgrading an older ERC20 contract that has a decimals value other than `18`, the upgraded contract **must** use a custom `decimals` implementation.
-See the [Customizing decimals](/erc20#customizing_decimals) guide.
+See the [Customizing decimals](#customizing-decimals) guide.
+
## Usage
@@ -63,15 +63,15 @@ The above example also includes the `ERC20InternalImpl` instance.
This allows the contract’s constructor to initialize the contract and create an initial supply of tokens.
-For a more complete guide on ERC20 token mechanisms, see [Creating ERC20 Supply](/guides/erc20-supply).
+For a more complete guide on ERC20 token mechanisms, see [Creating ERC20 Supply](guides/erc20-supply).
## Interface
-The following interface represents the full ABI of the Contracts for Cairo [ERC20Component](/api/erc20#ERC20Component).
-The interface includes the [IERC20](/api/erc20#IERC20) standard interface as well as the optional [IERC20Metadata](/api/erc20#IERC20Metadata).
+The following interface represents the full ABI of the Contracts for Cairo [ERC20Component](api/erc20#ERC20Component).
+The interface includes the [IERC20](api/erc20#IERC20) standard interface as well as the optional [IERC20Metadata](api/erc20#IERC20Metadata).
-To support older token deployments, as mentioned in [Dual interfaces](/interfaces#dual_interfaces), the component also includes an implementation of the interface written in camelCase.
+To support older token deployments, as mentioned in [Dual interfaces](guides/interfaces-and-dispatchers#dual-interfaces), the component also includes an implementation of the interface written in camelCase.
```rust
#[starknet::interface]
@@ -106,7 +106,7 @@ Although Starknet is not EVM compatible, this component aims to be as close as p
Some notable differences, however, can still be found, such as:
* The `ByteArray` type is used to represent strings in Cairo.
-* The component offers a [dual interface](/interfaces#dual_interfaces) which supports both snake_case and camelCase methods, as opposed to just camelCase in Solidity.
+* The component offers a [dual interface](guides/interfaces-and-dispatchers#dual-interfaces) which supports both snake_case and camelCase methods, as opposed to just camelCase in Solidity.
* `transfer`, `transfer_from` and `approve` will never return anything different from `true` because they will revert on any error.
* Function selectors are calculated differently between [Cairo](https://github.com/starkware-libs/cairo/blob/7dd34f6c57b7baf5cd5a30c15e00af39cb26f7e1/crates/cairo-lang-starknet/src/contract.rs#L39-L48) and [Solidity](https://solidity-by-example.org/function-selector/).
diff --git a/content/contracts-cairo/erc4626.mdx b/content/contracts-cairo/erc4626.mdx
index 56db813..534de0d 100644
--- a/content/contracts-cairo/erc4626.mdx
+++ b/content/contracts-cairo/erc4626.mdx
@@ -2,20 +2,26 @@
title: ERC4626
---
-[ERC4626](https://eips.ethereum.org/EIPS/eip-4626) is an extension of [ERC20](erc20) that proposes a standard interface for token vaults. This standard interface can be used by widely different contracts (including lending markets, aggregators, and intrinsically interest bearing tokens), which brings a number of subtleties. Navigating these potential issues is essential to implementing a compliant and composable token vault.
+[ERC4626](https://eips.ethereum.org/EIPS/eip-4626) is an extension of [ERC20](erc20) that proposes a standard interface for token vaults.
+This standard interface can be used by widely different contracts (including lending markets, aggregators, and intrinsically interest bearing tokens),
+which brings a number of subtleties. Navigating these potential issues is essential to implementing a compliant and composable token vault.
-We provide a base component of ERC4626 which is designed to allow developers to easily re-configure the vault’s behavior, using traits and hooks, while staying compliant. In this guide, we will discuss some security considerations that affect ERC4626. We will also discuss common customizations of the vault.
+We provide a base component of ERC4626 which is designed to allow developers to easily re-configure the vault’s behavior, using traits and hooks, while
+staying compliant. In this guide, we will discuss some security considerations that affect ERC4626. We will also discuss common customizations of the vault.
## Security concern: Inflation attack
### Visualizing the vault
-In exchange for the assets deposited into an ERC4626 vault, a user receives shares. These shares can later be burned to redeem the corresponding underlying assets. The number of shares a user gets depends on the amount of assets they put in and on the exchange rate of the vault. This exchange rate is defined by the current liquidity held by the vault.
+In exchange for the assets deposited into an ERC4626 vault, a user receives shares. These shares can later be burned to redeem the corresponding underlying assets.
+The number of shares a user gets depends on the amount of assets they put in and on the exchange rate of the vault. This exchange rate is defined by the
+current liquidity held by the vault.
* If a vault has 100 tokens to back 200 shares, then each share is worth 0.5 assets.
* If a vault has 200 tokens to back 100 shares, then each share is worth 2.0 assets.
-In other words, the exchange rate can be defined as the slope of the line that passes through the origin and the current number of assets and shares in the vault. Deposits and withdrawals move the vault in this line.
+In other words, the exchange rate can be defined as the slope of the line that passes through the origin and the current number of assets and shares in the vault.
+Deposits and withdrawals move the vault in this line.

@@ -29,17 +35,23 @@ In such a representation, widely different rates can be clearly visible in the s
### The attack
-When depositing tokens, the number of shares a user gets is rounded towards zero. This rounding takes away value from the user in favor of the vault (i.e. in favor of all the current shareholders). This rounding is often negligible because of the amount at stake. If you deposit 1e9 shares worth of tokens, the rounding will have you lose at most 0.0000001% of your deposit. However if you deposit 10 shares worth of tokens, you could lose 10% of your deposit. Even worse, if you deposit less than 1 share worth of tokens, you will receive 0 shares, effectively making a donation.
+When depositing tokens, the number of shares a user gets is rounded towards zero. This rounding takes away value from the user in favor of
+the vault (i.e. in favor of all the current shareholders). This rounding is often negligible because of the amount at stake. If you deposit 1e9 shares
+worth of tokens, the rounding will have you lose at most 0.0000001% of your deposit. However if you deposit 10 shares worth of tokens, you could
+lose 10% of your deposit. Even worse, if you deposit less than 1 share worth of tokens, you will receive 0 shares, effectively making a donation.
For a given amount of assets, the more shares you receive the safer you are. If you want to limit your losses to at most 1%, you need to receive at least 100 shares.

-In the figure we can see that for a given deposit of 500 assets, the number of shares we get and the corresponding rounding losses depend on the exchange rate. If the exchange rate is that of the orange curve, we are getting less than a share, so we lose 100% of our deposit. However, if the exchange rate is that of the green curve, we get 5000 shares, which limits our rounding losses to at most 0.02%.
+In the figure we can see that for a given deposit of 500 assets, the number of shares we get and the corresponding rounding losses depend on the exchange rate.
+If the exchange rate is that of the orange curve, we are getting less than a share, so we lose 100% of our deposit. However, if the exchange rate
+is that of the green curve, we get 5000 shares, which limits our rounding losses to at most 0.02%.

-Symmetrically, if we focus on limiting our losses to a maximum of 0.5%, we need to get at least 200 shares. With the green exchange rate that requires just 20 tokens, but with the orange rate that requires 200000 tokens.
+Symmetrically, if we focus on limiting our losses to a maximum of 0.5%, we need to get at least 200 shares. With the green exchange rate that requires
+just 20 tokens, but with the orange rate that requires 200000 tokens.
We can clearly see that the blue and green curves correspond to vaults that are safer than the yellow and orange curves.
@@ -47,9 +59,12 @@ The idea of an inflation attack is that an attacker can donate assets to the vau

-Figure 6 shows how an attacker can manipulate the rate of an empty vault. First the attacker must deposit a small amount of tokens (1 token) and follow up with a donation of 1e5 tokens directly to the vault to move the exchange rate "right". This puts the vault in a state where any deposit smaller than 1e5 would be completely lost to the vault. Given that the attacker is the only shareholder (from their donation), the attacker would steal all the tokens deposited.
+Figure 6 shows how an attacker can manipulate the rate of an empty vault. First the attacker must deposit a small amount of tokens (1 token) and follow up with
+a donation of 1e5 tokens directly to the vault to move the exchange rate "right". This puts the vault in a state where any deposit smaller than 1e5 would be
+completely lost to the vault. Given that the attacker is the only shareholder (from their donation), the attacker would steal all the tokens deposited.
-An attacker would typically wait for a user to do the first deposit into the vault, and would frontrun that operation with the attack described above. The risk is low, and the size of the "donation" required to manipulate the vault is equivalent to the size of the deposit that is being attacked.
+An attacker would typically wait for a user to do the first deposit into the vault, and would frontrun that operation with the attack described above. The risk is
+low, and the size of the "donation" required to manipulate the vault is equivalent to the size of the deposit that is being attacked.
In math that gives:
@@ -57,13 +72,17 @@ In math that gives:
* $a_1$ the attacker donation
* $u$ the user deposit
-| |
+| | Assets | Shares | Rate |
| --- | --- | --- | --- |
-| Assets | Shares | Rate | initial |
-| $0$ | $0$ | - | after attacker’s deposit |
-| $a_0$ | $a_0$ | $1$ | after attacker’s donation |
+| initial | $0$ | $0$ | - |
+| after attacker's deposit | $a_0$ | $a_0$ | $1$ |
+| after attacker's donation | $a_0 + a_1$ | $a_0$ | $\frac{a_0}{a_1 + a_0}$ |
-This means a deposit of $u$ will give $\fracu \times a_0a_0 + a_1$ shares.
+This means a deposit of $u$ will give this number of shares:
+
+```math
+\frac{u \times a_0}{a_0 + a_1}
+```
For the attacker to dilute that deposit to 0 shares, causing the user to lose all its deposit, it must ensure that
@@ -73,7 +92,7 @@ For the attacker to dilute that deposit to 0 shares, causing the user to lose al
Using $a_0 = 1$ and $a_1 = u$ is enough. So the attacker only needs $u+1$ assets to perform a successful attack.
-It is easy to generalize the above results to scenarios where the attacker is going after a smaller fraction of the user’s deposit. In order to target $\fracun$, the user needs to suffer rounding of a similar fraction, which means the user must receive at most $n$ shares. This results in:
+It is easy to generalize the above results to scenarios where the attacker is going after a smaller fraction of the user’s deposit. In order to target $\frac{u}{n}$, the user needs to suffer rounding of a similar fraction, which means the user must receive at most $n$ shares. This results in:
```math
\frac{u \times a_0}{a_0+a_1} < n \iff \frac{u}{n} < 1 + \frac{a_1}{a_0}
@@ -97,13 +116,14 @@ Following the previous math definitions, we have:
* $a_1$ the attacker donation
* $u$ the user deposit
-| |
+| | Assets | Shares | Rate |
| --- | --- | --- | --- |
-| Assets | Shares | Rate | initial |
-| $1$ | $10^\delta$ | $10^\delta$ | after attacker’s deposit |
-| $1+a_0$ | $10^\delta \times (1+a_0)$ | $10^\delta$ | after attacker’s donation |
+| initial | $1$ | $10^\delta$ | $10^\delta$ |
+| after attacker's deposit | $1+a_0$ | $10^\delta \times (1+a_0)$ | $10^\delta$ |
+| after attacker's donation | $1+a_0+a_1$ | $10^\delta \times (1+a_0)$ | $10^\delta$ |
-One important thing to note is that the attacker only owns a fraction $\fraca_01 + a_0$ of the shares, so when doing the donation, he will only be able to recover that fraction $\fraca_1 \times a_01 + a_0$ of the donation. The remaining $\fraca_11+a_0$ are captured by the vault.
+One important thing to note is that the attacker only owns a fraction $\frac{a_0}{1 + a_0}$ of the shares, so when doing the donation, he will only be able
+to recover that fraction $\frac{a_1 * a_0}{1 + a_0}$ of the donation. The remaining $\frac{a_1}{1+a_0}$ are captured by the vault.
```math
\mathit{loss} = \frac{a_1}{1+a_0}
@@ -154,14 +174,14 @@ $\delta = 6$, $a_0 = 1$, $a_1 = 10^5$
### Custom behavior: Adding fees to the vault
In ERC4626 vaults, fees can be captured during deposit/mint and/or withdraw/redeem operations. It is essential to remain
-compliant with the ERC4626 requirements regarding the preview functions. Fees are calculated through the [FeeConfigTrait](/api/erc20#ERC4626Component-FeeConfigTrait)
+compliant with the ERC4626 requirements regarding the preview functions. Fees are calculated through the [FeeConfigTrait](api/erc20#ERC4626Component-FeeConfigTrait)
implementation. By default, the ERC4626 component charges no fees. If this is the desired behavior, you can use the default
-[ERC4626DefaultNoFees](https://github.com/OpenZeppelin/cairo-contracts/tree/main/packages/token/src/erc20/extensions/erc4626/erc4626.cairo#L874) implementation.
+[ERC4626DefaultNoFees](https://github.com/OpenZeppelin/cairo-contracts/tree/main/packages/token/src/erc20/extensions/erc4626/erc4626.cairo#L899) implementation.
Starting from v3.0.0, fees can be charged in either assets or shares. Prior versions only supported fees taken in assets.
+See the updated [FeeConfigTrait](api/erc20#ERC4626Component-FeeConfigTrait) and implementation examples in [ERC4626 mocks](https://github.com/OpenZeppelin/cairo-contracts/tree/main/packages/test_common/src/mocks/erc4626.cairo).
-See the updated [FeeConfigTrait](/api/erc20#ERC4626Component-FeeConfigTrait) and implementation examples in [ERC4626 mocks](https://github.com/OpenZeppelin/cairo-contracts/tree/main/packages/test_common/src/mocks/erc4626.cairo).
For example, if calling `deposit(100, receiver)`, the caller should deposit exactly 100 underlying tokens, including fees, and the receiver should receive a number of shares that matches the value returned by `preview_deposit(100)`.
Similarly, `preview_mint` should account for the fees that the user will have to pay on top of share’s cost.
@@ -196,6 +216,7 @@ pub mod ERC4626Fees {
use starknet::storage::{StoragePointerReadAccess, StoragePointerWriteAccess};
const _BASIS_POINT_SCALE: u256 = 10_000;
+ const FEE_TRANSFER_FAILED: felt252 = 0x1;
// ERC4626
#[abi(embed_v0)]
@@ -235,10 +256,11 @@ pub mod ERC4626Fees {
self.erc20.mint(recipient, initial_supply);
self.erc4626.initializer(underlying_asset);
- self.entry_fee_basis_point_value.write(entry_fee);
- self.entry_fee_recipient.write(entry_treasury);
- self.exit_fee_basis_point_value.write(exit_fee);
- self.exit_fee_recipient.write(exit_treasury);
+ self.entry_fee_basis_point_value.write(entry_fee);
+ self.entry_fee_recipient.write(entry_treasury);
+ self.exit_fee_basis_point_value.write(exit_fee);
+ self.exit_fee_recipient.write(exit_treasury);
+ }
/// Hooks
impl ERC4626HooksImpl of ERC4626Component::ERC4626HooksTrait {
@@ -258,7 +280,7 @@ pub mod ERC4626Fees {
let asset_address = contract_state.asset();
let asset_dispatcher = IERC20Dispatcher { contract_address: asset_address };
assert(
- asset_dispatcher.transfer(fee_recipient, fee), 'Fee transfer failed',
+ asset_dispatcher.transfer(fee_recipient, fee), FEE_TRANSFER_FAILED,
);
},
Fee::Shares(fee) => contract_state.erc20.mint(fee_recipient, fee),
@@ -266,33 +288,34 @@ pub mod ERC4626Fees {
}
}
- fn before_withdraw(
- ref self: ERC4626Component::ComponentState,
- caller: ContractAddress,
- receiver: ContractAddress,
- owner: ContractAddress,
- assets: u256,
- shares: u256,
- fee: Option,
- ) {
- if let Option::Some(fee) = fee {
- let mut contract_state = self.get_contract_mut();
- let fee_recipient = contract_state.exit_fee_recipient.read();
- match fee {
- Fee::Assets(fee) => {
- let asset_address = contract_state.asset();
- let asset_dispatcher = IERC20Dispatcher { contract_address: asset_address };
- assert(
- asset_dispatcher.transfer(fee_recipient, fee), 'Fee transfer failed',
- );
- },
- Fee::Shares(fee) => {
- if caller != owner {
- contract_state.erc20._spend_allowance(owner, caller, fee);
- }
- contract_state.erc20._transfer(owner, fee_recipient, fee);
- },
- };
+ fn before_withdraw(
+ ref self: ERC4626Component::ComponentState,
+ caller: ContractAddress,
+ receiver: ContractAddress,
+ owner: ContractAddress,
+ assets: u256,
+ shares: u256,
+ fee: Option,
+ ) {
+ if let Option::Some(fee) = fee {
+ let mut contract_state = self.get_contract_mut();
+ let fee_recipient = contract_state.exit_fee_recipient.read();
+ match fee {
+ Fee::Assets(fee) => {
+ let asset_address = contract_state.asset();
+ let asset_dispatcher = IERC20Dispatcher { contract_address: asset_address };
+ assert(
+ asset_dispatcher.transfer(fee_recipient, fee), FEE_TRANSFER_FAILED,
+ );
+ },
+ Fee::Shares(fee) => {
+ if caller != owner {
+ contract_state.erc20._spend_allowance(owner, caller, fee);
+ }
+ contract_state.erc20._transfer(owner, fee_recipient, fee);
+ },
+ };
+ }
}
}
@@ -306,28 +329,29 @@ pub mod ERC4626Fees {
Option::Some(Fee::Assets(fee))
}
- fn calculate_mint_fee(
- self: @ERC4626Component::ComponentState, assets: u256, shares: u256,
- ) -> Option {
- let contract_state = self.get_contract();
- let fee = fee_on_raw(shares, contract_state.entry_fee_basis_point_value.read());
- Option::Some(Fee::Shares(fee))
- }
+ fn calculate_mint_fee(
+ self: @ERC4626Component::ComponentState, assets: u256, shares: u256,
+ ) -> Option {
+ let contract_state = self.get_contract();
+ let fee = fee_on_raw(shares, contract_state.entry_fee_basis_point_value.read());
+ Option::Some(Fee::Shares(fee))
+ }
- fn calculate_withdraw_fee(
- self: @ERC4626Component::ComponentState, assets: u256, shares: u256,
- ) -> Option {
- let contract_state = self.get_contract();
- let fee = fee_on_raw(assets, contract_state.exit_fee_basis_point_value.read());
- Option::Some(Fee::Assets(fee))
- }
+ fn calculate_withdraw_fee(
+ self: @ERC4626Component::ComponentState, assets: u256, shares: u256,
+ ) -> Option {
+ let contract_state = self.get_contract();
+ let fee = fee_on_raw(assets, contract_state.exit_fee_basis_point_value.read());
+ Option::Some(Fee::Assets(fee))
+ }
- fn calculate_redeem_fee(
- self: @ERC4626Component::ComponentState, assets: u256, shares: u256,
- ) -> Option {
- let contract_state = self.get_contract();
- let fee = fee_on_total(shares, contract_state.exit_fee_basis_point_value.read());
- Option::Some(Fee::Shares(fee))
+ fn calculate_redeem_fee(
+ self: @ERC4626Component::ComponentState, assets: u256, shares: u256,
+ ) -> Option {
+ let contract_state = self.get_contract();
+ let fee = fee_on_total(shares, contract_state.exit_fee_basis_point_value.read());
+ Option::Some(Fee::Shares(fee))
+ }
}
/// Calculates the fees that should be added to an amount `assets` that does not already
@@ -355,8 +379,8 @@ pub mod ERC4626Fees {
## Interface
-The following interface represents the full ABI of the Contracts for Cairo [ERC4626Component](/api/erc20#ERC4626Component).
-The full interface includes the [IERC4626](/api/erc20#IERC4626), [IERC20](/api/erc20#IERC20), and [IERC20Metadata](/api/erc20#IERC20Metadata) interfaces.
+The following interface represents the full ABI of the Contracts for Cairo [ERC4626Component](api/erc20#ERC4626Component).
+The full interface includes the [IERC4626](api/erc20#IERC4626), [IERC20](api/erc20#IERC20), and [IERC20Metadata](api/erc20#IERC20Metadata) interfaces.
Note that implementing the IERC20Metadata interface is a requirement of IERC4626.
```rust
diff --git a/content/contracts-cairo/erc721.mdx b/content/contracts-cairo/erc721.mdx
index d848396..eadb57a 100644
--- a/content/contracts-cairo/erc721.mdx
+++ b/content/contracts-cairo/erc721.mdx
@@ -61,10 +61,10 @@ mod MyNFT {
## Interface
-The following interface represents the full ABI of the Contracts for Cairo [ERC721Component](/api/erc721#ERC721Component).
-The interface includes the [IERC721](/api/erc721#IERC721) standard interface and the optional [IERC721Metadata](/api/erc721#IERC721Metadata) interface.
+The following interface represents the full ABI of the Contracts for Cairo [ERC721Component](api/erc721#ERC721Component).
+The interface includes the [IERC721](api/erc721#IERC721) standard interface and the optional [IERC721Metadata](api/erc721#IERC721Metadata) interface.
-To support older token deployments, as mentioned in [Dual interfaces](interfaces#dual_interfaces), the component also includes implementations of the interface written in camelCase.
+To support older token deployments, as mentioned in [Dual interfaces](guides/interfaces-and-dispatchers#dual-interfaces), the component also includes implementations of the interface written in camelCase.
```rust
#[starknet::interface]
@@ -121,7 +121,7 @@ The difference between both functions consists of accepting `data` as an argumen
`safe_transfer_from` by default accepts the `data` argument which is interpreted as `Span`.
If `data` is not used, simply pass an empty array.
* ERC721 utilizes [SRC5](introspection#src5) to declare and query interface support on Starknet as opposed to Ethereum’s [EIP165](https://eips.ethereum.org/EIPS/eip-165).
-The design for `SRC5` is similar to OpenZeppelin’s [ERC165Storage](https://docs.openzeppelin.com/contracts/4.x/api/utils#ERC165Storage).
+The design for `SRC5` is similar to OpenZeppelin’s [ERC165Storage](https://docs.openzeppelin.com/contracts/4.xapi/utils#ERC165Storage).
* `IERC721Receiver` compliant contracts return a hardcoded interface ID according to Starknet selectors (as opposed to selector calculation in Solidity).
## Token transfers
@@ -154,11 +154,11 @@ pub trait IERC721Receiver {
```
Implementing the `IERC721Receiver` interface exposes the [on_erc721_received](api/erc721#IERC721Receiver-on_erc721_received) method.
-When safe methods such as [safe_transfer_from](api/erc721#IERC721-safe_transfer_from) and [safe_mint](api/erc721#ERC721-safe_mint) are called, they invoke the recipient contract’s `on_erc721_received` method which **must** return the [IERC721Receiver interface ID](/api/erc721#IERC721Receiver).
+When safe methods such as [safe_transfer_from](api/erc721#IERC721-safe_transfer_from) and [safe_mint](api/erc721#ERC721-safe_mint) are called, they invoke the recipient contract’s `on_erc721_received` method which **must** return the [IERC721Receiver interface ID](api/erc721#IERC721Receiver).
Otherwise, the transaction will fail.
-For information on how to calculate interface IDs, see [Computing the interface ID](introspection#computing_the_interface_id).
+For information on how to calculate interface IDs, see [Computing the interface ID](introspection#computing-the-interface-id).
### Creating a token receiver contract
@@ -209,5 +209,5 @@ mod MyTokenReceiver {
## Storing ERC721 URIs
Token URIs were previously stored as single field elements prior to Cairo v0.2.5.
-ERC721Component now stores only the base URI as a `ByteArray` and the full token URI is returned as the `ByteArray` concatenation of the base URI and the token ID through the [token_uri](/api/erc721#IERC721Metadata-token_uri) method.
+ERC721Component now stores only the base URI as a `ByteArray` and the full token URI is returned as the `ByteArray` concatenation of the base URI and the token ID through the [token_uri](api/erc721#IERC721Metadata-token_uri) method.
This design mirrors OpenZeppelin’s default [Solidity implementation](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/932fddf69a699a9a80fd2396fd1a2ab91cdda123/contracts/token/ERC721/ERC721.sol#L85-L93) for ERC721.
diff --git a/content/contracts-cairo/finance.mdx b/content/contracts-cairo/finance.mdx
index 448d2f6..6266b42 100644
--- a/content/contracts-cairo/finance.mdx
+++ b/content/contracts-cairo/finance.mdx
@@ -12,13 +12,13 @@ This structure allows ownership rights of both the contract and the vested token
Any assets transferred to this contract will follow the vesting schedule as if they were locked from the beginning of the vesting period.
-
As a result, if the vesting has already started, a portion of the newly transferred tokens may become immediately releasable.
+
By setting the duration to 0, it’s possible to configure this contract to behave like an asset timelock that holds tokens
-
for a beneficiary until a specified date.
+
### Vesting schedule
@@ -28,9 +28,9 @@ implementation of the [VestingSchedule](api/finance#VestingComponent-Vesting-Sch
There’s a ready-made implementation of the [VestingSchedule](api/finance#VestingComponent-Vesting-Schedule) trait available named [LinearVestingSchedule](api/finance#LinearVestingSchedule).
-
It incorporates a cliff period by returning 0 vested amount until the cliff ends. After the cliff, the vested amount
is calculated as directly proportional to the time elapsed since the beginning of the vesting schedule.
+
### Usage
diff --git a/content/contracts-cairo/governance/governor.mdx b/content/contracts-cairo/governance/governor.mdx
index 2ff55c5..63b3cbb 100644
--- a/content/contracts-cairo/governance/governor.mdx
+++ b/content/contracts-cairo/governance/governor.mdx
@@ -19,7 +19,7 @@ but writing additional ones is simple, and we will be adding new features as req
### Token
The voting power of each account in our governance setup will be determined by an ERC20 or an ERC721 token. The token has
-to implement the [VotesComponent](api/governance#VotesComponent) extension. This extension will keep track of historical balances so that voting power
+to implement the [VotesComponent](../api/governance#VotesComponent) extension. This extension will keep track of historical balances so that voting power
is retrieved from past snapshots rather than current balance, which is an important protection that prevents double voting.
If your project already has a live token that does not include Votes and is not upgradeable, you can wrap it in a
@@ -31,13 +31,13 @@ The library currently does not include a wrapper for tokens, but it will be adde
Currently, the clock mode is fixed to block timestamps, since the Votes component uses the block timestamp to track
-
checkpoints. We plan to add support for more flexible clock modes in Votes in a future release, allowing to use, for example,
block numbers instead.
+
### Governor
-We will initially build a Governor without a timelock. The core logic is given by the [GovernorComponent](api/governance#GovernorComponent), but we
+We will initially build a Governor without a timelock. The core logic is given by the [GovernorComponent](../api/governance#GovernorComponent), but we
still need to choose:
1) how voting power is determined,
@@ -51,11 +51,11 @@ still need to choose:
Each of these aspects is customizable by writing your own extensions,
or more easily choosing one from the library.
-***For 1)*** we will use the GovernorVotes extension, which hooks to an [IVotes](api/governance#IVotes) instance to determine the voting power
+***For 1)*** we will use the GovernorVotes extension, which hooks to an [IVotes](../api/governance#IVotes) instance to determine the voting power
of an account based on the token balance they hold when a proposal becomes active.
This module requires the address of the token to be passed as an argument to the initializer.
-***For 2)*** we will use GovernorVotesQuorumFraction. This works together with the [IVotes](api/governance#IVotes) instance to define the quorum as a
+***For 2)*** we will use GovernorVotesQuorumFraction. This works together with the [IVotes](../api/governance#IVotes) instance to define the quorum as a
percentage of the total supply at the block when a proposal’s voting power is retrieved. This requires an initializer
parameter to set the percentage besides the votes token address. Most Governors nowadays use 4%. Since the quorum denominator
is 1000 for precision, we initialize the module with a numerator of 40, resulting in a 4% quorum (40/1000 = 0.04 or 4%).
@@ -223,15 +223,15 @@ mod MyGovernor {
### Timelock
It is good practice to add a timelock to governance decisions. This allows users to exit the system if they disagree
-with a decision before it is executed. We will use OpenZeppelin’s [TimelockController](governance/timelock) in combination with the
+with a decision before it is executed. We will use OpenZeppelin’s [TimelockController](timelock) in combination with the
GovernorTimelockExecution extension.
When using a timelock, it is the timelock that will execute proposals and thus the timelock that should
-
hold any funds, ownership, and access control roles.
+
-TimelockController uses an [AccessControl](access#role_based_accesscontrol) setup that we need to understand in order to set up roles.
+TimelockController uses an [AccessControl](../access#role_based_accesscontrol) setup that we need to understand in order to set up roles.
The Proposer role is in charge of queueing operations: this is the role the Governor instance must be granted,
and it MUST be the only proposer (and canceller) in the system.
diff --git a/content/contracts-cairo/governance/multisig.mdx b/content/contracts-cairo/governance/multisig.mdx
index 39f2a5d..c98fdf9 100644
--- a/content/contracts-cairo/governance/multisig.mdx
+++ b/content/contracts-cairo/governance/multisig.mdx
@@ -30,8 +30,8 @@ Component supports adding, removing, or replacing signers.
To prevent unauthorized modifications, only the contract itself can add, remove, or replace signers or change the quorum.
-
This ensures that all modifications pass through the multisig approval process.
+
## Transaction lifecycle
@@ -56,7 +56,7 @@ A transaction in the Multisig component follows a specific lifecycle:
## Usage
-Integrating the Multisig functionality into a contract requires implementing [MultisigComponent](api/governance#MultisigComponent).
+Integrating the Multisig functionality into a contract requires implementing [MultisigComponent](../api/governance#MultisigComponent).
The contract’s constructor should initialize the component with a quorum value and a list of initial signers.
Here’s an example of a simple wallet contract featuring the Multisig functionality:
@@ -95,7 +95,7 @@ mod MultisigWallet {
## Interface
-This is the interface of a contract implementing the [MultisigComponent](api/governance#MultisigComponent):
+This is the interface of a contract implementing the [MultisigComponent](../api/governance#MultisigComponent):
```rust
#[starknet::interface]
diff --git a/content/contracts-cairo/governance/timelock.mdx b/content/contracts-cairo/governance/timelock.mdx
index b8a767d..d340451 100644
--- a/content/contracts-cairo/governance/timelock.mdx
+++ b/content/contracts-cairo/governance/timelock.mdx
@@ -33,26 +33,26 @@ Timelocked operations follow a specific lifecycle:
### Schedule
-When a proposer calls [schedule](api/governance#ITimelock-schedule), the `OperationState` moves from `Unset` to `Waiting`.
+When a proposer calls [schedule](../api/governance#ITimelock-schedule), the `OperationState` moves from `Unset` to `Waiting`.
This starts a timer that must be greater than or equal to the minimum delay.
-The timer expires at a timestamp accessible through [get_timestamp](api/governance#ITimelock-get_timestamp).
+The timer expires at a timestamp accessible through [get_timestamp](../api/governance#ITimelock-get_timestamp).
Once the timer expires, the `OperationState` automatically moves to the `Ready` state.
At this point, it can be executed.
### Execute
-By calling [execute](api/governance#ITimelock-execute), an executor triggers the operation’s underlying transactions and moves it to the `Done` state. If the operation has a predecessor, the predecessor’s operation must be in the `Done` state for this transaction to succeed.
+By calling [execute](../api/governance#ITimelock-execute), an executor triggers the operation’s underlying transactions and moves it to the `Done` state. If the operation has a predecessor, the predecessor’s operation must be in the `Done` state for this transaction to succeed.
### Cancel
-The [cancel](api/governance#ITimelock-cancel) function allows cancellers to cancel any pending operations.
+The [cancel](../api/governance#ITimelock-cancel) function allows cancellers to cancel any pending operations.
This resets the operation to the `Unset` state.
It is therefore possible for a proposer to re-schedule an operation that has been cancelled.
In this case, the timer restarts when the operation is re-scheduled.
-### Roles
+## Roles
-[TimelockControllerComponent](api/governance#TimelockControllerComponent) leverages an [AccessControlComponent](api/access#AccessControlComponent) setup that we need to understand in order to set up roles.
+[TimelockControllerComponent](../api/governance#TimelockControllerComponent) leverages an [AccessControlComponent](../api/access#AccessControlComponent) setup that we need to understand in order to set up roles.
* `PROPOSER_ROLE` - in charge of queueing operations.
* `CANCELLER_ROLE` - may cancel scheduled operations.
@@ -63,8 +63,8 @@ Therefore, the initial proposers may also cancel operations after they are sched
The `DEFAULT_ADMIN_ROLE` is a sensitive role that will be granted automatically to the timelock itself and optionally to a second account.
-
The latter case may be required to ease a contract’s initial configuration; however, this role should promptly be renounced.
+
Furthermore, the timelock component supports the concept of open roles for the `EXECUTOR_ROLE`.
This allows anyone to execute an operation once it’s in the `Ready` OperationState.
@@ -74,18 +74,18 @@ To enable the `EXECUTOR_ROLE` to be open, grant the zero address with the `EXECU
Be very careful with enabling open roles as _anyone_ can call the function.
-### Minimum delay
+## Minimum delay
The minimum delay of the timelock acts as a buffer from when a proposer schedules an operation to the earliest point at which an executor may execute that operation.
The idea is for users, should they disagree with a scheduled proposal, to have options such as exiting the system or making their case for cancellers to cancel the operation.
After initialization, the only way to change the timelock’s minimum delay is to schedule it and execute it with the same flow as any other operation.
-The minimum delay of a contract is accessible through [get_min_delay](api/governance#ITimelock-get_min_delay).
+The minimum delay of a contract is accessible through [get_min_delay](../api/governance#ITimelock-get_min_delay).
-### Usage
+## Usage
-Integrating the timelock into a contract requires integrating [TimelockControllerComponent](api/governance#TimelockControllerComponent) as well as [SRC5Component](api/introspection#SRC5Component) and [AccessControlComponent](api/access#AccessControlComponent) as dependencies.
+Integrating the timelock into a contract requires integrating [TimelockControllerComponent](../api/governance#TimelockControllerComponent) as well as [SRC5Component](../api/introspection#SRC5Component) and [AccessControlComponent](../api/access#AccessControlComponent) as dependencies.
The contract’s constructor should initialize the timelock which consists of setting the:
* Proposers and executors.
@@ -150,7 +150,7 @@ mod TimelockControllerContract {
}
```
-### Interface
+## Interface
This is the full interface of the TimelockMixinImpl implementation:
diff --git a/content/contracts-cairo/governance/votes.mdx b/content/contracts-cairo/governance/votes.mdx
index 09cdf24..44d9e73 100644
--- a/content/contracts-cairo/governance/votes.mdx
+++ b/content/contracts-cairo/governance/votes.mdx
@@ -2,7 +2,7 @@
title: Votes
---
-The [VotesComponent](api/governance#VotesComponent) provides a flexible system for tracking and delegating voting power. This system allows users to delegate their voting power to other addresses, enabling more active participation in governance.
+The [VotesComponent](../api/governance#VotesComponent) provides a flexible system for tracking and delegating voting power. This system allows users to delegate their voting power to other addresses, enabling more active participation in governance.
By default, token balance does not account for voting power. This makes transfers cheaper. The downside is that it requires users to delegate to themselves in order to activate checkpoints and have their voting power tracked.
@@ -14,15 +14,15 @@ The transferring of voting units must be handled by the implementing contract. I
## Key features
-1. **Delegation**: Users can delegate their voting power to any address, including themselves. Vote power can be delegated either by calling the [delegate](api/governance#VotesComponent-delegate) function directly, or by providing a signature to be used with [delegate_by_sig](api/governance#VotesComponent-delegate_by_sig).
+1. **Delegation**: Users can delegate their voting power to any address, including themselves. Vote power can be delegated either by calling the [delegate](../api/governance#VotesComponent-delegate) function directly, or by providing a signature to be used with [delegate_by_sig](../api/governance#VotesComponent-delegate_by_sig).
2. **Historical lookups**: The system keeps track of historical snapshots for each account, which allows the voting power of an account to be queried at a specific timestamp.\
This can be used for example to determine the voting power of an account when a proposal was created, rather than using the current balance.
## Usage
-When integrating the `VotesComponent`, the [VotingUnitsTrait](api/governance#VotingUnitsTrait) must be implemented to get the voting units for a given account as a function of the implementing contract.\
+When integrating the `VotesComponent`, the [VotingUnitsTrait](../api/governance#VotingUnitsTrait) must be implemented to get the voting units for a given account as a function of the implementing contract.\
For simplicity, this module already provides two implementations for `ERC20` and `ERC721` tokens, which will work out of the box if the respective components are integrated.\
-Additionally, you must implement the [NoncesComponent](api/utilities#NoncesComponent) and the [SNIP12Metadata](api/utilities#snip12) trait to enable delegation by signatures.
+Additionally, you must implement the [NoncesComponent](../api/utilities#NoncesComponent) and the [SNIP12Metadata](../api/utilities#snip12) trait to enable delegation by signatures.
Here’s an example of how to structure a simple ERC20Votes contract:
@@ -204,6 +204,7 @@ pub mod ERC721VotesContract {
## Interface
This is the full interface of the `VotesImpl` implementation:
+
```rust
#[starknet::interface]
pub trait VotesABI {
diff --git a/content/contracts-cairo/guides/deployment.mdx b/content/contracts-cairo/guides/deployment.mdx
index 0f8165b..42a924d 100644
--- a/content/contracts-cairo/guides/deployment.mdx
+++ b/content/contracts-cairo/guides/deployment.mdx
@@ -18,7 +18,7 @@ Note that the `class_hash` must be previously declared for the deployment to suc
2. Send funds to the `contract_address`. Usually you will estimate the fee of the transaction first. Existing
tools usually do this for you.
3. Send a `DeployAccount` type transaction to the network.
-4. The protocol will then validate the transaction with the `\\__validate_deploy__` entrypoint of the contract to be deployed.
+4. The protocol will then validate the transaction with the `__validate_deploy__` entrypoint of the contract to be deployed.
5. If the validation succeeds, the protocol will charge the fee and then register the contract as deployed.
@@ -27,7 +27,7 @@ Although this method is very popular to deploy accounts, this works for any kind
## Deployment validation
-To be counterfactually deployed, the deploying contract must implement the `\\__validate_deploy__` entrypoint,
+To be counterfactually deployed, the deploying contract must implement the `__validate_deploy__` entrypoint,
called by the protocol when a `DeployAccount` transaction is sent to the network.
```rust
diff --git a/content/contracts-cairo/guides/erc20-permit.mdx b/content/contracts-cairo/guides/erc20-permit.mdx
index 80a0ad6..d2fb7f6 100644
--- a/content/contracts-cairo/guides/erc20-permit.mdx
+++ b/content/contracts-cairo/guides/erc20-permit.mdx
@@ -3,43 +3,44 @@ title: ERC20Permit
---
The [EIP-2612](https://eips.ethereum.org/EIPS/eip-2612) standard, commonly referred to as ERC20Permit, is designed to support gasless token approvals. This is achieved with an off-chain
-signature following the [SNIP12](https://github.com/starknet-io/SNIPs/blob/main/SNIPS/snip-12.md) standard, rather than with an on-chain transaction. The [permit](/api/erc20#ERC20Component-permit) function verifies the signature and sets
+signature following the [SNIP12](https://github.com/starknet-io/SNIPs/blob/main/SNIPS/snip-12.md) standard, rather than with an on-chain transaction. The [permit](../api/erc20#ERC20Component-permit) function verifies the signature and sets
the spender’s allowance if the signature is valid. This approach improves user experience and reduces gas costs.
## Differences from Solidity
-Although this extension is mostly similar to the [Solidity implementation](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/extensions/ERC20Permit.sol) of [EIP-2612](https://eips.ethereum.org/EIPS/eip-2612), there are some notable differences in the parameters of the [permit](/api/erc20#ERC20Component-permit) function:
+Although this extension is mostly similar to the [Solidity implementation](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/extensions/ERC20Permit.sol) of [EIP-2612](https://eips.ethereum.org/EIPS/eip-2612), there are some notable differences in the parameters of the [permit](../api/erc20#ERC20Component-permit) function:
* The `deadline` parameter is represented by `u64` rather than `u256`.
* The `signature` parameter is represented by a span of felts rather than `v`, `r`, and `s` values.
Unlike Solidity, there is no enforced format for signatures on Starknet. A signature is represented by an array or span of felts,
-
-and there is no universal method for validating signatures of unknown formats. Consequently, a signature provided to the [permit](/api/erc20#ERC20Component-permit) function
+and there is no universal method for validating signatures of unknown formats. Consequently, a signature provided to the [permit](../api/erc20#ERC20Component-permit) function
is validated through an external `is_valid_signature` call to the contract at the `owner` address.
+
+
## Usage
-The functionality is provided as an embeddable [ERC20Permit](/api/erc20#ERC20Component-Embeddable-Impls-ERC20PermitImpl) trait of the [ERC20Component](/api/erc20#ERC20Component).
+The functionality is provided as an embeddable [ERC20Permit](../api/erc20#ERC20Component-Embeddable-Impls-ERC20PermitImpl) trait of the [ERC20Component](../api/erc20#ERC20Component).
```rust
#[abi(embed_v0)]
impl ERC20PermitImpl = ERC20Component::ERC20PermitImpl;
```
-A contract must meet the following requirements to be able to use the [ERC20Permit](/api/erc20#ERC20Component-Embeddable-Impls-ERC20PermitImpl) trait:
+A contract must meet the following requirements to be able to use the [ERC20Permit](../api/erc20#ERC20Component-Embeddable-Impls-ERC20PermitImpl) trait:
-* Implement [ERC20Component](/api/erc20#ERC20Component).
-* Implement [NoncesComponent](/api/utilities#NoncesComponent).
-* Implement [SNIP12Metadata](api/utilities#snip12) trait (used in signature generation).
+* Implement [ERC20Component](../api/erc20#ERC20Component).
+* Implement [NoncesComponent](../api/utilities#NoncesComponent).
+* Implement [SNIP12Metadata](../api/utilities#snip12) trait (used in signature generation).
## Typed message
-To safeguard against replay attacks and ensure the uniqueness of each approval via [permit](/api/erc20#ERC20Component-permit), the data signed includes:
+To safeguard against replay attacks and ensure the uniqueness of each approval via [permit](../api/erc20#ERC20Component-permit), the data signed includes:
* The address of the `owner`.
-* The parameters specified in the [approve](/api/erc20#ERC20Component-approve) function (`spender` and `amount`)
+* The parameters specified in the [approve](../api/erc20#ERC20Component-approve) function (`spender` and `amount`)
* The address of the `token` contract itself.
* A `nonce`, which must be unique for each operation.
* The `chain_id`, which protects against cross-chain replay attacks.
@@ -59,4 +60,4 @@ struct Permit {
The owner of the tokens is also part of the signed message. It is used as the `signer` parameter in the `get_message_hash` call.
-Further details on preparing and signing a typed message can be found in the [SNIP12 guide](/guides/snip12).
+Further details on preparing and signing a typed message can be found in the [SNIP12 guide](snip12).
diff --git a/content/contracts-cairo/guides/erc20-supply.mdx b/content/contracts-cairo/guides/erc20-supply.mdx
index 0aea376..5146563 100644
--- a/content/contracts-cairo/guides/erc20-supply.mdx
+++ b/content/contracts-cairo/guides/erc20-supply.mdx
@@ -144,5 +144,5 @@ The `mint` function includes `assert_only_owner` which will ensure that only the
Now, we have a protected ERC20 minting mechanism to create a dynamic token supply.
-For a more thorough explanation of permission mechanisms, see [Access Control](/access).
+For a more thorough explanation of permission mechanisms, see [Access Control](../access).
diff --git a/content/contracts-cairo/guides/interfaces-and-dispatchers.mdx b/content/contracts-cairo/guides/interfaces-and-dispatchers.mdx
index 1581279..fbabbc3 100644
--- a/content/contracts-cairo/guides/interfaces-and-dispatchers.mdx
+++ b/content/contracts-cairo/guides/interfaces-and-dispatchers.mdx
@@ -8,8 +8,8 @@ Interfaces can be found in the `openzeppelin_interfaces` package modules, such a
Starting from version `3.x.x`, OpenZeppelin Contracts for Cairo interfaces have been separated from their implementation modules into a dedicated package.
+This architectural change brings several important benefits. Check the [Interfaces module](../interfaces) section for more information.
-This architectural change brings several important benefits. Check the [Interfaces](interfaces) section for more information.
For example:
@@ -57,8 +57,9 @@ the ERC20 preset that includes functions from different standards such as `IERC2
The library offers an ABI trait for most components, providing all external function signatures
+even when most of the time all of them don’t need to be implemented at the same time. This can be helpful when interacting with
+a contract implementing the component, instead of defining a new dispatcher.
-even when most of the time all of them don’t need to be implemented at the same time. This can be helpful when interacting with a contract implementing the component, instead of defining a new dispatcher.
```rust
#[starknet::interface]
@@ -100,16 +101,16 @@ Other types of dispatchers are also auto-generated from the annotated trait. See
In the example, the `IERC20Dispatcher` is the one used to interact with contracts, but the
-
`IERC20DispatcherTrait` needs to be in scope for the functions to be available.
+
## Dual interfaces
-`camelCase` functions are deprecated and maintained only for Backwards Compatibility.
-
+The `camelCase` functions are deprecated and maintained only for backwards compatibility.
It’s recommended to only use `snake_case` interfaces with contracts and components. The `camelCase` functions will be removed in
future versions.
+
Following the [Great Interface Migration](https://community.starknet.io/t/the-great-interface-migration/92107) plan, we added `snake_case` functions to all of our preexisting `camelCase` contracts with the goal of eventually dropping support for the latter.
diff --git a/content/contracts-cairo/guides/snip12.mdx b/content/contracts-cairo/guides/snip12.mdx
index 810b15d..e9f9ec2 100644
--- a/content/contracts-cairo/guides/snip12.mdx
+++ b/content/contracts-cairo/guides/snip12.mdx
@@ -230,8 +230,8 @@ Finally, the full implementation of the `CustomERC20` contract looks like this:
We are using the [`ISRC6Dispatcher`](/api/account#ISRC6) to verify the signature,
-
and the [`NoncesComponent`](/api/utilities#NoncesComponent) to handle nonces to prevent replay attacks.
+
```rust
use core::hash::{HashStateExTrait, HashStateTrait};
diff --git a/content/contracts-cairo/guides/src5-migration.mdx b/content/contracts-cairo/guides/src5-migration.mdx
deleted file mode 100644
index b22f3bf..0000000
--- a/content/contracts-cairo/guides/src5-migration.mdx
+++ /dev/null
@@ -1,125 +0,0 @@
----
-title: Migrating ERC165 to SRC5
----
-
-In the smart contract ecosystem, having the ability to query if a contract supports a given interface is an extremely important feature.
-The initial introspection design for Contracts for Cairo before version v0.7.0 followed Ethereum’s [EIP-165](https://eips.ethereum.org/EIPS/eip-165).
-Since the Cairo language evolved introducing native types, we needed an introspection solution tailored to the Cairo ecosystem: the [SNIP-5](https://github.com/starknet-io/SNIPs/blob/main/SNIPS/snip-5.md) standard.
-SNIP-5 allows interface ID calculations to use Cairo types and the Starknet keccak (`sn_keccak`) function.
-For more information on the decision, see the [Starknet Shamans proposal](https://community.starknet.io/t/starknet-standard-interface-detection/92664) or the [Dual Introspection Detection](https://github.com/OpenZeppelin/cairo-contracts/discussions/640) discussion.
-
-## How to migrate
-
-Migrating from ERC165 to SRC5 involves four major steps:
-
-1. Integrate SRC5 into the contract.
-2. Register SRC5 IDs.
-3. Add a `migrate` function to apply introspection changes.
-4. Upgrade the contract and call `migrate`.
-
-The following guide will go through the steps with examples.
-
-### Component integration
-
-The first step is to integrate the necessary components into the new contract.
-The contract should include the new introspection mechanism, [SRC5Component](/api/introspection#SRC5Component).
-It should also include the [InitializableComponent](/api/security#InitializableComponent) which will be used in the `migrate` function.
-Here’s the setup:
-
-```rust
-#[starknet::contract]
-mod MigratingContract {
- use openzeppelin_introspection::src5::SRC5Component;
- use openzeppelin_security::initializable::InitializableComponent;
-
- component!(path: SRC5Component, storage: src5, event: SRC5Event);
- component!(path: InitializableComponent, storage: initializable, event: InitializableEvent);
-
- // SRC5
- #[abi(embed_v0)]
- impl SRC5Impl = SRC5Component::SRC5Impl;
- impl SRC5InternalImpl = SRC5Component::InternalImpl;
-
- // Initializable
- impl InitializableInternalImpl = InitializableComponent::InternalImpl;
-
- #[storage]
- struct Storage {
- #[substorage(v0)]
- src5: SRC5Component::Storage,
- #[substorage(v0)]
- initializable: InitializableComponent::Storage
- }
-
- #[event]
- #[derive(Drop, starknet::Event)]
- enum Event {
- #[flat]
- SRC5Event: SRC5Component::Event,
- #[flat]
- InitializableEvent: InitializableComponent::Event
- }
-}
-```
-
-### Interface registration
-
-To successfully migrate ERC165 to SRC5, the contract needs to register the interface IDs that the contract supports with SRC5.
-
-For this example, let’s say that this contract supports the [IERC721](/api/erc721#IERC721) and [IERC721Metadata](/api/erc721#IERC721Metadata) interfaces.
-The contract should implement an `InternalImpl` and add a function to register those interfaces like this:
-
-```rust
-#[starknet::contract]
-mod MigratingContract {
- use openzeppelin_interfaces::erc721::{IERC721_ID, IERC721_METADATA_ID};
-
- (...)
-
- #[generate_trait]
- impl InternalImpl of InternalTrait {
- // Register SRC5 interfaces
- fn register_src5_interfaces(ref self: ContractState) {
- self.src5.register_interface(IERC721_ID);
- self.src5.register_interface(IERC721_METADATA_ID);
- }
- }
-}
-```
-
-Since the new contract integrates `SRC5Component`, it can leverage SRC5’s [register_interface](/api/introspection#SRC5Component-register_interface) function to register the supported interfaces.
-
-### Migration initializer
-
-Next, the contract should define and expose a migration function that will invoke the `register_src5_interfaces` function.
-Since the `migrate` function will be publicly callable, it should include some sort of [Access Control](/access) so that only permitted addresses can execute the migration.
-Finally, `migrate` should include a reinitialization check to ensure that it cannot be called more than once.
-
-
-If the original contract implemented `Initializable` at any point and called the `initialize` method, the `InitializableComponent` will not be usable at this time.
-
-Instead, the contract can take inspiration from `InitializableComponent` and create its own initialization mechanism.
-
-```rust
-#[starknet::contract]
-mod MigratingContract {
- (...)
-
- #[external(v0)]
- fn migrate(ref self: ContractState) {
- // WARNING: Missing Access Control mechanism. Make sure to add one
-
- // WARNING: If the contract ever implemented `Initializable` in the past,
- // this will not work. Make sure to create a new initialization mechanism
- self.initializable.initialize();
-
- // Register SRC5 interfaces
- self.register_src5_interfaces();
- }
-}
-```
-
-### Execute migration
-
-Once the new contract is prepared for migration and **rigorously tested**, all that’s left is to migrate!
-Simply upgrade the contract and then call `migrate`.
diff --git a/content/contracts-cairo/index.mdx b/content/contracts-cairo/index.mdx
index afa7889..6e9464f 100644
--- a/content/contracts-cairo/index.mdx
+++ b/content/contracts-cairo/index.mdx
@@ -2,13 +2,15 @@
title: Contracts for Cairo
---
-**A library for secure smart contract development** written in Cairo for [Starknet](https://starkware.co/product/starknet/). This library consists of a set of [reusable components](components) to build custom smart contracts, as well as
-ready-to-deploy [presets](presets). You can also find other [utilities](/api/utilities) including [interfaces and dispatchers](interfaces) and [test utilities](/api/testing)
-that facilitate testing with Starknet Foundry.
+[starknet]:https://starkware.co/product/starknet/
+[scarb]:https://docs.swmansion.com/scarb/
+[scarb-install]:https://docs.swmansion.com/scarb/download.html
-
-This repo contains highly experimental code. Expect rapid iteration. **Use at your own risk.**
-
+
+**A library for secure smart contract development** written in Cairo for [Starknet][starknet]. This library consists of a set of
+[reusable components](/contracts-cairo/components) to build custom smart contracts, as well as ready-to-deploy [presets](/contracts-cairo/presets). You can also
+find other [utilities](/contracts-cairo/api/utilities) including [interfaces and dispatchers](/contracts-cairo/interfaces) and [test utilities](/contracts-cairo/api/testing)
+that facilitate testing with Starknet Foundry.
You can track our roadmap and future milestones in our [Github Project](https://github.com/orgs/OpenZeppelin/projects/29/).
@@ -16,7 +18,7 @@ You can track our roadmap and future milestones in our [Github Project](https://
## Installation
-The library is available as a [Scarb](https://docs.swmansion.com/scarb) package. Follow [this guide](https://docs.swmansion.com/scarb/download.html) for installing Cairo and Scarb on your machine
+The library is available as a [Scarb][scarb] package. Follow [this guide][scarb-install] for installing Cairo and Scarb on your machine
before proceeding, and run the following command to check that the installation was successful:
```bash
@@ -51,18 +53,13 @@ Scarb.toml src
### Install the library
-
+
+The `openzeppelin` package is an umbrella (meta) package that aggregates all library subpackages. Prior to v3.x, the umbrella and its subpackages were
+versioned in lockstep—their versions always matched. Starting with v3.x, following the introduction of `openzeppelin_interfaces`, the umbrella is
+versioned independently from some of the subpackages.
-The `openzeppelin` package is an umbrella package that includes all the packages in the library.
-Before version `3.x.x`, the `openzeppelin` and its sub-packages
-were versioned together meaning that the version of the `openzeppelin`
-package was the same as the version of the sub-packages.
-
-Starting from version `3.x.x`, with the introduction of the `openzeppelin_interfaces` package,
-the `openzeppelin` package is versioned independently from the sub-packages.
-
-See the [Versioning of the sub-packages](index#versioning_of_the_sub_packages) section for more information.
+See the [Versioning of the sub-packages](/contracts-cairo#versioning-of-the-sub-packages) section for more information.
@@ -70,17 +67,17 @@ Install the library by declaring it as a dependency in the project’s `Scarb.to
```javascript
[dependencies]
-openzeppelin = "3.0.0-alpha.2"
+openzeppelin = "{{umbrella_version}}"
```
The previous example would import the entire library. We can also add each package as a separate dependency to
improve the building time by not including modules that won’t be used:
-```javascript
+```toml
[dependencies]
-openzeppelin_access = "3.0.0-alpha.2"
-openzeppelin_token = "3.0.0-alpha.2"
-openzeppelin_interfaces = "1.0.0"
+openzeppelin_access = "{{umbrella_version}}"
+openzeppelin_token = "{{umbrella_version}}"
+openzeppelin_interfaces = "{{openzeppelin_interfaces_version}}"
```
## Versioning of the sub-packages
@@ -89,25 +86,25 @@ Here you can find a reference of the versioning of the sub-packages for this umb
```javascript
[dependencies]
-openzeppelin_access = "3.0.0-alpha.2"
-openzeppelin_token = "3.0.0-alpha.2"
-openzeppelin_access = "3.0.0-alpha.2"
-openzeppelin_account = "3.0.0-alpha.2"
-openzeppelin_finance = "3.0.0-alpha.2"
-openzeppelin_interfaces = "1.0.0"
-openzeppelin_governance = "3.0.0-alpha.2"
-openzeppelin_introspection = "3.0.0-alpha.2"
-openzeppelin_merkle_tree = "3.0.0-alpha.2"
-openzeppelin_presets = "3.0.0-alpha.2"
-openzeppelin_security = "3.0.0-alpha.2"
-openzeppelin_token = "3.0.0-alpha.2"
-openzeppelin_upgrades = "3.0.0-alpha.2"
-openzeppelin_utils = "3.0.0-alpha.2"
+openzeppelin_access = "{{umbrella_version}}"
+openzeppelin_token = "{{umbrella_version}}"
+openzeppelin_access = "{{umbrella_version}}"
+openzeppelin_account = "{{umbrella_version}}"
+openzeppelin_finance = "{{umbrella_version}}"
+openzeppelin_interfaces = "{{openzeppelin_interfaces_version}}"
+openzeppelin_governance = "{{umbrella_version}}"
+openzeppelin_introspection = "{{umbrella_version}}"
+openzeppelin_merkle_tree = "{{umbrella_version}}"
+openzeppelin_presets = "{{umbrella_version}}"
+openzeppelin_security = "{{umbrella_version}}"
+openzeppelin_token = "{{umbrella_version}}"
+openzeppelin_upgrades = "{{umbrella_version}}"
+openzeppelin_utils = "{{openzeppelin_utils_version}}"
```
## Basic usage
-This is how it looks to build an ERC20 contract using the [ERC20 component](erc20).
+This is how it looks to build an ERC20 contract using the [ERC20 component](/contracts-cairo/erc20).
Copy the code into `src/lib.cairo`.
```rust
diff --git a/content/contracts-cairo/interfaces.mdx b/content/contracts-cairo/interfaces.mdx
index 479a4ea..48df12f 100644
--- a/content/contracts-cairo/interfaces.mdx
+++ b/content/contracts-cairo/interfaces.mdx
@@ -10,13 +10,13 @@ The main motivation behind this separation is to decouple dependencies among pac
```javascript
[dependencies]
-openzeppelin_interfaces = "{current_openzeppelin_interfaces_version}"
+openzeppelin_interfaces = "{{openzeppelin_interfaces_version}}"
```
The version of the interfaces package is independent from the version of the implementation packages.
+The current umbrella version is `v{{umbrella_version}}`, and it depends on the `openzeppelin_interfaces` package `v{{openzeppelin_interfaces_version}}`.
-The current umbrella version is `v3.0.0-alpha.2`, and it depends on the `openzeppelin_interfaces` package `vcurrent_openzeppelin_interfaces_version`.
## Stable Versioning
diff --git a/content/contracts-cairo/introspection.mdx b/content/contracts-cairo/introspection.mdx
index 936a35d..a53f703 100644
--- a/content/contracts-cairo/introspection.mdx
+++ b/content/contracts-cairo/introspection.mdx
@@ -133,5 +133,5 @@ mod MyContract {
If you are unsure whether a contract implements SRC5 or not, you can follow the process described in
-
[here](https://github.com/starknet-io/SNIPs/blob/main/SNIPS/snip-5.md#how-to-detect-if-a-contract-implements-src-5).
+
diff --git a/content/contracts-cairo/macros.mdx b/content/contracts-cairo/macros.mdx
index 4fcb6d4..27250ab 100644
--- a/content/contracts-cairo/macros.mdx
+++ b/content/contracts-cairo/macros.mdx
@@ -6,7 +6,7 @@ This crate provides a collection of macros that streamline and simplify developm
To use them, you need to add the `openzeppelin_macros` crate as a dependency in your `Scarb.toml` file:
```toml
-openzeppelin_macros = "3.0.0-alpha.2"
+openzeppelin_macros = "{{umbrella_version}}"
```
## Attribute macros
diff --git a/content/contracts-cairo/macros/type_hash.mdx b/content/contracts-cairo/macros/type_hash.mdx
index d988f20..279090a 100644
--- a/content/contracts-cairo/macros/type_hash.mdx
+++ b/content/contracts-cairo/macros/type_hash.mdx
@@ -101,8 +101,8 @@ The list of supported collection types as defined in the SNIP-12 standard is:
While Span is not directly supported by the SNIP-12 standard, it is treated as an array for the purposes of this macro, since
-
it is sometimes helpful to use `Span` instead of `Array` in order to save on gas.
+
### Examples
diff --git a/content/contracts-cairo/macros/with_components.mdx b/content/contracts-cairo/macros/with_components.mdx
index 8e4c365..ba7a6de 100644
--- a/content/contracts-cairo/macros/with_components.mdx
+++ b/content/contracts-cairo/macros/with_components.mdx
@@ -13,8 +13,8 @@ This macro simplifies the syntax for adding a set of components to a contract. I
Since the macro does not expose any external implementations, developers must make sure to specify explicitly
-
the ones required by the contract.
+
## Security considerations
diff --git a/content/contracts-cairo/presets.mdx b/content/contracts-cairo/presets.mdx
index 96bed2c..81f1e98 100644
--- a/content/contracts-cairo/presets.mdx
+++ b/content/contracts-cairo/presets.mdx
@@ -20,18 +20,19 @@ Class hashes were computed using class-hash-cairo-version and the `scarb --relea
-Before version 3.0.0-alpha.2, class hashes were computed using the `scarb --dev` profile.
+Before version 3.0.0, class hashes were computed using the `scarb --dev` profile.
| Name | Sierra Class Hash |
| --- | --- |
-| [`AccountUpgradeable`](/api/account#AccountUpgradeable) | `0x002de258cce5b9e160bf83956b09f982059582469f7e6fad07b438128317d029` |
-| [`ERC20Upgradeable`](/api/erc20#ERC20Upgradeable) | `0x07802658d99373a4002434cbdc8897d1936c6b1beea48af0cc3b5574707f8d92` |
-| [`ERC721Upgradeable`](/api/erc721#ERC721Upgradeable) | `0x04080084ac1ba5a26b4638ac7ca2ff009a9a9b86bf6db5df05e96c90aa143df5` |
-| [`ERC1155Upgradeable`](/api/erc1155#ERC1155Upgradeable) | `0x06c8912d4397bb25c73a571bced14cedb959a7caa40b76fb0ce19a57d4a7a9c0` |
-| [`EthAccountUpgradeable`](/api/account#EthAccountUpgradeable) | `0x07f54a43da3f7beb5099c87f5627b7fba5f31c7a704cce57f8fb73287c1ea3be` |
-| [`UniversalDeployer`](/api/udc#UniversalDeployer) | `0x037f5901deb2b20bf5b2ddb04f6c770a7c5581edd68aa49f199cf74dfaf03c06` |
-| [`VestingWallet`](/api/finance#VestingWallet) | `0x062050f8eb6942d067d9d6fc6c2d01aaedbee284f339e58196d5a3bd3d4d6c6f` |
+| [`AccountUpgradeable`](/api/account#AccountUpgradeable) | `{{AccountUpgradeableClassHash}}` |
+| [`ERC20Upgradeable`](/api/erc20#ERC20Upgradeable) | `{{ERC20UpgradeableClassHash}}` |
+| [`ERC721Upgradeable`](/api/erc721#ERC721Upgradeable) | `{{ERC721UpgradeableClassHash}}` |
+| [`ERC1155Upgradeable`](/api/erc1155#ERC1155Upgradeable) | `{{ERC1155UpgradeableClassHash}}` |
+| [`EthAccountUpgradeable`](/api/account#EthAccountUpgradeable) | `{{EthAccountUpgradeableClassHash}}` |
+| [`UniversalDeployer`](/api/udc#UniversalDeployer) | `{{UniversalDeployerClassHash}}` |
+| [`VestingWallet`](/api/finance#VestingWallet) | `{{VestingWalletClassHash}}` |
+
[starkli](https://book.starkli.rs/introduction) class-hash command can be used to compute the class hash from a Sierra artifact.
@@ -49,8 +50,9 @@ starkli deploy {ERC20Upgradeable-class-hash} \
```
If a class hash has yet to be declared, copy/paste the preset contract code and declare it locally.
-Start by [setting up a project](index#set_up_your_project) and [installing the Contracts for Cairo library](index#install_the_library).
-Copy the target preset contract from the [presets directory](https://github.com/OpenZeppelin/cairo-contracts/blob/release-v3.0.0-alpha.2/packages/presets/src) and paste it in the new project’s `src/lib.cairo` like this:
+Start by [setting up a project](/contracts-cairo#set-up-your-project) and [installing the Contracts for Cairo library](/contracts-cairo#install-the-library).
+Copy the target preset contract from the [presets directory](https://github.com/OpenZeppelin/cairo-contracts/blob/release-v{{umbrella_version}}/packages/presets/src)
+and paste it in the new project’s `src/lib.cairo` like this:
```rust
// src/lib.cairo
diff --git a/content/contracts-cairo/security.mdx b/content/contracts-cairo/security.mdx
index e38df47..d098ef8 100644
--- a/content/contracts-cairo/security.mdx
+++ b/content/contracts-cairo/security.mdx
@@ -214,5 +214,5 @@ mod MyReentrancyContract {
The guard prevents the execution flow occurring inside `protected_function`
-
to call itself or `another_protected_function`, and vice versa.
+
diff --git a/content/contracts-cairo/udc.mdx b/content/contracts-cairo/udc.mdx
index 46724a2..4f453d7 100644
--- a/content/contracts-cairo/udc.mdx
+++ b/content/contracts-cairo/udc.mdx
@@ -4,7 +4,7 @@ title: Universal Deployer Contract
The Universal Deployer Contract (UDC) is a singleton smart contract that wraps the [deploy syscall](https://docs.starknet.io/architecture-and-concepts/smart-contracts/system-calls-cairo1/#deploy) to expose it to any contract that doesn’t implement it, such as account contracts. You can think of it as a standardized generic factory for Starknet contracts.
-Since Starknet has no deployment transaction type, it offers a standardized way to deploy smart contracts by following the [Standard Deployer Interface](https://community.starknet.io/t/snip-deployer-contract-interface/2772) and emitting a [ContractDeployed](/api/udc#IUniversalDeployer-ContractDeployed) event.
+Since Starknet has no deployment transaction type, it offers a standardized way to deploy smart contracts by following the [Standard Deployer Interface](https://community.starknet.io/t/snip-deployer-contract-interface/2772) and emitting a [ContractDeployed](api/udc#IUniversalDeployer-ContractDeployed) event.
For details on the motivation and the decision making process, see the [Universal Deployer Contract proposal](https://community.starknet.io/t/universal-deployer-contract-proposal/1864).
@@ -76,7 +76,7 @@ By making deployments dependent upon the origin address, users can reserve a who
Only the owner of the origin address can deploy to those addresses.
-Achieving this type of deployment necessitates that the origin sets `not_from_zero` to `true` in the [deploy_contract](/api/udc#UniversalDeployer-deploy_contract) call.
+Achieving this type of deployment necessitates that the origin sets `not_from_zero` to `true` in the [deploy_contract](api/udc#UniversalDeployer-deploy_contract) call.
Under the hood, the function passes a modified salt to the `deploy_syscall`, which is the hash of the origin’s address with the given salt.
To deploy a unique contract address pass:
@@ -104,11 +104,11 @@ See the [previous Universal Deployer API](https://docs.starknet.io/architecture-
The latest iteration of the UDC includes some notable changes to the API which include:
-* `deployContract` method is replaced with the snake_case [deploy_contract](/api/udc#UniversalDeployer-deploy_contract).
-* `unique` parameter is replaced with `not_from_zero` in both the `deploy_contract` method and [ContractDeployed](/api/udc#IUniversalDeployer-ContractDeployed) event.
+* `deployContract` method is replaced with the snake_case [deploy_contract](api/udc#UniversalDeployer-deploy_contract).
+* `unique` parameter is replaced with `not_from_zero` in both the `deploy_contract` method and [ContractDeployed](api/udc#IUniversalDeployer-ContractDeployed) event.
## Precomputing contract addresses
This library offers utility functions written in Cairo to precompute contract addresses.
-They include the generic [calculate_contract_address_from_deploy_syscall](/api/utilities#deployments-calculate_contract_address_from_deploy_syscall) as well as the UDC-specific [calculate_contract_address_from_udc](/api/utilities#deployments-calculate_contract_address_from_udc).
-Check out the [deployments](/api/utilities#deployments) for more information.
+They include the generic [calculate_contract_address_from_deploy_syscall](api/utilities#deployments-calculate_contract_address_from_deploy_syscall) as well as the UDC-specific [calculate_contract_address_from_udc](api/utilities#deployments-calculate_contract_address_from_udc).
+Check out the [deployments](api/utilities#deployments) for more information.
diff --git a/content/contracts-cairo/upgrades.mdx b/content/contracts-cairo/upgrades.mdx
index 691e042..a13de8f 100644
--- a/content/contracts-cairo/upgrades.mdx
+++ b/content/contracts-cairo/upgrades.mdx
@@ -4,7 +4,7 @@ title: Upgrades
In different blockchains, multiple patterns have been developed for making a contract upgradeable including the widely adopted proxy patterns.
-Starknet has native upgradeability through a syscall that updates the contract source code, removing [the need for proxies](#proxies_in_starknet).
+Starknet has native upgradeability through a syscall that updates the contract source code, removing [the need for proxies](#proxies-in-starknet).
Make sure you follow [our security recommendations](#security) before upgrading.
@@ -14,16 +14,21 @@ Make sure you follow [our security recommendations](#security) before upgrading.
To better comprehend how upgradeability works in Starknet, it’s important to understand the difference between a contract and its contract class.
-[Contract Classes](https://docs.starknet.io/architecture-and-concepts/smart-contracts/contract-classes/) represent the source code of a program. All contracts are associated to a class, and many contracts can be instances of the same one. Classes are usually represented by a [class hash](https://docs.starknet.io/architecture-and-concepts/smart-contracts/class-hash/), and before a contract of a class can be deployed, the class hash needs to be declared.
+[Contract Classes](https://docs.starknet.io/architecture-and-concepts/smart-contracts/contract-classes/) represent the source code of a program. All
+contracts are associated to a class, and many contracts can be instances of the same one. Classes are usually represented by
+a [class hash](https://docs.starknet.io/architecture-and-concepts/smart-contracts/class-hash/), and before a contract of a class can be deployed,
+the class hash needs to be declared.
### `replace_class_syscall`
-The `[replace_class](https://docs.starknet.io/architecture-and-concepts/smart-contracts/system-calls-cairo1/#replace_class)` syscall allows a contract to update its source code by replacing its class hash once deployed.
+The `[replace_class](https://docs.starknet.io/architecture-and-concepts/smart-contracts/system-calls-cairo1/#replace_class)` syscall allows a contract to
+update its source code by replacing its class hash once deployed.
```rust
/// Upgrades the contract source code to the new contract class.
fn upgrade(new_class_hash: ClassHash) {
- assert(!new_class_hash.is_zero(), 'Class hash cannot be zero');
+ let CLASS_HASH_CANNOT_BE_ZERO: felt252 = 0x1;
+ assert(!new_class_hash.is_zero(), CLASS_HASH_CANNOT_BE_ZERO);
starknet::replace_class_syscall(new_class_hash).unwrap_syscall();
}
```
@@ -34,12 +39,12 @@ If a contract is deployed without this mechanism, its class hash can still be re
## `Upgradeable` component
-OpenZeppelin Contracts for Cairo provides [Upgradeable](https://github.com/OpenZeppelin/cairo-contracts/blob/release-v3.0.0-alpha.2/packages/upgrades/src/upgradeable.cairo) to add upgradeability support to your contracts.
+OpenZeppelin Contracts for Cairo provides [Upgradeable](https://github.com/OpenZeppelin/cairo-contracts/blob/release-v{{umbrella_version}}/packages/upgrades/src/upgradeable.cairo) to add upgradeability support to your contracts.
### Usage
Upgrades are often very sensitive operations, and some form of access control is usually required to
-avoid unauthorized upgrades. The [Ownable](access#ownership_and_ownable) module is used in this example.
+avoid unauthorized upgrades. The [Ownable](access#ownership-and-ownable) module is used in this example.
We will be using the following module to implement the [IUpgradeable](api/upgrades#IUpgradeable) interface described in the API Reference section.
diff --git a/content/contracts-cairo/utils/_class_hashes.mdx b/content/contracts-cairo/utils/_class_hashes.mdx
deleted file mode 100644
index 57d019e..0000000
--- a/content/contracts-cairo/utils/_class_hashes.mdx
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: _class_hashes
----
-
diff --git a/content/contracts-cairo/utils/_common.mdx b/content/contracts-cairo/utils/_common.mdx
deleted file mode 100644
index 41f52f6..0000000
--- a/content/contracts-cairo/utils/_common.mdx
+++ /dev/null
@@ -1,4 +0,0 @@
----
-title: _common
----
-
diff --git a/content/contracts-cairo/utils/constants.js b/content/contracts-cairo/utils/constants.js
new file mode 100644
index 0000000..d7b5a08
--- /dev/null
+++ b/content/contracts-cairo/utils/constants.js
@@ -0,0 +1,20 @@
+export const OPENZEPPELIN_INTERFACES_VERSION = "2.1.0-alpha.0";
+export const OPENZEPPELIN_UTILS_VERSION = "3.1.0-alpha.0";
+export const UMBRELLA_VERSION = "3.0.0-alpha.1";
+
+export const CLASS_HASHES = {
+ AccountUpgradeableClassHash:
+ "0x002de258cce5b9e160bf83956b09f982059582469f7e6fad07b438128317d029",
+ ERC20UpgradeableClassHash:
+ "0x07802658d99373a4002434cbdc8897d1936c6b1beea48af0cc3b5574707f8d92",
+ ERC721UpgradeableClassHash:
+ "0x04080084ac1ba5a26b4638ac7ca2ff009a9a9b86bf6db5df05e96c90aa143df5",
+ ERC1155UpgradeableClassHash:
+ "0x06c8912d4397bb25c73a571bced14cedb959a7caa40b76fb0ce19a57d4a7a9c0",
+ EthAccountUpgradeableClassHash:
+ "0x07f54a43da3f7beb5099c87f5627b7fba5f31c7a704cce57f8fb73287c1ea3be",
+ UniversalDeployerClassHash:
+ "0x037f5901deb2b20bf5b2ddb04f6c770a7c5581edd68aa49f199cf74dfaf03c06",
+ VestingWalletClassHash:
+ "0x062050f8eb6942d067d9d6fc6c2d01aaedbee284f339e58196d5a3bd3d4d6c6f",
+};
diff --git a/content/contracts-cairo/utils/replacements.ts b/content/contracts-cairo/utils/replacements.ts
new file mode 100644
index 0000000..ca797b8
--- /dev/null
+++ b/content/contracts-cairo/utils/replacements.ts
@@ -0,0 +1,11 @@
+import { CLASS_HASHES, OPENZEPPELIN_INTERFACES_VERSION, OPENZEPPELIN_UTILS_VERSION, UMBRELLA_VERSION } from "./constants";
+
+export const REPLACEMENTS = {
+ include: ['**/content/contracts-cairo/**/*.mdx'],
+ replacements: {
+ umbrella_version: UMBRELLA_VERSION,
+ openzeppelin_interfaces_version: OPENZEPPELIN_INTERFACES_VERSION,
+ openzeppelin_utils_version: OPENZEPPELIN_UTILS_VERSION,
+ ...CLASS_HASHES,
+ }
+}
diff --git a/content/upgrades-plugins/writing-upgradeable.mdx b/content/upgrades-plugins/writing-upgradeable.mdx
index efddd46..cac11a3 100644
--- a/content/upgrades-plugins/writing-upgradeable.mdx
+++ b/content/upgrades-plugins/writing-upgradeable.mdx
@@ -386,7 +386,7 @@ Then the variable `base2` would be assigned the slot that `child` had in the pre
Storage gaps are a convention for reserving storage slots in a base contract, allowing future versions of that contract to use up those slots without affecting the storage layout of child contracts.
-To create a storage gap, declare a fixed-size array in the base contract with an initial number of slots. This can be an array of `uint256` so that each element reserves a 32 byte slot. Use the name `\\__gap` or a name starting with `__gap_` for the array so that OpenZeppelin Upgrades will recognize the gap:
+To create a storage gap, declare a fixed-size array in the base contract with an initial number of slots. This can be an array of `uint256` so that each element reserves a 32 byte slot. Use the name `__gap` or a name starting with `__gap_` for the array so that OpenZeppelin Upgrades will recognize the gap:
```solidity
contract Base
diff --git a/package.json b/package.json
index 3d60d9f..664e480 100644
--- a/package.json
+++ b/package.json
@@ -2,6 +2,7 @@
"name": "docs",
"version": "0.0.0",
"private": true,
+ "type": "module",
"scripts": {
"build": "NODE_OPTIONS=\"--max-old-space-size=8192\" next build",
"dev": "next dev --turbo",
@@ -35,7 +36,8 @@
"katex": "^0.16.22",
"lucide-react": "^0.540.0",
"mermaid": "^11.11.0",
- "next": "15.4.5",
+ "micromatch": "^4.0.8",
+ "next": "^15.5.3",
"next-themes": "^0.4.6",
"react": "^19.1.1",
"react-dom": "^19.1.1",
@@ -45,13 +47,15 @@
"remark-math": "^6.0.0",
"remark-mdx": "^3.1.1",
"shiki": "^3.12.2",
- "tailwind-merge": "^3.3.1"
+ "tailwind-merge": "^3.3.1",
+ "unist-util-visit": "^5.0.0"
},
"devDependencies": {
"@biomejs/biome": "^2.2.4",
"@tailwindcss/postcss": "^4.1.13",
"@tanstack/react-query-devtools": "^5.89.0",
"@types/mdx": "^2.0.13",
+ "@types/micromatch": "^4.0.9",
"@types/node": "24.1.0",
"@types/react": "^19.1.12",
"@types/react-dom": "^19.1.9",
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index bfebfce..701112e 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -10,7 +10,7 @@ importers:
dependencies:
'@fumadocs/mdx-remote':
specifier: ^1.4.0
- version: 1.4.0(@types/react@19.1.12)(fumadocs-core@15.7.11(@types/react@19.1.12)(algoliasearch@5.37.0)(next@15.4.5(react-dom@19.1.1(react@19.1.1))(react@19.1.1))(react-dom@19.1.1(react@19.1.1))(react@19.1.1))(react@19.1.1)
+ version: 1.4.0(@types/react@19.1.12)(fumadocs-core@15.7.11(@types/react@19.1.12)(algoliasearch@5.37.0)(next@15.5.3(react-dom@19.1.1(react@19.1.1))(react@19.1.1))(react-dom@19.1.1(react@19.1.1))(react@19.1.1))(react@19.1.1)
'@netlify/plugin-nextjs':
specifier: ^5.13.1
version: 5.13.1
@@ -46,16 +46,16 @@ importers:
version: 2.1.1
fumadocs-core:
specifier: 15.7.11
- version: 15.7.11(@types/react@19.1.12)(algoliasearch@5.37.0)(next@15.4.5(react-dom@19.1.1(react@19.1.1))(react@19.1.1))(react-dom@19.1.1(react@19.1.1))(react@19.1.1)
+ version: 15.7.11(@types/react@19.1.12)(algoliasearch@5.37.0)(next@15.5.3(react-dom@19.1.1(react@19.1.1))(react@19.1.1))(react-dom@19.1.1(react@19.1.1))(react@19.1.1)
fumadocs-mdx:
specifier: 11.9.1
- version: 11.9.1(@fumadocs/mdx-remote@1.4.0(@types/react@19.1.12)(fumadocs-core@15.7.11(@types/react@19.1.12)(algoliasearch@5.37.0)(next@15.4.5(react-dom@19.1.1(react@19.1.1))(react@19.1.1))(react-dom@19.1.1(react@19.1.1))(react@19.1.1))(react@19.1.1))(fumadocs-core@15.7.11(@types/react@19.1.12)(algoliasearch@5.37.0)(next@15.4.5(react-dom@19.1.1(react@19.1.1))(react@19.1.1))(react-dom@19.1.1(react@19.1.1))(react@19.1.1))(next@15.4.5(react-dom@19.1.1(react@19.1.1))(react@19.1.1))(react@19.1.1)
+ version: 11.9.1(@fumadocs/mdx-remote@1.4.0(@types/react@19.1.12)(fumadocs-core@15.7.11(@types/react@19.1.12)(algoliasearch@5.37.0)(next@15.5.3(react-dom@19.1.1(react@19.1.1))(react@19.1.1))(react-dom@19.1.1(react@19.1.1))(react@19.1.1))(react@19.1.1))(fumadocs-core@15.7.11(@types/react@19.1.12)(algoliasearch@5.37.0)(next@15.5.3(react-dom@19.1.1(react@19.1.1))(react@19.1.1))(react-dom@19.1.1(react@19.1.1))(react@19.1.1))(next@15.5.3(react-dom@19.1.1(react@19.1.1))(react@19.1.1))(react@19.1.1)
fumadocs-openapi:
specifier: ^9.3.8
- version: 9.3.8(@types/react-dom@19.1.9(@types/react@19.1.12))(@types/react@19.1.12)(algoliasearch@5.37.0)(next@15.4.5(react-dom@19.1.1(react@19.1.1))(react@19.1.1))(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(tailwindcss@4.1.13)(typescript@5.9.2)
+ version: 9.3.8(@types/react-dom@19.1.9(@types/react@19.1.12))(@types/react@19.1.12)(algoliasearch@5.37.0)(next@15.5.3(react-dom@19.1.1(react@19.1.1))(react@19.1.1))(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(tailwindcss@4.1.13)(typescript@5.9.2)
fumadocs-ui:
specifier: 15.7.11
- version: 15.7.11(@types/react-dom@19.1.9(@types/react@19.1.12))(@types/react@19.1.12)(algoliasearch@5.37.0)(next@15.4.5(react-dom@19.1.1(react@19.1.1))(react@19.1.1))(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(tailwindcss@4.1.13)
+ version: 15.7.11(@types/react-dom@19.1.9(@types/react@19.1.12))(@types/react@19.1.12)(algoliasearch@5.37.0)(next@15.5.3(react-dom@19.1.1(react@19.1.1))(react@19.1.1))(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(tailwindcss@4.1.13)
glob:
specifier: ^11.0.3
version: 11.0.3
@@ -68,9 +68,12 @@ importers:
mermaid:
specifier: ^11.11.0
version: 11.11.0
+ micromatch:
+ specifier: ^4.0.8
+ version: 4.0.8
next:
- specifier: 15.4.5
- version: 15.4.5(react-dom@19.1.1(react@19.1.1))(react@19.1.1)
+ specifier: ^15.5.3
+ version: 15.5.3(react-dom@19.1.1(react@19.1.1))(react@19.1.1)
next-themes:
specifier: ^0.4.6
version: 0.4.6(react-dom@19.1.1(react@19.1.1))(react@19.1.1)
@@ -101,6 +104,9 @@ importers:
tailwind-merge:
specifier: ^3.3.1
version: 3.3.1
+ unist-util-visit:
+ specifier: ^5.0.0
+ version: 5.0.0
devDependencies:
'@biomejs/biome':
specifier: ^2.2.4
@@ -114,6 +120,9 @@ importers:
'@types/mdx':
specifier: ^2.0.13
version: 2.0.13
+ '@types/micromatch':
+ specifier: ^4.0.9
+ version: 4.0.9
'@types/node':
specifier: 24.1.0
version: 24.1.0
@@ -660,53 +669,53 @@ packages:
resolution: {integrity: sha512-dAswWBpvjtkqTd6AmgPfwQI7kNnCEnaz0SjlWYtN/H0FTY6fkpo+0yq8fVKWzKu+5ckO0QzNPMoWfJ4chDXcrw==}
engines: {node: '>=18.0.0'}
- '@next/env@15.4.5':
- resolution: {integrity: sha512-ruM+q2SCOVCepUiERoxOmZY9ZVoecR3gcXNwCYZRvQQWRjhOiPJGmQ2fAiLR6YKWXcSAh7G79KEFxN3rwhs4LQ==}
+ '@next/env@15.5.3':
+ resolution: {integrity: sha512-RSEDTRqyihYXygx/OJXwvVupfr9m04+0vH8vyy0HfZ7keRto6VX9BbEk0J2PUk0VGy6YhklJUSrgForov5F9pw==}
- '@next/swc-darwin-arm64@15.4.5':
- resolution: {integrity: sha512-84dAN4fkfdC7nX6udDLz9GzQlMUwEMKD7zsseXrl7FTeIItF8vpk1lhLEnsotiiDt+QFu3O1FVWnqwcRD2U3KA==}
+ '@next/swc-darwin-arm64@15.5.3':
+ resolution: {integrity: sha512-nzbHQo69+au9wJkGKTU9lP7PXv0d1J5ljFpvb+LnEomLtSbJkbZyEs6sbF3plQmiOB2l9OBtN2tNSvCH1nQ9Jg==}
engines: {node: '>= 10'}
cpu: [arm64]
os: [darwin]
- '@next/swc-darwin-x64@15.4.5':
- resolution: {integrity: sha512-CL6mfGsKuFSyQjx36p2ftwMNSb8PQog8y0HO/ONLdQqDql7x3aJb/wB+LA651r4we2pp/Ck+qoRVUeZZEvSurA==}
+ '@next/swc-darwin-x64@15.5.3':
+ resolution: {integrity: sha512-w83w4SkOOhekJOcA5HBvHyGzgV1W/XvOfpkrxIse4uPWhYTTRwtGEM4v/jiXwNSJvfRvah0H8/uTLBKRXlef8g==}
engines: {node: '>= 10'}
cpu: [x64]
os: [darwin]
- '@next/swc-linux-arm64-gnu@15.4.5':
- resolution: {integrity: sha512-1hTVd9n6jpM/thnDc5kYHD1OjjWYpUJrJxY4DlEacT7L5SEOXIifIdTye6SQNNn8JDZrcN+n8AWOmeJ8u3KlvQ==}
+ '@next/swc-linux-arm64-gnu@15.5.3':
+ resolution: {integrity: sha512-+m7pfIs0/yvgVu26ieaKrifV8C8yiLe7jVp9SpcIzg7XmyyNE7toC1fy5IOQozmr6kWl/JONC51osih2RyoXRw==}
engines: {node: '>= 10'}
cpu: [arm64]
os: [linux]
- '@next/swc-linux-arm64-musl@15.4.5':
- resolution: {integrity: sha512-4W+D/nw3RpIwGrqpFi7greZ0hjrCaioGErI7XHgkcTeWdZd146NNu1s4HnaHonLeNTguKnL2Urqvj28UJj6Gqw==}
+ '@next/swc-linux-arm64-musl@15.5.3':
+ resolution: {integrity: sha512-u3PEIzuguSenoZviZJahNLgCexGFhso5mxWCrrIMdvpZn6lkME5vc/ADZG8UUk5K1uWRy4hqSFECrON6UKQBbQ==}
engines: {node: '>= 10'}
cpu: [arm64]
os: [linux]
- '@next/swc-linux-x64-gnu@15.4.5':
- resolution: {integrity: sha512-N6Mgdxe/Cn2K1yMHge6pclffkxzbSGOydXVKYOjYqQXZYjLCfN/CuFkaYDeDHY2VBwSHyM2fUjYBiQCIlxIKDA==}
+ '@next/swc-linux-x64-gnu@15.5.3':
+ resolution: {integrity: sha512-lDtOOScYDZxI2BENN9m0pfVPJDSuUkAD1YXSvlJF0DKwZt0WlA7T7o3wrcEr4Q+iHYGzEaVuZcsIbCps4K27sA==}
engines: {node: '>= 10'}
cpu: [x64]
os: [linux]
- '@next/swc-linux-x64-musl@15.4.5':
- resolution: {integrity: sha512-YZ3bNDrS8v5KiqgWE0xZQgtXgCTUacgFtnEgI4ccotAASwSvcMPDLua7BWLuTfucoRv6mPidXkITJLd8IdJplQ==}
+ '@next/swc-linux-x64-musl@15.5.3':
+ resolution: {integrity: sha512-9vWVUnsx9PrY2NwdVRJ4dUURAQ8Su0sLRPqcCCxtX5zIQUBES12eRVHq6b70bbfaVaxIDGJN2afHui0eDm+cLg==}
engines: {node: '>= 10'}
cpu: [x64]
os: [linux]
- '@next/swc-win32-arm64-msvc@15.4.5':
- resolution: {integrity: sha512-9Wr4t9GkZmMNcTVvSloFtjzbH4vtT4a8+UHqDoVnxA5QyfWe6c5flTH1BIWPGNWSUlofc8dVJAE7j84FQgskvQ==}
+ '@next/swc-win32-arm64-msvc@15.5.3':
+ resolution: {integrity: sha512-1CU20FZzY9LFQigRi6jM45oJMU3KziA5/sSG+dXeVaTm661snQP6xu3ykGxxwU5sLG3sh14teO/IOEPVsQMRfA==}
engines: {node: '>= 10'}
cpu: [arm64]
os: [win32]
- '@next/swc-win32-x64-msvc@15.4.5':
- resolution: {integrity: sha512-voWk7XtGvlsP+w8VBz7lqp8Y+dYw/MTI4KeS0gTVtfdhdJ5QwhXLmNrndFOin/MDoCvUaLWMkYKATaCoUkt2/A==}
+ '@next/swc-win32-x64-msvc@15.5.3':
+ resolution: {integrity: sha512-JMoLAq3n3y5tKXPQwCK5c+6tmwkuFDa2XAxz8Wm4+IVthdBZdZGh+lmiLUHg9f9IDwIQpUjp+ysd6OkYTyZRZw==}
engines: {node: '>= 10'}
cpu: [x64]
os: [win32]
@@ -1259,6 +1268,9 @@ packages:
peerDependencies:
react: ^18 || ^19
+ '@types/braces@3.0.5':
+ resolution: {integrity: sha512-SQFof9H+LXeWNz8wDe7oN5zu7ket0qwMu5vZubW4GCJ8Kkeh6nBWUz87+KTz/G3Kqsrp0j/W253XJb3KMEeg3w==}
+
'@types/d3-array@3.2.1':
resolution: {integrity: sha512-Y2Jn2idRrLzUfAKV2LyRImR+y4oa2AntrgID95SHJxuMUrkNXmanDSed71sRNZysveJVt1hLLemQZIady0FpEg==}
@@ -1379,6 +1391,9 @@ packages:
'@types/mdx@2.0.13':
resolution: {integrity: sha512-+OWZQfAYyio6YkJb3HLxDrvnx6SWWDbC0zVPfBRzUk0/nqoDyf6dNxQi3eArPe8rJ473nobTMQ/8Zk+LxJ+Yuw==}
+ '@types/micromatch@4.0.9':
+ resolution: {integrity: sha512-7V+8ncr22h4UoYRLnLXSpTxjQrNUXtWHGeMPRJt1nULXI57G9bIcpyrHlmrQ7QK24EyyuXvYcSSWAM8GA9nqCg==}
+
'@types/ms@2.1.0':
resolution: {integrity: sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==}
@@ -1500,6 +1515,10 @@ packages:
bail@2.0.2:
resolution: {integrity: sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw==}
+ braces@3.0.3:
+ resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==}
+ engines: {node: '>=8'}
+
caniuse-lite@1.0.30001741:
resolution: {integrity: sha512-QGUGitqsc8ARjLdgAfxETDhRbJ0REsP6O3I96TAth/mVjh2cYzN2u+3AzPP3aVSm2FehEItaJw1xd+IGBXWeSw==}
@@ -1887,6 +1906,10 @@ packages:
picomatch:
optional: true
+ fill-range@7.1.1:
+ resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==}
+ engines: {node: '>=8'}
+
foreach@2.0.6:
resolution: {integrity: sha512-k6GAGDyqLe9JaebCsFCoudPPWfihKu8pylYXRlqP1J7ms39iPoTtk2fviNglIeQEwdh0bQeKJ01ZPyuyQvKzwg==}
@@ -2087,6 +2110,10 @@ packages:
is-hexadecimal@2.0.1:
resolution: {integrity: sha512-DgZQp241c8oO6cA1SbTEWiXeoxV42vlcJxgH+B3hi1AiqqKruZR3ZGF8In3fj4+/y/7rHvlOZLZtgJ/4ttYGZg==}
+ is-number@7.0.0:
+ resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==}
+ engines: {node: '>=0.12.0'}
+
is-plain-obj@4.1.0:
resolution: {integrity: sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==}
engines: {node: '>=12'}
@@ -2411,6 +2438,10 @@ packages:
micromark@4.0.2:
resolution: {integrity: sha512-zpe98Q6kvavpCr1NPVSCMebCKfD7CA2NqZ+rykeNhONIJBpc1tFKt9hucLGwha3jNTNI8lHpctWJWoimVF4PfA==}
+ micromatch@4.0.8:
+ resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==}
+ engines: {node: '>=8.6'}
+
minimatch@10.0.3:
resolution: {integrity: sha512-IPZ167aShDZZUMdRk66cyQAW3qr0WzbHkPdMYa8bzZhlHhO3jALbKdxcaak7W9FfT2rZNpQuUu4Od7ILEpXSaw==}
engines: {node: 20 || >=22}
@@ -2449,8 +2480,8 @@ packages:
react: ^16.8 || ^17 || ^18 || ^19 || ^19.0.0-rc
react-dom: ^16.8 || ^17 || ^18 || ^19 || ^19.0.0-rc
- next@15.4.5:
- resolution: {integrity: sha512-nJ4v+IO9CPmbmcvsPebIoX3Q+S7f6Fu08/dEWu0Ttfa+wVwQRh9epcmsyCPjmL2b8MxC+CkBR97jgDhUUztI3g==}
+ next@15.5.3:
+ resolution: {integrity: sha512-r/liNAx16SQj4D+XH/oI1dlpv9tdKJ6cONYPwwcCC46f2NjpaRWY+EKCzULfgQYV6YKXjHBchff2IZBSlZmJNw==}
engines: {node: ^18.18.0 || ^19.8.0 || >= 20.0.0}
hasBin: true
peerDependencies:
@@ -2512,6 +2543,10 @@ packages:
picocolors@1.1.1:
resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==}
+ picomatch@2.3.1:
+ resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==}
+ engines: {node: '>=8.6'}
+
picomatch@4.0.3:
resolution: {integrity: sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==}
engines: {node: '>=12'}
@@ -2795,6 +2830,10 @@ packages:
resolution: {integrity: sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==}
engines: {node: '>=12.0.0'}
+ to-regex-range@5.0.1:
+ resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==}
+ engines: {node: '>=8.0'}
+
trim-lines@3.0.1:
resolution: {integrity: sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==}
@@ -3223,10 +3262,10 @@ snapshots:
dependencies:
tslib: 2.8.1
- '@fumadocs/mdx-remote@1.4.0(@types/react@19.1.12)(fumadocs-core@15.7.11(@types/react@19.1.12)(algoliasearch@5.37.0)(next@15.4.5(react-dom@19.1.1(react@19.1.1))(react@19.1.1))(react-dom@19.1.1(react@19.1.1))(react@19.1.1))(react@19.1.1)':
+ '@fumadocs/mdx-remote@1.4.0(@types/react@19.1.12)(fumadocs-core@15.7.11(@types/react@19.1.12)(algoliasearch@5.37.0)(next@15.5.3(react-dom@19.1.1(react@19.1.1))(react@19.1.1))(react-dom@19.1.1(react@19.1.1))(react@19.1.1))(react@19.1.1)':
dependencies:
'@mdx-js/mdx': 3.1.1
- fumadocs-core: 15.7.11(@types/react@19.1.12)(algoliasearch@5.37.0)(next@15.4.5(react-dom@19.1.1(react@19.1.1))(react@19.1.1))(react-dom@19.1.1(react@19.1.1))(react@19.1.1)
+ fumadocs-core: 15.7.11(@types/react@19.1.12)(algoliasearch@5.37.0)(next@15.5.3(react-dom@19.1.1(react@19.1.1))(react@19.1.1))(react-dom@19.1.1(react@19.1.1))(react@19.1.1)
gray-matter: 4.0.3
react: 19.1.1
zod: 4.1.8
@@ -3418,30 +3457,30 @@ snapshots:
'@netlify/plugin-nextjs@5.13.1': {}
- '@next/env@15.4.5': {}
+ '@next/env@15.5.3': {}
- '@next/swc-darwin-arm64@15.4.5':
+ '@next/swc-darwin-arm64@15.5.3':
optional: true
- '@next/swc-darwin-x64@15.4.5':
+ '@next/swc-darwin-x64@15.5.3':
optional: true
- '@next/swc-linux-arm64-gnu@15.4.5':
+ '@next/swc-linux-arm64-gnu@15.5.3':
optional: true
- '@next/swc-linux-arm64-musl@15.4.5':
+ '@next/swc-linux-arm64-musl@15.5.3':
optional: true
- '@next/swc-linux-x64-gnu@15.4.5':
+ '@next/swc-linux-x64-gnu@15.5.3':
optional: true
- '@next/swc-linux-x64-musl@15.4.5':
+ '@next/swc-linux-x64-musl@15.5.3':
optional: true
- '@next/swc-win32-arm64-msvc@15.4.5':
+ '@next/swc-win32-arm64-msvc@15.5.3':
optional: true
- '@next/swc-win32-x64-msvc@15.4.5':
+ '@next/swc-win32-x64-msvc@15.5.3':
optional: true
'@orama/orama@3.1.13': {}
@@ -4010,6 +4049,8 @@ snapshots:
'@tanstack/query-core': 5.89.0
react: 19.1.1
+ '@types/braces@3.0.5': {}
+
'@types/d3-array@3.2.1': {}
'@types/d3-axis@3.0.6':
@@ -4153,6 +4194,10 @@ snapshots:
'@types/mdx@2.0.13': {}
+ '@types/micromatch@4.0.9':
+ dependencies:
+ '@types/braces': 3.0.5
+
'@types/ms@2.1.0': {}
'@types/node@24.1.0':
@@ -4292,6 +4337,10 @@ snapshots:
bail@2.0.2: {}
+ braces@3.0.3:
+ dependencies:
+ fill-range: 7.1.1
+
caniuse-lite@1.0.30001741: {}
ccount@2.0.1: {}
@@ -4715,6 +4764,10 @@ snapshots:
optionalDependencies:
picomatch: 4.0.3
+ fill-range@7.1.1:
+ dependencies:
+ to-regex-range: 5.0.1
+
foreach@2.0.6: {}
foreground-child@3.3.1:
@@ -4722,7 +4775,7 @@ snapshots:
cross-spawn: 7.0.6
signal-exit: 4.1.0
- fumadocs-core@15.7.11(@types/react@19.1.12)(algoliasearch@5.37.0)(next@15.4.5(react-dom@19.1.1(react@19.1.1))(react@19.1.1))(react-dom@19.1.1(react@19.1.1))(react@19.1.1):
+ fumadocs-core@15.7.11(@types/react@19.1.12)(algoliasearch@5.37.0)(next@15.5.3(react-dom@19.1.1(react@19.1.1))(react@19.1.1))(react-dom@19.1.1(react@19.1.1))(react@19.1.1):
dependencies:
'@formatjs/intl-localematcher': 0.6.1
'@orama/orama': 3.1.13
@@ -4744,20 +4797,20 @@ snapshots:
optionalDependencies:
'@types/react': 19.1.12
algoliasearch: 5.37.0
- next: 15.4.5(react-dom@19.1.1(react@19.1.1))(react@19.1.1)
+ next: 15.5.3(react-dom@19.1.1(react@19.1.1))(react@19.1.1)
react: 19.1.1
react-dom: 19.1.1(react@19.1.1)
transitivePeerDependencies:
- supports-color
- fumadocs-mdx@11.9.1(@fumadocs/mdx-remote@1.4.0(@types/react@19.1.12)(fumadocs-core@15.7.11(@types/react@19.1.12)(algoliasearch@5.37.0)(next@15.4.5(react-dom@19.1.1(react@19.1.1))(react@19.1.1))(react-dom@19.1.1(react@19.1.1))(react@19.1.1))(react@19.1.1))(fumadocs-core@15.7.11(@types/react@19.1.12)(algoliasearch@5.37.0)(next@15.4.5(react-dom@19.1.1(react@19.1.1))(react@19.1.1))(react-dom@19.1.1(react@19.1.1))(react@19.1.1))(next@15.4.5(react-dom@19.1.1(react@19.1.1))(react@19.1.1))(react@19.1.1):
+ fumadocs-mdx@11.9.1(@fumadocs/mdx-remote@1.4.0(@types/react@19.1.12)(fumadocs-core@15.7.11(@types/react@19.1.12)(algoliasearch@5.37.0)(next@15.5.3(react-dom@19.1.1(react@19.1.1))(react@19.1.1))(react-dom@19.1.1(react@19.1.1))(react@19.1.1))(react@19.1.1))(fumadocs-core@15.7.11(@types/react@19.1.12)(algoliasearch@5.37.0)(next@15.5.3(react-dom@19.1.1(react@19.1.1))(react@19.1.1))(react-dom@19.1.1(react@19.1.1))(react@19.1.1))(next@15.5.3(react-dom@19.1.1(react@19.1.1))(react@19.1.1))(react@19.1.1):
dependencies:
'@mdx-js/mdx': 3.1.1
'@standard-schema/spec': 1.0.0
chokidar: 4.0.3
esbuild: 0.25.9
estree-util-value-to-estree: 3.4.0
- fumadocs-core: 15.7.11(@types/react@19.1.12)(algoliasearch@5.37.0)(next@15.4.5(react-dom@19.1.1(react@19.1.1))(react@19.1.1))(react-dom@19.1.1(react@19.1.1))(react@19.1.1)
+ fumadocs-core: 15.7.11(@types/react@19.1.12)(algoliasearch@5.37.0)(next@15.5.3(react-dom@19.1.1(react@19.1.1))(react@19.1.1))(react-dom@19.1.1(react@19.1.1))(react@19.1.1)
js-yaml: 4.1.0
lru-cache: 11.2.1
picocolors: 1.1.1
@@ -4769,13 +4822,13 @@ snapshots:
unist-util-visit: 5.0.0
zod: 4.1.8
optionalDependencies:
- '@fumadocs/mdx-remote': 1.4.0(@types/react@19.1.12)(fumadocs-core@15.7.11(@types/react@19.1.12)(algoliasearch@5.37.0)(next@15.4.5(react-dom@19.1.1(react@19.1.1))(react@19.1.1))(react-dom@19.1.1(react@19.1.1))(react@19.1.1))(react@19.1.1)
- next: 15.4.5(react-dom@19.1.1(react@19.1.1))(react@19.1.1)
+ '@fumadocs/mdx-remote': 1.4.0(@types/react@19.1.12)(fumadocs-core@15.7.11(@types/react@19.1.12)(algoliasearch@5.37.0)(next@15.5.3(react-dom@19.1.1(react@19.1.1))(react@19.1.1))(react-dom@19.1.1(react@19.1.1))(react@19.1.1))(react@19.1.1)
+ next: 15.5.3(react-dom@19.1.1(react@19.1.1))(react@19.1.1)
react: 19.1.1
transitivePeerDependencies:
- supports-color
- fumadocs-openapi@9.3.8(@types/react-dom@19.1.9(@types/react@19.1.12))(@types/react@19.1.12)(algoliasearch@5.37.0)(next@15.4.5(react-dom@19.1.1(react@19.1.1))(react@19.1.1))(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(tailwindcss@4.1.13)(typescript@5.9.2):
+ fumadocs-openapi@9.3.8(@types/react-dom@19.1.9(@types/react@19.1.12))(@types/react@19.1.12)(algoliasearch@5.37.0)(next@15.5.3(react-dom@19.1.1(react@19.1.1))(react@19.1.1))(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(tailwindcss@4.1.13)(typescript@5.9.2):
dependencies:
'@fumari/json-schema-to-typescript': 1.1.3
'@radix-ui/react-accordion': 1.2.12(@types/react-dom@19.1.9(@types/react@19.1.12))(@types/react@19.1.12)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)
@@ -4786,8 +4839,8 @@ snapshots:
'@scalar/openapi-parser': 0.20.3(typescript@5.9.2)
ajv: 8.17.1
class-variance-authority: 0.7.1
- fumadocs-core: 15.7.11(@types/react@19.1.12)(algoliasearch@5.37.0)(next@15.4.5(react-dom@19.1.1(react@19.1.1))(react@19.1.1))(react-dom@19.1.1(react@19.1.1))(react@19.1.1)
- fumadocs-ui: 15.7.11(@types/react-dom@19.1.9(@types/react@19.1.12))(@types/react@19.1.12)(algoliasearch@5.37.0)(next@15.4.5(react-dom@19.1.1(react@19.1.1))(react@19.1.1))(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(tailwindcss@4.1.13)
+ fumadocs-core: 15.7.11(@types/react@19.1.12)(algoliasearch@5.37.0)(next@15.5.3(react-dom@19.1.1(react@19.1.1))(react@19.1.1))(react-dom@19.1.1(react@19.1.1))(react@19.1.1)
+ fumadocs-ui: 15.7.11(@types/react-dom@19.1.9(@types/react@19.1.12))(@types/react@19.1.12)(algoliasearch@5.37.0)(next@15.5.3(react-dom@19.1.1(react@19.1.1))(react@19.1.1))(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(tailwindcss@4.1.13)
github-slugger: 2.0.0
gray-matter: 4.0.3
hast-util-to-jsx-runtime: 2.3.6
@@ -4816,7 +4869,7 @@ snapshots:
- typescript
- waku
- fumadocs-ui@15.7.11(@types/react-dom@19.1.9(@types/react@19.1.12))(@types/react@19.1.12)(algoliasearch@5.37.0)(next@15.4.5(react-dom@19.1.1(react@19.1.1))(react@19.1.1))(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(tailwindcss@4.1.13):
+ fumadocs-ui@15.7.11(@types/react-dom@19.1.9(@types/react@19.1.12))(@types/react@19.1.12)(algoliasearch@5.37.0)(next@15.5.3(react-dom@19.1.1(react@19.1.1))(react@19.1.1))(react-dom@19.1.1(react@19.1.1))(react@19.1.1)(tailwindcss@4.1.13):
dependencies:
'@radix-ui/react-accordion': 1.2.12(@types/react-dom@19.1.9(@types/react@19.1.12))(@types/react@19.1.12)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)
'@radix-ui/react-collapsible': 1.1.12(@types/react-dom@19.1.9(@types/react@19.1.12))(@types/react@19.1.12)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)
@@ -4829,7 +4882,7 @@ snapshots:
'@radix-ui/react-slot': 1.2.3(@types/react@19.1.12)(react@19.1.1)
'@radix-ui/react-tabs': 1.1.13(@types/react-dom@19.1.9(@types/react@19.1.12))(@types/react@19.1.12)(react-dom@19.1.1(react@19.1.1))(react@19.1.1)
class-variance-authority: 0.7.1
- fumadocs-core: 15.7.11(@types/react@19.1.12)(algoliasearch@5.37.0)(next@15.4.5(react-dom@19.1.1(react@19.1.1))(react@19.1.1))(react-dom@19.1.1(react@19.1.1))(react@19.1.1)
+ fumadocs-core: 15.7.11(@types/react@19.1.12)(algoliasearch@5.37.0)(next@15.5.3(react-dom@19.1.1(react@19.1.1))(react@19.1.1))(react-dom@19.1.1(react@19.1.1))(react@19.1.1)
lodash.merge: 4.6.2
next-themes: 0.4.6(react-dom@19.1.1(react@19.1.1))(react@19.1.1)
postcss-selector-parser: 7.1.0
@@ -4840,7 +4893,7 @@ snapshots:
tailwind-merge: 3.3.1
optionalDependencies:
'@types/react': 19.1.12
- next: 15.4.5(react-dom@19.1.1(react@19.1.1))(react@19.1.1)
+ next: 15.5.3(react-dom@19.1.1(react@19.1.1))(react@19.1.1)
tailwindcss: 4.1.13
transitivePeerDependencies:
- '@mixedbread/sdk'
@@ -5029,6 +5082,8 @@ snapshots:
is-hexadecimal@2.0.1: {}
+ is-number@7.0.0: {}
+
is-plain-obj@4.1.0: {}
isexe@2.0.0: {}
@@ -5627,6 +5682,11 @@ snapshots:
transitivePeerDependencies:
- supports-color
+ micromatch@4.0.8:
+ dependencies:
+ braces: 3.0.3
+ picomatch: 2.3.1
+
minimatch@10.0.3:
dependencies:
'@isaacs/brace-expansion': 5.0.0
@@ -5657,9 +5717,9 @@ snapshots:
react: 19.1.1
react-dom: 19.1.1(react@19.1.1)
- next@15.4.5(react-dom@19.1.1(react@19.1.1))(react@19.1.1):
+ next@15.5.3(react-dom@19.1.1(react@19.1.1))(react@19.1.1):
dependencies:
- '@next/env': 15.4.5
+ '@next/env': 15.5.3
'@swc/helpers': 0.5.15
caniuse-lite: 1.0.30001741
postcss: 8.4.31
@@ -5667,14 +5727,14 @@ snapshots:
react-dom: 19.1.1(react@19.1.1)
styled-jsx: 5.1.6(react@19.1.1)
optionalDependencies:
- '@next/swc-darwin-arm64': 15.4.5
- '@next/swc-darwin-x64': 15.4.5
- '@next/swc-linux-arm64-gnu': 15.4.5
- '@next/swc-linux-arm64-musl': 15.4.5
- '@next/swc-linux-x64-gnu': 15.4.5
- '@next/swc-linux-x64-musl': 15.4.5
- '@next/swc-win32-arm64-msvc': 15.4.5
- '@next/swc-win32-x64-msvc': 15.4.5
+ '@next/swc-darwin-arm64': 15.5.3
+ '@next/swc-darwin-x64': 15.5.3
+ '@next/swc-linux-arm64-gnu': 15.5.3
+ '@next/swc-linux-arm64-musl': 15.5.3
+ '@next/swc-linux-x64-gnu': 15.5.3
+ '@next/swc-linux-x64-musl': 15.5.3
+ '@next/swc-win32-arm64-msvc': 15.5.3
+ '@next/swc-win32-x64-msvc': 15.5.3
sharp: 0.34.3
transitivePeerDependencies:
- '@babel/core'
@@ -5727,6 +5787,8 @@ snapshots:
picocolors@1.1.1: {}
+ picomatch@2.3.1: {}
+
picomatch@4.0.3: {}
pkg-types@1.3.1:
@@ -6091,6 +6153,10 @@ snapshots:
fdir: 6.5.0(picomatch@4.0.3)
picomatch: 4.0.3
+ to-regex-range@5.0.1:
+ dependencies:
+ is-number: 7.0.0
+
trim-lines@3.0.1: {}
trough@2.2.0: {}
diff --git a/source.config.ts b/source.config.ts
index 80b409a..a1a011b 100644
--- a/source.config.ts
+++ b/source.config.ts
@@ -2,6 +2,8 @@ import { defineConfig, defineDocs } from "fumadocs-mdx/config";
import remarkMath from "remark-math";
import rehypeKatex from "rehype-katex";
import { remarkMdxMermaid } from "fumadocs-core/mdx-plugins";
+import remarkReplace from "@/lib/remark-replace";
+import { REPLACEMENTS as cairoContractReplacements } from "content/contracts-cairo/utils/replacements";
// You can customise Zod schemas for frontmatter and `meta.json` here
// see https://fumadocs.vercel.app/docs/mdx/collections#define-docs
@@ -25,7 +27,14 @@ export default defineConfig({
dark: "github-dark",
},
},
- remarkPlugins: [remarkMath, remarkMdxMermaid],
+ remarkPlugins: [remarkMath, remarkMdxMermaid,
+ [
+ remarkReplace,
+ [
+ cairoContractReplacements,
+ ]
+ ],
+ ],
rehypePlugins: (v) => [rehypeKatex, ...v],
},
});
diff --git a/src/components/ui/api-reference/api-github-link-header.tsx b/src/components/ui/api-reference/api-github-link-header.tsx
new file mode 100644
index 0000000..cde8684
--- /dev/null
+++ b/src/components/ui/api-reference/api-github-link-header.tsx
@@ -0,0 +1,39 @@
+export function APIGithubLinkHeader({
+ moduleName,
+ link,
+}: {
+ moduleName: string;
+ link: string;
+}) {
+ const id = moduleName;
+ return (
+
+ );
+}
diff --git a/src/components/ui/api-reference/api-item.tsx b/src/components/ui/api-reference/api-item.tsx
new file mode 100644
index 0000000..fbf270f
--- /dev/null
+++ b/src/components/ui/api-reference/api-item.tsx
@@ -0,0 +1,37 @@
+import type * as React from "react";
+
+type Props = React.PropsWithChildren<{
+ functionSignature: string;
+ kind: string;
+ id?: string;
+}>;
+
+export async function APIItem({
+ functionSignature,
+ kind,
+ id,
+ children,
+}: Props) {
+ const anchorId =
+ id ?? `api-${functionSignature.replace(/\W+/g, "-").toLowerCase()}`;
+
+ return (
+
+
+
+
{functionSignature}
+
+
+
+
+ {children}
+
+
+
+ );
+}
diff --git a/src/lib/remark-replace.ts b/src/lib/remark-replace.ts
new file mode 100644
index 0000000..c0185a2
--- /dev/null
+++ b/src/lib/remark-replace.ts
@@ -0,0 +1,114 @@
+import micromatch from "micromatch";
+import { visit } from "unist-util-visit";
+
+/**
+ * A replacement rule applied to MDX/Markdown files.
+ *
+ * - Use `include` to match files via glob(s).
+ * - Or use `includeFn` for custom logic (receives the normalized file path or undefined).
+ * - `replacements` maps placeholders like `{{key}}` → "value".
+ * - If `exclusive` is true, the first matching rule stops further replacements for that node.
+ */
+export type Rule = {
+ include?: string | string[];
+ includeFn?: (info: { path?: string }) => boolean;
+ replacements: Record;
+ exclusive?: boolean;
+};
+
+type File = { path: string; history: string[] };
+
+/**
+ * Multi-rule remark plugin to replace placeholders in text, inlineCode and code blocks.
+ *
+ * Placeholders are written as `{{key}}` and replaced with the corresponding string
+ * from the active rule's `replacements` map.
+ *
+ * Safe defaults:
+ * - If `file.path` is missing (virtual content), rules are considered active unless
+ * their `includeFn` explicitly returns false.
+ * - Empty/whitespace patterns are ignored; if no valid patterns are left,
+ * the rule falls back to "match all".
+ *
+ * Example usage (Fumadocs / MDX config):
+ *
+ * import { defineConfig } from "fumadocs-mdx/config";
+ * import remarkReplaceMulti, { Rule } from "@/lib/remark-replace-multi";
+ *
+ * const rules: Rule[] = [
+ * { include: "content/docs/**", replacements: { version: "3.0.0", api: "/docs/api" }, exclusive: true },
+ * { include: "content/guides/**", replacements: { version: "2.2.0", api: "/guides/api" }, exclusive: true },
+ * ];
+ *
+ * export default defineConfig({
+ * mdxOptions: {
+ * remarkPlugins: (prev) => [[remarkReplaceMulti, rules], ...prev],
+ * },
+ * });
+ */
+export default function remarkReplaceMulti(rules: Rule[]) {
+ // --- helpers ---------------------------------------------------------------
+
+ /** Normalize vfile path (may be missing in virtual files). */
+ const getPath = (file?: File): string | undefined => {
+ const raw =
+ (typeof file?.path === "string" && file.path) ||
+ (Array.isArray(file?.history) && file.history[0]) ||
+ undefined;
+ return raw ? raw.replace(/\\/g, "/") : undefined;
+ };
+
+ /** Turn include into a clean, non-empty patterns array (or ["** /*"]). */
+ const toPatterns = (include?: string | string[]): string[] => {
+ const arr = Array.isArray(include) ? include : include ? [include] : [];
+ const cleaned = arr.map((p) => p.trim()).filter((p) => p.length > 0);
+ return cleaned.length ? cleaned : ["**/*"];
+ };
+
+ /** Does this rule apply to the given file path? */
+ const isRuleActive = (rule: Rule, path?: string): boolean => {
+ if (rule.includeFn) return rule.includeFn({ path });
+ // If we don't have a path, default to active (virtual files).
+ if (!path) return true;
+ return micromatch.isMatch(path, toPatterns(rule.include));
+ };
+
+ /** Replace all `{{key}}` with values from `map`. */
+ const replaceAll = (input: string, map: Record): string => {
+ let out = input;
+ for (const [k, v] of Object.entries(map)) {
+ out = out.split(`{{${k}}}`).join(String(v));
+ }
+ return out;
+ };
+
+ // --- plugin ---------------------------------------------------------------
+
+ // biome-ignore lint/suspicious/noExplicitAny: third-party type, safe here
+ return (tree: any, file?: File) => {
+ const path = getPath(file);
+
+ // Collect rules that apply to this file.
+ const active = rules.filter((r) => isRuleActive(r, path));
+ if (active.length === 0) return;
+
+ // Apply replacements to text & code nodes.
+ visit(tree, ["text", "inlineCode", "code"], (node: { value: string }) => {
+ if (typeof node.value !== "string") return;
+
+ for (const rule of active) {
+ node.value = replaceAll(node.value, rule.replacements);
+ if (rule.exclusive) break; // stop after first exclusive rule
+ }
+ });
+
+ // 2) Markdown links/images: replace in the URL
+ visit(tree, ["link", "image", "definition"], (node: { url: string }) => {
+ if (typeof node.url !== "string") return;
+ for (const rule of active) {
+ node.url = replaceAll(node.url, rule.replacements);
+ if (rule.exclusive) break;
+ }
+ });
+ };
+}
diff --git a/src/mdx-components.tsx b/src/mdx-components.tsx
index 9ece326..89c4f97 100644
--- a/src/mdx-components.tsx
+++ b/src/mdx-components.tsx
@@ -20,12 +20,16 @@ import type { MDXComponents } from "mdx/types";
import { Mermaid } from "@/components/mdx/mermaid";
import { openapi } from "@/lib/openapi";
import OZWizard from "./components/oz-wizard";
+import { APIGithubLinkHeader } from "./components/ui/api-reference/api-github-link-header";
+import { APIItem } from "./components/ui/api-reference/api-item";
// use this function to get MDX components, you will need it for rendering MDX
export function getMDXComponents(components?: MDXComponents): MDXComponents {
return {
...defaultMdxComponents,
OZWizard,
+ APIGithubLinkHeader,
+ APIItem,
FileTextIcon,
UsersIcon,
ShieldIcon,
diff --git a/src/navigation/starknet.json b/src/navigation/starknet.json
index bbf32dc..60f7af3 100644
--- a/src/navigation/starknet.json
+++ b/src/navigation/starknet.json
@@ -16,6 +16,7 @@
{
"type": "folder",
"name": "Learn",
+ "defaultOpen": true,
"children": [
{
"type": "page",
@@ -41,21 +42,6 @@
"type": "page",
"name": "SNIP12 and Typed Messages",
"url": "/contracts-cairo/guides/snip12"
- },
- {
- "type": "page",
- "name": "ERC20 Permit",
- "url": "/contracts-cairo/guides/erc20-permit"
- },
- {
- "type": "page",
- "name": "ERC20 Supply",
- "url": "/contracts-cairo/guides/erc20-supply"
- },
- {
- "type": "page",
- "name": "SRC5 Migration",
- "url": "/contracts-cairo/guides/src5-migration"
}
]
},
@@ -145,9 +131,25 @@
"name": "Tokens",
"children": [
{
- "type": "page",
+ "type": "folder",
"name": "ERC-20",
- "url": "/contracts-cairo/erc20"
+ "index": {
+ "type": "page",
+ "name": "Overview",
+ "url": "/contracts-cairo/erc20"
+ },
+ "children": [
+ {
+ "type": "page",
+ "name": "Creating Supply",
+ "url": "/contracts-cairo/guides/erc20-supply"
+ },
+ {
+ "type": "page",
+ "name": "ERC20 Permit",
+ "url": "/contracts-cairo/guides/erc20-permit"
+ }
+ ]
},
{
"type": "page",
@@ -178,11 +180,6 @@
}
]
},
- {
- "type": "page",
- "name": "Backwards Compatibility",
- "url": "/contracts-cairo/backwards-compatibility"
- },
{
"type": "folder",
"name": "API Reference",
@@ -197,6 +194,16 @@
"name": "Account",
"url": "/contracts-cairo/api/account"
},
+ {
+ "type": "page",
+ "name": "ERC-20",
+ "url": "/contracts-cairo/api/erc20"
+ },
+ {
+ "type": "page",
+ "name": "ERC-721",
+ "url": "/contracts-cairo/api/erc721"
+ },
{
"type": "page",
"name": "ERC-1155",
@@ -204,13 +211,13 @@
},
{
"type": "page",
- "name": "ERC-20",
- "url": "/contracts-cairo/api/erc20"
+ "name": "ERC-4626",
+ "url": "/contracts-cairo/api/erc20#ERC4626Component"
},
{
"type": "page",
- "name": "ERC-721",
- "url": "/contracts-cairo/api/erc721"
+ "name": "Token Common",
+ "url": "/contracts-cairo/api/token_common"
},
{
"type": "page",
@@ -239,8 +246,8 @@
},
{
"type": "page",
- "name": "Token Common",
- "url": "/contracts-cairo/api/token_common"
+ "name": "Testing",
+ "url": "/contracts-cairo/api/testing"
},
{
"type": "page",
@@ -260,350 +267,8 @@
]
},
{
- "type": "folder",
- "name": "Previous Versions",
- "children": [
- {
- "type": "folder",
- "name": "v2.0.0",
- "children": [
- {
- "type": "page",
- "name": "Overview",
- "url": "/contracts-cairo/2.0.0"
- },
- {
- "type": "folder",
- "name": "Learn",
- "children": [
- {
- "type": "page",
- "name": "Components",
- "url": "/contracts-cairo/2.0.0/components"
- },
- {
- "type": "page",
- "name": "Presets",
- "url": "/contracts-cairo/2.0.0/presets"
- },
- {
- "type": "page",
- "name": "Counterfactual Deployments",
- "url": "/contracts-cairo/2.0.0/guides/deployment"
- },
- {
- "type": "page",
- "name": "SNIP12 and Typed Messages",
- "url": "/contracts-cairo/2.0.0/guides/snip12"
- },
- {
- "type": "page",
- "name": "ERC20 Permit",
- "url": "/contracts-cairo/2.0.0/guides/erc20-permit"
- },
- {
- "type": "page",
- "name": "ERC20 Supply",
- "url": "/contracts-cairo/2.0.0/guides/erc20-supply"
- },
- {
- "type": "page",
- "name": "SRC5 Migration",
- "url": "/contracts-cairo/2.0.0/guides/src5-migration"
- }
- ]
- },
- {
- "type": "page",
- "name": "Backwards Compatibility",
- "url": "/contracts-cairo/2.0.0/backwards-compatibility"
- },
- {
- "type": "folder",
- "name": "Tokens",
- "children": [
- {
- "type": "page",
- "name": "ERC-20",
- "url": "/contracts-cairo/2.0.0/erc20"
- },
- {
- "type": "page",
- "name": "ERC-721",
- "url": "/contracts-cairo/2.0.0/erc721"
- },
- {
- "type": "page",
- "name": "ERC-1155",
- "url": "/contracts-cairo/2.0.0/erc1155"
- },
- {
- "type": "page",
- "name": "ERC-4626",
- "url": "/contracts-cairo/2.0.0/erc4626"
- }
- ]
- },
- {
- "type": "folder",
- "name": "Governance",
- "children": [
- {
- "type": "page",
- "name": "Governor",
- "url": "/contracts-cairo/2.0.0/governance/governor"
- },
- {
- "type": "page",
- "name": "Multisig",
- "url": "/contracts-cairo/2.0.0/governance/multisig"
- },
- {
- "type": "page",
- "name": "Timelock",
- "url": "/contracts-cairo/2.0.0/governance/timelock"
- },
- {
- "type": "page",
- "name": "Votes",
- "url": "/contracts-cairo/2.0.0/governance/votes"
- }
- ]
- },
- {
- "type": "page",
- "name": "Access Control",
- "url": "/contracts-cairo/2.0.0/access"
- },
- {
- "type": "page",
- "name": "Accounts",
- "url": "/contracts-cairo/2.0.0/accounts"
- },
- {
- "type": "page",
- "name": "Finance",
- "url": "/contracts-cairo/2.0.0/finance"
- },
- {
- "type": "page",
- "name": "Interfaces",
- "url": "/contracts-cairo/2.0.0/interfaces"
- },
- {
- "type": "page",
- "name": "Introspection",
- "url": "/contracts-cairo/2.0.0/introspection"
- },
- {
- "type": "page",
- "name": "Security",
- "url": "/contracts-cairo/2.0.0/security"
- },
- {
- "type": "page",
- "name": "Upgrades",
- "url": "/contracts-cairo/2.0.0/upgrades"
- },
- {
- "type": "page",
- "name": "Universal Deployer Contract",
- "url": "/contracts-cairo/2.0.0/udc"
- },
- {
- "type": "folder",
- "name": "Macros",
- "children": [
- {
- "type": "page",
- "name": "Overview",
- "url": "/contracts-cairo/2.0.0/macros"
- },
- {
- "type": "page",
- "name": "Type Hash",
- "url": "/contracts-cairo/2.0.0/macros/type_hash"
- },
- {
- "type": "page",
- "name": "With Components",
- "url": "/contracts-cairo/2.0.0/macros/with_components"
- }
- ]
- },
- {
- "type": "folder",
- "name": "Utils",
- "children": [
- {
- "type": "page",
- "name": "Common",
- "url": "/contracts-cairo/2.0.0/utils/_common"
- },
- {
- "type": "page",
- "name": "Class Hashes",
- "url": "/contracts-cairo/2.0.0/utils/_class_hashes"
- }
- ]
- }
- ]
- },
- {
- "type": "folder",
- "name": "v1.0.0",
- "children": [
- {
- "type": "page",
- "name": "Overview",
- "url": "/contracts-cairo/1.0.0"
- },
- {
- "type": "folder",
- "name": "Learn",
- "children": [
- {
- "type": "page",
- "name": "Components",
- "url": "/contracts-cairo/1.0.0/components"
- },
- {
- "type": "page",
- "name": "Presets",
- "url": "/contracts-cairo/1.0.0/presets"
- },
- {
- "type": "page",
- "name": "Counterfactual Deployments",
- "url": "/contracts-cairo/1.0.0/guides/deployment"
- },
- {
- "type": "page",
- "name": "SNIP12 and Typed Messages",
- "url": "/contracts-cairo/1.0.0/guides/snip12"
- },
- {
- "type": "page",
- "name": "ERC20 Permit",
- "url": "/contracts-cairo/1.0.0/guides/erc20-permit"
- },
- {
- "type": "page",
- "name": "ERC20 Supply",
- "url": "/contracts-cairo/1.0.0/guides/erc20-supply"
- },
- {
- "type": "page",
- "name": "SRC5 Migration",
- "url": "/contracts-cairo/1.0.0/guides/src5-migration"
- }
- ]
- },
- {
- "type": "page",
- "name": "Backwards Compatibility",
- "url": "/contracts-cairo/1.0.0/backwards-compatibility"
- },
- {
- "type": "folder",
- "name": "Tokens",
- "children": [
- {
- "type": "page",
- "name": "ERC-20",
- "url": "/contracts-cairo/1.0.0/erc20"
- },
- {
- "type": "page",
- "name": "ERC-721",
- "url": "/contracts-cairo/1.0.0/erc721"
- },
- {
- "type": "page",
- "name": "ERC-1155",
- "url": "/contracts-cairo/1.0.0/erc1155"
- }
- ]
- },
- {
- "type": "folder",
- "name": "Governance",
- "children": [
- {
- "type": "page",
- "name": "Governor",
- "url": "/contracts-cairo/1.0.0/governance/governor"
- },
- {
- "type": "page",
- "name": "Timelock",
- "url": "/contracts-cairo/1.0.0/governance/timelock"
- },
- {
- "type": "page",
- "name": "Votes",
- "url": "/contracts-cairo/1.0.0/governance/votes"
- }
- ]
- },
- {
- "type": "page",
- "name": "Access Control",
- "url": "/contracts-cairo/1.0.0/access"
- },
- {
- "type": "page",
- "name": "Accounts",
- "url": "/contracts-cairo/1.0.0/accounts"
- },
- {
- "type": "page",
- "name": "Finance",
- "url": "/contracts-cairo/1.0.0/finance"
- },
- {
- "type": "page",
- "name": "Interfaces",
- "url": "/contracts-cairo/1.0.0/interfaces"
- },
- {
- "type": "page",
- "name": "Introspection",
- "url": "/contracts-cairo/1.0.0/introspection"
- },
- {
- "type": "page",
- "name": "Security",
- "url": "/contracts-cairo/1.0.0/security"
- },
- {
- "type": "page",
- "name": "Upgrades",
- "url": "/contracts-cairo/1.0.0/upgrades"
- },
- {
- "type": "page",
- "name": "Universal Deployer Contract",
- "url": "/contracts-cairo/1.0.0/udc"
- },
- {
- "type": "folder",
- "name": "Utils",
- "children": [
- {
- "type": "page",
- "name": "Common",
- "url": "/contracts-cairo/1.0.0/utils/_common"
- },
- {
- "type": "page",
- "name": "Class Hashes",
- "url": "/contracts-cairo/1.0.0/utils/_class_hashes"
- }
- ]
- }
- ]
- }
- ]
+ "type": "page",
+ "name": "Backwards Compatibility",
+ "url": "/contracts-cairo/backwards-compatibility"
}
]