Skip to content

Commit

Permalink
Cairo: Use mixins (#348)
Browse files Browse the repository at this point in the history
  • Loading branch information
ericglau authored Mar 27, 2024
1 parent a594e07 commit 705924a
Show file tree
Hide file tree
Showing 13 changed files with 97 additions and 184 deletions.
4 changes: 4 additions & 0 deletions packages/core-cairo/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# Changelog

## 0.10.1 (2024-03-27)

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

## 0.10.0 (2024-03-12)

- **Breaking changes**:
Expand Down
2 changes: 1 addition & 1 deletion packages/core-cairo/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@openzeppelin/wizard-cairo",
"version": "0.10.0",
"version": "0.10.1",
"description": "A boilerplate generator to get started with OpenZeppelin Contracts for Cairo",
"license": "MIT",
"repository": "github:OpenZeppelin/contracts-wizard",
Expand Down
15 changes: 9 additions & 6 deletions packages/core-cairo/src/common-components.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,18 @@ const components = defineComponents( {
name: 'SRC5Event',
type: 'SRC5Component::Event',
},
impls: [
{
name: 'SRC5Impl',
value: 'SRC5Component::SRC5Impl<ContractState>',
},
],
impls: [],
},
})

export function addSRC5Component(c: ContractBuilder) {
c.addComponent(components.SRC5Component, [], false);

if (!c.interfaceFlags.has('ISRC5')) {
c.addImplToComponent(components.SRC5Component, {
name: 'SRC5Impl',
value: 'SRC5Component::SRC5Impl<ContractState>',
});
c.addInterfaceFlag('ISRC5');
}
}
12 changes: 12 additions & 0 deletions packages/core-cairo/src/contract.ts
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ export class ContractBuilder implements Contract {
private implementedTraitsMap: Map<string, ImplementedTrait> = new Map<string, ImplementedTrait>();
private superVariablesMap: Map<string, Variable> = new Map<string, Variable>();
private standaloneImportsSet: Set<string> = new Set();
private interfaceFlagsSet: Set<string> = new Set();

constructor(name: string) {
this.name = toIdentifier(name, true);
Expand All @@ -110,6 +111,13 @@ export class ContractBuilder implements Contract {
return [...this.standaloneImportsSet];
}

/**
* Custom flags to denote that the contract implements a specific interface, e.g. ISRC5, to avoid duplicates
**/
get interfaceFlags(): Set<string> {
return this.interfaceFlagsSet;
}

addStandaloneImport(fullyQualified: string) {
this.standaloneImportsSet.add(fullyQualified);
}
Expand Down Expand Up @@ -208,4 +216,8 @@ export class ContractBuilder implements Contract {
addConstructorCode(code: string) {
this.constructorCode.push(code);
}

addInterfaceFlag(flag: string) {
this.interfaceFlagsSet.add(flag);
}
}
22 changes: 5 additions & 17 deletions packages/core-cairo/src/custom.test.ts.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,7 @@ Generated by [AVA](https://avajs.dev).
#[abi(embed_v0)]␊
impl PausableImpl = PausableComponent::PausableImpl<ContractState>;␊
#[abi(embed_v0)]␊
impl OwnableImpl = OwnableComponent::OwnableImpl<ContractState>;␊
#[abi(embed_v0)]␊
impl OwnableCamelOnlyImpl = OwnableComponent::OwnableCamelOnlyImpl<ContractState>;␊
impl OwnableMixinImpl = OwnableComponent::OwnableMixinImpl<ContractState>;␊
impl PausableInternalImpl = PausableComponent::InternalImpl<ContractState>;␊
impl OwnableInternalImpl = OwnableComponent::InternalImpl<ContractState>;␊
Expand Down Expand Up @@ -104,9 +102,7 @@ Generated by [AVA](https://avajs.dev).
component!(path: OwnableComponent, storage: ownable, event: OwnableEvent);␊
#[abi(embed_v0)]␊
impl OwnableImpl = OwnableComponent::OwnableImpl<ContractState>;␊
#[abi(embed_v0)]␊
impl OwnableCamelOnlyImpl = OwnableComponent::OwnableCamelOnlyImpl<ContractState>;␊
impl OwnableMixinImpl = OwnableComponent::OwnableMixinImpl<ContractState>;␊
impl UpgradeableInternalImpl = UpgradeableComponent::InternalImpl<ContractState>;␊
impl OwnableInternalImpl = OwnableComponent::InternalImpl<ContractState>;␊
Expand Down Expand Up @@ -173,9 +169,7 @@ Generated by [AVA](https://avajs.dev).
component!(path: OwnableComponent, storage: ownable, event: OwnableEvent);␊
#[abi(embed_v0)]␊
impl OwnableImpl = OwnableComponent::OwnableImpl<ContractState>;␊
#[abi(embed_v0)]␊
impl OwnableCamelOnlyImpl = OwnableComponent::OwnableCamelOnlyImpl<ContractState>;␊
impl OwnableMixinImpl = OwnableComponent::OwnableMixinImpl<ContractState>;␊
impl OwnableInternalImpl = OwnableComponent::InternalImpl<ContractState>;␊
Expand Down Expand Up @@ -217,11 +211,7 @@ Generated by [AVA](https://avajs.dev).
component!(path: SRC5Component, storage: src5, event: SRC5Event);␊
#[abi(embed_v0)]␊
impl AccessControlImpl = AccessControlComponent::AccessControlImpl<ContractState>;␊
#[abi(embed_v0)]␊
impl AccessControlCamelImpl = AccessControlComponent::AccessControlCamelImpl<ContractState>;␊
#[abi(embed_v0)]␊
impl SRC5Impl = SRC5Component::SRC5Impl<ContractState>;␊
impl AccessControlMixinImpl = AccessControlComponent::AccessControlMixinImpl<ContractState>;␊
impl AccessControlInternalImpl = AccessControlComponent::InternalImpl<ContractState>;␊
Expand Down Expand Up @@ -270,9 +260,7 @@ Generated by [AVA](https://avajs.dev).
#[abi(embed_v0)]␊
impl PausableImpl = PausableComponent::PausableImpl<ContractState>;␊
#[abi(embed_v0)]␊
impl OwnableImpl = OwnableComponent::OwnableImpl<ContractState>;␊
#[abi(embed_v0)]␊
impl OwnableCamelOnlyImpl = OwnableComponent::OwnableCamelOnlyImpl<ContractState>;␊
impl OwnableMixinImpl = OwnableComponent::OwnableMixinImpl<ContractState>;␊
impl PausableInternalImpl = PausableComponent::InternalImpl<ContractState>;␊
impl OwnableInternalImpl = OwnableComponent::InternalImpl<ContractState>;␊
Expand Down
Binary file modified packages/core-cairo/src/custom.test.ts.snap
Binary file not shown.
70 changes: 13 additions & 57 deletions packages/core-cairo/src/erc20.test.ts.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,7 @@ Generated by [AVA](https://avajs.dev).
component!(path: ERC20Component, storage: erc20, event: ERC20Event);␊
#[abi(embed_v0)]␊
impl ERC20MetadataImpl = ERC20Component::ERC20MetadataImpl<ContractState>;␊
#[abi(embed_v0)]␊
impl ERC20Impl = ERC20Component::ERC20Impl<ContractState>;␊
#[abi(embed_v0)]␊
impl ERC20CamelOnlyImpl = ERC20Component::ERC20CamelOnlyImpl<ContractState>;␊
impl ERC20MixinImpl = ERC20Component::ERC20ABI<ContractState>;␊
impl ERC20InternalImpl = ERC20Component::InternalImpl<ContractState>;␊
Expand Down Expand Up @@ -61,11 +57,7 @@ Generated by [AVA](https://avajs.dev).
component!(path: ERC20Component, storage: erc20, event: ERC20Event);␊
#[abi(embed_v0)]␊
impl ERC20MetadataImpl = ERC20Component::ERC20MetadataImpl<ContractState>;␊
#[abi(embed_v0)]␊
impl ERC20Impl = ERC20Component::ERC20Impl<ContractState>;␊
#[abi(embed_v0)]␊
impl ERC20CamelOnlyImpl = ERC20Component::ERC20CamelOnlyImpl<ContractState>;␊
impl ERC20MixinImpl = ERC20Component::ERC20ABI<ContractState>;␊
impl ERC20InternalImpl = ERC20Component::InternalImpl<ContractState>;␊
Expand Down Expand Up @@ -123,9 +115,7 @@ Generated by [AVA](https://avajs.dev).
#[abi(embed_v0)]␊
impl PausableImpl = PausableComponent::PausableImpl<ContractState>;␊
#[abi(embed_v0)]␊
impl OwnableImpl = OwnableComponent::OwnableImpl<ContractState>;␊
#[abi(embed_v0)]␊
impl OwnableCamelOnlyImpl = OwnableComponent::OwnableCamelOnlyImpl<ContractState>;␊
impl OwnableMixinImpl = OwnableComponent::OwnableMixinImpl<ContractState>;␊
impl ERC20InternalImpl = ERC20Component::InternalImpl<ContractState>;␊
impl PausableInternalImpl = PausableComponent::InternalImpl<ContractState>;␊
Expand Down Expand Up @@ -262,11 +252,7 @@ Generated by [AVA](https://avajs.dev).
#[abi(embed_v0)]␊
impl PausableImpl = PausableComponent::PausableImpl<ContractState>;␊
#[abi(embed_v0)]␊
impl AccessControlImpl = AccessControlComponent::AccessControlImpl<ContractState>;␊
#[abi(embed_v0)]␊
impl AccessControlCamelImpl = AccessControlComponent::AccessControlCamelImpl<ContractState>;␊
#[abi(embed_v0)]␊
impl SRC5Impl = SRC5Component::SRC5Impl<ContractState>;␊
impl AccessControlMixinImpl = AccessControlComponent::AccessControlMixinImpl<ContractState>;␊
impl ERC20InternalImpl = ERC20Component::InternalImpl<ContractState>;␊
impl PausableInternalImpl = PausableComponent::InternalImpl<ContractState>;␊
Expand Down Expand Up @@ -405,9 +391,7 @@ Generated by [AVA](https://avajs.dev).
#[abi(embed_v0)]␊
impl PausableImpl = PausableComponent::PausableImpl<ContractState>;␊
#[abi(embed_v0)]␊
impl OwnableImpl = OwnableComponent::OwnableImpl<ContractState>;␊
#[abi(embed_v0)]␊
impl OwnableCamelOnlyImpl = OwnableComponent::OwnableCamelOnlyImpl<ContractState>;␊
impl OwnableMixinImpl = OwnableComponent::OwnableMixinImpl<ContractState>;␊
impl ERC20InternalImpl = ERC20Component::InternalImpl<ContractState>;␊
impl PausableInternalImpl = PausableComponent::InternalImpl<ContractState>;␊
Expand Down Expand Up @@ -536,11 +520,7 @@ Generated by [AVA](https://avajs.dev).
component!(path: ERC20Component, storage: erc20, event: ERC20Event);␊
#[abi(embed_v0)]␊
impl ERC20MetadataImpl = ERC20Component::ERC20MetadataImpl<ContractState>;␊
#[abi(embed_v0)]␊
impl ERC20Impl = ERC20Component::ERC20Impl<ContractState>;␊
#[abi(embed_v0)]␊
impl ERC20CamelOnlyImpl = ERC20Component::ERC20CamelOnlyImpl<ContractState>;␊
impl ERC20MixinImpl = ERC20Component::ERC20ABI<ContractState>;␊
impl ERC20InternalImpl = ERC20Component::InternalImpl<ContractState>;␊
Expand Down Expand Up @@ -580,11 +560,7 @@ Generated by [AVA](https://avajs.dev).
component!(path: ERC20Component, storage: erc20, event: ERC20Event);␊
#[abi(embed_v0)]␊
impl ERC20MetadataImpl = ERC20Component::ERC20MetadataImpl<ContractState>;␊
#[abi(embed_v0)]␊
impl ERC20Impl = ERC20Component::ERC20Impl<ContractState>;␊
#[abi(embed_v0)]␊
impl ERC20CamelOnlyImpl = ERC20Component::ERC20CamelOnlyImpl<ContractState>;␊
impl ERC20MixinImpl = ERC20Component::ERC20ABI<ContractState>;␊
impl ERC20InternalImpl = ERC20Component::InternalImpl<ContractState>;␊
Expand Down Expand Up @@ -625,15 +601,9 @@ Generated by [AVA](https://avajs.dev).
component!(path: OwnableComponent, storage: ownable, event: OwnableEvent);␊
#[abi(embed_v0)]␊
impl ERC20MetadataImpl = ERC20Component::ERC20MetadataImpl<ContractState>;␊
#[abi(embed_v0)]␊
impl ERC20Impl = ERC20Component::ERC20Impl<ContractState>;␊
impl ERC20MixinImpl = ERC20Component::ERC20ABI<ContractState>;␊
#[abi(embed_v0)]␊
impl ERC20CamelOnlyImpl = ERC20Component::ERC20CamelOnlyImpl<ContractState>;␊
#[abi(embed_v0)]␊
impl OwnableImpl = OwnableComponent::OwnableImpl<ContractState>;␊
#[abi(embed_v0)]␊
impl OwnableCamelOnlyImpl = OwnableComponent::OwnableCamelOnlyImpl<ContractState>;␊
impl OwnableMixinImpl = OwnableComponent::OwnableMixinImpl<ContractState>;␊
impl ERC20InternalImpl = ERC20Component::InternalImpl<ContractState>;␊
impl OwnableInternalImpl = OwnableComponent::InternalImpl<ContractState>;␊
Expand Down Expand Up @@ -696,17 +666,9 @@ Generated by [AVA](https://avajs.dev).
component!(path: SRC5Component, storage: src5, event: SRC5Event);␊
#[abi(embed_v0)]␊
impl ERC20MetadataImpl = ERC20Component::ERC20MetadataImpl<ContractState>;␊
#[abi(embed_v0)]␊
impl ERC20Impl = ERC20Component::ERC20Impl<ContractState>;␊
#[abi(embed_v0)]␊
impl ERC20CamelOnlyImpl = ERC20Component::ERC20CamelOnlyImpl<ContractState>;␊
#[abi(embed_v0)]␊
impl AccessControlImpl = AccessControlComponent::AccessControlImpl<ContractState>;␊
#[abi(embed_v0)]␊
impl AccessControlCamelImpl = AccessControlComponent::AccessControlCamelImpl<ContractState>;␊
impl ERC20MixinImpl = ERC20Component::ERC20ABI<ContractState>;␊
#[abi(embed_v0)]␊
impl SRC5Impl = SRC5Component::SRC5Impl<ContractState>;␊
impl AccessControlMixinImpl = AccessControlComponent::AccessControlMixinImpl<ContractState>;␊
impl ERC20InternalImpl = ERC20Component::InternalImpl<ContractState>;␊
impl AccessControlInternalImpl = AccessControlComponent::InternalImpl<ContractState>;␊
Expand Down Expand Up @@ -782,9 +744,7 @@ Generated by [AVA](https://avajs.dev).
#[abi(embed_v0)]␊
impl PausableImpl = PausableComponent::PausableImpl<ContractState>;␊
#[abi(embed_v0)]␊
impl OwnableImpl = OwnableComponent::OwnableImpl<ContractState>;␊
#[abi(embed_v0)]␊
impl OwnableCamelOnlyImpl = OwnableComponent::OwnableCamelOnlyImpl<ContractState>;␊
impl OwnableMixinImpl = OwnableComponent::OwnableMixinImpl<ContractState>;␊
impl ERC20InternalImpl = ERC20Component::InternalImpl<ContractState>;␊
impl PausableInternalImpl = PausableComponent::InternalImpl<ContractState>;␊
Expand Down Expand Up @@ -957,11 +917,7 @@ Generated by [AVA](https://avajs.dev).
#[abi(embed_v0)]␊
impl PausableImpl = PausableComponent::PausableImpl<ContractState>;␊
#[abi(embed_v0)]␊
impl AccessControlImpl = AccessControlComponent::AccessControlImpl<ContractState>;␊
#[abi(embed_v0)]␊
impl AccessControlCamelImpl = AccessControlComponent::AccessControlCamelImpl<ContractState>;␊
#[abi(embed_v0)]␊
impl SRC5Impl = SRC5Component::SRC5Impl<ContractState>;␊
impl AccessControlMixinImpl = AccessControlComponent::AccessControlMixinImpl<ContractState>;␊
impl ERC20InternalImpl = ERC20Component::InternalImpl<ContractState>;␊
impl PausableInternalImpl = PausableComponent::InternalImpl<ContractState>;␊
Expand Down
Binary file modified packages/core-cairo/src/erc20.test.ts.snap
Binary file not shown.
24 changes: 10 additions & 14 deletions packages/core-cairo/src/erc20.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ export function buildERC20(opts: ERC20Options): Contract {
const allOpts = withDefaults(opts);

addBase(c, toStringLiteral(allOpts.name), toStringLiteral(allOpts.symbol));
addERC20ImplAndCamelOnlyImpl(c, allOpts.pausable);
addERC20MixinOrImpls(c, allOpts.pausable);

if (allOpts.premint) {
addPremint(c, allOpts.premint);
Expand Down Expand Up @@ -93,10 +93,15 @@ function addERC20Interface(c: ContractBuilder) {
c.addStandaloneImport('openzeppelin::token::erc20::interface');
}

function addERC20ImplAndCamelOnlyImpl(c: ContractBuilder, pausable: boolean) {
function addERC20MixinOrImpls(c: ContractBuilder, pausable: boolean) {
if (pausable) {
addERC20Interface(c);

c.addImplToComponent(components.ERC20Component, {
name: 'ERC20MetadataImpl',
value: 'ERC20Component::ERC20MetadataImpl<ContractState>',
});

const ERC20Impl: BaseImplementedTrait = {
name: 'ERC20Impl',
of: 'interface::IERC20<ContractState>',
Expand All @@ -123,12 +128,8 @@ function addERC20ImplAndCamelOnlyImpl(c: ContractBuilder, pausable: boolean) {
setPausable(c, ERC20CamelOnlyImpl, functions.transferFrom);
} else {
c.addImplToComponent(components.ERC20Component, {
name: 'ERC20Impl',
value: 'ERC20Component::ERC20Impl<ContractState>',
});
c.addImplToComponent(components.ERC20Component, {
name: 'ERC20CamelOnlyImpl',
value: 'ERC20Component::ERC20CamelOnlyImpl<ContractState>',
name: 'ERC20MixinImpl',
value: 'ERC20Component::ERC20ABI<ContractState>',
});
}
}
Expand Down Expand Up @@ -223,12 +224,7 @@ const components = defineComponents( {
name: 'ERC20Event',
type: 'ERC20Component::Event',
},
impls: [
{
name: 'ERC20MetadataImpl',
value: 'ERC20Component::ERC20MetadataImpl<ContractState>',
},
],
impls: [],
internalImpl: {
name: 'ERC20InternalImpl',
value: 'ERC20Component::InternalImpl<ContractState>',
Expand Down
Loading

0 comments on commit 705924a

Please sign in to comment.