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.

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

AccountUpgradeable

0x02b31e19e45c06f29234e06e2ee98a9966479ba3067f8785ed972794fdb0065c

ERC20Upgradeable

0x041385cd42de9877180b006fc01d613c70e2429fc2e660df6a791b4cc0e747de

ERC721Upgradeable

0x015922a7436b4ee45120d5f6442bcfd8dd407fa2283dfa2276ccb9db10a9deda

ERC1155Upgradeable

0x046ec13b3dc855cddbaad504c5d3526f34134541f04207c7cfa7b6919f5fd2be

EthAccountUpgradeable

0x02ba7c42372cf971c8ee60166544e7ff72c2e38bc2835d7edd89b327b1000d8b

UniversalDeployer

0x06b79a175c8be9fb2acf40a1b0289018c95d04092dd4f080a133d83f9e9c696b

VestingWallet

0x0386b4e438105ef2ba52b12dae76e6afef54a234083137d32c57d06693a8c7c7

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 0x041385cd42de9877180b006fc01d613c70e2429fc2e660df6a791b4cc0e747de \
  <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"