Skip to content

Commit

Permalink
Add upgrades to presets (OpenZeppelin#964)
Browse files Browse the repository at this point in the history
* make account upgradeable

* add upgradeable to preset name

* add contract param to event assertion, add assert_only_event fn

* add contract param in event assertions

* switch param order for consistency in event assertion

* update event assertion

* make erc20 preset upgradeable and ownable

* update erc20 preset contract name

* add interfaces dir, add ierc20upgradeable

* add new preset tests

* fix mod name

* add account preset interface

* add interface for eth account preset

* fix formatting

* add erc721 upgradeable interface

* make erc721 upgradeable

* add tests for preset

* fix formatting

* add erc1155 preset interface

* make erc1155 preset upgradeable

* use case-specific interface for checking state after upgrade

* add ownable and upgradeable tests

* fix formatting

* start changelog entries

* update attributes

* update account preset api

* update erc20 preset api

* fix typo

* update erc721 preset api

* add line in description

* update erc1155 preset api

* normalize descriptions

* add upgradeable to the in-code doc

* normalize in-code docs

* update constructor comments

* fix link

* clean up imports

* add contract param to event assertions, add assert_only_

* import event assertions from token tests

* fix formatting

* add changelog entry

* fix comment

* Apply suggestions from code review

Co-authored-by: Eric Nordelo <[email protected]>

* fix comments

* update preset refs/names

* add external fn index for presets

* fix comment

* add requirements to upgrade in api

* update code block ex

* update preset ex in usage

* Apply suggestions from code review

Co-authored-by: Eric Nordelo <[email protected]>

* update preset interface names

* update preset names in KNOWN_ORDER

* fix comment in code block

---------

Co-authored-by: Eric Nordelo <[email protected]>
  • Loading branch information
andrew-fleming and ericnordelo authored Apr 16, 2024
1 parent afd683f commit 061cab2
Show file tree
Hide file tree
Showing 32 changed files with 1,501 additions and 354 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- before_update and after_update hooks to ERC20Component (#951)
- INSUFFICIENT_BALANCE and INSUFFICIENT_ALLOWANCE errors to ERC20Component (#951)
- ERC20Votes component (#951)
- Preset interfaces (#964)
- UDC docs (#954)
- Util functions to precompute addresses (#954)

Expand All @@ -21,6 +22,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Allow testing utilities to be importable (#963)
- Utilities documentation (#963)
- Parameter name in `tests::utils::drop_events` (`count` -> `n_events`) (#963)
- Presets to include upgradeable functionality (#964)
- ERC20, ERC721, and ERC1155 presets include Ownable functionality (#964)

## 0.11.0 (2024-03-29)

Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ mod MyToken {
component!(path: ERC20Component, storage: erc20, event: ERC20Event);
// ERC20 Mixin
// ERC20 Mixin
#[abi(embed_v0)]
impl ERC20MixinImpl = ERC20Component::ERC20MixinImpl<ContractState>;
impl ERC20InternalImpl = ERC20Component::InternalImpl<ContractState>;
Expand Down
43 changes: 34 additions & 9 deletions docs/modules/ROOT/pages/api/account.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -504,27 +504,27 @@ Emitted when a `public_key` is removed.
== Presets

[.contract]
[[Account]]
=== `++Account++` link:https://github.com/OpenZeppelin/cairo-contracts/blob/release-v0.11.0/src/presets/account.cairo[{github-icon},role=heading-link]
[[AccountUpgradeable]]
=== `++AccountUpgradeable++` link:https://github.com/OpenZeppelin/cairo-contracts/blob/release-v0.11.0/src/presets/account.cairo[{github-icon},role=heading-link]

```javascript
use openzeppelin::presets::Account;
use openzeppelin::presets::AccountUpgradeable;
```

Basic account contract leveraging xref:#AccountComponent[AccountComponent].
Upgradeable account contract leveraging xref:#AccountComponent[AccountComponent].

include::../utils/_class_hashes.adoc[]

[.contract-index]
.{presets-page}
--
{Account-class-hash}
{AccountUpgradeable-class-hash}
--

[.contract-index]
.Constructor
--
* xref:#Account-constructor[`++constructor(self, public_key)++`]
* xref:#AccountUpgradeable-constructor[`++constructor(self, public_key)++`]
--

[.contract-index]
Expand All @@ -535,15 +535,35 @@ include::../utils/_class_hashes.adoc[]
* xref:#AccountComponent-Embeddable-Mixin-Impl[`++AccountMixinImpl++`]
--

[#Account-constructor-section]
[.contract-index]
.External Functions
--
* xref:#AccountUpgradeable-upgrade[`++upgrade(self, new_class_hash)++`]
--

[#AccountUpgradeable-constructor-section]
==== Constructor

[.contract-item]
[[Account-constructor]]
[[AccountUpgradeable-constructor]]
==== `[.contract-item-name]#++constructor++#++(ref self: ContractState, public_key: felt252)++` [.item-kind]#constructor#

Sets the account `public_key` and registers the interfaces the contract supports.

[#AccountUpgradeable-external-functions]
==== External functions

[.contract-item]
[[AccountUpgradeable-upgrade]]
==== `[.contract-item-name]#++upgrade++#++(ref self: ContractState, new_class_hash: ClassHash)++` [.item-kind]#external#

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.

[.contract]
[[EthAccountUpgradeable]]
=== `++EthAccountUpgradeable++` link:https://github.com/OpenZeppelin/cairo-contracts/blob/release-v0.11.0/src/presets/eth_account.cairo[{github-icon},role=heading-link]
Expand All @@ -552,7 +572,7 @@ Sets the account `public_key` and registers the interfaces the contract supports
use openzeppelin::presets::EthAccountUpgradeable;
```

Account contract leveraging xref:#EthAccountComponent[EthAccountComponent].
Upgradeable account contract leveraging xref:#EthAccountComponent[EthAccountComponent].

NOTE: The `EthPublicKey` type is an alias for `starknet::secp256k1::Secp256k1Point`.

Expand Down Expand Up @@ -601,3 +621,8 @@ Sets the account `public_key` and registers the interfaces the contract supports
==== `[.contract-item-name]#++upgrade++#++(ref self: ContractState, new_class_hash: ClassHash)++` [.item-kind]#external#

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.
41 changes: 33 additions & 8 deletions docs/modules/ROOT/pages/api/erc1155.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -623,27 +623,27 @@ Registers the `IERC1155Receiver` interface ID as supported through introspection
== Presets

[.contract]
[[ERC1155]]
=== `++ERC1155++` link:https://github.com/OpenZeppelin/cairo-contracts/blob/release-v0.11.0/src/presets/erc1155.cairo[{github-icon},role=heading-link]
[[ERC1155Upgradeable]]
=== `++ERC1155Upgradeable++` link:https://github.com/OpenZeppelin/cairo-contracts/blob/release-v0.11.0/src/presets/erc1155.cairo[{github-icon},role=heading-link]

```javascript
use openzeppelin::presets::ERC1155;
```

Basic ERC1155 contract leveraging xref:#ERC1155Component[ERC1155Component].
Upgradeable ERC1155 contract leveraging xref:#ERC1155Component[ERC1155Component].

include::../utils/_class_hashes.adoc[]

[.contract-index]
.{presets-page}
--
{ERC1155-class-hash}
{ERC1155Upgradeable-class-hash}
--

[.contract-index]
.Constructor
--
* xref:#ERC1155-constructor[`++constructor(self, base_uri, recipient, token_ids, values)++`]
* xref:#ERC1155Upgradeable-constructor[`++constructor(self, base_uri, recipient, token_ids, values, owner)++`]
--

[.contract-index]
Expand All @@ -652,20 +652,45 @@ include::../utils/_class_hashes.adoc[]
.ERC1155Component

* xref:#ERC1155Component-Embeddable-Mixin-Impl[`++ERC1155MixinImpl++`]

.OwnableMixinImpl

* xref:/api/access.adoc#OwnableComponent-Mixin-Impl[`++OwnableMixinImpl++`]
--

[#ERC1155-constructor-section]
[.contract-index]
.External Functions
--
* xref:#ERC1155Upgradeable-upgrade[`++upgrade(self, new_class_hash)++`]
--

[#ERC1155Upgradeable-constructor-section]
==== Constructor

[.contract-item]
[[ERC1155-constructor]]
==== `[.contract-item-name]#++constructor++#++(ref self: ContractState, base_uri: ByteArray, recipient: ContractAddress, token_ids: Span<u256>, values: Span<u256>)++` [.item-kind]#constructor#
[[ERC1155Upgradeable-constructor]]
==== `[.contract-item-name]#++constructor++#++(ref self: ContractState, base_uri: ByteArray, recipient: ContractAddress, token_ids: Span<u256>, values: Span<u256>, owner: ContractAddress)++` [.item-kind]#constructor#

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

[.contract-item]
[[ERC1155Upgradeable-upgrade]]
==== `[.contract-item-name]#++upgrade++#++(ref self: ContractState, new_class_hash: ClassHash)++` [.item-kind]#external#

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.
43 changes: 34 additions & 9 deletions docs/modules/ROOT/pages/api/erc20.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -653,27 +653,27 @@ Emitted when `delegate` votes are updated from `previous_votes` to `new_votes`.
== Presets

[.contract]
[[ERC20]]
=== `++ERC20++` link:https://github.com/OpenZeppelin/cairo-contracts/blob/release-v0.11.0/src/presets/erc20.cairo[{github-icon},role=heading-link]
[[ERC20Upgradeable]]
=== `++ERC20Upgradeable++` link:https://github.com/OpenZeppelin/cairo-contracts/blob/release-v0.11.0/src/presets/erc20.cairo[{github-icon},role=heading-link]

```javascript
use openzeppelin::presets::ERC20;
use openzeppelin::presets::ERC20Upgradeable;
```

Basic ERC20 contract leveraging xref:#ERC20Component[ERC20Component] with a fixed-supply mechanism for token distribution.
Upgradeable ERC20 contract leveraging xref:#ERC20Component[ERC20Component] with a fixed-supply mechanism for token distribution.

include::../utils/_class_hashes.adoc[]

[.contract-index]
.{presets-page}
--
{ERC20-class-hash}
{ERC20Upgradeable-class-hash}
--

[.contract-index]
.Constructor
--
* xref:#ERC20-constructor[`++constructor(self, name, symbol, fixed_supply, recipient)++`]
* xref:#ERC20Upgradeable-constructor[`++constructor(self, name, symbol, fixed_supply, recipient, owner)++`]
--

[.contract-index]
Expand All @@ -682,13 +682,38 @@ include::../utils/_class_hashes.adoc[]
.ERC20MixinImpl

* xref:#ERC20Component-Embeddable-Mixin-Impl[`++ERC20MixinImpl++`]

.OwnableMixinImpl

* xref:/api/access.adoc#OwnableComponent-Mixin-Impl[`++OwnableMixinImpl++`]
--

[#ERC20-constructor-section]
[.contract-index]
.External Functions
--
* xref:#ERC20Upgradeable-upgrade[`++upgrade(self, new_class_hash)++`]
--

[#ERC20Upgradeable-constructor-section]
==== Constructor

[.contract-item]
[[ERC20-constructor]]
==== `[.contract-item-name]#++constructor++#++(ref self: ContractState, name: ByteArray, symbol: ByteArray, fixed_supply: u256, recipient: ContractAddress)++` [.item-kind]#constructor#
[[ERC20Upgradeable-constructor]]
==== `[.contract-item-name]#++constructor++#++(ref self: ContractState, name: ByteArray, symbol: ByteArray, fixed_supply: u256, recipient: ContractAddress, owner: ContractAddress)++` [.item-kind]#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

[.contract-item]
[[ERC20Upgradeable-upgrade]]
==== `[.contract-item-name]#++upgrade++#++(ref self: ContractState, new_class_hash: ClassHash)++` [.item-kind]#external#

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.
44 changes: 34 additions & 10 deletions docs/modules/ROOT/pages/api/erc721.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -689,27 +689,27 @@ Registers the `IERC721Receiver` interface ID as supported through introspection.
== Presets

[.contract]
[[ERC721]]
=== `++ERC721++` link:https://github.com/OpenZeppelin/cairo-contracts/blob/release-v0.11.0/src/presets/erc721.cairo[{github-icon},role=heading-link]
[[ERC721Upgradeable]]
=== `++ERC721Upgradeable++` link:https://github.com/OpenZeppelin/cairo-contracts/blob/release-v0.11.0/src/presets/erc721.cairo[{github-icon},role=heading-link]

```javascript
use openzeppelin::presets::ERC721;
use openzeppelin::presets::ERC721Upgradeable;
```

Basic ERC721 contract leveraging xref:#ERC721Component[ERC721Component].
Upgradeable ERC721 contract leveraging xref:#ERC721Component[ERC721Component].

include::../utils/_class_hashes.adoc[]

[.contract-index]
.{presets-page}
--
{ERC721-class-hash}
{ERC721Upgradeable-class-hash}
--

[.contract-index]
.Constructor
--
* xref:#ERC721-constructor[`++constructor(self, name, symbol, recipient, token_ids, base_uri)++`]
* xref:#ERC721Upgradeable-constructor[`++constructor(self, name, symbol, recipient, token_ids, base_uri, owner)++`]
--

[.contract-index]
Expand All @@ -718,15 +718,39 @@ include::../utils/_class_hashes.adoc[]
.ERC721MixinImpl

* xref:#ERC721Component-Embeddable-Mixin-Impl[`++ERC721MixinImpl++`]

.OwnableMixinImpl

* xref:/api/access.adoc#OwnableComponent-Mixin-Impl[`++OwnableMixinImpl++`]
--

[#ERC721-constructor-section]
[.contract-index]
.External Functions
--
* xref:#ERC721Upgradeable-upgrade[`++upgrade(self, new_class_hash)++`]
--

[#ERC721Upgradeable-constructor-section]
==== Constructor

[.contract-item]
[[ERC721Component-constructor]]
==== `[.contract-item-name]#++constructor++#++(ref self: ContractState, name: ByteArray, symbol: ByteArray, recipient: ContractAddress, token_ids: Span<u256>, base_uri: ByteArray)++` [.item-kind]#constructor#
[[ERC721Upgradeable-constructor]]
==== `[.contract-item-name]#++constructor++#++(ref self: ContractState, name: ByteArray, symbol: ByteArray, recipient: ContractAddress, token_ids: Span<u256>, base_uri: ByteArray, owner: ContractAddress)++` [.item-kind]#constructor#

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

[.contract-item]
[[ERC721Upgradeable-upgrade]]
==== `[.contract-item-name]#++upgrade++#++(ref self: ContractState, new_class_hash: ClassHash)++` [.item-kind]#external#

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.
4 changes: 2 additions & 2 deletions docs/modules/ROOT/pages/api/utilities.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -422,15 +422,15 @@ The `contract_address_salt` is always set to zero, and `deploy_from_zero` is set
Usage example:

```javascript
use openzeppelin::presets::Account;
use openzeppelin::presets::AccountUpgradeable;
use openzeppelin::tests::utils;
use starknet::ContractAddress;

const PUBKEY: felt252 = 'PUBKEY';

fn deploy_test_contract() -> ContractAddress {
let calldata = array![PUBKEY];
utils::deploy(Account::TEST_CLASS_HASH, calldata)
utils::deploy(AccountUpgradeable::TEST_CLASS_HASH, calldata)
}
```

Expand Down
Loading

0 comments on commit 061cab2

Please sign in to comment.