You are not reading the current version of this documentation. 1.0.0 is the current version.

Presets

Presets are ready-to-deploy contracts provided by the library. Since presets are intended to be very simple and as generic as possible, there’s no support for custom or complex contracts such as ERC20Pausable or ERC721Mintable.

For contract customization and combination of modules you can use Wizard for Cairo, our code-generation tool.

Available presets

List of available presets and their corresponding Sierra class hashes. Like Contracts for Cairo, use of preset contracts are subject to the terms of the MIT License.

Class hashes were computed using cairo 2.11.4.
Name Sierra Class Hash

AccountUpgradeable

0x07fa937960fd981bc9a7f54f02786cfa6c6f194fc66cb0c35c1588bd83448062

ERC20Upgradeable

0x05ae0a6a994b2145a80c31fb3cd46f7150d984de8e104becdebe481d7724daf3

ERC721Upgradeable

0x0077dcbd0d9907cff8b84dcf0c3006ab07b27a7db1e1e4e12b272d6b1fcdad4c

ERC1155Upgradeable

0x019f291ac71b768cef21602a19bedbc2f45d38374bba086585cd434c2c0e28cd

EthAccountUpgradeable

0x06c71d751a10084fa31758b50348bfaa7f0b8e4b1ce36c2ab5b159cb4c307f74

UniversalDeployer

0x025cc49fb4b211e46b3b91bfbdd4741202ca371cd25abe2806d1b5e1250e1759

VestingWallet

0x01865aa64d7cbc465ab675d87b493c4c58af82eef726e702d87ca8ca4f6040e2

starkli class-hash command can be used to compute the class hash from a Sierra artifact.

Usage

These preset contracts are ready-to-deploy which means they should already be declared on the Sepolia network. Simply deploy the preset class hash and add the appropriate constructor arguments. Deploying the ERC20Upgradeable preset with starkli, for example, will look like this:

starkli deploy 0x05ae0a6a994b2145a80c31fb3cd46f7150d984de8e104becdebe481d7724daf3 \
  <CONSTRUCTOR_ARGS> \
  --network="sepolia"

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 and installing the Contracts for Cairo library. Copy the target preset contract from the presets directory and paste it in the new project’s src/lib.cairo like this:

// src/lib.cairo

#[starknet::contract]
mod ERC20Upgradeable {
    use openzeppelin_access::ownable::OwnableComponent;
    use openzeppelin_token::erc20::{ERC20Component, ERC20HooksEmptyImpl};
    use openzeppelin_upgrades::UpgradeableComponent;
    use openzeppelin_upgrades::interface::IUpgradeable;
    use starknet::{ContractAddress, ClassHash};

    component!(path: OwnableComponent, storage: ownable, event: OwnableEvent);
    component!(path: ERC20Component, storage: erc20, event: ERC20Event);
    component!(path: UpgradeableComponent, storage: upgradeable, event: UpgradeableEvent);

    // Ownable Mixin
    #[abi(embed_v0)]
    impl OwnableMixinImpl = OwnableComponent::OwnableMixinImpl<ContractState>;
    impl OwnableInternalImpl = OwnableComponent::InternalImpl<ContractState>;

    // ERC20 Mixin
    #[abi(embed_v0)]
    impl ERC20MixinImpl = ERC20Component::ERC20MixinImpl<ContractState>;
    impl ERC20InternalImpl = ERC20Component::InternalImpl<ContractState>;

    // Upgradeable
    impl UpgradeableInternalImpl = UpgradeableComponent::InternalImpl<ContractState>;

    #[storage]
    struct Storage {
        #[substorage(v0)]
        ownable: OwnableComponent::Storage,
        #[substorage(v0)]
        erc20: ERC20Component::Storage,
        #[substorage(v0)]
        upgradeable: UpgradeableComponent::Storage
    }

    #[event]
    #[derive(Drop, starknet::Event)]
    enum Event {
        #[flat]
        OwnableEvent: OwnableComponent::Event,
        #[flat]
        ERC20Event: ERC20Component::Event,
        #[flat]
        UpgradeableEvent: UpgradeableComponent::Event
    }

    #[constructor]
    fn constructor(
        ref self: ContractState,
        name: ByteArray,
        symbol: ByteArray,
        fixed_supply: u256,
        recipient: ContractAddress,
        owner: ContractAddress
    ) {
        self.ownable.initializer(owner);
        self.erc20.initializer(name, symbol);
        self.erc20.mint(recipient, fixed_supply);
    }

    #[abi(embed_v0)]
    impl UpgradeableImpl of IUpgradeable<ContractState> {
        fn upgrade(ref self: ContractState, new_class_hash: ClassHash) {
            self.ownable.assert_only_owner();
            self.upgradeable.upgrade(new_class_hash);
        }
    }
}

Next, compile the contract.

scarb build

Finally, declare the preset.

starkli declare target/dev/my_project_ERC20Upgradeable.contract_class.json \
  --network="sepolia"