Skip to content

Commit 8d9189d

Browse files
authored
Cairo: Add ERC1155 (#351)
1 parent 56dbddf commit 8d9189d

25 files changed

+1725
-132
lines changed

packages/core-cairo/CHANGELOG.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,13 @@
11
# Changelog
22

3+
## 0.10.2 (2024-04-03)
4+
5+
- Use OpenZeppelin Contracts for Cairo v0.11.0. ([#351](https://github.com/OpenZeppelin/contracts-wizard/pull/351))
6+
- Add ERC1155.
7+
- Remove redundant not paused assertions for camel case functions.
8+
- Fix use of ERC20 mixin.
9+
- Sort imports alphabetically.
10+
311
## 0.10.1 (2024-03-27)
412

513
- Use mixins. ([#348](https://github.com/OpenZeppelin/contracts-wizard/pull/348))

packages/core-cairo/README.md

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -80,17 +80,6 @@ Calculates the initial supply that would be used in an ERC20 contract based on a
8080
Returns `premint` with zeros padded or removed based on `decimals`.
8181
Throws an error if `premint` has more than one decimal character or is more precise than allowed by the `decimals` argument.
8282

83-
### Utility functions
84-
85-
#### `utils.toUint256`
86-
87-
Returns Uint256 components for low and high bits based on a given number in string format.
88-
89-
- `num` Number in string format
90-
91-
Returns an object with lowBits and highBits.
92-
Throws an error if the provided number is larger than 256 bits.
93-
9483
### Examples
9584

9685
Import the contract type(s) or function categories (for example, `erc20` or `utils`) that you want to use from the `@openzeppelin/wizard-cairo` package:

packages/core-cairo/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@openzeppelin/wizard-cairo",
3-
"version": "0.10.1",
3+
"version": "0.10.2",
44
"description": "A boilerplate generator to get started with OpenZeppelin Contracts for Cairo",
55
"license": "MIT",
66
"repository": "github:OpenZeppelin/contracts-wizard",

packages/core-cairo/src/api.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import type { CommonOptions } from './common-options';
22
import { printERC20, defaults as erc20defaults, isAccessControlRequired as erc20IsAccessControlRequired, ERC20Options } from './erc20';
33
import { printERC721, defaults as erc721defaults, isAccessControlRequired as erc721IsAccessControlRequired, ERC721Options } from './erc721';
4+
import { printERC1155, defaults as erc1155defaults, isAccessControlRequired as erc1155IsAccessControlRequired, ERC1155Options } from './erc1155';
45
import { printCustom, defaults as customDefaults, isAccessControlRequired as customIsAccessControlRequired, CustomOptions } from './custom';
56

67
export interface WizardContractAPI<Options extends CommonOptions> {
@@ -23,6 +24,7 @@ export interface WizardContractAPI<Options extends CommonOptions> {
2324

2425
export type ERC20 = WizardContractAPI<ERC20Options>;
2526
export type ERC721 = WizardContractAPI<ERC721Options>;
27+
export type ERC1155 = WizardContractAPI<ERC1155Options>;
2628
export type Custom = WizardContractAPI<CustomOptions>;
2729

2830
export const erc20: ERC20 = {
@@ -35,6 +37,11 @@ export const erc721: ERC721 = {
3537
defaults: erc721defaults,
3638
isAccessControlRequired: erc721IsAccessControlRequired
3739
}
40+
export const erc1155: ERC1155 = {
41+
print: printERC1155,
42+
defaults: erc1155defaults,
43+
isAccessControlRequired: erc1155IsAccessControlRequired
44+
}
3845
export const custom: Custom = {
3946
print: printCustom,
4047
defaults: customDefaults,

packages/core-cairo/src/build-generic.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
import { ERC20Options, buildERC20 } from './erc20';
22
import { ERC721Options, buildERC721 } from './erc721';
3+
import { ERC1155Options, buildERC1155 } from './erc1155';
34
import { CustomOptions, buildCustom } from './custom';
45

56
export interface KindedOptions {
67
ERC20: { kind: 'ERC20' } & ERC20Options;
78
ERC721: { kind: 'ERC721' } & ERC721Options;
9+
ERC1155: { kind: 'ERC1155' } & ERC1155Options;
810
Custom: { kind: 'Custom' } & CustomOptions;
911
}
1012

@@ -18,6 +20,9 @@ export function buildGeneric(opts: GenericOptions) {
1820
case 'ERC721':
1921
return buildERC721(opts);
2022

23+
case 'ERC1155':
24+
return buildERC1155(opts);
25+
2126
case 'Custom':
2227
return buildCustom(opts);
2328

packages/core-cairo/src/contract.test.ts.md

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ Generated by [AVA](https://avajs.dev).
99
> Snapshot 1
1010
1111
`// SPDX-License-Identifier: MIT␊
12-
// Compatible with OpenZeppelin Contracts for Cairo ^0.10.0␊
12+
// Compatible with OpenZeppelin Contracts for Cairo ^0.11.0␊
1313
1414
#[starknet::contract]␊
1515
mod Foo {␊
@@ -24,7 +24,7 @@ Generated by [AVA](https://avajs.dev).
2424
> Snapshot 1
2525
2626
`// SPDX-License-Identifier: MIT␊
27-
// Compatible with OpenZeppelin Contracts for Cairo ^0.10.0␊
27+
// Compatible with OpenZeppelin Contracts for Cairo ^0.11.0␊
2828
2929
#[starknet::contract]␊
3030
mod Foo {␊
@@ -44,7 +44,7 @@ Generated by [AVA](https://avajs.dev).
4444
> Snapshot 1
4545
4646
`// SPDX-License-Identifier: MIT␊
47-
// Compatible with OpenZeppelin Contracts for Cairo ^0.10.0␊
47+
// Compatible with OpenZeppelin Contracts for Cairo ^0.11.0␊
4848
4949
#[starknet::contract]␊
5050
mod Foo {␊
@@ -64,7 +64,7 @@ Generated by [AVA](https://avajs.dev).
6464
> Snapshot 1
6565
6666
`// SPDX-License-Identifier: MIT␊
67-
// Compatible with OpenZeppelin Contracts for Cairo ^0.10.0␊
67+
// Compatible with OpenZeppelin Contracts for Cairo ^0.11.0␊
6868
6969
#[starknet::contract]␊
7070
mod Foo {␊
@@ -89,7 +89,7 @@ Generated by [AVA](https://avajs.dev).
8989
> Snapshot 1
9090
9191
`// SPDX-License-Identifier: MIT␊
92-
// Compatible with OpenZeppelin Contracts for Cairo ^0.10.0␊
92+
// Compatible with OpenZeppelin Contracts for Cairo ^0.11.0␊
9393
9494
#[starknet::contract]␊
9595
mod Foo {␊
@@ -114,7 +114,7 @@ Generated by [AVA](https://avajs.dev).
114114
> Snapshot 1
115115
116116
`// SPDX-License-Identifier: MIT␊
117-
// Compatible with OpenZeppelin Contracts for Cairo ^0.10.0␊
117+
// Compatible with OpenZeppelin Contracts for Cairo ^0.11.0␊
118118
119119
#[starknet::contract]␊
120120
mod Foo {␊
@@ -152,12 +152,12 @@ Generated by [AVA](https://avajs.dev).
152152
> Snapshot 1
153153
154154
`// SPDX-License-Identifier: MIT␊
155-
// Compatible with OpenZeppelin Contracts for Cairo ^0.10.0␊
155+
// Compatible with OpenZeppelin Contracts for Cairo ^0.11.0␊
156156
157157
#[starknet::contract]␊
158158
mod Foo {␊
159-
use some::path::FooComponent;␊
160159
use some::library::SomeLibrary;␊
160+
use some::path::FooComponent;␊
161161
162162
component!(path: FooComponent, storage: foo, event: FooEvent);␊
163163
-4 Bytes
Binary file not shown.

packages/core-cairo/src/custom.test.ts.md

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ Generated by [AVA](https://avajs.dev).
99
> Snapshot 1
1010
1111
`// SPDX-License-Identifier: MIT␊
12-
// Compatible with OpenZeppelin Contracts for Cairo ^0.10.0␊
12+
// Compatible with OpenZeppelin Contracts for Cairo ^0.11.0␊
1313
1414
#[starknet::contract]␊
1515
mod MyContract {␊
@@ -24,12 +24,12 @@ Generated by [AVA](https://avajs.dev).
2424
> Snapshot 1
2525
2626
`// SPDX-License-Identifier: MIT␊
27-
// Compatible with OpenZeppelin Contracts for Cairo ^0.10.0␊
27+
// Compatible with OpenZeppelin Contracts for Cairo ^0.11.0␊
2828
2929
#[starknet::contract]␊
3030
mod MyContract {␊
31-
use openzeppelin::security::pausable::PausableComponent;␊
3231
use openzeppelin::access::ownable::OwnableComponent;␊
32+
use openzeppelin::security::pausable::PausableComponent;␊
3333
use starknet::ContractAddress;␊
3434
3535
component!(path: PausableComponent, storage: pausable, event: PausableEvent);␊
@@ -88,12 +88,12 @@ Generated by [AVA](https://avajs.dev).
8888
> Snapshot 1
8989
9090
`// SPDX-License-Identifier: MIT␊
91-
// Compatible with OpenZeppelin Contracts for Cairo ^0.10.0␊
91+
// Compatible with OpenZeppelin Contracts for Cairo ^0.11.0␊
9292
9393
#[starknet::contract]␊
9494
mod MyContract {␊
95-
use openzeppelin::upgrades::UpgradeableComponent;␊
9695
use openzeppelin::access::ownable::OwnableComponent;␊
96+
use openzeppelin::upgrades::UpgradeableComponent;␊
9797
use openzeppelin::upgrades::interface::IUpgradeable;␊
9898
use starknet::ClassHash;␊
9999
use starknet::ContractAddress;␊
@@ -144,7 +144,7 @@ Generated by [AVA](https://avajs.dev).
144144
> Snapshot 1
145145
146146
`// SPDX-License-Identifier: MIT␊
147-
// Compatible with OpenZeppelin Contracts for Cairo ^0.10.0␊
147+
// Compatible with OpenZeppelin Contracts for Cairo ^0.11.0␊
148148
149149
#[starknet::contract]␊
150150
mod MyContract {␊
@@ -159,7 +159,7 @@ Generated by [AVA](https://avajs.dev).
159159
> Snapshot 1
160160
161161
`// SPDX-License-Identifier: MIT␊
162-
// Compatible with OpenZeppelin Contracts for Cairo ^0.10.0␊
162+
// Compatible with OpenZeppelin Contracts for Cairo ^0.11.0␊
163163
164164
#[starknet::contract]␊
165165
mod MyContract {␊
@@ -198,13 +198,13 @@ Generated by [AVA](https://avajs.dev).
198198
> Snapshot 1
199199
200200
`// SPDX-License-Identifier: MIT␊
201-
// Compatible with OpenZeppelin Contracts for Cairo ^0.10.0␊
201+
// Compatible with OpenZeppelin Contracts for Cairo ^0.11.0␊
202202
203203
#[starknet::contract]␊
204204
mod MyContract {␊
205205
use openzeppelin::access::accesscontrol::AccessControlComponent;␊
206-
use openzeppelin::introspection::src5::SRC5Component;␊
207206
use openzeppelin::access::accesscontrol::DEFAULT_ADMIN_ROLE;␊
207+
use openzeppelin::introspection::src5::SRC5Component;␊
208208
use starknet::ContractAddress;␊
209209
210210
component!(path: AccessControlComponent, storage: accesscontrol, event: AccessControlEvent);␊
@@ -246,12 +246,12 @@ Generated by [AVA](https://avajs.dev).
246246
> Snapshot 1
247247
248248
`// SPDX-License-Identifier: MIT␊
249-
// Compatible with OpenZeppelin Contracts for Cairo ^0.10.0␊
249+
// Compatible with OpenZeppelin Contracts for Cairo ^0.11.0␊
250250
251251
#[starknet::contract]␊
252252
mod MyContract {␊
253-
use openzeppelin::security::pausable::PausableComponent;␊
254253
use openzeppelin::access::ownable::OwnableComponent;␊
254+
use openzeppelin::security::pausable::PausableComponent;␊
255255
use starknet::ContractAddress;␊
256256
257257
component!(path: PausableComponent, storage: pausable, event: PausableEvent);␊
0 Bytes
Binary file not shown.
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
import test from 'ava';
2+
import { erc1155 } from '.';
3+
4+
import { buildERC1155, ERC1155Options } from './erc1155';
5+
import { printContract } from './print';
6+
7+
function testERC1155(title: string, opts: Partial<ERC1155Options>) {
8+
test(title, t => {
9+
const c = buildERC1155({
10+
name: 'MyToken',
11+
baseUri: 'https://gateway.pinata.cloud/ipfs/QmcP9hxrnC1T5ATPmq2saFeAM1ypFX9BnAswCdHB9JCjLA/',
12+
...opts,
13+
});
14+
t.snapshot(printContract(c));
15+
});
16+
}
17+
18+
/**
19+
* Tests external API for equivalence with internal API
20+
*/
21+
function testAPIEquivalence(title: string, opts?: ERC1155Options) {
22+
test(title, t => {
23+
t.is(erc1155.print(opts), printContract(buildERC1155({
24+
name: 'MyToken',
25+
baseUri: '',
26+
...opts,
27+
})));
28+
});
29+
}
30+
31+
testERC1155('basic', {});
32+
33+
testERC1155('basic + roles', {
34+
access: 'roles',
35+
});
36+
37+
testERC1155('no updatable uri', {
38+
updatableUri: false,
39+
});
40+
41+
testERC1155('burnable', {
42+
burnable: true,
43+
});
44+
45+
testERC1155('pausable', {
46+
pausable: true,
47+
});
48+
49+
testERC1155('mintable', {
50+
mintable: true,
51+
});
52+
53+
testERC1155('mintable + roles', {
54+
mintable: true,
55+
access: 'roles',
56+
});
57+
58+
testERC1155('full upgradeable', {
59+
mintable: true,
60+
access: 'roles',
61+
burnable: true,
62+
pausable: true,
63+
upgradeable: true,
64+
});
65+
66+
testAPIEquivalence('API default');
67+
68+
testAPIEquivalence('API basic', { name: 'CustomToken', baseUri: 'https://gateway.pinata.cloud/ipfs/QmcP9hxrnC1T5ATPmq2saFeAM1ypFX9BnAswCdHB9JCjLA/' });
69+
70+
testAPIEquivalence('API full upgradeable', {
71+
name: 'CustomToken',
72+
baseUri: 'https://gateway.pinata.cloud/ipfs/QmcP9hxrnC1T5ATPmq2saFeAM1ypFX9BnAswCdHB9JCjLA/',
73+
mintable: true,
74+
access: 'roles',
75+
burnable: true,
76+
pausable: true,
77+
upgradeable: true,
78+
});
79+
80+
test('API assert defaults', async t => {
81+
t.is(erc1155.print(erc1155.defaults), erc1155.print());
82+
});
83+
84+
test('API isAccessControlRequired', async t => {
85+
t.is(erc1155.isAccessControlRequired({ updatableUri: false, mintable: true }), true);
86+
t.is(erc1155.isAccessControlRequired({ updatableUri: false, pausable: true }), true);
87+
t.is(erc1155.isAccessControlRequired({ updatableUri: false, upgradeable: true }), true);
88+
t.is(erc1155.isAccessControlRequired({ updatableUri: true }), true);
89+
t.is(erc1155.isAccessControlRequired({ updatableUri: false}), false);
90+
t.is(erc1155.isAccessControlRequired({}), true); // updatableUri is true by default
91+
});

0 commit comments

Comments
 (0)