Spells for setting up and using Hats Protocol within MakerDAO
hats-protocol / maker-hats-spells Goto Github PK
View Code? Open in Web Editor NEWMakerDAOSpells for deploying and using Hats Protocol
MakerDAOSpells for deploying and using Hats Protocol
Hey guys, just a few pointers regarding spell crafting:
maker-hats-spells/src/CreateHatSpell.sol
Lines 75 to 77 in c8069ab
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:
maker-hats-spells/src/MintTopHatSpell.sol
Line 65 in c8069ab
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 {}
}
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.