GithubHelp home page GithubHelp logo

maker-hats-spells's Introduction

MakerDAO Hats Spells

Spells for setting up and using Hats Protocol within MakerDAO

maker-hats-spells's People

Contributors

spengrah avatar

Watchers

 avatar

maker-hats-spells's Issues

Spell crafting tips

Hey guys, just a few pointers regarding spell crafting:

constructor(IHats _hats, DSPauseProxy _pauseHatsProxy, uint256 _tophat)
DssExec(block.timestamp + 30 days, address(new DssSpellAction(_hats, _pauseHatsProxy, _tophat)))
{ }

For the sake of auditability, spells need to be as static as possible.
You probably don't want have constructor params, but use constants with hard-coded values instead. See this for some reference.


The same principle applies here:

constructor(IHats _hats) DssExec(block.timestamp + 30 days, address(new DssSpellAction(_hats))) { }


import { IHats } from "hats-protocol/Interfaces/IHats.sol";

Avoid pulling external interfaces into a spell. Most of the time, you want to inline them, declaring only the methods used in the spell.


From what I could get, MintTopHatSpell will create the dependencies required for CreateHatSpell.

I would suggest having something like this:

// MintTopHatSpell.sol
interface HatsLike {
    function mintTopHat(
        address _target, 
        string memory _details, 
        string memory _imageURI
    ) external returns (uint256 topHatId);
}

contract DssSpellAction is DssAction {
    // ...
    address public constant HATS = address(0); // TODO: fill with the hats contract instance;

    function actions() public override {
        // https://vote.makerdao.com/polling/TODO#poll-detail TODO: UPDATE THIS ONCE THERE'S A POLL

        /* For security & separation of concerns reasons, we create a new proxy to wear 
         * the tophat. The new proxy is owned/controlled by the original pauseProxy.
         * Since minting a tophat can be done on behalf of another contract, the present 
         * spell is straightforward and can be executed within the context of the 
         * pauseProxy.
         * 
         * However, subsequent executive spells operating under this tophat will need to * executed from the context of the new proxy, which will require using something 
         * like the following pattern of spell actions:
         *
         *  1. Generate the abi-encoded bytes for a tx to be called against Hats.sol
         *  2. Call `hatsPauseProxy.exec(usr: Hats.sol, fax: the_bytes_from_1);`
         * 
         * This will execute the Hats tx from the execution context of the hatsPauseProxy.
         */

        // deploy a new DSPauseProxy that will be owned by the original pauseProxy
        DSPauseProxy hatsPauseProxy = new DSPauseProxy(); // owner == msg.sender == pauseProxy

        // mint a tophat to the hatsPauseProxy
        uint256 topHatId = HatsLike(HATS).mintTopHat(
            address(hatsPauseProxy),
            // the tophat's details and imageURI can both be updated later
            "", // TODO MakerDAO to decide which details to use initially
            "" // TODO MakerDAO to decide which image to use initially
        );
    }
    
    // ...
}


contract DssSpell is DssExec {
    constructor() DssExec(block.timestamp + 30 days, address(new DssSpellAction())) public {}
}

And:

// CreateHatSpell.sol

interface DSPauseProxyLike {
    function exec(address usr, bytes memory fax) external returns (bytes memory out);
}

interface HatsLike {
  function createHat(
        uint256 _admin,
        string memory _details,
        uint32 _maxSupply,
        address _eligibility,
        address _toggle,
        bool _mutable,
        string memory _imageURI
    ) external returns (uint256 newHatId);
}

contract DssSpellAction is DssAction {
    address public constant HATS = address(0); // TODO: fill with the hats contract instance
    address public constant HATS_PAUSE_PROXY = address(0); // TODO: fill with the hats pause proxy instance
    uint256 public constant TOP_HAT_ID = 0; // TODO: fill with the top hat ID created before

    // DssAction developer must override `actions()` and place all actions to be called inside.
    //   The DssExec function will call this subject to the officeHours limiter
    //   By keeping this function public we allow simulations of `execute()` on the actions outside of the cast time.
    function actions() public override {
        /* For security & separation of concerns reasons, MakerDAO's tophat is owned and 
         * controlled by a separate proxy called pauseHatsProxy.
         * 
         * Spells taking actions from or underneath the tophat must be executed from the 
         * context of the pauseHatsProxy, which will require using something like the 
         * following pattern:
         *
         *  1. Generate the abi-encoded bytes for a tx to be called against Hats.sol
         *  2. Call `pauseHatsProxy.exec(usr: Hats.sol, fax: the_bytes_from_1);`
         * 
         * This will execute the Hats tx from the execution context of the pauseHatsProxy.
         */
        // 0. define new hat parameters
        string memory details;
        uint32 maxSupply;
        address eligibility;
        address toggle;
        bool mutable_;
        string memory imageURI;

        // 1. generate the abi-encoded bytes for the createHat transaction to be called against Hats.sol
        bytes memory fax = abi.encodeWithSelector(
            HatsLike(0).createHat.selector,
            TOP_HAT_ID, // admin
            details,
            maxSupply,
            eligibility,
            toggle,
            mutable_,
            imageURI
        );

        // 2. pass the fax as a payload to hatsPauseProxy
        DSPauseProxyLike(HATS_PAUSE_PROXY).exec(hats, fax);
    }
}

contract DssSpell is DssExec {
    constructor() DssExec(block.timestamp + 30 days, address(new DssSpellAction())) public {}
}

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.