dojoengine / origami

The magic of origami is in seeing a single piece of cairo evolve into a masterpiece through careful folds.
MIT License
34 stars 18 forks source link

World Marionette #42

Open tarrencev opened 6 months ago

tarrencev commented 6 months ago

World admins have unlimited authority in to modify the world, including setting arbitrary state, upgrading contracts, etc. This is a useful functionality in the early days of the worlds deployment but can be a liability in certain cases. Currently, it is only possible to have unlimited power or none at all. This issue is to create a proxy contract that would take ownership of a world, enabling progressive decentralization of world administration over time.

The basic idea is to wrap the permissioned endpoints in a proxy contract that will be the world admin. The Marionette contract should support the ability to gate calls to these endpoints based on an exception list.

For example, in the case of set_entity, the owner of the Marionette contract can set model exceptions that will prevent the world admin from writing directly to those models. For example, if the world had a erc20 token deployed to it, it could add the erc20 balance model as an exemption which would prevent the admin from modifying that state. The same should be possible for preventing upgrades of particular contracts by the admin.

This will enable world admins to progressively decentralize the operation of the world by selectively making different resources immutable.

An additional feature that could be useful, is to support timelocks for exceptions, so the admin could be able to upgrade and erc20 contract implementation but could be subject to a t day timelock.

The permissioned endpoints to proxy:

    fn set_entity(
        ref self: T,
        model: felt252,
        keys: Span<felt252>,
        offset: u8,
        values: Span<felt252>,
        layout: Span<u8>
    );
    fn delete_entity(ref self: T, model: felt252, keys: Span<felt252>, layout: Span<u8>);
    fn upgrade_contract(ref self: T, address: ContractAddress, class_hash: ClassHash) -> ClassHash;
    fn set_executor(ref self: T, contract_address: ContractAddress);
    fn upgrade(ref self: T, new_class_hash: ClassHash);
    fn grant_owner(ref self: T, address: ContractAddress, resource: felt252);
    fn revoke_owner(ref self: T, address: ContractAddress, resource: felt252);
    fn grant_writer(ref self: T, model: felt252, contract: ContractAddress);
    fn revoke_writer(ref self: T, model: felt252, contract: ContractAddress);

Addition interfaces:

OwnableTwoStep https://github.com/OpenZeppelin/cairo-contracts/blob/44b5259ca316c4a7931e8ca77699bb3c00c70a54/src/access/ownable/interface.cairo#L20

#[starknet::interface]
trait IMarionetteFreeze<TState> {
    fn freeze(ref self: TState, resource: felt252, timelock: felt252);
}

In the token example, if the model is erc20_balance and the contract is erc20, to make the contract immutable, the admin would call freeze on the model and contract resources. Then any permissioned endpoints that interact with models / contracts will assert the exemption criteria before proxying the call to the underlying world.

ebukizy1 commented 4 months ago

will love to work on this can i be assign this task

PedroRosalba commented 2 months ago

@tarrencev Can I work on this?

jsanchez556 commented 1 month ago

I am applying to this issue via OnlyDust platform.

My background and how it can be leveraged

Hello, I’m Jose Mario from Costa Rica. With over 15 years of experience in development, I am passionate about contributing to open-source projects and currently expanding my skill set with Rust, Cairo, and Solidity as part of my involvement with Dojo Coding. My recent role as a Senior Backend Developer allowed me to specialize in a range of technologies including Node.js, JavaScript, TypeScript, and Docker, among others. I am eager to apply my extensive experience and newly acquired skills to new challenges and innovative projects.

How I plan on tackling this issue

  1. Develop a Marionette Proxy Contract:

    • Create a contract that functions as the Marionette proxy, capable of managing permissioned endpoints.
  2. Implement Proxy Functions:

    • Develop proxy functions for each permissioned endpoint:
      • set_entity
      • delete_entity
      • upgrade_contract
      • set_executor
      • upgrade
      • grant_owner
      • revoke_owner
      • grant_writer
      • revoke_writer
  3. Manage Exceptions for Models and Contracts:

    • Implement functionality to add and remove exceptions for specific models and contracts.
    • Exceptions should prevent the world admin from modifying certain states or upgrading specific contracts.
    • Consider creating an interface for managing these exceptions effectively.
  4. Develop a Timelock Mechanism for Exceptions:

    • Implement functionality to set a timelock on modifications or upgrades.
    • Ensure this mechanism supports managing exceptions.
  5. Integrate Secure Ownership Transfers:

    • Use the OwnableTwoStep interface to manage ownership transfers securely.
  6. Implement Resource Freezing with Timelocks:

    • Support freezing resources with a timelock by implementing the IMarionetteFreeze interface.
  7. Create Comprehensive Test Cases:

    • Develop test cases to validate the functionality of each proxy function, exception list management, and timelock mechanism.