Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion STANDARDS.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ The OpenZeppelin approach to achieve this goal will include the following sectio

⊞ Quadrants: Information-Oriented/Reference

📖 [Reference Example](https://docs.openzeppelin.com/contracts-cairo/alpha/api/access)
📖 [Reference Example](https://docs.openzeppelin.com/contracts-cairo/3.x/api/access)


It should be noted that not every library or tool may have every section, and that’s ok. This is purely a guide to help kickstart helpful documentation, not a strict pattern to follow.
Expand Down
2 changes: 1 addition & 1 deletion content/contracts-cairo/2.x/api/merkle-tree.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ This module provides:

To use it as a standalone package, you can add it in your `Scarb.toml` as follows:

`openzeppelin_merkle_tree = "3.0.0-alpha.1"`
`openzeppelin_merkle_tree = "2.0.0"`

## [](#modules)Modules

Expand Down
4 changes: 2 additions & 2 deletions content/contracts-cairo/2.x/index.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ title: Contracts for Cairo


**A library for secure smart contract development** written in Cairo for [Starknet][starknet]. This library consists of a set of
[reusable components](/contracts-cairo/2.x/components) to build custom smart contracts, as well as ready-to-deploy [presets](/contracts-cairo/2.x/presets). You can also
find other [utilities](/contracts-cairo/2.x/api/utilities) including [interfaces and dispatchers](/contracts-cairo/alpha/interfaces) and [test utilities](/contracts-cairo/2.x/api/testing)
[reusable components](/contracts-cairo/2.x/components) to build custom smart contracts, as well as ready-to-deploy [presets](/contracts-cairo/2.x/presets). It also provides
helpful [utilities](/contracts-cairo/2.x/api/utilities) and [test utilities](/contracts-cairo/2.x/api/testing)
that facilitate testing with Starknet Foundry.

<Callout>
Expand Down
4 changes: 3 additions & 1 deletion content/contracts-cairo/2.x/wizard.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,6 @@ contract and learn about the components offered in OpenZeppelin Contracts for Ca
We strongly recommend checking the [Components](./components) section to understand how to extend from our library.
</Callout>

<OZWizard lang="cairo" version="2.0.0" />
import { UMBRELLA_VERSION } from "./utils/constants.js";

<OZWizard lang="cairo" version={UMBRELLA_VERSION} />
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,13 @@ The most common and basic form of access control is the concept of ownership: th
of a contract and can do administrative tasks on it.
This approach is perfectly reasonable for contracts that have a single administrative user.

OpenZeppelin Contracts for Cairo provides [OwnableComponent](/contracts-cairo/alpha/api/access#OwnableComponent) for implementing ownership in your contracts.
OpenZeppelin Contracts for Cairo provides [OwnableComponent](/contracts-cairo/3.x/api/access#OwnableComponent) for implementing ownership in your contracts.

### Usage

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`](/contracts-cairo/alpha/api/access#OwnableComponent-initializer) like this:
[`initializer`](/contracts-cairo/3.x/api/access#OwnableComponent-initializer) like this:

```rust
#[starknet::contract]
Expand Down Expand Up @@ -106,7 +106,7 @@ will no longer be callable!
### Two step transfer

The component also offers a more robust way of transferring ownership via the
[OwnableTwoStepImpl](/contracts-cairo/alpha/api/access#OwnableComponent-Embeddable-Impls-OwnableTwoStepImpl) implementation. A two step transfer mechanism helps
[OwnableTwoStepImpl](/contracts-cairo/3.x/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:

Expand Down Expand Up @@ -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`](/contracts-cairo/alpha/api/access#OwnableComponent-assert_only_owner). This check can be enforced through [`assert_only_role`](/contracts-cairo/alpha/api/access#AccessControlComponent-assert_only_role).
instead of simply using [`assert_only_owner`](/contracts-cairo/3.x/api/access#OwnableComponent-assert_only_owner). This check can be enforced through [`assert_only_role`](/contracts-cairo/3.x/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
Expand All @@ -158,7 +158,7 @@ For each role that you want to define, you will create a new _role identifier_ t
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](/contracts-cairo/alpha/api/access#AccessControlComponent) on a portion of an ERC20 token contract which defines
Here’s a simple example of implementing [AccessControl](/contracts-cairo/3.x/api/access#AccessControlComponent) on a portion of an ERC20 token contract which defines
and sets a 'minter' role:

```rust
Expand Down Expand Up @@ -242,12 +242,12 @@ mod MyContract {
```

<Callout type='warn'>
Make sure you fully understand how [AccessControl](/contracts-cairo/alpha/api/access#AccessControlComponent) works before
Make sure you fully understand how [AccessControl](/contracts-cairo/3.x/api/access#AccessControlComponent) works before
using it on your system, or copy-pasting the examples from this guide.
</Callout>

While clear and explicit, this isn’t anything we wouldn’t have been able to achieve with
[Ownable](/contracts-cairo/alpha/api/access#OwnableComponent). Where [AccessControl](/contracts-cairo/alpha/api/access#AccessControlComponent) shines the most is in scenarios where granular
[Ownable](/contracts-cairo/3.x/api/access#OwnableComponent). Where [AccessControl](/contracts-cairo/3.x/api/access#AccessControlComponent) shines the most is in scenarios where granular
permissions are required, which can be implemented by defining _multiple_ roles.

Let’s augment our ERC20 token example by also defining a 'burner' role, which lets accounts destroy tokens:
Expand Down Expand Up @@ -350,16 +350,16 @@ security practice. Note that each account may still have more than one role, if

### Granting and revoking roles

The ERC20 token example above uses [`_grant_role`](/contracts-cairo/alpha/api/access#AccessControlComponent-_grant_role),
The ERC20 token example above uses [`_grant_role`](/contracts-cairo/3.x/api/access#AccessControlComponent-_grant_role),
an `internal` function that is useful when programmatically assigning
roles (such as during construction). But what if we later want to grant the 'minter' role to additional accounts?

By default, **accounts with a role cannot grant it or revoke it from other accounts**: all having a role does is making
the [`assert_only_role`](/contracts-cairo/alpha/api/access#AccessControlComponent-assert_only_role) check pass. To grant and revoke roles dynamically, you will need help from the role’s _admin_.
the [`assert_only_role`](/contracts-cairo/3.x/api/access#AccessControlComponent-assert_only_role) check pass. To grant and revoke roles dynamically, you will need help from the role’s _admin_.

Every role has an associated admin role, which grants permission to call the
[`grant_role`](/contracts-cairo/alpha/api/access#AccessControlComponent-grant_role) and
[`revoke_role`](/contracts-cairo/alpha/api/access#AccessControlComponent-revoke_role) functions.
[`grant_role`](/contracts-cairo/3.x/api/access#AccessControlComponent-grant_role) and
[`revoke_role`](/contracts-cairo/3.x/api/access#AccessControlComponent-revoke_role) functions.
A role can be granted or revoked by using these if the calling account has the corresponding admin role.
Multiple roles may have the same admin role to make management easier.
A role’s admin can even be the same role itself, which would cause accounts with that role to be able
Expand All @@ -369,9 +369,9 @@ This mechanism can be used to create complex permissioning structures resembling
provides an easy way to manage simpler applications. `AccessControl` includes a special role with the role identifier
of `0`, called `DEFAULT_ADMIN_ROLE`, which acts as the **default admin role for all roles**.
An account with this role will be able to manage any other role, unless
[`set_role_admin`](/contracts-cairo/alpha/api/access#AccessControlComponent-set_role_admin) is used to select a new admin role.
[`set_role_admin`](/contracts-cairo/3.x/api/access#AccessControlComponent-set_role_admin) is used to select a new admin role.

Since it is the admin for all roles by default, and in fact it is also its own admin, this role carries significant risk. To mitigate this risk we provide [AccessControlDefaultAdminRules](/contracts-cairo/alpha/api/access#AccessControlDefaultAdminRulesComponent), a recommended extension of AccessControl that adds a number of enforced security measures for this role: the admin is restricted to a single account, with a 2-step transfer procedure with a delay in between steps.
Since it is the admin for all roles by default, and in fact it is also its own admin, this role carries significant risk. To mitigate this risk we provide [AccessControlDefaultAdminRules](/contracts-cairo/3.x/api/access#AccessControlDefaultAdminRulesComponent), a recommended extension of AccessControl that adds a number of enforced security measures for this role: the admin is restricted to a single account, with a 2-step transfer procedure with a delay in between steps.

Let’s take a look at the ERC20 token example, this time taking advantage of the default admin role:

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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).

<Callout>
For detailed information on the usage and implementation check the [API Reference](/contracts-cairo/alpha/api/account) section.
For detailed information on the usage and implementation check the [API Reference](/contracts-cairo/3.x/api/account) section.
</Callout>

## What is an account?
Expand Down Expand Up @@ -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/learn/protocol/cryptography#the-stark-curve) which is the most efficient way
of validating signatures since it is a STARK-friendly curve.

OpenZeppelin Contracts for Cairo provides [AccountComponent](/contracts-cairo/alpha/api/account#AccountComponent) for implementing this validation scheme.
OpenZeppelin Contracts for Cairo provides [AccountComponent](/contracts-cairo/3.x/api/account#AccountComponent) for implementing this validation scheme.

### Usage

Constructing an account contract requires integrating both [AccountComponent](/contracts-cairo/alpha/api/account#AccountComponent) and [SRC5Component](/contracts-cairo/alpha/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](/contracts-cairo/3.x/api/account#AccountComponent) and [SRC5Component](/contracts-cairo/3.x/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)]
Expand Down Expand Up @@ -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](/contracts-cairo/alpha/api/account#EthAccountComponent) must be used.
For this the [EthAccountComponent](/contracts-cairo/3.x/api/account#EthAccountComponent) must be used.

### Usage

Constructing a secp256k1 account contract also requires integrating both [EthAccountComponent](/contracts-cairo/alpha/api/account#EthAccountComponent) and [SRC5Component](/contracts-cairo/alpha/api/introspection#SRC5Component).
Constructing a secp256k1 account contract also requires integrating both [EthAccountComponent](/contracts-cairo/3.x/api/account#EthAccountComponent) and [SRC5Component](/contracts-cairo/3.x/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:

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,7 @@ Functions
- [`change_default_admin_delay(new_delay)`](#IAccessControlDefaultAdminRules-change_default_admin_delay)
- [`rollback_default_admin_delay()`](#IAccessControlDefaultAdminRules-rollback_default_admin_delay)
- [`default_admin_delay_increase_wait()`](#IAccessControlDefaultAdminRules-default_admin_delay_increase_wait)
- [`maximum_default_admin_transfer_delay()`](#IAccessControlDefaultAdminRules-maximum_default_admin_transfer_delay)

Events

Expand Down Expand Up @@ -401,11 +402,25 @@ May emit a [DefaultAdminDelayChangeCanceled](#IAccessControlDefaultAdminRules-De
id="IAccessControlDefaultAdminRules-default_admin_delay_increase_wait"
kind="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.
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.

<Callout type='warn'>
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).
</Callout>

Consider carefully the value set for `MAXIMUM_DEFAULT_ADMIN_TRANSFER_DELAY` too, since it will affect how fast you can recover from an accidental delay increase.
</APIItem>

<APIItem
functionSignature="maximum_default_admin_transfer_delay() → u64"
id="IAccessControlDefaultAdminRules-maximum_default_admin_transfer_delay"
kind="external"
>
Maximum time in seconds for a `default_admin` transfer delay.

<Callout type='warn'>
If `MAXIMUM_DEFAULT_ADMIN_TRANSFER_DELAY` is set too high, you might be unable to recover from an accidental delay increase for an extended period. Too low, and it unnecessarily restricts how much security delay you can impose for `default_admin` transfers. As a best practice, consider setting it in the 30-60 day range for a good balance between security and recoverability.
</Callout>
</APIItem>

#### Events [!toc] [#IAccessControlDefaultAdminRules-Events]
Expand Down Expand Up @@ -1148,6 +1163,7 @@ Embeddable Implementations
- [`change_default_admin_delay(self, new_delay)`](#IAccessControlDefaultAdminRules-change_default_admin_delay)
- [`rollback_default_admin_delay(self)`](#IAccessControlDefaultAdminRules-rollback_default_admin_delay)
- [`default_admin_delay_increase_wait(self)`](#IAccessControlDefaultAdminRules-default_admin_delay_increase_wait)
- [`maximum_default_admin_transfer_delay(self)`](#IAccessControlDefaultAdminRules-maximum_default_admin_transfer_delay)

#### AccessControlImpl [!toc] [#AccessControlDefaultAdminRulesComponent-Embeddable-Impls-AccessControlImpl]

Expand Down Expand Up @@ -1368,6 +1384,18 @@ Make sure to add a reasonable amount of time while overriding this value, otherw
</Callout>
</APIItem>

<APIItem
functionSignature="maximum_default_admin_transfer_delay(self: @ContractState) → u64"
id="AccessControlDefaultAdminRulesComponent-maximum_default_admin_transfer_delay"
kind="external"
>
Maximum time in seconds for a `default_admin` transfer delay.

<Callout type='warn'>
If `MAXIMUM_DEFAULT_ADMIN_TRANSFER_DELAY` is set too high, you might be unable to recover from an accidental delay increase for an extended period. Too low, and it unnecessarily restricts how much security delay you can impose for `default_admin` transfers. As a best practice, consider setting it in the 30-60 day range for a good balance between security and recoverability.
</Callout>
</APIItem>

<APIItem
functionSignature="has_role(self: @ContractState, role: felt252, account: ContractAddress) → bool"
id="AccessControlDefaultAdminRulesComponent-has_role"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1139,6 +1139,8 @@ Allows contracts to hook logic into deposit and withdraw transactions. This is w

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.

When a vault implements fees on deposits or withdrawals (either in shares or assets), fee transfers must be handled in these hooks by library clients. This creates a non-atomic operation flow consisting of multiple state-changing steps: transferring assets, minting or burning shares, and transferring (or minting) fees. Between these steps, the vault's state is temporarily inconsistent: the asset-to-share conversion rate does not accurately reflect the vault's final state until all steps have completed. Therefore, it is critical to avoid making any external calls (including to the vault contract itself) or querying conversion rates during hook execution.

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.
Expand Down
Loading