From 169724b4f5482996cf2ad54d9675b339899277c4 Mon Sep 17 00:00:00 2001 From: Kellar Date: Fri, 25 Oct 2024 15:15:14 +0100 Subject: [PATCH 1/3] deploy contracts --- deployments/base/DecentHats_0_1_0.json | 208 ++++++++++++++-- .../4754a2f0c9d6a191a066af246491b62a.json | 59 +++++ deployments/mainnet/DecentHats_0_1_0.json | 208 ++++++++++++++-- .../4754a2f0c9d6a191a066af246491b62a.json | 59 +++++ deployments/optimism/DecentHats_0_1_0.json | 208 ++++++++++++++-- .../4754a2f0c9d6a191a066af246491b62a.json | 59 +++++ deployments/polygon/DecentHats_0_1_0.json | 224 ++++++++++++++++-- .../4754a2f0c9d6a191a066af246491b62a.json | 59 +++++ deployments/sepolia/DecentHats_0_1_0.json | 210 ++++++++++++++-- .../4754a2f0c9d6a191a066af246491b62a.json | 59 +++++ 10 files changed, 1264 insertions(+), 89 deletions(-) create mode 100644 deployments/base/solcInputs/4754a2f0c9d6a191a066af246491b62a.json create mode 100644 deployments/mainnet/solcInputs/4754a2f0c9d6a191a066af246491b62a.json create mode 100644 deployments/optimism/solcInputs/4754a2f0c9d6a191a066af246491b62a.json create mode 100644 deployments/polygon/solcInputs/4754a2f0c9d6a191a066af246491b62a.json create mode 100644 deployments/sepolia/solcInputs/4754a2f0c9d6a191a066af246491b62a.json diff --git a/deployments/base/DecentHats_0_1_0.json b/deployments/base/DecentHats_0_1_0.json index 6ecfc1b4..ec1bdb20 100644 --- a/deployments/base/DecentHats_0_1_0.json +++ b/deployments/base/DecentHats_0_1_0.json @@ -1,5 +1,5 @@ { - "address": "0x00b089E0A6fdE24cf8978994c7BcD24fc1D79825", + "address": "0x2A8Bf5E47FDcceA8Ab31A995C25198996D5ac514", "abi": [ { "inputs": [], @@ -275,6 +275,168 @@ "stateMutability": "nonpayable", "type": "function" }, + { + "inputs": [ + { + "internalType": "contract IHats", + "name": "hatsProtocol", + "type": "address" + }, + { + "internalType": "uint256", + "name": "adminHatId", + "type": "uint256" + }, + { + "components": [ + { + "internalType": "uint32", + "name": "maxSupply", + "type": "uint32" + }, + { + "internalType": "string", + "name": "details", + "type": "string" + }, + { + "internalType": "string", + "name": "imageURI", + "type": "string" + }, + { + "internalType": "bool", + "name": "isMutable", + "type": "bool" + }, + { + "internalType": "address", + "name": "wearer", + "type": "address" + }, + { + "components": [ + { + "internalType": "contract ISablierV2LockupLinear", + "name": "sablier", + "type": "address" + }, + { + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "internalType": "uint128", + "name": "totalAmount", + "type": "uint128" + }, + { + "internalType": "address", + "name": "asset", + "type": "address" + }, + { + "internalType": "bool", + "name": "cancelable", + "type": "bool" + }, + { + "internalType": "bool", + "name": "transferable", + "type": "bool" + }, + { + "components": [ + { + "internalType": "uint40", + "name": "start", + "type": "uint40" + }, + { + "internalType": "uint40", + "name": "cliff", + "type": "uint40" + }, + { + "internalType": "uint40", + "name": "end", + "type": "uint40" + } + ], + "internalType": "struct LockupLinear.Timestamps", + "name": "timestamps", + "type": "tuple" + }, + { + "components": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "uint256", + "name": "fee", + "type": "uint256" + } + ], + "internalType": "struct LockupLinear.Broker", + "name": "broker", + "type": "tuple" + } + ], + "internalType": "struct DecentHats_0_1_0.SablierStreamParams[]", + "name": "sablierParams", + "type": "tuple[]" + } + ], + "internalType": "struct DecentHats_0_1_0.Hat", + "name": "hat", + "type": "tuple" + }, + { + "internalType": "uint256", + "name": "topHatId", + "type": "uint256" + }, + { + "internalType": "address", + "name": "topHatAccount", + "type": "address" + }, + { + "internalType": "contract IERC6551Registry", + "name": "registry", + "type": "address" + }, + { + "internalType": "address", + "name": "hatsAccountImplementation", + "type": "address" + }, + { + "internalType": "bytes32", + "name": "salt", + "type": "bytes32" + } + ], + "name": "createRoleHat", + "outputs": [ + { + "internalType": "uint256", + "name": "hatId", + "type": "uint256" + }, + { + "internalType": "address", + "name": "accountAddress", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, { "inputs": [], "name": "getSalt", @@ -289,36 +451,50 @@ "type": "function" } ], - "transactionHash": "0x5d86a480602424ac02518917b0eb305225c80775da3569f318942c31ac8424b3", + "transactionHash": "0x5e1f773df67fb54ba7cf1b3b500c8bf99b45f2c4bc0442f53ffb9e2b42738a00", "receipt": { "to": null, "from": "0xb5Ca125166C1987A35EDD550E16846Fa1e1D9bB3", - "contractAddress": "0x00b089E0A6fdE24cf8978994c7BcD24fc1D79825", - "transactionIndex": 56, - "gasUsed": "1162443", + "contractAddress": "0x2A8Bf5E47FDcceA8Ab31A995C25198996D5ac514", + "transactionIndex": 67, + "gasUsed": "1243979", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x1eb0f75b3947cd2eacb086e5add97af2d11d11b47767445a9daf2cebc6589b07", - "transactionHash": "0x5d86a480602424ac02518917b0eb305225c80775da3569f318942c31ac8424b3", + "blockHash": "0x4972942095f87c4710d5794d86dd19283408255356cabe89217a00cf41239cf8", + "transactionHash": "0x5e1f773df67fb54ba7cf1b3b500c8bf99b45f2c4bc0442f53ffb9e2b42738a00", "logs": [], - "blockNumber": 20902423, - "cumulativeGasUsed": "8359038", + "blockNumber": 21538074, + "cumulativeGasUsed": "14620525", "status": 1, "byzantium": true }, "args": [], - "numDeployments": 3, - "solcInputHash": "6ceb8d75a501322d052845dbe517017d", - "metadata": "{\"compiler\":{\"version\":\"0.8.19+commit.7dd6d404\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"NAME\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"contract IHats\",\"name\":\"hatsProtocol\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"hatsAccountImplementation\",\"type\":\"address\"},{\"internalType\":\"contract IERC6551Registry\",\"name\":\"registry\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"keyValuePairs\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"topHatDetails\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"topHatImageURI\",\"type\":\"string\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"maxSupply\",\"type\":\"uint32\"},{\"internalType\":\"string\",\"name\":\"details\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"imageURI\",\"type\":\"string\"},{\"internalType\":\"bool\",\"name\":\"isMutable\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"wearer\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"contract ISablierV2LockupLinear\",\"name\":\"sablier\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint128\",\"name\":\"totalAmount\",\"type\":\"uint128\"},{\"internalType\":\"address\",\"name\":\"asset\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"cancelable\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"transferable\",\"type\":\"bool\"},{\"components\":[{\"internalType\":\"uint40\",\"name\":\"start\",\"type\":\"uint40\"},{\"internalType\":\"uint40\",\"name\":\"cliff\",\"type\":\"uint40\"},{\"internalType\":\"uint40\",\"name\":\"end\",\"type\":\"uint40\"}],\"internalType\":\"struct LockupLinear.Timestamps\",\"name\":\"timestamps\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"fee\",\"type\":\"uint256\"}],\"internalType\":\"struct LockupLinear.Broker\",\"name\":\"broker\",\"type\":\"tuple\"}],\"internalType\":\"struct DecentHats_0_1_0.SablierStreamParams[]\",\"name\":\"sablierParams\",\"type\":\"tuple[]\"}],\"internalType\":\"struct DecentHats_0_1_0.Hat\",\"name\":\"adminHat\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"maxSupply\",\"type\":\"uint32\"},{\"internalType\":\"string\",\"name\":\"details\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"imageURI\",\"type\":\"string\"},{\"internalType\":\"bool\",\"name\":\"isMutable\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"wearer\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"contract ISablierV2LockupLinear\",\"name\":\"sablier\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint128\",\"name\":\"totalAmount\",\"type\":\"uint128\"},{\"internalType\":\"address\",\"name\":\"asset\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"cancelable\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"transferable\",\"type\":\"bool\"},{\"components\":[{\"internalType\":\"uint40\",\"name\":\"start\",\"type\":\"uint40\"},{\"internalType\":\"uint40\",\"name\":\"cliff\",\"type\":\"uint40\"},{\"internalType\":\"uint40\",\"name\":\"end\",\"type\":\"uint40\"}],\"internalType\":\"struct LockupLinear.Timestamps\",\"name\":\"timestamps\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"fee\",\"type\":\"uint256\"}],\"internalType\":\"struct LockupLinear.Broker\",\"name\":\"broker\",\"type\":\"tuple\"}],\"internalType\":\"struct DecentHats_0_1_0.SablierStreamParams[]\",\"name\":\"sablierParams\",\"type\":\"tuple[]\"}],\"internalType\":\"struct DecentHats_0_1_0.Hat[]\",\"name\":\"hats\",\"type\":\"tuple[]\"}],\"internalType\":\"struct DecentHats_0_1_0.CreateTreeParams\",\"name\":\"params\",\"type\":\"tuple\"}],\"name\":\"createAndDeclareTree\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getSalt\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"salt\",\"type\":\"bytes32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/DecentHats_0_1_0.sol\":\"DecentHats_0_1_0\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\":{\"content\":\"// SPDX-License-Identifier: LGPL-3.0-only\\npragma solidity >=0.7.0 <0.9.0;\\n\\n/// @title Enum - Collection of enums\\n/// @author Richard Meissner - \\ncontract Enum {\\n enum Operation {Call, DelegateCall}\\n}\\n\",\"keccak256\":\"0x473e45b1a5cc47be494b0e123c9127f0c11c1e0992a321ae5a644c0bfdb2c14f\",\"license\":\"LGPL-3.0-only\"},\"@gnosis.pm/zodiac/contracts/interfaces/IAvatar.sol\":{\"content\":\"// SPDX-License-Identifier: LGPL-3.0-only\\n\\n/// @title Zodiac Avatar - A contract that manages modules that can execute transactions via this contract.\\npragma solidity >=0.7.0 <0.9.0;\\n\\nimport \\\"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\\\";\\n\\ninterface IAvatar {\\n event EnabledModule(address module);\\n event DisabledModule(address module);\\n event ExecutionFromModuleSuccess(address indexed module);\\n event ExecutionFromModuleFailure(address indexed module);\\n\\n /// @dev Enables a module on the avatar.\\n /// @notice Can only be called by the avatar.\\n /// @notice Modules should be stored as a linked list.\\n /// @notice Must emit EnabledModule(address module) if successful.\\n /// @param module Module to be enabled.\\n function enableModule(address module) external;\\n\\n /// @dev Disables a module on the avatar.\\n /// @notice Can only be called by the avatar.\\n /// @notice Must emit DisabledModule(address module) if successful.\\n /// @param prevModule Address that pointed to the module to be removed in the linked list\\n /// @param module Module to be removed.\\n function disableModule(address prevModule, address module) external;\\n\\n /// @dev Allows a Module to execute a transaction.\\n /// @notice Can only be called by an enabled module.\\n /// @notice Must emit ExecutionFromModuleSuccess(address module) if successful.\\n /// @notice Must emit ExecutionFromModuleFailure(address module) if unsuccessful.\\n /// @param to Destination address of module transaction.\\n /// @param value Ether value of module transaction.\\n /// @param data Data payload of module transaction.\\n /// @param operation Operation type of module transaction: 0 == call, 1 == delegate call.\\n function execTransactionFromModule(\\n address to,\\n uint256 value,\\n bytes memory data,\\n Enum.Operation operation\\n ) external returns (bool success);\\n\\n /// @dev Allows a Module to execute a transaction and return data\\n /// @notice Can only be called by an enabled module.\\n /// @notice Must emit ExecutionFromModuleSuccess(address module) if successful.\\n /// @notice Must emit ExecutionFromModuleFailure(address module) if unsuccessful.\\n /// @param to Destination address of module transaction.\\n /// @param value Ether value of module transaction.\\n /// @param data Data payload of module transaction.\\n /// @param operation Operation type of module transaction: 0 == call, 1 == delegate call.\\n function execTransactionFromModuleReturnData(\\n address to,\\n uint256 value,\\n bytes memory data,\\n Enum.Operation operation\\n ) external returns (bool success, bytes memory returnData);\\n\\n /// @dev Returns if an module is enabled\\n /// @return True if the module is enabled\\n function isModuleEnabled(address module) external view returns (bool);\\n\\n /// @dev Returns array of modules.\\n /// @param start Start of the page.\\n /// @param pageSize Maximum number of modules that should be returned.\\n /// @return array Array of modules.\\n /// @return next Start of the next page.\\n function getModulesPaginated(address start, uint256 pageSize)\\n external\\n view\\n returns (address[] memory array, address next);\\n}\\n\",\"keccak256\":\"0xcd5508ffe596eef8fbccfd5fc4f10a34397773547ce64e212d48b5212865ec1f\",\"license\":\"LGPL-3.0-only\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20 {\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `to`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address to, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `from` to `to` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(\\n address from,\\n address to,\\n uint256 amount\\n ) external returns (bool);\\n}\\n\",\"keccak256\":\"0x9750c6b834f7b43000631af5cc30001c5f547b3ceb3635488f140f60e897ea6b\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Strings.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev String operations.\\n */\\nlibrary Strings {\\n bytes16 private constant _HEX_SYMBOLS = \\\"0123456789abcdef\\\";\\n uint8 private constant _ADDRESS_LENGTH = 20;\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\\n */\\n function toString(uint256 value) internal pure returns (string memory) {\\n // Inspired by OraclizeAPI's implementation - MIT licence\\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\\n\\n if (value == 0) {\\n return \\\"0\\\";\\n }\\n uint256 temp = value;\\n uint256 digits;\\n while (temp != 0) {\\n digits++;\\n temp /= 10;\\n }\\n bytes memory buffer = new bytes(digits);\\n while (value != 0) {\\n digits -= 1;\\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\\n value /= 10;\\n }\\n return string(buffer);\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\\n */\\n function toHexString(uint256 value) internal pure returns (string memory) {\\n if (value == 0) {\\n return \\\"0x00\\\";\\n }\\n uint256 temp = value;\\n uint256 length = 0;\\n while (temp != 0) {\\n length++;\\n temp >>= 8;\\n }\\n return toHexString(value, length);\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\\n */\\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\\n bytes memory buffer = new bytes(2 * length + 2);\\n buffer[0] = \\\"0\\\";\\n buffer[1] = \\\"x\\\";\\n for (uint256 i = 2 * length + 1; i > 1; --i) {\\n buffer[i] = _HEX_SYMBOLS[value & 0xf];\\n value >>= 4;\\n }\\n require(value == 0, \\\"Strings: hex length insufficient\\\");\\n return string(buffer);\\n }\\n\\n /**\\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\\n */\\n function toHexString(address addr) internal pure returns (string memory) {\\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\\n }\\n}\\n\",\"keccak256\":\"0xaf159a8b1923ad2a26d516089bceca9bdeaeacd04be50983ea00ba63070f08a3\",\"license\":\"MIT\"},\"contracts/DecentHats_0_1_0.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity =0.8.19;\\n\\nimport {Enum} from \\\"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\\\";\\nimport {IAvatar} from \\\"@gnosis.pm/zodiac/contracts/interfaces/IAvatar.sol\\\";\\nimport {Strings} from \\\"@openzeppelin/contracts/utils/Strings.sol\\\";\\nimport {IERC20} from \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\nimport {IERC6551Registry} from \\\"./interfaces/IERC6551Registry.sol\\\";\\nimport {IHats} from \\\"./interfaces/hats/IHats.sol\\\";\\nimport {ISablierV2LockupLinear} from \\\"./interfaces/sablier/ISablierV2LockupLinear.sol\\\";\\nimport {LockupLinear} from \\\"./interfaces/sablier/LockupLinear.sol\\\";\\n\\ncontract DecentHats_0_1_0 {\\n string public constant NAME = \\\"DecentHats_0_1_0\\\";\\n\\n struct SablierStreamParams {\\n ISablierV2LockupLinear sablier;\\n address sender;\\n uint128 totalAmount;\\n address asset;\\n bool cancelable;\\n bool transferable;\\n LockupLinear.Timestamps timestamps;\\n LockupLinear.Broker broker;\\n }\\n\\n struct Hat {\\n uint32 maxSupply;\\n string details;\\n string imageURI;\\n bool isMutable;\\n address wearer;\\n SablierStreamParams[] sablierParams; // Optional Sablier stream parameters\\n }\\n\\n struct CreateTreeParams {\\n IHats hatsProtocol;\\n address hatsAccountImplementation;\\n IERC6551Registry registry;\\n address keyValuePairs;\\n string topHatDetails;\\n string topHatImageURI;\\n Hat adminHat;\\n Hat[] hats;\\n }\\n\\n function getSalt() public pure returns (bytes32 salt) {\\n return\\n 0x5d0e6ce4fd951366cc55da93f6e79d8b81483109d79676a04bcc2bed6a4b5072;\\n }\\n\\n function updateKeyValuePairs(\\n address _keyValuePairs,\\n uint256 topHatId\\n ) internal {\\n string[] memory keys = new string[](1);\\n string[] memory values = new string[](1);\\n keys[0] = \\\"topHatId\\\";\\n values[0] = Strings.toString(topHatId);\\n\\n IAvatar(msg.sender).execTransactionFromModule(\\n _keyValuePairs,\\n 0,\\n abi.encodeWithSignature(\\n \\\"updateValues(string[],string[])\\\",\\n keys,\\n values\\n ),\\n Enum.Operation.Call\\n );\\n }\\n\\n function createHat(\\n IHats _hatsProtocol,\\n uint256 adminHatId,\\n Hat memory _hat,\\n address topHatAccount\\n ) internal returns (uint256) {\\n return\\n _hatsProtocol.createHat(\\n adminHatId,\\n _hat.details,\\n _hat.maxSupply,\\n topHatAccount,\\n topHatAccount,\\n _hat.isMutable,\\n _hat.imageURI\\n );\\n }\\n\\n function createAccount(\\n IERC6551Registry _registry,\\n address _hatsAccountImplementation,\\n bytes32 salt,\\n address protocolAddress,\\n uint256 hatId\\n ) internal returns (address) {\\n return\\n _registry.createAccount(\\n _hatsAccountImplementation,\\n salt,\\n block.chainid,\\n protocolAddress,\\n hatId\\n );\\n }\\n\\n function createTopHatAndAccount(\\n IHats _hatsProtocol,\\n string memory _topHatDetails,\\n string memory _topHatImageURI,\\n IERC6551Registry _registry,\\n address _hatsAccountImplementation,\\n bytes32 salt\\n ) internal returns (uint256 topHatId, address topHatAccount) {\\n topHatId = _hatsProtocol.mintTopHat(\\n address(this),\\n _topHatDetails,\\n _topHatImageURI\\n );\\n\\n topHatAccount = createAccount(\\n _registry,\\n _hatsAccountImplementation,\\n salt,\\n address(_hatsProtocol),\\n topHatId\\n );\\n }\\n\\n function createHatAndAccountAndMintAndStreams(\\n IHats hatsProtocol,\\n uint256 adminHatId,\\n Hat calldata hat,\\n address topHatAccount,\\n IERC6551Registry registry,\\n address hatsAccountImplementation,\\n bytes32 salt\\n ) internal returns (uint256 hatId, address accountAddress) {\\n hatId = createHat(hatsProtocol, adminHatId, hat, topHatAccount);\\n\\n accountAddress = createAccount(\\n registry,\\n hatsAccountImplementation,\\n salt,\\n address(hatsProtocol),\\n hatId\\n );\\n\\n if (hat.wearer != address(0)) {\\n hatsProtocol.mintHat(hatId, hat.wearer);\\n }\\n\\n for (uint256 i = 0; i < hat.sablierParams.length; ) {\\n SablierStreamParams memory sablierParams = hat.sablierParams[i];\\n\\n // Approve tokens for Sablier\\n IAvatar(msg.sender).execTransactionFromModule(\\n sablierParams.asset,\\n 0,\\n abi.encodeWithSignature(\\n \\\"approve(address,uint256)\\\",\\n address(sablierParams.sablier),\\n sablierParams.totalAmount\\n ),\\n Enum.Operation.Call\\n );\\n\\n LockupLinear.CreateWithTimestamps memory params = LockupLinear\\n .CreateWithTimestamps({\\n sender: sablierParams.sender,\\n recipient: accountAddress,\\n totalAmount: sablierParams.totalAmount,\\n asset: IERC20(sablierParams.asset),\\n cancelable: sablierParams.cancelable,\\n transferable: sablierParams.transferable,\\n timestamps: sablierParams.timestamps,\\n broker: sablierParams.broker\\n });\\n\\n // Proxy the Sablier call through IAvatar\\n IAvatar(msg.sender).execTransactionFromModule(\\n address(sablierParams.sablier),\\n 0,\\n abi.encodeWithSignature(\\n \\\"createWithTimestamps((address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256)))\\\",\\n params\\n ),\\n Enum.Operation.Call\\n );\\n\\n unchecked {\\n ++i;\\n }\\n }\\n }\\n\\n function createAndDeclareTree(CreateTreeParams calldata params) public {\\n bytes32 salt = getSalt();\\n\\n (uint256 topHatId, address topHatAccount) = createTopHatAndAccount(\\n params.hatsProtocol,\\n params.topHatDetails,\\n params.topHatImageURI,\\n params.registry,\\n params.hatsAccountImplementation,\\n salt\\n );\\n\\n updateKeyValuePairs(params.keyValuePairs, topHatId);\\n\\n (uint256 adminHatId, ) = createHatAndAccountAndMintAndStreams(\\n params.hatsProtocol,\\n topHatId,\\n params.adminHat,\\n topHatAccount,\\n params.registry,\\n params.hatsAccountImplementation,\\n salt\\n );\\n\\n for (uint256 i = 0; i < params.hats.length; ) {\\n createHatAndAccountAndMintAndStreams(\\n params.hatsProtocol,\\n adminHatId,\\n params.hats[i],\\n topHatAccount,\\n params.registry,\\n params.hatsAccountImplementation,\\n salt\\n );\\n\\n unchecked {\\n ++i;\\n }\\n }\\n\\n params.hatsProtocol.transferHat(topHatId, address(this), msg.sender);\\n }\\n}\\n\",\"keccak256\":\"0xcf4e6d62ca64f62b8eb638805a8a4e715aea8fc201f3dea9a522edc1034599f1\",\"license\":\"MIT\"},\"contracts/interfaces/IERC6551Registry.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.4;\\n\\ninterface IERC6551Registry {\\n /**\\n * @dev Creates a token bound account for a non-fungible token.\\n *\\n * If account has already been created, returns the account address without calling create2.\\n *\\n * Emits ERC6551AccountCreated event.\\n *\\n * @return account The address of the token bound account\\n */\\n function createAccount(\\n address implementation,\\n bytes32 salt,\\n uint256 chainId,\\n address tokenContract,\\n uint256 tokenId\\n ) external returns (address account);\\n}\\n\",\"keccak256\":\"0x64c52de8a8e68398e61dd8b42dda8e9af8cf6abf93bb85629c322440991ea568\",\"license\":\"MIT\"},\"contracts/interfaces/hats/IHats.sol\":{\"content\":\"// SPDX-License-Identifier: AGPL-3.0\\n// Copyright (C) 2023 Haberdasher Labs\\n//\\n// This program is free software: you can redistribute it and/or modify\\n// it under the terms of the GNU Affero General Public License as published by\\n// the Free Software Foundation, either version 3 of the License, or\\n// (at your option) any later version.\\n//\\n// This program is distributed in the hope that it will be useful,\\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\\n// GNU Affero General Public License for more details.\\n//\\n// You should have received a copy of the GNU Affero General Public License\\n// along with this program. If not, see .\\n\\npragma solidity >=0.8.13;\\n\\ninterface IHats {\\n function mintTopHat(\\n address _target,\\n string memory _details,\\n string memory _imageURI\\n ) external returns (uint256 topHatId);\\n\\n function createHat(\\n uint256 _admin,\\n string calldata _details,\\n uint32 _maxSupply,\\n address _eligibility,\\n address _toggle,\\n bool _mutable,\\n string calldata _imageURI\\n ) external returns (uint256 newHatId);\\n\\n function mintHat(\\n uint256 _hatId,\\n address _wearer\\n ) external returns (bool success);\\n\\n function transferHat(uint256 _hatId, address _from, address _to) external;\\n}\\n\",\"keccak256\":\"0x8e35022f5c0fcf0059033abec78ec890f0cf3bbac09d6d24051cff9679239511\",\"license\":\"AGPL-3.0\"},\"contracts/interfaces/sablier/ISablierV2LockupLinear.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport {LockupLinear} from \\\"./LockupLinear.sol\\\";\\nimport {IERC20} from \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\n\\ninterface ISablierV2LockupLinear {\\n function createWithTimestamps(\\n LockupLinear.CreateWithTimestamps calldata params\\n ) external returns (uint256 streamId);\\n}\\n\",\"keccak256\":\"0xf4899637eb2e6c76c35e2d201e56e162a50e6bc7b5b9156e00866f0703ad07ca\",\"license\":\"MIT\"},\"contracts/interfaces/sablier/LockupLinear.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport {IERC20} from \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\n\\nlibrary LockupLinear {\\n struct CreateWithTimestamps {\\n address sender;\\n address recipient;\\n uint128 totalAmount;\\n IERC20 asset;\\n bool cancelable;\\n bool transferable;\\n Timestamps timestamps;\\n Broker broker;\\n }\\n\\n struct Timestamps {\\n uint40 start;\\n uint40 cliff;\\n uint40 end;\\n }\\n\\n struct Broker {\\n address account;\\n uint256 fee;\\n }\\n}\\n\",\"keccak256\":\"0x497fdb52b5e1a5a7e0711a9f7d5fb036eb668ccb92ea908ee088f56ee08a4ce8\",\"license\":\"MIT\"}},\"version\":1}", - "bytecode": "0x608060405234801561001057600080fd5b50611410806100206000396000f3fe608060405234801561001057600080fd5b50600436106100415760003560e01c806313a9589c146100465780638c5f591a14610079578063a3f4df7e1461008e575b600080fd5b6040517f5d0e6ce4fd951366cc55da93f6e79d8b81483109d79676a04bcc2bed6a4b507281526020015b60405180910390f35b61008c610087366004610aa8565b6100ca565b005b6100bd6040518060400160405280601081526020016f0446563656e74486174735f305f315f360841b81525081565b6040516100709190610b30565b7f5d0e6ce4fd951366cc55da93f6e79d8b81483109d79676a04bcc2bed6a4b50726000806101a86100fe6020860186610b5b565b61010b6080870187610b78565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061014d9250505060a0880188610b78565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610192925050506060890160408a01610b5b565b6101a260408a0160208b01610b5b565b88610317565b90925090506101c66101c06080860160608701610b5b565b836103a9565b600061020d6101d86020870187610b5b565b846101e660c0890189610bd5565b856101f760608b0160408c01610b5b565b61020760408c0160208d01610b5b565b8a610529565b50905060005b61022060e0870187610bf5565b905081101561029a576102906102396020880188610b5b565b8361024760e08a018a610bf5565b8581811061025757610257610c3e565b90506020028101906102699190610bd5565b8661027a60608c0160408d01610b5b565b61028a60408d0160208e01610b5b565b8b610529565b5050600101610213565b506102a86020860186610b5b565b6040516329287c1b60e21b8152600481018590523060248201523360448201526001600160a01b03919091169063a4a1f06c90606401600060405180830381600087803b1580156102f857600080fd5b505af115801561030c573d6000803e3d6000fd5b505050505050505050565b600080876001600160a01b0316631a64dfad3089896040518463ffffffff1660e01b815260040161034a93929190610c54565b6020604051808303816000875af1158015610369573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061038d9190610c8a565b915061039c8585858b86610878565b9050965096945050505050565b604080516001808252818301909252600091816020015b60608152602001906001900390816103c057505060408051600180825281830190925291925060009190602082015b60608152602001906001900390816103ef579050509050604051806040016040528060088152602001671d1bdc12185d125960c21b8152508260008151811061043a5761043a610c3e565b602002602001018190525061044e8361090e565b8160008151811061046157610461610c3e565b6020026020010181905250336001600160a01b031663468721a78560008585604051602401610491929190610d11565b60408051601f198184030181529181526020820180516001600160e01b031663579374b960e11b1790525160e085901b6001600160e01b03191681526104df93929190600090600401610d36565b6020604051808303816000875af11580156104fe573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105229190610d9a565b5050505050565b600080610540898961053a8a6110d4565b89610a16565b915061054f8585858c86610878565b9050600061056360a0890160808a01610b5b565b6001600160a01b031614610603576001600160a01b03891663641f776e8361059160a08b0160808c01610b5b565b6040516001600160e01b031960e085901b16815260048101929092526001600160a01b031660248201526044016020604051808303816000875af11580156105dd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106019190610d9a565b505b60005b61061360a0890189611198565b905081101561086b57600061062b60a08a018a611198565b8381811061063b5761063b610c3e565b9050610160020180360381019061065291906111e1565b6060810151815160408084015190516001600160a01b0390921660248301526001600160801b03166044820152919250339163468721a7919060009060640160408051601f198184030181529181526020820180516001600160e01b031663095ea7b360e01b1790525160e085901b6001600160e01b03191681526106df93929190600090600401610d36565b6020604051808303816000875af11580156106fe573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107229190610d9a565b50600060405180610100016040528083602001516001600160a01b03168152602001856001600160a01b0316815260200183604001516001600160801b0316815260200183606001516001600160a01b031681526020018360800151151581526020018360a00151151581526020018360c0015181526020018360e001518152509050336001600160a01b031663468721a783600001516000846040516024016107cc91906111fe565b60408051601f198184030181529181526020820180516001600160e01b03166353b1572760e01b1790525160e085901b6001600160e01b031916815261081a93929190600090600401610d36565b6020604051808303816000875af1158015610839573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061085d9190610d9a565b508260010192505050610606565b5097509795505050505050565b604051638a54c52f60e01b81526001600160a01b0385811660048301526024820185905246604483015283811660648301526084820183905260009190871690638a54c52f9060a4016020604051808303816000875af11580156108e0573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061090491906112c0565b9695505050505050565b6060816000036109355750506040805180820190915260018152600360fc1b602082015290565b8160005b811561095f5780610949816112f3565b91506109589050600a83611322565b9150610939565b6000816001600160401b0381111561097957610979610ca3565b6040519080825280601f01601f1916602001820160405280156109a3576020820181803683370190505b5090505b8415610a0e576109b8600183611336565b91506109c5600a8661134f565b6109d0906030611363565b60f81b8183815181106109e5576109e5610c3e565b60200101906001600160f81b031916908160001a905350610a07600a86611322565b94506109a7565b949350505050565b6020820151825160608401516040808601519051635829492f60e11b81526000946001600160a01b038a169463b052925e94610a5c948b948a9283929091600401611376565b6020604051808303816000875af1158015610a7b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a9f9190610c8a565b95945050505050565b600060208284031215610aba57600080fd5b81356001600160401b03811115610ad057600080fd5b82016101008185031215610ae357600080fd5b9392505050565b6000815180845260005b81811015610b1057602081850181015186830182015201610af4565b506000602082860101526020601f19601f83011685010191505092915050565b602081526000610ae36020830184610aea565b6001600160a01b0381168114610b5857600080fd5b50565b600060208284031215610b6d57600080fd5b8135610ae381610b43565b6000808335601e19843603018112610b8f57600080fd5b8301803591506001600160401b03821115610ba957600080fd5b602001915036819003821315610bbe57600080fd5b9250929050565b8035610bd081610b43565b919050565b6000823560be19833603018112610beb57600080fd5b9190910192915050565b6000808335601e19843603018112610c0c57600080fd5b8301803591506001600160401b03821115610c2657600080fd5b6020019150600581901b3603821315610bbe57600080fd5b634e487b7160e01b600052603260045260246000fd5b6001600160a01b0384168152606060208201819052600090610c7890830185610aea565b82810360408401526109048185610aea565b600060208284031215610c9c57600080fd5b5051919050565b634e487b7160e01b600052604160045260246000fd5b600082825180855260208086019550808260051b84010181860160005b84811015610d0457601f19868403018952610cf2838351610aea565b98840198925090830190600101610cd6565b5090979650505050505050565b604081526000610d246040830185610cb9565b8281036020840152610a9f8185610cb9565b60018060a01b0385168152836020820152608060408201526000610d5d6080830185610aea565b905060028310610d7d57634e487b7160e01b600052602160045260246000fd5b82606083015295945050505050565b8015158114610b5857600080fd5b600060208284031215610dac57600080fd5b8151610ae381610d8c565b60405160c081016001600160401b0381118282101715610dd957610dd9610ca3565b60405290565b604051601f8201601f191681016001600160401b0381118282101715610e0757610e07610ca3565b604052919050565b803563ffffffff81168114610bd057600080fd5b600082601f830112610e3457600080fd5b81356001600160401b03811115610e4d57610e4d610ca3565b610e60601f8201601f1916602001610ddf565b818152846020838601011115610e7557600080fd5b816020850160208301376000918101602001919091529392505050565b8035610bd081610d8c565b80356001600160801b0381168114610bd057600080fd5b803564ffffffffff81168114610bd057600080fd5b600060608284031215610edb57600080fd5b604051606081018181106001600160401b0382111715610efd57610efd610ca3565b604052905080610f0c83610eb4565b8152610f1a60208401610eb4565b6020820152610f2b60408401610eb4565b60408201525092915050565b600060408284031215610f4957600080fd5b604051604081018181106001600160401b0382111715610f6b57610f6b610ca3565b6040529050808235610f7c81610b43565b8152602092830135920191909152919050565b60006101608284031215610fa257600080fd5b60405161010081018181106001600160401b0382111715610fc557610fc5610ca3565b604052905080610fd483610bc5565b8152610fe260208401610bc5565b6020820152610ff360408401610e9d565b604082015261100460608401610bc5565b606082015261101560808401610e92565b608082015261102660a08401610e92565b60a08201526110388460c08501610ec9565b60c082015261104b846101208501610f37565b60e08201525092915050565b600082601f83011261106857600080fd5b813560206001600160401b0382111561108357611083610ca3565b611091818360051b01610ddf565b82815261016092830285018201928282019190878511156110b157600080fd5b8387015b85811015610d04576110c78982610f8f565b84529284019281016110b5565b600060c082360312156110e657600080fd5b6110ee610db7565b6110f783610e0f565b815260208301356001600160401b038082111561111357600080fd5b61111f36838701610e23565b6020840152604085013591508082111561113857600080fd5b61114436838701610e23565b604084015261115560608601610e92565b606084015261116660808601610bc5565b608084015260a085013591508082111561117f57600080fd5b5061118c36828601611057565b60a08301525092915050565b6000808335601e198436030181126111af57600080fd5b8301803591506001600160401b038211156111c957600080fd5b602001915061016081023603821315610bbe57600080fd5b600061016082840312156111f457600080fd5b610ae38383610f8f565b81516001600160a01b0390811682526020808401518216908301526040808401516001600160801b031690830152606080840151909116908201526080808301516101608301916112529084018215159052565b5060a083015161126660a084018215159052565b5060c083015161129960c0840182805164ffffffffff908116835260208083015182169084015260409182015116910152565b5060e0929092015180516001600160a01b0316610120830152602001516101409091015290565b6000602082840312156112d257600080fd5b8151610ae381610b43565b634e487b7160e01b600052601160045260246000fd5b600060018201611305576113056112dd565b5060010190565b634e487b7160e01b600052601260045260246000fd5b6000826113315761133161130c565b500490565b81810381811115611349576113496112dd565b92915050565b60008261135e5761135e61130c565b500690565b80820180821115611349576113496112dd565b87815260e06020820152600061138f60e0830189610aea565b63ffffffff881660408401526001600160a01b0387811660608501528616608084015284151560a084015282810360c08401526113cc8185610aea565b9a995050505050505050505056fea2646970667358221220fcb8ad75991fd171fd33998d718d5f54883d99a48d56657e7e938e34a55d6a2664736f6c63430008130033", - "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100415760003560e01c806313a9589c146100465780638c5f591a14610079578063a3f4df7e1461008e575b600080fd5b6040517f5d0e6ce4fd951366cc55da93f6e79d8b81483109d79676a04bcc2bed6a4b507281526020015b60405180910390f35b61008c610087366004610aa8565b6100ca565b005b6100bd6040518060400160405280601081526020016f0446563656e74486174735f305f315f360841b81525081565b6040516100709190610b30565b7f5d0e6ce4fd951366cc55da93f6e79d8b81483109d79676a04bcc2bed6a4b50726000806101a86100fe6020860186610b5b565b61010b6080870187610b78565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061014d9250505060a0880188610b78565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610192925050506060890160408a01610b5b565b6101a260408a0160208b01610b5b565b88610317565b90925090506101c66101c06080860160608701610b5b565b836103a9565b600061020d6101d86020870187610b5b565b846101e660c0890189610bd5565b856101f760608b0160408c01610b5b565b61020760408c0160208d01610b5b565b8a610529565b50905060005b61022060e0870187610bf5565b905081101561029a576102906102396020880188610b5b565b8361024760e08a018a610bf5565b8581811061025757610257610c3e565b90506020028101906102699190610bd5565b8661027a60608c0160408d01610b5b565b61028a60408d0160208e01610b5b565b8b610529565b5050600101610213565b506102a86020860186610b5b565b6040516329287c1b60e21b8152600481018590523060248201523360448201526001600160a01b03919091169063a4a1f06c90606401600060405180830381600087803b1580156102f857600080fd5b505af115801561030c573d6000803e3d6000fd5b505050505050505050565b600080876001600160a01b0316631a64dfad3089896040518463ffffffff1660e01b815260040161034a93929190610c54565b6020604051808303816000875af1158015610369573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061038d9190610c8a565b915061039c8585858b86610878565b9050965096945050505050565b604080516001808252818301909252600091816020015b60608152602001906001900390816103c057505060408051600180825281830190925291925060009190602082015b60608152602001906001900390816103ef579050509050604051806040016040528060088152602001671d1bdc12185d125960c21b8152508260008151811061043a5761043a610c3e565b602002602001018190525061044e8361090e565b8160008151811061046157610461610c3e565b6020026020010181905250336001600160a01b031663468721a78560008585604051602401610491929190610d11565b60408051601f198184030181529181526020820180516001600160e01b031663579374b960e11b1790525160e085901b6001600160e01b03191681526104df93929190600090600401610d36565b6020604051808303816000875af11580156104fe573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105229190610d9a565b5050505050565b600080610540898961053a8a6110d4565b89610a16565b915061054f8585858c86610878565b9050600061056360a0890160808a01610b5b565b6001600160a01b031614610603576001600160a01b03891663641f776e8361059160a08b0160808c01610b5b565b6040516001600160e01b031960e085901b16815260048101929092526001600160a01b031660248201526044016020604051808303816000875af11580156105dd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106019190610d9a565b505b60005b61061360a0890189611198565b905081101561086b57600061062b60a08a018a611198565b8381811061063b5761063b610c3e565b9050610160020180360381019061065291906111e1565b6060810151815160408084015190516001600160a01b0390921660248301526001600160801b03166044820152919250339163468721a7919060009060640160408051601f198184030181529181526020820180516001600160e01b031663095ea7b360e01b1790525160e085901b6001600160e01b03191681526106df93929190600090600401610d36565b6020604051808303816000875af11580156106fe573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107229190610d9a565b50600060405180610100016040528083602001516001600160a01b03168152602001856001600160a01b0316815260200183604001516001600160801b0316815260200183606001516001600160a01b031681526020018360800151151581526020018360a00151151581526020018360c0015181526020018360e001518152509050336001600160a01b031663468721a783600001516000846040516024016107cc91906111fe565b60408051601f198184030181529181526020820180516001600160e01b03166353b1572760e01b1790525160e085901b6001600160e01b031916815261081a93929190600090600401610d36565b6020604051808303816000875af1158015610839573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061085d9190610d9a565b508260010192505050610606565b5097509795505050505050565b604051638a54c52f60e01b81526001600160a01b0385811660048301526024820185905246604483015283811660648301526084820183905260009190871690638a54c52f9060a4016020604051808303816000875af11580156108e0573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061090491906112c0565b9695505050505050565b6060816000036109355750506040805180820190915260018152600360fc1b602082015290565b8160005b811561095f5780610949816112f3565b91506109589050600a83611322565b9150610939565b6000816001600160401b0381111561097957610979610ca3565b6040519080825280601f01601f1916602001820160405280156109a3576020820181803683370190505b5090505b8415610a0e576109b8600183611336565b91506109c5600a8661134f565b6109d0906030611363565b60f81b8183815181106109e5576109e5610c3e565b60200101906001600160f81b031916908160001a905350610a07600a86611322565b94506109a7565b949350505050565b6020820151825160608401516040808601519051635829492f60e11b81526000946001600160a01b038a169463b052925e94610a5c948b948a9283929091600401611376565b6020604051808303816000875af1158015610a7b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a9f9190610c8a565b95945050505050565b600060208284031215610aba57600080fd5b81356001600160401b03811115610ad057600080fd5b82016101008185031215610ae357600080fd5b9392505050565b6000815180845260005b81811015610b1057602081850181015186830182015201610af4565b506000602082860101526020601f19601f83011685010191505092915050565b602081526000610ae36020830184610aea565b6001600160a01b0381168114610b5857600080fd5b50565b600060208284031215610b6d57600080fd5b8135610ae381610b43565b6000808335601e19843603018112610b8f57600080fd5b8301803591506001600160401b03821115610ba957600080fd5b602001915036819003821315610bbe57600080fd5b9250929050565b8035610bd081610b43565b919050565b6000823560be19833603018112610beb57600080fd5b9190910192915050565b6000808335601e19843603018112610c0c57600080fd5b8301803591506001600160401b03821115610c2657600080fd5b6020019150600581901b3603821315610bbe57600080fd5b634e487b7160e01b600052603260045260246000fd5b6001600160a01b0384168152606060208201819052600090610c7890830185610aea565b82810360408401526109048185610aea565b600060208284031215610c9c57600080fd5b5051919050565b634e487b7160e01b600052604160045260246000fd5b600082825180855260208086019550808260051b84010181860160005b84811015610d0457601f19868403018952610cf2838351610aea565b98840198925090830190600101610cd6565b5090979650505050505050565b604081526000610d246040830185610cb9565b8281036020840152610a9f8185610cb9565b60018060a01b0385168152836020820152608060408201526000610d5d6080830185610aea565b905060028310610d7d57634e487b7160e01b600052602160045260246000fd5b82606083015295945050505050565b8015158114610b5857600080fd5b600060208284031215610dac57600080fd5b8151610ae381610d8c565b60405160c081016001600160401b0381118282101715610dd957610dd9610ca3565b60405290565b604051601f8201601f191681016001600160401b0381118282101715610e0757610e07610ca3565b604052919050565b803563ffffffff81168114610bd057600080fd5b600082601f830112610e3457600080fd5b81356001600160401b03811115610e4d57610e4d610ca3565b610e60601f8201601f1916602001610ddf565b818152846020838601011115610e7557600080fd5b816020850160208301376000918101602001919091529392505050565b8035610bd081610d8c565b80356001600160801b0381168114610bd057600080fd5b803564ffffffffff81168114610bd057600080fd5b600060608284031215610edb57600080fd5b604051606081018181106001600160401b0382111715610efd57610efd610ca3565b604052905080610f0c83610eb4565b8152610f1a60208401610eb4565b6020820152610f2b60408401610eb4565b60408201525092915050565b600060408284031215610f4957600080fd5b604051604081018181106001600160401b0382111715610f6b57610f6b610ca3565b6040529050808235610f7c81610b43565b8152602092830135920191909152919050565b60006101608284031215610fa257600080fd5b60405161010081018181106001600160401b0382111715610fc557610fc5610ca3565b604052905080610fd483610bc5565b8152610fe260208401610bc5565b6020820152610ff360408401610e9d565b604082015261100460608401610bc5565b606082015261101560808401610e92565b608082015261102660a08401610e92565b60a08201526110388460c08501610ec9565b60c082015261104b846101208501610f37565b60e08201525092915050565b600082601f83011261106857600080fd5b813560206001600160401b0382111561108357611083610ca3565b611091818360051b01610ddf565b82815261016092830285018201928282019190878511156110b157600080fd5b8387015b85811015610d04576110c78982610f8f565b84529284019281016110b5565b600060c082360312156110e657600080fd5b6110ee610db7565b6110f783610e0f565b815260208301356001600160401b038082111561111357600080fd5b61111f36838701610e23565b6020840152604085013591508082111561113857600080fd5b61114436838701610e23565b604084015261115560608601610e92565b606084015261116660808601610bc5565b608084015260a085013591508082111561117f57600080fd5b5061118c36828601611057565b60a08301525092915050565b6000808335601e198436030181126111af57600080fd5b8301803591506001600160401b038211156111c957600080fd5b602001915061016081023603821315610bbe57600080fd5b600061016082840312156111f457600080fd5b610ae38383610f8f565b81516001600160a01b0390811682526020808401518216908301526040808401516001600160801b031690830152606080840151909116908201526080808301516101608301916112529084018215159052565b5060a083015161126660a084018215159052565b5060c083015161129960c0840182805164ffffffffff908116835260208083015182169084015260409182015116910152565b5060e0929092015180516001600160a01b0316610120830152602001516101409091015290565b6000602082840312156112d257600080fd5b8151610ae381610b43565b634e487b7160e01b600052601160045260246000fd5b600060018201611305576113056112dd565b5060010190565b634e487b7160e01b600052601260045260246000fd5b6000826113315761133161130c565b500490565b81810381811115611349576113496112dd565b92915050565b60008261135e5761135e61130c565b500690565b80820180821115611349576113496112dd565b87815260e06020820152600061138f60e0830189610aea565b63ffffffff881660408401526001600160a01b0387811660608501528616608084015284151560a084015282810360c08401526113cc8185610aea565b9a995050505050505050505056fea2646970667358221220fcb8ad75991fd171fd33998d718d5f54883d99a48d56657e7e938e34a55d6a2664736f6c63430008130033", + "numDeployments": 4, + "solcInputHash": "4754a2f0c9d6a191a066af246491b62a", + "metadata": "{\"compiler\":{\"version\":\"0.8.19+commit.7dd6d404\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"NAME\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"contract IHats\",\"name\":\"hatsProtocol\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"hatsAccountImplementation\",\"type\":\"address\"},{\"internalType\":\"contract IERC6551Registry\",\"name\":\"registry\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"keyValuePairs\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"topHatDetails\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"topHatImageURI\",\"type\":\"string\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"maxSupply\",\"type\":\"uint32\"},{\"internalType\":\"string\",\"name\":\"details\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"imageURI\",\"type\":\"string\"},{\"internalType\":\"bool\",\"name\":\"isMutable\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"wearer\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"contract ISablierV2LockupLinear\",\"name\":\"sablier\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint128\",\"name\":\"totalAmount\",\"type\":\"uint128\"},{\"internalType\":\"address\",\"name\":\"asset\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"cancelable\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"transferable\",\"type\":\"bool\"},{\"components\":[{\"internalType\":\"uint40\",\"name\":\"start\",\"type\":\"uint40\"},{\"internalType\":\"uint40\",\"name\":\"cliff\",\"type\":\"uint40\"},{\"internalType\":\"uint40\",\"name\":\"end\",\"type\":\"uint40\"}],\"internalType\":\"struct LockupLinear.Timestamps\",\"name\":\"timestamps\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"fee\",\"type\":\"uint256\"}],\"internalType\":\"struct LockupLinear.Broker\",\"name\":\"broker\",\"type\":\"tuple\"}],\"internalType\":\"struct DecentHats_0_1_0.SablierStreamParams[]\",\"name\":\"sablierParams\",\"type\":\"tuple[]\"}],\"internalType\":\"struct DecentHats_0_1_0.Hat\",\"name\":\"adminHat\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"maxSupply\",\"type\":\"uint32\"},{\"internalType\":\"string\",\"name\":\"details\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"imageURI\",\"type\":\"string\"},{\"internalType\":\"bool\",\"name\":\"isMutable\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"wearer\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"contract ISablierV2LockupLinear\",\"name\":\"sablier\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint128\",\"name\":\"totalAmount\",\"type\":\"uint128\"},{\"internalType\":\"address\",\"name\":\"asset\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"cancelable\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"transferable\",\"type\":\"bool\"},{\"components\":[{\"internalType\":\"uint40\",\"name\":\"start\",\"type\":\"uint40\"},{\"internalType\":\"uint40\",\"name\":\"cliff\",\"type\":\"uint40\"},{\"internalType\":\"uint40\",\"name\":\"end\",\"type\":\"uint40\"}],\"internalType\":\"struct LockupLinear.Timestamps\",\"name\":\"timestamps\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"fee\",\"type\":\"uint256\"}],\"internalType\":\"struct LockupLinear.Broker\",\"name\":\"broker\",\"type\":\"tuple\"}],\"internalType\":\"struct DecentHats_0_1_0.SablierStreamParams[]\",\"name\":\"sablierParams\",\"type\":\"tuple[]\"}],\"internalType\":\"struct DecentHats_0_1_0.Hat[]\",\"name\":\"hats\",\"type\":\"tuple[]\"}],\"internalType\":\"struct DecentHats_0_1_0.CreateTreeParams\",\"name\":\"params\",\"type\":\"tuple\"}],\"name\":\"createAndDeclareTree\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract IHats\",\"name\":\"hatsProtocol\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"adminHatId\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"maxSupply\",\"type\":\"uint32\"},{\"internalType\":\"string\",\"name\":\"details\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"imageURI\",\"type\":\"string\"},{\"internalType\":\"bool\",\"name\":\"isMutable\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"wearer\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"contract ISablierV2LockupLinear\",\"name\":\"sablier\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint128\",\"name\":\"totalAmount\",\"type\":\"uint128\"},{\"internalType\":\"address\",\"name\":\"asset\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"cancelable\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"transferable\",\"type\":\"bool\"},{\"components\":[{\"internalType\":\"uint40\",\"name\":\"start\",\"type\":\"uint40\"},{\"internalType\":\"uint40\",\"name\":\"cliff\",\"type\":\"uint40\"},{\"internalType\":\"uint40\",\"name\":\"end\",\"type\":\"uint40\"}],\"internalType\":\"struct LockupLinear.Timestamps\",\"name\":\"timestamps\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"fee\",\"type\":\"uint256\"}],\"internalType\":\"struct LockupLinear.Broker\",\"name\":\"broker\",\"type\":\"tuple\"}],\"internalType\":\"struct DecentHats_0_1_0.SablierStreamParams[]\",\"name\":\"sablierParams\",\"type\":\"tuple[]\"}],\"internalType\":\"struct DecentHats_0_1_0.Hat\",\"name\":\"hat\",\"type\":\"tuple\"},{\"internalType\":\"uint256\",\"name\":\"topHatId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"topHatAccount\",\"type\":\"address\"},{\"internalType\":\"contract IERC6551Registry\",\"name\":\"registry\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"hatsAccountImplementation\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"salt\",\"type\":\"bytes32\"}],\"name\":\"createRoleHat\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"hatId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"accountAddress\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getSalt\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"salt\",\"type\":\"bytes32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"createAndDeclareTree((address,address,address,address,string,string,(uint32,string,string,bool,address,(address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256))[]),(uint32,string,string,bool,address,(address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256))[])[]))\":{\"details\":\"In order for a Safe to seamlessly create roles even if it has never previously created a role and thus has no hat tree, we defer the creation of the hat tree and its setup to this contract. This way, in a single tx block, the resulting topHatId of the newly created hat can be used to create an admin hat and any other hats needed. We also make use of `KeyValuePairs` to associate the topHatId with the Safe.\"},\"createRoleHat(address,uint256,(uint32,string,string,bool,address,(address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256))[]),uint256,address,address,address,bytes32)\":{\"details\":\"Role hat creation, minting, smart account creation and stream creation are handled here in order to avoid a race condition where not more than one active proposal to create a new role can exist at a time. See: https://github.com/decentdao/decent-interface/issues/2402\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"createAndDeclareTree((address,address,address,address,string,string,(uint32,string,string,bool,address,(address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256))[]),(uint32,string,string,bool,address,(address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256))[])[]))\":{\"notice\":\"For a safe without any roles previously created on it, this function should be called. It sets up the top hat and admin hat, as well as any other hats and their streams that are provided. This contract should be enabled a module on the Safe for which the role(s) are to be created, and disabled after.\"},\"createRoleHat(address,uint256,(uint32,string,string,bool,address,(address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256))[]),uint256,address,address,address,bytes32)\":{\"notice\":\"Creates a new role hat and any streams on it. This contract should be enabled a module on the Safe for which the role is to be created, and disable after. In order for the module to be able to create hats on behalf of the Safe, the Safe must first transfer its top hat to this contract. This function transfers the top hat back to the Safe after creating the role hat. The function simply calls `createHatAndAccountAndMintAndStreams` and then transfers the top hat back to the Safe.\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/DecentHats_0_1_0.sol\":\"DecentHats_0_1_0\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\":{\"content\":\"// SPDX-License-Identifier: LGPL-3.0-only\\npragma solidity >=0.7.0 <0.9.0;\\n\\n/// @title Enum - Collection of enums\\n/// @author Richard Meissner - \\ncontract Enum {\\n enum Operation {Call, DelegateCall}\\n}\\n\",\"keccak256\":\"0x473e45b1a5cc47be494b0e123c9127f0c11c1e0992a321ae5a644c0bfdb2c14f\",\"license\":\"LGPL-3.0-only\"},\"@gnosis.pm/zodiac/contracts/interfaces/IAvatar.sol\":{\"content\":\"// SPDX-License-Identifier: LGPL-3.0-only\\n\\n/// @title Zodiac Avatar - A contract that manages modules that can execute transactions via this contract.\\npragma solidity >=0.7.0 <0.9.0;\\n\\nimport \\\"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\\\";\\n\\ninterface IAvatar {\\n event EnabledModule(address module);\\n event DisabledModule(address module);\\n event ExecutionFromModuleSuccess(address indexed module);\\n event ExecutionFromModuleFailure(address indexed module);\\n\\n /// @dev Enables a module on the avatar.\\n /// @notice Can only be called by the avatar.\\n /// @notice Modules should be stored as a linked list.\\n /// @notice Must emit EnabledModule(address module) if successful.\\n /// @param module Module to be enabled.\\n function enableModule(address module) external;\\n\\n /// @dev Disables a module on the avatar.\\n /// @notice Can only be called by the avatar.\\n /// @notice Must emit DisabledModule(address module) if successful.\\n /// @param prevModule Address that pointed to the module to be removed in the linked list\\n /// @param module Module to be removed.\\n function disableModule(address prevModule, address module) external;\\n\\n /// @dev Allows a Module to execute a transaction.\\n /// @notice Can only be called by an enabled module.\\n /// @notice Must emit ExecutionFromModuleSuccess(address module) if successful.\\n /// @notice Must emit ExecutionFromModuleFailure(address module) if unsuccessful.\\n /// @param to Destination address of module transaction.\\n /// @param value Ether value of module transaction.\\n /// @param data Data payload of module transaction.\\n /// @param operation Operation type of module transaction: 0 == call, 1 == delegate call.\\n function execTransactionFromModule(\\n address to,\\n uint256 value,\\n bytes memory data,\\n Enum.Operation operation\\n ) external returns (bool success);\\n\\n /// @dev Allows a Module to execute a transaction and return data\\n /// @notice Can only be called by an enabled module.\\n /// @notice Must emit ExecutionFromModuleSuccess(address module) if successful.\\n /// @notice Must emit ExecutionFromModuleFailure(address module) if unsuccessful.\\n /// @param to Destination address of module transaction.\\n /// @param value Ether value of module transaction.\\n /// @param data Data payload of module transaction.\\n /// @param operation Operation type of module transaction: 0 == call, 1 == delegate call.\\n function execTransactionFromModuleReturnData(\\n address to,\\n uint256 value,\\n bytes memory data,\\n Enum.Operation operation\\n ) external returns (bool success, bytes memory returnData);\\n\\n /// @dev Returns if an module is enabled\\n /// @return True if the module is enabled\\n function isModuleEnabled(address module) external view returns (bool);\\n\\n /// @dev Returns array of modules.\\n /// @param start Start of the page.\\n /// @param pageSize Maximum number of modules that should be returned.\\n /// @return array Array of modules.\\n /// @return next Start of the next page.\\n function getModulesPaginated(address start, uint256 pageSize)\\n external\\n view\\n returns (address[] memory array, address next);\\n}\\n\",\"keccak256\":\"0xcd5508ffe596eef8fbccfd5fc4f10a34397773547ce64e212d48b5212865ec1f\",\"license\":\"LGPL-3.0-only\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20 {\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `to`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address to, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `from` to `to` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(\\n address from,\\n address to,\\n uint256 amount\\n ) external returns (bool);\\n}\\n\",\"keccak256\":\"0x9750c6b834f7b43000631af5cc30001c5f547b3ceb3635488f140f60e897ea6b\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Strings.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev String operations.\\n */\\nlibrary Strings {\\n bytes16 private constant _HEX_SYMBOLS = \\\"0123456789abcdef\\\";\\n uint8 private constant _ADDRESS_LENGTH = 20;\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\\n */\\n function toString(uint256 value) internal pure returns (string memory) {\\n // Inspired by OraclizeAPI's implementation - MIT licence\\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\\n\\n if (value == 0) {\\n return \\\"0\\\";\\n }\\n uint256 temp = value;\\n uint256 digits;\\n while (temp != 0) {\\n digits++;\\n temp /= 10;\\n }\\n bytes memory buffer = new bytes(digits);\\n while (value != 0) {\\n digits -= 1;\\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\\n value /= 10;\\n }\\n return string(buffer);\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\\n */\\n function toHexString(uint256 value) internal pure returns (string memory) {\\n if (value == 0) {\\n return \\\"0x00\\\";\\n }\\n uint256 temp = value;\\n uint256 length = 0;\\n while (temp != 0) {\\n length++;\\n temp >>= 8;\\n }\\n return toHexString(value, length);\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\\n */\\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\\n bytes memory buffer = new bytes(2 * length + 2);\\n buffer[0] = \\\"0\\\";\\n buffer[1] = \\\"x\\\";\\n for (uint256 i = 2 * length + 1; i > 1; --i) {\\n buffer[i] = _HEX_SYMBOLS[value & 0xf];\\n value >>= 4;\\n }\\n require(value == 0, \\\"Strings: hex length insufficient\\\");\\n return string(buffer);\\n }\\n\\n /**\\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\\n */\\n function toHexString(address addr) internal pure returns (string memory) {\\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\\n }\\n}\\n\",\"keccak256\":\"0xaf159a8b1923ad2a26d516089bceca9bdeaeacd04be50983ea00ba63070f08a3\",\"license\":\"MIT\"},\"contracts/DecentHats_0_1_0.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity =0.8.19;\\n\\nimport {Enum} from \\\"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\\\";\\nimport {IAvatar} from \\\"@gnosis.pm/zodiac/contracts/interfaces/IAvatar.sol\\\";\\nimport {Strings} from \\\"@openzeppelin/contracts/utils/Strings.sol\\\";\\nimport {IERC20} from \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\nimport {IERC6551Registry} from \\\"./interfaces/IERC6551Registry.sol\\\";\\nimport {IHats} from \\\"./interfaces/hats/IHats.sol\\\";\\nimport {ISablierV2LockupLinear} from \\\"./interfaces/sablier/ISablierV2LockupLinear.sol\\\";\\nimport {LockupLinear} from \\\"./interfaces/sablier/LockupLinear.sol\\\";\\n\\ncontract DecentHats_0_1_0 {\\n string public constant NAME = \\\"DecentHats_0_1_0\\\";\\n\\n struct SablierStreamParams {\\n ISablierV2LockupLinear sablier;\\n address sender;\\n uint128 totalAmount;\\n address asset;\\n bool cancelable;\\n bool transferable;\\n LockupLinear.Timestamps timestamps;\\n LockupLinear.Broker broker;\\n }\\n\\n struct Hat {\\n uint32 maxSupply;\\n string details;\\n string imageURI;\\n bool isMutable;\\n address wearer;\\n SablierStreamParams[] sablierParams; // Optional Sablier stream parameters\\n }\\n\\n struct CreateTreeParams {\\n IHats hatsProtocol;\\n address hatsAccountImplementation;\\n IERC6551Registry registry;\\n address keyValuePairs;\\n string topHatDetails;\\n string topHatImageURI;\\n Hat adminHat;\\n Hat[] hats;\\n }\\n\\n function getSalt() public pure returns (bytes32 salt) {\\n return\\n 0x5d0e6ce4fd951366cc55da93f6e79d8b81483109d79676a04bcc2bed6a4b5072;\\n }\\n\\n function declareSafeHatTree(\\n address _keyValuePairs,\\n uint256 topHatId\\n ) internal {\\n string[] memory keys = new string[](1);\\n string[] memory values = new string[](1);\\n keys[0] = \\\"topHatId\\\";\\n values[0] = Strings.toString(topHatId);\\n\\n IAvatar(msg.sender).execTransactionFromModule(\\n _keyValuePairs,\\n 0,\\n abi.encodeWithSignature(\\n \\\"updateValues(string[],string[])\\\",\\n keys,\\n values\\n ),\\n Enum.Operation.Call\\n );\\n }\\n\\n function createHat(\\n IHats _hatsProtocol,\\n uint256 adminHatId,\\n Hat memory _hat,\\n address topHatAccount\\n ) internal returns (uint256) {\\n return\\n _hatsProtocol.createHat(\\n adminHatId,\\n _hat.details,\\n _hat.maxSupply,\\n topHatAccount,\\n topHatAccount,\\n _hat.isMutable,\\n _hat.imageURI\\n );\\n }\\n\\n function createAccount(\\n IERC6551Registry _registry,\\n address _hatsAccountImplementation,\\n bytes32 salt,\\n address protocolAddress,\\n uint256 hatId\\n ) internal returns (address) {\\n return\\n _registry.createAccount(\\n _hatsAccountImplementation,\\n salt,\\n block.chainid,\\n protocolAddress,\\n hatId\\n );\\n }\\n\\n function createTopHatAndAccount(\\n IHats _hatsProtocol,\\n string memory _topHatDetails,\\n string memory _topHatImageURI,\\n IERC6551Registry _registry,\\n address _hatsAccountImplementation,\\n bytes32 salt\\n ) internal returns (uint256 topHatId, address topHatAccount) {\\n topHatId = _hatsProtocol.mintTopHat(\\n address(this),\\n _topHatDetails,\\n _topHatImageURI\\n );\\n\\n topHatAccount = createAccount(\\n _registry,\\n _hatsAccountImplementation,\\n salt,\\n address(_hatsProtocol),\\n topHatId\\n );\\n }\\n\\n function createHatAndAccountAndMintAndStreams(\\n IHats hatsProtocol,\\n uint256 adminHatId,\\n Hat calldata hat,\\n address topHatAccount,\\n IERC6551Registry registry,\\n address hatsAccountImplementation,\\n bytes32 salt\\n ) internal returns (uint256 hatId, address accountAddress) {\\n hatId = createHat(hatsProtocol, adminHatId, hat, topHatAccount);\\n\\n accountAddress = createAccount(\\n registry,\\n hatsAccountImplementation,\\n salt,\\n address(hatsProtocol),\\n hatId\\n );\\n\\n if (hat.wearer != address(0)) {\\n hatsProtocol.mintHat(hatId, hat.wearer);\\n }\\n\\n for (uint256 i = 0; i < hat.sablierParams.length; ) {\\n SablierStreamParams memory sablierParams = hat.sablierParams[i];\\n\\n // Approve tokens for Sablier\\n IAvatar(msg.sender).execTransactionFromModule(\\n sablierParams.asset,\\n 0,\\n abi.encodeWithSignature(\\n \\\"approve(address,uint256)\\\",\\n address(sablierParams.sablier),\\n sablierParams.totalAmount\\n ),\\n Enum.Operation.Call\\n );\\n\\n LockupLinear.CreateWithTimestamps memory params = LockupLinear\\n .CreateWithTimestamps({\\n sender: sablierParams.sender,\\n recipient: accountAddress,\\n totalAmount: sablierParams.totalAmount,\\n asset: IERC20(sablierParams.asset),\\n cancelable: sablierParams.cancelable,\\n transferable: sablierParams.transferable,\\n timestamps: sablierParams.timestamps,\\n broker: sablierParams.broker\\n });\\n\\n // Proxy the Sablier call through IAvatar\\n IAvatar(msg.sender).execTransactionFromModule(\\n address(sablierParams.sablier),\\n 0,\\n abi.encodeWithSignature(\\n \\\"createWithTimestamps((address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256)))\\\",\\n params\\n ),\\n Enum.Operation.Call\\n );\\n\\n unchecked {\\n ++i;\\n }\\n }\\n }\\n\\n /**\\n * Creates a new role hat and any streams on it.\\n *\\n * This contract should be enabled a module on the Safe for which the role is to be created, and disable after.\\n * In order for the module to be able to create hats on behalf of the Safe, the Safe must first\\n * transfer its top hat to this contract. This function transfers the top hat back to the Safe after\\n * creating the role hat.\\n *\\n * The function simply calls `createHatAndAccountAndMintAndStreams` and then transfers the top hat back to the Safe.\\n *\\n * @dev Role hat creation, minting, smart account creation and stream creation are handled here in order\\n * to avoid a race condition where not more than one active proposal to create a new role can exist at a time.\\n * See: https://github.com/decentdao/decent-interface/issues/2402\\n */\\n function createRoleHat(\\n IHats hatsProtocol,\\n uint256 adminHatId,\\n Hat calldata hat,\\n uint256 topHatId,\\n address topHatAccount,\\n IERC6551Registry registry,\\n address hatsAccountImplementation,\\n bytes32 salt\\n ) public returns (uint256 hatId, address accountAddress) {\\n (hatId, accountAddress) = createHatAndAccountAndMintAndStreams(\\n hatsProtocol,\\n adminHatId,\\n hat,\\n topHatAccount,\\n registry,\\n hatsAccountImplementation,\\n salt\\n );\\n\\n hatsProtocol.transferHat(topHatId, address(this), msg.sender);\\n }\\n\\n /**\\n * For a safe without any roles previously created on it, this function should be called. It sets up the\\n * top hat and admin hat, as well as any other hats and their streams that are provided.\\n *\\n * This contract should be enabled a module on the Safe for which the role(s) are to be created, and disabled after.\\n *\\n * @dev In order for a Safe to seamlessly create roles even if it has never previously created a role and thus has\\n * no hat tree, we defer the creation of the hat tree and its setup to this contract. This way, in a single tx block,\\n * the resulting topHatId of the newly created hat can be used to create an admin hat and any other hats needed.\\n * We also make use of `KeyValuePairs` to associate the topHatId with the Safe.\\n */\\n function createAndDeclareTree(CreateTreeParams calldata params) public {\\n bytes32 salt = getSalt();\\n\\n (uint256 topHatId, address topHatAccount) = createTopHatAndAccount(\\n params.hatsProtocol,\\n params.topHatDetails,\\n params.topHatImageURI,\\n params.registry,\\n params.hatsAccountImplementation,\\n salt\\n );\\n\\n declareSafeHatTree(params.keyValuePairs, topHatId);\\n\\n (uint256 adminHatId, ) = createHatAndAccountAndMintAndStreams(\\n params.hatsProtocol,\\n topHatId,\\n params.adminHat,\\n topHatAccount,\\n params.registry,\\n params.hatsAccountImplementation,\\n salt\\n );\\n\\n for (uint256 i = 0; i < params.hats.length; ) {\\n createHatAndAccountAndMintAndStreams(\\n params.hatsProtocol,\\n adminHatId,\\n params.hats[i],\\n topHatAccount,\\n params.registry,\\n params.hatsAccountImplementation,\\n salt\\n );\\n\\n unchecked {\\n ++i;\\n }\\n }\\n\\n params.hatsProtocol.transferHat(topHatId, address(this), msg.sender);\\n }\\n}\\n\",\"keccak256\":\"0x1886fc2edf8c34e58f6a95d33139d7513aa4b581a2c323af6394485752137e20\",\"license\":\"MIT\"},\"contracts/interfaces/IERC6551Registry.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.4;\\n\\ninterface IERC6551Registry {\\n /**\\n * @dev Creates a token bound account for a non-fungible token.\\n *\\n * If account has already been created, returns the account address without calling create2.\\n *\\n * Emits ERC6551AccountCreated event.\\n *\\n * @return account The address of the token bound account\\n */\\n function createAccount(\\n address implementation,\\n bytes32 salt,\\n uint256 chainId,\\n address tokenContract,\\n uint256 tokenId\\n ) external returns (address account);\\n}\\n\",\"keccak256\":\"0x64c52de8a8e68398e61dd8b42dda8e9af8cf6abf93bb85629c322440991ea568\",\"license\":\"MIT\"},\"contracts/interfaces/hats/IHats.sol\":{\"content\":\"// SPDX-License-Identifier: AGPL-3.0\\n// Copyright (C) 2023 Haberdasher Labs\\n//\\n// This program is free software: you can redistribute it and/or modify\\n// it under the terms of the GNU Affero General Public License as published by\\n// the Free Software Foundation, either version 3 of the License, or\\n// (at your option) any later version.\\n//\\n// This program is distributed in the hope that it will be useful,\\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\\n// GNU Affero General Public License for more details.\\n//\\n// You should have received a copy of the GNU Affero General Public License\\n// along with this program. If not, see .\\n\\npragma solidity >=0.8.13;\\n\\ninterface IHats {\\n function mintTopHat(\\n address _target,\\n string memory _details,\\n string memory _imageURI\\n ) external returns (uint256 topHatId);\\n\\n function createHat(\\n uint256 _admin,\\n string calldata _details,\\n uint32 _maxSupply,\\n address _eligibility,\\n address _toggle,\\n bool _mutable,\\n string calldata _imageURI\\n ) external returns (uint256 newHatId);\\n\\n function mintHat(\\n uint256 _hatId,\\n address _wearer\\n ) external returns (bool success);\\n\\n function transferHat(uint256 _hatId, address _from, address _to) external;\\n}\\n\",\"keccak256\":\"0x8e35022f5c0fcf0059033abec78ec890f0cf3bbac09d6d24051cff9679239511\",\"license\":\"AGPL-3.0\"},\"contracts/interfaces/sablier/ISablierV2LockupLinear.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport {LockupLinear} from \\\"./LockupLinear.sol\\\";\\nimport {IERC20} from \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\n\\ninterface ISablierV2LockupLinear {\\n function createWithTimestamps(\\n LockupLinear.CreateWithTimestamps calldata params\\n ) external returns (uint256 streamId);\\n}\\n\",\"keccak256\":\"0xf4899637eb2e6c76c35e2d201e56e162a50e6bc7b5b9156e00866f0703ad07ca\",\"license\":\"MIT\"},\"contracts/interfaces/sablier/LockupLinear.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport {IERC20} from \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\n\\nlibrary LockupLinear {\\n struct CreateWithTimestamps {\\n address sender;\\n address recipient;\\n uint128 totalAmount;\\n IERC20 asset;\\n bool cancelable;\\n bool transferable;\\n Timestamps timestamps;\\n Broker broker;\\n }\\n\\n struct Timestamps {\\n uint40 start;\\n uint40 cliff;\\n uint40 end;\\n }\\n\\n struct Broker {\\n address account;\\n uint256 fee;\\n }\\n}\\n\",\"keccak256\":\"0x497fdb52b5e1a5a7e0711a9f7d5fb036eb668ccb92ea908ee088f56ee08a4ce8\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x608060405234801561001057600080fd5b5061158a806100206000396000f3fe608060405234801561001057600080fd5b506004361061004c5760003560e01c806313a9589c146100515780636592b2ac146100845780638c5f591a146100b4578063a3f4df7e146100c9575b600080fd5b6040517f5d0e6ce4fd951366cc55da93f6e79d8b81483109d79676a04bcc2bed6a4b507281526020015b60405180910390f35b610097610092366004610b95565b610105565b604080519283526001600160a01b0390911660208301520161007b565b6100c76100c2366004610c40565b61018f565b005b6100f86040518060400160405280601081526020016f0446563656e74486174735f305f315f360841b81525081565b60405161007b9190610cc8565b6000806101178a8a8a898989896103dc565b6040516329287c1b60e21b8152600481018a905230602482015233604482015291935091506001600160a01b038b169063a4a1f06c90606401600060405180830381600087803b15801561016a57600080fd5b505af115801561017e573d6000803e3d6000fd5b505050509850989650505050505050565b7f5d0e6ce4fd951366cc55da93f6e79d8b81483109d79676a04bcc2bed6a4b507260008061026d6101c36020860186610cdb565b6101d06080870187610cf8565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506102129250505060a0880188610cf8565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610257925050506060890160408a01610cdb565b61026760408a0160208b01610cdb565b8861072b565b909250905061028b6102856080860160608701610cdb565b836107bd565b60006102d261029d6020870187610cdb565b846102ab60c0890189610d45565b856102bc60608b0160408c01610cdb565b6102cc60408c0160208d01610cdb565b8a6103dc565b50905060005b6102e560e0870187610d65565b905081101561035f576103556102fe6020880188610cdb565b8361030c60e08a018a610d65565b8581811061031c5761031c610dae565b905060200281019061032e9190610d45565b8661033f60608c0160408d01610cdb565b61034f60408d0160208e01610cdb565b8b6103dc565b50506001016102d8565b5061036d6020860186610cdb565b6040516329287c1b60e21b8152600481018590523060248201523360448201526001600160a01b03919091169063a4a1f06c90606401600060405180830381600087803b1580156103bd57600080fd5b505af11580156103d1573d6000803e3d6000fd5b505050505050505050565b6000806103f389896103ed8a611112565b8961093d565b91506104028585858c866109cf565b9050600061041660a0890160808a01610cdb565b6001600160a01b0316146104b6576001600160a01b03891663641f776e8361044460a08b0160808c01610cdb565b6040516001600160e01b031960e085901b16815260048101929092526001600160a01b031660248201526044016020604051808303816000875af1158015610490573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104b491906111d6565b505b60005b6104c660a08901896111f3565b905081101561071e5760006104de60a08a018a6111f3565b838181106104ee576104ee610dae565b90506101600201803603810190610505919061123c565b6060810151815160408084015190516001600160a01b0390921660248301526001600160801b03166044820152919250339163468721a7919060009060640160408051601f198184030181529181526020820180516001600160e01b031663095ea7b360e01b1790525160e085901b6001600160e01b031916815261059293929190600090600401611259565b6020604051808303816000875af11580156105b1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105d591906111d6565b50600060405180610100016040528083602001516001600160a01b03168152602001856001600160a01b0316815260200183604001516001600160801b0316815260200183606001516001600160a01b031681526020018360800151151581526020018360a00151151581526020018360c0015181526020018360e001518152509050336001600160a01b031663468721a7836000015160008460405160240161067f91906112af565b60408051601f198184030181529181526020820180516001600160e01b03166353b1572760e01b1790525160e085901b6001600160e01b03191681526106cd93929190600090600401611259565b6020604051808303816000875af11580156106ec573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061071091906111d6565b5082600101925050506104b9565b5097509795505050505050565b600080876001600160a01b0316631a64dfad3089896040518463ffffffff1660e01b815260040161075e93929190611371565b6020604051808303816000875af115801561077d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107a191906113a7565b91506107b08585858b866109cf565b9050965096945050505050565b604080516001808252818301909252600091816020015b60608152602001906001900390816107d457505060408051600180825281830190925291925060009190602082015b6060815260200190600190039081610803579050509050604051806040016040528060088152602001671d1bdc12185d125960c21b8152508260008151811061084e5761084e610dae565b602002602001018190525061086283610a65565b8160008151811061087557610875610dae565b6020026020010181905250336001600160a01b031663468721a785600085856040516024016108a5929190611415565b60408051601f198184030181529181526020820180516001600160e01b031663579374b960e11b1790525160e085901b6001600160e01b03191681526108f393929190600090600401611259565b6020604051808303816000875af1158015610912573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061093691906111d6565b5050505050565b6020820151825160608401516040808601519051635829492f60e11b81526000946001600160a01b038a169463b052925e94610983948b948a928392909160040161143a565b6020604051808303816000875af11580156109a2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109c691906113a7565b95945050505050565b604051638a54c52f60e01b81526001600160a01b0385811660048301526024820185905246604483015283811660648301526084820183905260009190871690638a54c52f9060a4016020604051808303816000875af1158015610a37573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a5b919061149e565b9695505050505050565b606081600003610a8c5750506040805180820190915260018152600360fc1b602082015290565b8160005b8115610ab65780610aa0816114d1565b9150610aaf9050600a83611500565b9150610a90565b6000816001600160401b03811115610ad057610ad0610dc4565b6040519080825280601f01601f191660200182016040528015610afa576020820181803683370190505b5090505b8415610b6557610b0f600183611514565b9150610b1c600a8661152d565b610b27906030611541565b60f81b818381518110610b3c57610b3c610dae565b60200101906001600160f81b031916908160001a905350610b5e600a86611500565b9450610afe565b949350505050565b6001600160a01b0381168114610b8257600080fd5b50565b8035610b9081610b6d565b919050565b600080600080600080600080610100898b031215610bb257600080fd5b8835610bbd81610b6d565b97506020890135965060408901356001600160401b03811115610bdf57600080fd5b890160c0818c031215610bf157600080fd5b9550606089013594506080890135610c0881610b6d565b935060a0890135610c1881610b6d565b925060c0890135610c2881610b6d565b8092505060e089013590509295985092959890939650565b600060208284031215610c5257600080fd5b81356001600160401b03811115610c6857600080fd5b82016101008185031215610c7b57600080fd5b9392505050565b6000815180845260005b81811015610ca857602081850181015186830182015201610c8c565b506000602082860101526020601f19601f83011685010191505092915050565b602081526000610c7b6020830184610c82565b600060208284031215610ced57600080fd5b8135610c7b81610b6d565b6000808335601e19843603018112610d0f57600080fd5b8301803591506001600160401b03821115610d2957600080fd5b602001915036819003821315610d3e57600080fd5b9250929050565b6000823560be19833603018112610d5b57600080fd5b9190910192915050565b6000808335601e19843603018112610d7c57600080fd5b8301803591506001600160401b03821115610d9657600080fd5b6020019150600581901b3603821315610d3e57600080fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b60405160c081016001600160401b0381118282101715610dfc57610dfc610dc4565b60405290565b604051601f8201601f191681016001600160401b0381118282101715610e2a57610e2a610dc4565b604052919050565b803563ffffffff81168114610b9057600080fd5b600082601f830112610e5757600080fd5b81356001600160401b03811115610e7057610e70610dc4565b610e83601f8201601f1916602001610e02565b818152846020838601011115610e9857600080fd5b816020850160208301376000918101602001919091529392505050565b8015158114610b8257600080fd5b8035610b9081610eb5565b80356001600160801b0381168114610b9057600080fd5b803564ffffffffff81168114610b9057600080fd5b600060608284031215610f0c57600080fd5b604051606081018181106001600160401b0382111715610f2e57610f2e610dc4565b604052905080610f3d83610ee5565b8152610f4b60208401610ee5565b6020820152610f5c60408401610ee5565b60408201525092915050565b600060408284031215610f7a57600080fd5b604051604081018181106001600160401b0382111715610f9c57610f9c610dc4565b6040529050808235610fad81610b6d565b8152602092830135920191909152919050565b60006101608284031215610fd357600080fd5b60405161010081018181106001600160401b0382111715610ff657610ff6610dc4565b60405290508061100583610b85565b815261101360208401610b85565b602082015261102460408401610ece565b604082015261103560608401610b85565b606082015261104660808401610ec3565b608082015261105760a08401610ec3565b60a08201526110698460c08501610efa565b60c082015261107c846101208501610f68565b60e08201525092915050565b600082601f83011261109957600080fd5b813560206001600160401b038211156110b4576110b4610dc4565b6110c2818360051b01610e02565b82815261016092830285018201928282019190878511156110e257600080fd5b8387015b85811015611105576110f88982610fc0565b84529284019281016110e6565b5090979650505050505050565b600060c0823603121561112457600080fd5b61112c610dda565b61113583610e32565b815260208301356001600160401b038082111561115157600080fd5b61115d36838701610e46565b6020840152604085013591508082111561117657600080fd5b61118236838701610e46565b604084015261119360608601610ec3565b60608401526111a460808601610b85565b608084015260a08501359150808211156111bd57600080fd5b506111ca36828601611088565b60a08301525092915050565b6000602082840312156111e857600080fd5b8151610c7b81610eb5565b6000808335601e1984360301811261120a57600080fd5b8301803591506001600160401b0382111561122457600080fd5b602001915061016081023603821315610d3e57600080fd5b6000610160828403121561124f57600080fd5b610c7b8383610fc0565b60018060a01b03851681528360208201526080604082015260006112806080830185610c82565b9050600283106112a057634e487b7160e01b600052602160045260246000fd5b82606083015295945050505050565b81516001600160a01b0390811682526020808401518216908301526040808401516001600160801b031690830152606080840151909116908201526080808301516101608301916113039084018215159052565b5060a083015161131760a084018215159052565b5060c083015161134a60c0840182805164ffffffffff908116835260208083015182169084015260409182015116910152565b5060e0929092015180516001600160a01b0316610120830152602001516101409091015290565b6001600160a01b038416815260606020820181905260009061139590830185610c82565b8281036040840152610a5b8185610c82565b6000602082840312156113b957600080fd5b5051919050565b600081518084526020808501808196508360051b8101915082860160005b858110156114085782840389526113f6848351610c82565b988501989350908401906001016113de565b5091979650505050505050565b60408152600061142860408301856113c0565b82810360208401526109c681856113c0565b87815260e06020820152600061145360e0830189610c82565b63ffffffff881660408401526001600160a01b0387811660608501528616608084015284151560a084015282810360c08401526114908185610c82565b9a9950505050505050505050565b6000602082840312156114b057600080fd5b8151610c7b81610b6d565b634e487b7160e01b600052601160045260246000fd5b6000600182016114e3576114e36114bb565b5060010190565b634e487b7160e01b600052601260045260246000fd5b60008261150f5761150f6114ea565b500490565b81810381811115611527576115276114bb565b92915050565b60008261153c5761153c6114ea565b500690565b80820180821115611527576115276114bb56fea26469706673582212208431b5cb9e9defda60834dc065f918f11d92dcbf19aba7475b779059a216011d64736f6c63430008130033", + "deployedBytecode": "0x608060405234801561001057600080fd5b506004361061004c5760003560e01c806313a9589c146100515780636592b2ac146100845780638c5f591a146100b4578063a3f4df7e146100c9575b600080fd5b6040517f5d0e6ce4fd951366cc55da93f6e79d8b81483109d79676a04bcc2bed6a4b507281526020015b60405180910390f35b610097610092366004610b95565b610105565b604080519283526001600160a01b0390911660208301520161007b565b6100c76100c2366004610c40565b61018f565b005b6100f86040518060400160405280601081526020016f0446563656e74486174735f305f315f360841b81525081565b60405161007b9190610cc8565b6000806101178a8a8a898989896103dc565b6040516329287c1b60e21b8152600481018a905230602482015233604482015291935091506001600160a01b038b169063a4a1f06c90606401600060405180830381600087803b15801561016a57600080fd5b505af115801561017e573d6000803e3d6000fd5b505050509850989650505050505050565b7f5d0e6ce4fd951366cc55da93f6e79d8b81483109d79676a04bcc2bed6a4b507260008061026d6101c36020860186610cdb565b6101d06080870187610cf8565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506102129250505060a0880188610cf8565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610257925050506060890160408a01610cdb565b61026760408a0160208b01610cdb565b8861072b565b909250905061028b6102856080860160608701610cdb565b836107bd565b60006102d261029d6020870187610cdb565b846102ab60c0890189610d45565b856102bc60608b0160408c01610cdb565b6102cc60408c0160208d01610cdb565b8a6103dc565b50905060005b6102e560e0870187610d65565b905081101561035f576103556102fe6020880188610cdb565b8361030c60e08a018a610d65565b8581811061031c5761031c610dae565b905060200281019061032e9190610d45565b8661033f60608c0160408d01610cdb565b61034f60408d0160208e01610cdb565b8b6103dc565b50506001016102d8565b5061036d6020860186610cdb565b6040516329287c1b60e21b8152600481018590523060248201523360448201526001600160a01b03919091169063a4a1f06c90606401600060405180830381600087803b1580156103bd57600080fd5b505af11580156103d1573d6000803e3d6000fd5b505050505050505050565b6000806103f389896103ed8a611112565b8961093d565b91506104028585858c866109cf565b9050600061041660a0890160808a01610cdb565b6001600160a01b0316146104b6576001600160a01b03891663641f776e8361044460a08b0160808c01610cdb565b6040516001600160e01b031960e085901b16815260048101929092526001600160a01b031660248201526044016020604051808303816000875af1158015610490573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104b491906111d6565b505b60005b6104c660a08901896111f3565b905081101561071e5760006104de60a08a018a6111f3565b838181106104ee576104ee610dae565b90506101600201803603810190610505919061123c565b6060810151815160408084015190516001600160a01b0390921660248301526001600160801b03166044820152919250339163468721a7919060009060640160408051601f198184030181529181526020820180516001600160e01b031663095ea7b360e01b1790525160e085901b6001600160e01b031916815261059293929190600090600401611259565b6020604051808303816000875af11580156105b1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105d591906111d6565b50600060405180610100016040528083602001516001600160a01b03168152602001856001600160a01b0316815260200183604001516001600160801b0316815260200183606001516001600160a01b031681526020018360800151151581526020018360a00151151581526020018360c0015181526020018360e001518152509050336001600160a01b031663468721a7836000015160008460405160240161067f91906112af565b60408051601f198184030181529181526020820180516001600160e01b03166353b1572760e01b1790525160e085901b6001600160e01b03191681526106cd93929190600090600401611259565b6020604051808303816000875af11580156106ec573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061071091906111d6565b5082600101925050506104b9565b5097509795505050505050565b600080876001600160a01b0316631a64dfad3089896040518463ffffffff1660e01b815260040161075e93929190611371565b6020604051808303816000875af115801561077d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107a191906113a7565b91506107b08585858b866109cf565b9050965096945050505050565b604080516001808252818301909252600091816020015b60608152602001906001900390816107d457505060408051600180825281830190925291925060009190602082015b6060815260200190600190039081610803579050509050604051806040016040528060088152602001671d1bdc12185d125960c21b8152508260008151811061084e5761084e610dae565b602002602001018190525061086283610a65565b8160008151811061087557610875610dae565b6020026020010181905250336001600160a01b031663468721a785600085856040516024016108a5929190611415565b60408051601f198184030181529181526020820180516001600160e01b031663579374b960e11b1790525160e085901b6001600160e01b03191681526108f393929190600090600401611259565b6020604051808303816000875af1158015610912573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061093691906111d6565b5050505050565b6020820151825160608401516040808601519051635829492f60e11b81526000946001600160a01b038a169463b052925e94610983948b948a928392909160040161143a565b6020604051808303816000875af11580156109a2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109c691906113a7565b95945050505050565b604051638a54c52f60e01b81526001600160a01b0385811660048301526024820185905246604483015283811660648301526084820183905260009190871690638a54c52f9060a4016020604051808303816000875af1158015610a37573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a5b919061149e565b9695505050505050565b606081600003610a8c5750506040805180820190915260018152600360fc1b602082015290565b8160005b8115610ab65780610aa0816114d1565b9150610aaf9050600a83611500565b9150610a90565b6000816001600160401b03811115610ad057610ad0610dc4565b6040519080825280601f01601f191660200182016040528015610afa576020820181803683370190505b5090505b8415610b6557610b0f600183611514565b9150610b1c600a8661152d565b610b27906030611541565b60f81b818381518110610b3c57610b3c610dae565b60200101906001600160f81b031916908160001a905350610b5e600a86611500565b9450610afe565b949350505050565b6001600160a01b0381168114610b8257600080fd5b50565b8035610b9081610b6d565b919050565b600080600080600080600080610100898b031215610bb257600080fd5b8835610bbd81610b6d565b97506020890135965060408901356001600160401b03811115610bdf57600080fd5b890160c0818c031215610bf157600080fd5b9550606089013594506080890135610c0881610b6d565b935060a0890135610c1881610b6d565b925060c0890135610c2881610b6d565b8092505060e089013590509295985092959890939650565b600060208284031215610c5257600080fd5b81356001600160401b03811115610c6857600080fd5b82016101008185031215610c7b57600080fd5b9392505050565b6000815180845260005b81811015610ca857602081850181015186830182015201610c8c565b506000602082860101526020601f19601f83011685010191505092915050565b602081526000610c7b6020830184610c82565b600060208284031215610ced57600080fd5b8135610c7b81610b6d565b6000808335601e19843603018112610d0f57600080fd5b8301803591506001600160401b03821115610d2957600080fd5b602001915036819003821315610d3e57600080fd5b9250929050565b6000823560be19833603018112610d5b57600080fd5b9190910192915050565b6000808335601e19843603018112610d7c57600080fd5b8301803591506001600160401b03821115610d9657600080fd5b6020019150600581901b3603821315610d3e57600080fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b60405160c081016001600160401b0381118282101715610dfc57610dfc610dc4565b60405290565b604051601f8201601f191681016001600160401b0381118282101715610e2a57610e2a610dc4565b604052919050565b803563ffffffff81168114610b9057600080fd5b600082601f830112610e5757600080fd5b81356001600160401b03811115610e7057610e70610dc4565b610e83601f8201601f1916602001610e02565b818152846020838601011115610e9857600080fd5b816020850160208301376000918101602001919091529392505050565b8015158114610b8257600080fd5b8035610b9081610eb5565b80356001600160801b0381168114610b9057600080fd5b803564ffffffffff81168114610b9057600080fd5b600060608284031215610f0c57600080fd5b604051606081018181106001600160401b0382111715610f2e57610f2e610dc4565b604052905080610f3d83610ee5565b8152610f4b60208401610ee5565b6020820152610f5c60408401610ee5565b60408201525092915050565b600060408284031215610f7a57600080fd5b604051604081018181106001600160401b0382111715610f9c57610f9c610dc4565b6040529050808235610fad81610b6d565b8152602092830135920191909152919050565b60006101608284031215610fd357600080fd5b60405161010081018181106001600160401b0382111715610ff657610ff6610dc4565b60405290508061100583610b85565b815261101360208401610b85565b602082015261102460408401610ece565b604082015261103560608401610b85565b606082015261104660808401610ec3565b608082015261105760a08401610ec3565b60a08201526110698460c08501610efa565b60c082015261107c846101208501610f68565b60e08201525092915050565b600082601f83011261109957600080fd5b813560206001600160401b038211156110b4576110b4610dc4565b6110c2818360051b01610e02565b82815261016092830285018201928282019190878511156110e257600080fd5b8387015b85811015611105576110f88982610fc0565b84529284019281016110e6565b5090979650505050505050565b600060c0823603121561112457600080fd5b61112c610dda565b61113583610e32565b815260208301356001600160401b038082111561115157600080fd5b61115d36838701610e46565b6020840152604085013591508082111561117657600080fd5b61118236838701610e46565b604084015261119360608601610ec3565b60608401526111a460808601610b85565b608084015260a08501359150808211156111bd57600080fd5b506111ca36828601611088565b60a08301525092915050565b6000602082840312156111e857600080fd5b8151610c7b81610eb5565b6000808335601e1984360301811261120a57600080fd5b8301803591506001600160401b0382111561122457600080fd5b602001915061016081023603821315610d3e57600080fd5b6000610160828403121561124f57600080fd5b610c7b8383610fc0565b60018060a01b03851681528360208201526080604082015260006112806080830185610c82565b9050600283106112a057634e487b7160e01b600052602160045260246000fd5b82606083015295945050505050565b81516001600160a01b0390811682526020808401518216908301526040808401516001600160801b031690830152606080840151909116908201526080808301516101608301916113039084018215159052565b5060a083015161131760a084018215159052565b5060c083015161134a60c0840182805164ffffffffff908116835260208083015182169084015260409182015116910152565b5060e0929092015180516001600160a01b0316610120830152602001516101409091015290565b6001600160a01b038416815260606020820181905260009061139590830185610c82565b8281036040840152610a5b8185610c82565b6000602082840312156113b957600080fd5b5051919050565b600081518084526020808501808196508360051b8101915082860160005b858110156114085782840389526113f6848351610c82565b988501989350908401906001016113de565b5091979650505050505050565b60408152600061142860408301856113c0565b82810360208401526109c681856113c0565b87815260e06020820152600061145360e0830189610c82565b63ffffffff881660408401526001600160a01b0387811660608501528616608084015284151560a084015282810360c08401526114908185610c82565b9a9950505050505050505050565b6000602082840312156114b057600080fd5b8151610c7b81610b6d565b634e487b7160e01b600052601160045260246000fd5b6000600182016114e3576114e36114bb565b5060010190565b634e487b7160e01b600052601260045260246000fd5b60008261150f5761150f6114ea565b500490565b81810381811115611527576115276114bb565b92915050565b60008261153c5761153c6114ea565b500690565b80820180821115611527576115276114bb56fea26469706673582212208431b5cb9e9defda60834dc065f918f11d92dcbf19aba7475b779059a216011d64736f6c63430008130033", "devdoc": { "kind": "dev", - "methods": {}, + "methods": { + "createAndDeclareTree((address,address,address,address,string,string,(uint32,string,string,bool,address,(address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256))[]),(uint32,string,string,bool,address,(address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256))[])[]))": { + "details": "In order for a Safe to seamlessly create roles even if it has never previously created a role and thus has no hat tree, we defer the creation of the hat tree and its setup to this contract. This way, in a single tx block, the resulting topHatId of the newly created hat can be used to create an admin hat and any other hats needed. We also make use of `KeyValuePairs` to associate the topHatId with the Safe." + }, + "createRoleHat(address,uint256,(uint32,string,string,bool,address,(address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256))[]),uint256,address,address,address,bytes32)": { + "details": "Role hat creation, minting, smart account creation and stream creation are handled here in order to avoid a race condition where not more than one active proposal to create a new role can exist at a time. See: https://github.com/decentdao/decent-interface/issues/2402" + } + }, "version": 1 }, "userdoc": { "kind": "user", - "methods": {}, + "methods": { + "createAndDeclareTree((address,address,address,address,string,string,(uint32,string,string,bool,address,(address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256))[]),(uint32,string,string,bool,address,(address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256))[])[]))": { + "notice": "For a safe without any roles previously created on it, this function should be called. It sets up the top hat and admin hat, as well as any other hats and their streams that are provided. This contract should be enabled a module on the Safe for which the role(s) are to be created, and disabled after." + }, + "createRoleHat(address,uint256,(uint32,string,string,bool,address,(address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256))[]),uint256,address,address,address,bytes32)": { + "notice": "Creates a new role hat and any streams on it. This contract should be enabled a module on the Safe for which the role is to be created, and disable after. In order for the module to be able to create hats on behalf of the Safe, the Safe must first transfer its top hat to this contract. This function transfers the top hat back to the Safe after creating the role hat. The function simply calls `createHatAndAccountAndMintAndStreams` and then transfers the top hat back to the Safe." + } + }, "version": 1 }, "storageLayout": { diff --git a/deployments/base/solcInputs/4754a2f0c9d6a191a066af246491b62a.json b/deployments/base/solcInputs/4754a2f0c9d6a191a066af246491b62a.json new file mode 100644 index 00000000..87cba363 --- /dev/null +++ b/deployments/base/solcInputs/4754a2f0c9d6a191a066af246491b62a.json @@ -0,0 +1,59 @@ +{ + "language": "Solidity", + "sources": { + "@gnosis.pm/safe-contracts/contracts/common/Enum.sol": { + "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\n\n/// @title Enum - Collection of enums\n/// @author Richard Meissner - \ncontract Enum {\n enum Operation {Call, DelegateCall}\n}\n" + }, + "@gnosis.pm/zodiac/contracts/interfaces/IAvatar.sol": { + "content": "// SPDX-License-Identifier: LGPL-3.0-only\n\n/// @title Zodiac Avatar - A contract that manages modules that can execute transactions via this contract.\npragma solidity >=0.7.0 <0.9.0;\n\nimport \"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\";\n\ninterface IAvatar {\n event EnabledModule(address module);\n event DisabledModule(address module);\n event ExecutionFromModuleSuccess(address indexed module);\n event ExecutionFromModuleFailure(address indexed module);\n\n /// @dev Enables a module on the avatar.\n /// @notice Can only be called by the avatar.\n /// @notice Modules should be stored as a linked list.\n /// @notice Must emit EnabledModule(address module) if successful.\n /// @param module Module to be enabled.\n function enableModule(address module) external;\n\n /// @dev Disables a module on the avatar.\n /// @notice Can only be called by the avatar.\n /// @notice Must emit DisabledModule(address module) if successful.\n /// @param prevModule Address that pointed to the module to be removed in the linked list\n /// @param module Module to be removed.\n function disableModule(address prevModule, address module) external;\n\n /// @dev Allows a Module to execute a transaction.\n /// @notice Can only be called by an enabled module.\n /// @notice Must emit ExecutionFromModuleSuccess(address module) if successful.\n /// @notice Must emit ExecutionFromModuleFailure(address module) if unsuccessful.\n /// @param to Destination address of module transaction.\n /// @param value Ether value of module transaction.\n /// @param data Data payload of module transaction.\n /// @param operation Operation type of module transaction: 0 == call, 1 == delegate call.\n function execTransactionFromModule(\n address to,\n uint256 value,\n bytes memory data,\n Enum.Operation operation\n ) external returns (bool success);\n\n /// @dev Allows a Module to execute a transaction and return data\n /// @notice Can only be called by an enabled module.\n /// @notice Must emit ExecutionFromModuleSuccess(address module) if successful.\n /// @notice Must emit ExecutionFromModuleFailure(address module) if unsuccessful.\n /// @param to Destination address of module transaction.\n /// @param value Ether value of module transaction.\n /// @param data Data payload of module transaction.\n /// @param operation Operation type of module transaction: 0 == call, 1 == delegate call.\n function execTransactionFromModuleReturnData(\n address to,\n uint256 value,\n bytes memory data,\n Enum.Operation operation\n ) external returns (bool success, bytes memory returnData);\n\n /// @dev Returns if an module is enabled\n /// @return True if the module is enabled\n function isModuleEnabled(address module) external view returns (bool);\n\n /// @dev Returns array of modules.\n /// @param start Start of the page.\n /// @param pageSize Maximum number of modules that should be returned.\n /// @return array Array of modules.\n /// @return next Start of the next page.\n function getModulesPaginated(address start, uint256 pageSize)\n external\n view\n returns (address[] memory array, address next);\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/IERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20 {\n /**\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\n * another (`to`).\n *\n * Note that `value` may be zero.\n */\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n /**\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n * a call to {approve}. `value` is the new allowance.\n */\n event Approval(address indexed owner, address indexed spender, uint256 value);\n\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by `account`.\n */\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * @dev Moves `amount` tokens from the caller's account to `to`.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transfer(address to, uint256 amount) external returns (bool);\n\n /**\n * @dev Returns the remaining number of tokens that `spender` will be\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\n * zero by default.\n *\n * This value changes when {approve} or {transferFrom} are called.\n */\n function allowance(address owner, address spender) external view returns (uint256);\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\n * that someone may use both the old and the new allowance by unfortunate\n * transaction ordering. One possible solution to mitigate this race\n * condition is to first reduce the spender's allowance to 0 and set the\n * desired value afterwards:\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n *\n * Emits an {Approval} event.\n */\n function approve(address spender, uint256 amount) external returns (bool);\n\n /**\n * @dev Moves `amount` tokens from `from` to `to` using the\n * allowance mechanism. `amount` is then deducted from the caller's\n * allowance.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(\n address from,\n address to,\n uint256 amount\n ) external returns (bool);\n}\n" + }, + "@openzeppelin/contracts/utils/Strings.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n uint8 private constant _ADDRESS_LENGTH = 20;\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp >>= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i > 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value & 0xf];\n value >>= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n\n /**\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\n */\n function toHexString(address addr) internal pure returns (string memory) {\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\n }\n}\n" + }, + "contracts/DecentHats_0_1_0.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity =0.8.19;\n\nimport {Enum} from \"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\";\nimport {IAvatar} from \"@gnosis.pm/zodiac/contracts/interfaces/IAvatar.sol\";\nimport {Strings} from \"@openzeppelin/contracts/utils/Strings.sol\";\nimport {IERC20} from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport {IERC6551Registry} from \"./interfaces/IERC6551Registry.sol\";\nimport {IHats} from \"./interfaces/hats/IHats.sol\";\nimport {ISablierV2LockupLinear} from \"./interfaces/sablier/ISablierV2LockupLinear.sol\";\nimport {LockupLinear} from \"./interfaces/sablier/LockupLinear.sol\";\n\ncontract DecentHats_0_1_0 {\n string public constant NAME = \"DecentHats_0_1_0\";\n\n struct SablierStreamParams {\n ISablierV2LockupLinear sablier;\n address sender;\n uint128 totalAmount;\n address asset;\n bool cancelable;\n bool transferable;\n LockupLinear.Timestamps timestamps;\n LockupLinear.Broker broker;\n }\n\n struct Hat {\n uint32 maxSupply;\n string details;\n string imageURI;\n bool isMutable;\n address wearer;\n SablierStreamParams[] sablierParams; // Optional Sablier stream parameters\n }\n\n struct CreateTreeParams {\n IHats hatsProtocol;\n address hatsAccountImplementation;\n IERC6551Registry registry;\n address keyValuePairs;\n string topHatDetails;\n string topHatImageURI;\n Hat adminHat;\n Hat[] hats;\n }\n\n function getSalt() public pure returns (bytes32 salt) {\n return\n 0x5d0e6ce4fd951366cc55da93f6e79d8b81483109d79676a04bcc2bed6a4b5072;\n }\n\n function declareSafeHatTree(\n address _keyValuePairs,\n uint256 topHatId\n ) internal {\n string[] memory keys = new string[](1);\n string[] memory values = new string[](1);\n keys[0] = \"topHatId\";\n values[0] = Strings.toString(topHatId);\n\n IAvatar(msg.sender).execTransactionFromModule(\n _keyValuePairs,\n 0,\n abi.encodeWithSignature(\n \"updateValues(string[],string[])\",\n keys,\n values\n ),\n Enum.Operation.Call\n );\n }\n\n function createHat(\n IHats _hatsProtocol,\n uint256 adminHatId,\n Hat memory _hat,\n address topHatAccount\n ) internal returns (uint256) {\n return\n _hatsProtocol.createHat(\n adminHatId,\n _hat.details,\n _hat.maxSupply,\n topHatAccount,\n topHatAccount,\n _hat.isMutable,\n _hat.imageURI\n );\n }\n\n function createAccount(\n IERC6551Registry _registry,\n address _hatsAccountImplementation,\n bytes32 salt,\n address protocolAddress,\n uint256 hatId\n ) internal returns (address) {\n return\n _registry.createAccount(\n _hatsAccountImplementation,\n salt,\n block.chainid,\n protocolAddress,\n hatId\n );\n }\n\n function createTopHatAndAccount(\n IHats _hatsProtocol,\n string memory _topHatDetails,\n string memory _topHatImageURI,\n IERC6551Registry _registry,\n address _hatsAccountImplementation,\n bytes32 salt\n ) internal returns (uint256 topHatId, address topHatAccount) {\n topHatId = _hatsProtocol.mintTopHat(\n address(this),\n _topHatDetails,\n _topHatImageURI\n );\n\n topHatAccount = createAccount(\n _registry,\n _hatsAccountImplementation,\n salt,\n address(_hatsProtocol),\n topHatId\n );\n }\n\n function createHatAndAccountAndMintAndStreams(\n IHats hatsProtocol,\n uint256 adminHatId,\n Hat calldata hat,\n address topHatAccount,\n IERC6551Registry registry,\n address hatsAccountImplementation,\n bytes32 salt\n ) internal returns (uint256 hatId, address accountAddress) {\n hatId = createHat(hatsProtocol, adminHatId, hat, topHatAccount);\n\n accountAddress = createAccount(\n registry,\n hatsAccountImplementation,\n salt,\n address(hatsProtocol),\n hatId\n );\n\n if (hat.wearer != address(0)) {\n hatsProtocol.mintHat(hatId, hat.wearer);\n }\n\n for (uint256 i = 0; i < hat.sablierParams.length; ) {\n SablierStreamParams memory sablierParams = hat.sablierParams[i];\n\n // Approve tokens for Sablier\n IAvatar(msg.sender).execTransactionFromModule(\n sablierParams.asset,\n 0,\n abi.encodeWithSignature(\n \"approve(address,uint256)\",\n address(sablierParams.sablier),\n sablierParams.totalAmount\n ),\n Enum.Operation.Call\n );\n\n LockupLinear.CreateWithTimestamps memory params = LockupLinear\n .CreateWithTimestamps({\n sender: sablierParams.sender,\n recipient: accountAddress,\n totalAmount: sablierParams.totalAmount,\n asset: IERC20(sablierParams.asset),\n cancelable: sablierParams.cancelable,\n transferable: sablierParams.transferable,\n timestamps: sablierParams.timestamps,\n broker: sablierParams.broker\n });\n\n // Proxy the Sablier call through IAvatar\n IAvatar(msg.sender).execTransactionFromModule(\n address(sablierParams.sablier),\n 0,\n abi.encodeWithSignature(\n \"createWithTimestamps((address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256)))\",\n params\n ),\n Enum.Operation.Call\n );\n\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * Creates a new role hat and any streams on it.\n *\n * This contract should be enabled a module on the Safe for which the role is to be created, and disable after.\n * In order for the module to be able to create hats on behalf of the Safe, the Safe must first\n * transfer its top hat to this contract. This function transfers the top hat back to the Safe after\n * creating the role hat.\n *\n * The function simply calls `createHatAndAccountAndMintAndStreams` and then transfers the top hat back to the Safe.\n *\n * @dev Role hat creation, minting, smart account creation and stream creation are handled here in order\n * to avoid a race condition where not more than one active proposal to create a new role can exist at a time.\n * See: https://github.com/decentdao/decent-interface/issues/2402\n */\n function createRoleHat(\n IHats hatsProtocol,\n uint256 adminHatId,\n Hat calldata hat,\n uint256 topHatId,\n address topHatAccount,\n IERC6551Registry registry,\n address hatsAccountImplementation,\n bytes32 salt\n ) public returns (uint256 hatId, address accountAddress) {\n (hatId, accountAddress) = createHatAndAccountAndMintAndStreams(\n hatsProtocol,\n adminHatId,\n hat,\n topHatAccount,\n registry,\n hatsAccountImplementation,\n salt\n );\n\n hatsProtocol.transferHat(topHatId, address(this), msg.sender);\n }\n\n /**\n * For a safe without any roles previously created on it, this function should be called. It sets up the\n * top hat and admin hat, as well as any other hats and their streams that are provided.\n *\n * This contract should be enabled a module on the Safe for which the role(s) are to be created, and disabled after.\n *\n * @dev In order for a Safe to seamlessly create roles even if it has never previously created a role and thus has\n * no hat tree, we defer the creation of the hat tree and its setup to this contract. This way, in a single tx block,\n * the resulting topHatId of the newly created hat can be used to create an admin hat and any other hats needed.\n * We also make use of `KeyValuePairs` to associate the topHatId with the Safe.\n */\n function createAndDeclareTree(CreateTreeParams calldata params) public {\n bytes32 salt = getSalt();\n\n (uint256 topHatId, address topHatAccount) = createTopHatAndAccount(\n params.hatsProtocol,\n params.topHatDetails,\n params.topHatImageURI,\n params.registry,\n params.hatsAccountImplementation,\n salt\n );\n\n declareSafeHatTree(params.keyValuePairs, topHatId);\n\n (uint256 adminHatId, ) = createHatAndAccountAndMintAndStreams(\n params.hatsProtocol,\n topHatId,\n params.adminHat,\n topHatAccount,\n params.registry,\n params.hatsAccountImplementation,\n salt\n );\n\n for (uint256 i = 0; i < params.hats.length; ) {\n createHatAndAccountAndMintAndStreams(\n params.hatsProtocol,\n adminHatId,\n params.hats[i],\n topHatAccount,\n params.registry,\n params.hatsAccountImplementation,\n salt\n );\n\n unchecked {\n ++i;\n }\n }\n\n params.hatsProtocol.transferHat(topHatId, address(this), msg.sender);\n }\n}\n" + }, + "contracts/interfaces/hats/IHats.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0\n// Copyright (C) 2023 Haberdasher Labs\n//\n// This program is free software: you can redistribute it and/or modify\n// it under the terms of the GNU Affero General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU Affero General Public License for more details.\n//\n// You should have received a copy of the GNU Affero General Public License\n// along with this program. If not, see .\n\npragma solidity >=0.8.13;\n\ninterface IHats {\n function mintTopHat(\n address _target,\n string memory _details,\n string memory _imageURI\n ) external returns (uint256 topHatId);\n\n function createHat(\n uint256 _admin,\n string calldata _details,\n uint32 _maxSupply,\n address _eligibility,\n address _toggle,\n bool _mutable,\n string calldata _imageURI\n ) external returns (uint256 newHatId);\n\n function mintHat(\n uint256 _hatId,\n address _wearer\n ) external returns (bool success);\n\n function transferHat(uint256 _hatId, address _from, address _to) external;\n}\n" + }, + "contracts/interfaces/IERC6551Registry.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.4;\n\ninterface IERC6551Registry {\n /**\n * @dev Creates a token bound account for a non-fungible token.\n *\n * If account has already been created, returns the account address without calling create2.\n *\n * Emits ERC6551AccountCreated event.\n *\n * @return account The address of the token bound account\n */\n function createAccount(\n address implementation,\n bytes32 salt,\n uint256 chainId,\n address tokenContract,\n uint256 tokenId\n ) external returns (address account);\n}\n" + }, + "contracts/interfaces/sablier/ISablierV2LockupLinear.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport {LockupLinear} from \"./LockupLinear.sol\";\nimport {IERC20} from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\n\ninterface ISablierV2LockupLinear {\n function createWithTimestamps(\n LockupLinear.CreateWithTimestamps calldata params\n ) external returns (uint256 streamId);\n}\n" + }, + "contracts/interfaces/sablier/LockupLinear.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport {IERC20} from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\n\nlibrary LockupLinear {\n struct CreateWithTimestamps {\n address sender;\n address recipient;\n uint128 totalAmount;\n IERC20 asset;\n bool cancelable;\n bool transferable;\n Timestamps timestamps;\n Broker broker;\n }\n\n struct Timestamps {\n uint40 start;\n uint40 cliff;\n uint40 end;\n }\n\n struct Broker {\n address account;\n uint256 fee;\n }\n}\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200 + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers", + "metadata", + "devdoc", + "userdoc", + "storageLayout", + "evm.gasEstimates" + ], + "": [ + "ast" + ] + } + }, + "metadata": { + "useLiteralContent": true + } + } +} \ No newline at end of file diff --git a/deployments/mainnet/DecentHats_0_1_0.json b/deployments/mainnet/DecentHats_0_1_0.json index 616a515a..6f619b3f 100644 --- a/deployments/mainnet/DecentHats_0_1_0.json +++ b/deployments/mainnet/DecentHats_0_1_0.json @@ -1,5 +1,5 @@ { - "address": "0x5843E6fa58163453A0A753a831E3BbdB2da06259", + "address": "0x3F852ac21185E62F322F8d0Ca680b06c077280D5", "abi": [ { "inputs": [], @@ -275,6 +275,168 @@ "stateMutability": "nonpayable", "type": "function" }, + { + "inputs": [ + { + "internalType": "contract IHats", + "name": "hatsProtocol", + "type": "address" + }, + { + "internalType": "uint256", + "name": "adminHatId", + "type": "uint256" + }, + { + "components": [ + { + "internalType": "uint32", + "name": "maxSupply", + "type": "uint32" + }, + { + "internalType": "string", + "name": "details", + "type": "string" + }, + { + "internalType": "string", + "name": "imageURI", + "type": "string" + }, + { + "internalType": "bool", + "name": "isMutable", + "type": "bool" + }, + { + "internalType": "address", + "name": "wearer", + "type": "address" + }, + { + "components": [ + { + "internalType": "contract ISablierV2LockupLinear", + "name": "sablier", + "type": "address" + }, + { + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "internalType": "uint128", + "name": "totalAmount", + "type": "uint128" + }, + { + "internalType": "address", + "name": "asset", + "type": "address" + }, + { + "internalType": "bool", + "name": "cancelable", + "type": "bool" + }, + { + "internalType": "bool", + "name": "transferable", + "type": "bool" + }, + { + "components": [ + { + "internalType": "uint40", + "name": "start", + "type": "uint40" + }, + { + "internalType": "uint40", + "name": "cliff", + "type": "uint40" + }, + { + "internalType": "uint40", + "name": "end", + "type": "uint40" + } + ], + "internalType": "struct LockupLinear.Timestamps", + "name": "timestamps", + "type": "tuple" + }, + { + "components": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "uint256", + "name": "fee", + "type": "uint256" + } + ], + "internalType": "struct LockupLinear.Broker", + "name": "broker", + "type": "tuple" + } + ], + "internalType": "struct DecentHats_0_1_0.SablierStreamParams[]", + "name": "sablierParams", + "type": "tuple[]" + } + ], + "internalType": "struct DecentHats_0_1_0.Hat", + "name": "hat", + "type": "tuple" + }, + { + "internalType": "uint256", + "name": "topHatId", + "type": "uint256" + }, + { + "internalType": "address", + "name": "topHatAccount", + "type": "address" + }, + { + "internalType": "contract IERC6551Registry", + "name": "registry", + "type": "address" + }, + { + "internalType": "address", + "name": "hatsAccountImplementation", + "type": "address" + }, + { + "internalType": "bytes32", + "name": "salt", + "type": "bytes32" + } + ], + "name": "createRoleHat", + "outputs": [ + { + "internalType": "uint256", + "name": "hatId", + "type": "uint256" + }, + { + "internalType": "address", + "name": "accountAddress", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, { "inputs": [], "name": "getSalt", @@ -289,36 +451,50 @@ "type": "function" } ], - "transactionHash": "0x45225faa4aac42f403a10912758bb375c1889ddf98627000370b20f840cc6365", + "transactionHash": "0x1a2b34ff7f671d4a727d06ad509eca16d699e76b87c36bc0996579b9e649272e", "receipt": { "to": null, "from": "0xb5Ca125166C1987A35EDD550E16846Fa1e1D9bB3", - "contractAddress": "0x5843E6fa58163453A0A753a831E3BbdB2da06259", - "transactionIndex": 38, - "gasUsed": "1162443", + "contractAddress": "0x3F852ac21185E62F322F8d0Ca680b06c077280D5", + "transactionIndex": 9, + "gasUsed": "1243979", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0xc9ec4b47f2e757a387beeebfc3a17c51f90b4a81df75af0eab0d5286f5637cfe", - "transactionHash": "0x45225faa4aac42f403a10912758bb375c1889ddf98627000370b20f840cc6365", + "blockHash": "0x9aac8241b655d66208a24411411b3f2b81bd4edda3d80847c6b1c46b8e71d85e", + "transactionHash": "0x1a2b34ff7f671d4a727d06ad509eca16d699e76b87c36bc0996579b9e649272e", "logs": [], - "blockNumber": 20937775, - "cumulativeGasUsed": "5113096", + "blockNumber": 21043134, + "cumulativeGasUsed": "2480225", "status": 1, "byzantium": true }, "args": [], - "numDeployments": 3, - "solcInputHash": "6ceb8d75a501322d052845dbe517017d", - "metadata": "{\"compiler\":{\"version\":\"0.8.19+commit.7dd6d404\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"NAME\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"contract IHats\",\"name\":\"hatsProtocol\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"hatsAccountImplementation\",\"type\":\"address\"},{\"internalType\":\"contract IERC6551Registry\",\"name\":\"registry\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"keyValuePairs\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"topHatDetails\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"topHatImageURI\",\"type\":\"string\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"maxSupply\",\"type\":\"uint32\"},{\"internalType\":\"string\",\"name\":\"details\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"imageURI\",\"type\":\"string\"},{\"internalType\":\"bool\",\"name\":\"isMutable\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"wearer\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"contract ISablierV2LockupLinear\",\"name\":\"sablier\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint128\",\"name\":\"totalAmount\",\"type\":\"uint128\"},{\"internalType\":\"address\",\"name\":\"asset\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"cancelable\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"transferable\",\"type\":\"bool\"},{\"components\":[{\"internalType\":\"uint40\",\"name\":\"start\",\"type\":\"uint40\"},{\"internalType\":\"uint40\",\"name\":\"cliff\",\"type\":\"uint40\"},{\"internalType\":\"uint40\",\"name\":\"end\",\"type\":\"uint40\"}],\"internalType\":\"struct LockupLinear.Timestamps\",\"name\":\"timestamps\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"fee\",\"type\":\"uint256\"}],\"internalType\":\"struct LockupLinear.Broker\",\"name\":\"broker\",\"type\":\"tuple\"}],\"internalType\":\"struct DecentHats_0_1_0.SablierStreamParams[]\",\"name\":\"sablierParams\",\"type\":\"tuple[]\"}],\"internalType\":\"struct DecentHats_0_1_0.Hat\",\"name\":\"adminHat\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"maxSupply\",\"type\":\"uint32\"},{\"internalType\":\"string\",\"name\":\"details\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"imageURI\",\"type\":\"string\"},{\"internalType\":\"bool\",\"name\":\"isMutable\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"wearer\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"contract ISablierV2LockupLinear\",\"name\":\"sablier\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint128\",\"name\":\"totalAmount\",\"type\":\"uint128\"},{\"internalType\":\"address\",\"name\":\"asset\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"cancelable\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"transferable\",\"type\":\"bool\"},{\"components\":[{\"internalType\":\"uint40\",\"name\":\"start\",\"type\":\"uint40\"},{\"internalType\":\"uint40\",\"name\":\"cliff\",\"type\":\"uint40\"},{\"internalType\":\"uint40\",\"name\":\"end\",\"type\":\"uint40\"}],\"internalType\":\"struct LockupLinear.Timestamps\",\"name\":\"timestamps\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"fee\",\"type\":\"uint256\"}],\"internalType\":\"struct LockupLinear.Broker\",\"name\":\"broker\",\"type\":\"tuple\"}],\"internalType\":\"struct DecentHats_0_1_0.SablierStreamParams[]\",\"name\":\"sablierParams\",\"type\":\"tuple[]\"}],\"internalType\":\"struct DecentHats_0_1_0.Hat[]\",\"name\":\"hats\",\"type\":\"tuple[]\"}],\"internalType\":\"struct DecentHats_0_1_0.CreateTreeParams\",\"name\":\"params\",\"type\":\"tuple\"}],\"name\":\"createAndDeclareTree\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getSalt\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"salt\",\"type\":\"bytes32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/DecentHats_0_1_0.sol\":\"DecentHats_0_1_0\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\":{\"content\":\"// SPDX-License-Identifier: LGPL-3.0-only\\npragma solidity >=0.7.0 <0.9.0;\\n\\n/// @title Enum - Collection of enums\\n/// @author Richard Meissner - \\ncontract Enum {\\n enum Operation {Call, DelegateCall}\\n}\\n\",\"keccak256\":\"0x473e45b1a5cc47be494b0e123c9127f0c11c1e0992a321ae5a644c0bfdb2c14f\",\"license\":\"LGPL-3.0-only\"},\"@gnosis.pm/zodiac/contracts/interfaces/IAvatar.sol\":{\"content\":\"// SPDX-License-Identifier: LGPL-3.0-only\\n\\n/// @title Zodiac Avatar - A contract that manages modules that can execute transactions via this contract.\\npragma solidity >=0.7.0 <0.9.0;\\n\\nimport \\\"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\\\";\\n\\ninterface IAvatar {\\n event EnabledModule(address module);\\n event DisabledModule(address module);\\n event ExecutionFromModuleSuccess(address indexed module);\\n event ExecutionFromModuleFailure(address indexed module);\\n\\n /// @dev Enables a module on the avatar.\\n /// @notice Can only be called by the avatar.\\n /// @notice Modules should be stored as a linked list.\\n /// @notice Must emit EnabledModule(address module) if successful.\\n /// @param module Module to be enabled.\\n function enableModule(address module) external;\\n\\n /// @dev Disables a module on the avatar.\\n /// @notice Can only be called by the avatar.\\n /// @notice Must emit DisabledModule(address module) if successful.\\n /// @param prevModule Address that pointed to the module to be removed in the linked list\\n /// @param module Module to be removed.\\n function disableModule(address prevModule, address module) external;\\n\\n /// @dev Allows a Module to execute a transaction.\\n /// @notice Can only be called by an enabled module.\\n /// @notice Must emit ExecutionFromModuleSuccess(address module) if successful.\\n /// @notice Must emit ExecutionFromModuleFailure(address module) if unsuccessful.\\n /// @param to Destination address of module transaction.\\n /// @param value Ether value of module transaction.\\n /// @param data Data payload of module transaction.\\n /// @param operation Operation type of module transaction: 0 == call, 1 == delegate call.\\n function execTransactionFromModule(\\n address to,\\n uint256 value,\\n bytes memory data,\\n Enum.Operation operation\\n ) external returns (bool success);\\n\\n /// @dev Allows a Module to execute a transaction and return data\\n /// @notice Can only be called by an enabled module.\\n /// @notice Must emit ExecutionFromModuleSuccess(address module) if successful.\\n /// @notice Must emit ExecutionFromModuleFailure(address module) if unsuccessful.\\n /// @param to Destination address of module transaction.\\n /// @param value Ether value of module transaction.\\n /// @param data Data payload of module transaction.\\n /// @param operation Operation type of module transaction: 0 == call, 1 == delegate call.\\n function execTransactionFromModuleReturnData(\\n address to,\\n uint256 value,\\n bytes memory data,\\n Enum.Operation operation\\n ) external returns (bool success, bytes memory returnData);\\n\\n /// @dev Returns if an module is enabled\\n /// @return True if the module is enabled\\n function isModuleEnabled(address module) external view returns (bool);\\n\\n /// @dev Returns array of modules.\\n /// @param start Start of the page.\\n /// @param pageSize Maximum number of modules that should be returned.\\n /// @return array Array of modules.\\n /// @return next Start of the next page.\\n function getModulesPaginated(address start, uint256 pageSize)\\n external\\n view\\n returns (address[] memory array, address next);\\n}\\n\",\"keccak256\":\"0xcd5508ffe596eef8fbccfd5fc4f10a34397773547ce64e212d48b5212865ec1f\",\"license\":\"LGPL-3.0-only\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20 {\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `to`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address to, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `from` to `to` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(\\n address from,\\n address to,\\n uint256 amount\\n ) external returns (bool);\\n}\\n\",\"keccak256\":\"0x9750c6b834f7b43000631af5cc30001c5f547b3ceb3635488f140f60e897ea6b\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Strings.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev String operations.\\n */\\nlibrary Strings {\\n bytes16 private constant _HEX_SYMBOLS = \\\"0123456789abcdef\\\";\\n uint8 private constant _ADDRESS_LENGTH = 20;\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\\n */\\n function toString(uint256 value) internal pure returns (string memory) {\\n // Inspired by OraclizeAPI's implementation - MIT licence\\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\\n\\n if (value == 0) {\\n return \\\"0\\\";\\n }\\n uint256 temp = value;\\n uint256 digits;\\n while (temp != 0) {\\n digits++;\\n temp /= 10;\\n }\\n bytes memory buffer = new bytes(digits);\\n while (value != 0) {\\n digits -= 1;\\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\\n value /= 10;\\n }\\n return string(buffer);\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\\n */\\n function toHexString(uint256 value) internal pure returns (string memory) {\\n if (value == 0) {\\n return \\\"0x00\\\";\\n }\\n uint256 temp = value;\\n uint256 length = 0;\\n while (temp != 0) {\\n length++;\\n temp >>= 8;\\n }\\n return toHexString(value, length);\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\\n */\\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\\n bytes memory buffer = new bytes(2 * length + 2);\\n buffer[0] = \\\"0\\\";\\n buffer[1] = \\\"x\\\";\\n for (uint256 i = 2 * length + 1; i > 1; --i) {\\n buffer[i] = _HEX_SYMBOLS[value & 0xf];\\n value >>= 4;\\n }\\n require(value == 0, \\\"Strings: hex length insufficient\\\");\\n return string(buffer);\\n }\\n\\n /**\\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\\n */\\n function toHexString(address addr) internal pure returns (string memory) {\\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\\n }\\n}\\n\",\"keccak256\":\"0xaf159a8b1923ad2a26d516089bceca9bdeaeacd04be50983ea00ba63070f08a3\",\"license\":\"MIT\"},\"contracts/DecentHats_0_1_0.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity =0.8.19;\\n\\nimport {Enum} from \\\"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\\\";\\nimport {IAvatar} from \\\"@gnosis.pm/zodiac/contracts/interfaces/IAvatar.sol\\\";\\nimport {Strings} from \\\"@openzeppelin/contracts/utils/Strings.sol\\\";\\nimport {IERC20} from \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\nimport {IERC6551Registry} from \\\"./interfaces/IERC6551Registry.sol\\\";\\nimport {IHats} from \\\"./interfaces/hats/IHats.sol\\\";\\nimport {ISablierV2LockupLinear} from \\\"./interfaces/sablier/ISablierV2LockupLinear.sol\\\";\\nimport {LockupLinear} from \\\"./interfaces/sablier/LockupLinear.sol\\\";\\n\\ncontract DecentHats_0_1_0 {\\n string public constant NAME = \\\"DecentHats_0_1_0\\\";\\n\\n struct SablierStreamParams {\\n ISablierV2LockupLinear sablier;\\n address sender;\\n uint128 totalAmount;\\n address asset;\\n bool cancelable;\\n bool transferable;\\n LockupLinear.Timestamps timestamps;\\n LockupLinear.Broker broker;\\n }\\n\\n struct Hat {\\n uint32 maxSupply;\\n string details;\\n string imageURI;\\n bool isMutable;\\n address wearer;\\n SablierStreamParams[] sablierParams; // Optional Sablier stream parameters\\n }\\n\\n struct CreateTreeParams {\\n IHats hatsProtocol;\\n address hatsAccountImplementation;\\n IERC6551Registry registry;\\n address keyValuePairs;\\n string topHatDetails;\\n string topHatImageURI;\\n Hat adminHat;\\n Hat[] hats;\\n }\\n\\n function getSalt() public pure returns (bytes32 salt) {\\n return\\n 0x5d0e6ce4fd951366cc55da93f6e79d8b81483109d79676a04bcc2bed6a4b5072;\\n }\\n\\n function updateKeyValuePairs(\\n address _keyValuePairs,\\n uint256 topHatId\\n ) internal {\\n string[] memory keys = new string[](1);\\n string[] memory values = new string[](1);\\n keys[0] = \\\"topHatId\\\";\\n values[0] = Strings.toString(topHatId);\\n\\n IAvatar(msg.sender).execTransactionFromModule(\\n _keyValuePairs,\\n 0,\\n abi.encodeWithSignature(\\n \\\"updateValues(string[],string[])\\\",\\n keys,\\n values\\n ),\\n Enum.Operation.Call\\n );\\n }\\n\\n function createHat(\\n IHats _hatsProtocol,\\n uint256 adminHatId,\\n Hat memory _hat,\\n address topHatAccount\\n ) internal returns (uint256) {\\n return\\n _hatsProtocol.createHat(\\n adminHatId,\\n _hat.details,\\n _hat.maxSupply,\\n topHatAccount,\\n topHatAccount,\\n _hat.isMutable,\\n _hat.imageURI\\n );\\n }\\n\\n function createAccount(\\n IERC6551Registry _registry,\\n address _hatsAccountImplementation,\\n bytes32 salt,\\n address protocolAddress,\\n uint256 hatId\\n ) internal returns (address) {\\n return\\n _registry.createAccount(\\n _hatsAccountImplementation,\\n salt,\\n block.chainid,\\n protocolAddress,\\n hatId\\n );\\n }\\n\\n function createTopHatAndAccount(\\n IHats _hatsProtocol,\\n string memory _topHatDetails,\\n string memory _topHatImageURI,\\n IERC6551Registry _registry,\\n address _hatsAccountImplementation,\\n bytes32 salt\\n ) internal returns (uint256 topHatId, address topHatAccount) {\\n topHatId = _hatsProtocol.mintTopHat(\\n address(this),\\n _topHatDetails,\\n _topHatImageURI\\n );\\n\\n topHatAccount = createAccount(\\n _registry,\\n _hatsAccountImplementation,\\n salt,\\n address(_hatsProtocol),\\n topHatId\\n );\\n }\\n\\n function createHatAndAccountAndMintAndStreams(\\n IHats hatsProtocol,\\n uint256 adminHatId,\\n Hat calldata hat,\\n address topHatAccount,\\n IERC6551Registry registry,\\n address hatsAccountImplementation,\\n bytes32 salt\\n ) internal returns (uint256 hatId, address accountAddress) {\\n hatId = createHat(hatsProtocol, adminHatId, hat, topHatAccount);\\n\\n accountAddress = createAccount(\\n registry,\\n hatsAccountImplementation,\\n salt,\\n address(hatsProtocol),\\n hatId\\n );\\n\\n if (hat.wearer != address(0)) {\\n hatsProtocol.mintHat(hatId, hat.wearer);\\n }\\n\\n for (uint256 i = 0; i < hat.sablierParams.length; ) {\\n SablierStreamParams memory sablierParams = hat.sablierParams[i];\\n\\n // Approve tokens for Sablier\\n IAvatar(msg.sender).execTransactionFromModule(\\n sablierParams.asset,\\n 0,\\n abi.encodeWithSignature(\\n \\\"approve(address,uint256)\\\",\\n address(sablierParams.sablier),\\n sablierParams.totalAmount\\n ),\\n Enum.Operation.Call\\n );\\n\\n LockupLinear.CreateWithTimestamps memory params = LockupLinear\\n .CreateWithTimestamps({\\n sender: sablierParams.sender,\\n recipient: accountAddress,\\n totalAmount: sablierParams.totalAmount,\\n asset: IERC20(sablierParams.asset),\\n cancelable: sablierParams.cancelable,\\n transferable: sablierParams.transferable,\\n timestamps: sablierParams.timestamps,\\n broker: sablierParams.broker\\n });\\n\\n // Proxy the Sablier call through IAvatar\\n IAvatar(msg.sender).execTransactionFromModule(\\n address(sablierParams.sablier),\\n 0,\\n abi.encodeWithSignature(\\n \\\"createWithTimestamps((address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256)))\\\",\\n params\\n ),\\n Enum.Operation.Call\\n );\\n\\n unchecked {\\n ++i;\\n }\\n }\\n }\\n\\n function createAndDeclareTree(CreateTreeParams calldata params) public {\\n bytes32 salt = getSalt();\\n\\n (uint256 topHatId, address topHatAccount) = createTopHatAndAccount(\\n params.hatsProtocol,\\n params.topHatDetails,\\n params.topHatImageURI,\\n params.registry,\\n params.hatsAccountImplementation,\\n salt\\n );\\n\\n updateKeyValuePairs(params.keyValuePairs, topHatId);\\n\\n (uint256 adminHatId, ) = createHatAndAccountAndMintAndStreams(\\n params.hatsProtocol,\\n topHatId,\\n params.adminHat,\\n topHatAccount,\\n params.registry,\\n params.hatsAccountImplementation,\\n salt\\n );\\n\\n for (uint256 i = 0; i < params.hats.length; ) {\\n createHatAndAccountAndMintAndStreams(\\n params.hatsProtocol,\\n adminHatId,\\n params.hats[i],\\n topHatAccount,\\n params.registry,\\n params.hatsAccountImplementation,\\n salt\\n );\\n\\n unchecked {\\n ++i;\\n }\\n }\\n\\n params.hatsProtocol.transferHat(topHatId, address(this), msg.sender);\\n }\\n}\\n\",\"keccak256\":\"0xcf4e6d62ca64f62b8eb638805a8a4e715aea8fc201f3dea9a522edc1034599f1\",\"license\":\"MIT\"},\"contracts/interfaces/IERC6551Registry.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.4;\\n\\ninterface IERC6551Registry {\\n /**\\n * @dev Creates a token bound account for a non-fungible token.\\n *\\n * If account has already been created, returns the account address without calling create2.\\n *\\n * Emits ERC6551AccountCreated event.\\n *\\n * @return account The address of the token bound account\\n */\\n function createAccount(\\n address implementation,\\n bytes32 salt,\\n uint256 chainId,\\n address tokenContract,\\n uint256 tokenId\\n ) external returns (address account);\\n}\\n\",\"keccak256\":\"0x64c52de8a8e68398e61dd8b42dda8e9af8cf6abf93bb85629c322440991ea568\",\"license\":\"MIT\"},\"contracts/interfaces/hats/IHats.sol\":{\"content\":\"// SPDX-License-Identifier: AGPL-3.0\\n// Copyright (C) 2023 Haberdasher Labs\\n//\\n// This program is free software: you can redistribute it and/or modify\\n// it under the terms of the GNU Affero General Public License as published by\\n// the Free Software Foundation, either version 3 of the License, or\\n// (at your option) any later version.\\n//\\n// This program is distributed in the hope that it will be useful,\\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\\n// GNU Affero General Public License for more details.\\n//\\n// You should have received a copy of the GNU Affero General Public License\\n// along with this program. If not, see .\\n\\npragma solidity >=0.8.13;\\n\\ninterface IHats {\\n function mintTopHat(\\n address _target,\\n string memory _details,\\n string memory _imageURI\\n ) external returns (uint256 topHatId);\\n\\n function createHat(\\n uint256 _admin,\\n string calldata _details,\\n uint32 _maxSupply,\\n address _eligibility,\\n address _toggle,\\n bool _mutable,\\n string calldata _imageURI\\n ) external returns (uint256 newHatId);\\n\\n function mintHat(\\n uint256 _hatId,\\n address _wearer\\n ) external returns (bool success);\\n\\n function transferHat(uint256 _hatId, address _from, address _to) external;\\n}\\n\",\"keccak256\":\"0x8e35022f5c0fcf0059033abec78ec890f0cf3bbac09d6d24051cff9679239511\",\"license\":\"AGPL-3.0\"},\"contracts/interfaces/sablier/ISablierV2LockupLinear.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport {LockupLinear} from \\\"./LockupLinear.sol\\\";\\nimport {IERC20} from \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\n\\ninterface ISablierV2LockupLinear {\\n function createWithTimestamps(\\n LockupLinear.CreateWithTimestamps calldata params\\n ) external returns (uint256 streamId);\\n}\\n\",\"keccak256\":\"0xf4899637eb2e6c76c35e2d201e56e162a50e6bc7b5b9156e00866f0703ad07ca\",\"license\":\"MIT\"},\"contracts/interfaces/sablier/LockupLinear.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport {IERC20} from \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\n\\nlibrary LockupLinear {\\n struct CreateWithTimestamps {\\n address sender;\\n address recipient;\\n uint128 totalAmount;\\n IERC20 asset;\\n bool cancelable;\\n bool transferable;\\n Timestamps timestamps;\\n Broker broker;\\n }\\n\\n struct Timestamps {\\n uint40 start;\\n uint40 cliff;\\n uint40 end;\\n }\\n\\n struct Broker {\\n address account;\\n uint256 fee;\\n }\\n}\\n\",\"keccak256\":\"0x497fdb52b5e1a5a7e0711a9f7d5fb036eb668ccb92ea908ee088f56ee08a4ce8\",\"license\":\"MIT\"}},\"version\":1}", - "bytecode": "0x608060405234801561001057600080fd5b50611410806100206000396000f3fe608060405234801561001057600080fd5b50600436106100415760003560e01c806313a9589c146100465780638c5f591a14610079578063a3f4df7e1461008e575b600080fd5b6040517f5d0e6ce4fd951366cc55da93f6e79d8b81483109d79676a04bcc2bed6a4b507281526020015b60405180910390f35b61008c610087366004610aa8565b6100ca565b005b6100bd6040518060400160405280601081526020016f0446563656e74486174735f305f315f360841b81525081565b6040516100709190610b30565b7f5d0e6ce4fd951366cc55da93f6e79d8b81483109d79676a04bcc2bed6a4b50726000806101a86100fe6020860186610b5b565b61010b6080870187610b78565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061014d9250505060a0880188610b78565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610192925050506060890160408a01610b5b565b6101a260408a0160208b01610b5b565b88610317565b90925090506101c66101c06080860160608701610b5b565b836103a9565b600061020d6101d86020870187610b5b565b846101e660c0890189610bd5565b856101f760608b0160408c01610b5b565b61020760408c0160208d01610b5b565b8a610529565b50905060005b61022060e0870187610bf5565b905081101561029a576102906102396020880188610b5b565b8361024760e08a018a610bf5565b8581811061025757610257610c3e565b90506020028101906102699190610bd5565b8661027a60608c0160408d01610b5b565b61028a60408d0160208e01610b5b565b8b610529565b5050600101610213565b506102a86020860186610b5b565b6040516329287c1b60e21b8152600481018590523060248201523360448201526001600160a01b03919091169063a4a1f06c90606401600060405180830381600087803b1580156102f857600080fd5b505af115801561030c573d6000803e3d6000fd5b505050505050505050565b600080876001600160a01b0316631a64dfad3089896040518463ffffffff1660e01b815260040161034a93929190610c54565b6020604051808303816000875af1158015610369573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061038d9190610c8a565b915061039c8585858b86610878565b9050965096945050505050565b604080516001808252818301909252600091816020015b60608152602001906001900390816103c057505060408051600180825281830190925291925060009190602082015b60608152602001906001900390816103ef579050509050604051806040016040528060088152602001671d1bdc12185d125960c21b8152508260008151811061043a5761043a610c3e565b602002602001018190525061044e8361090e565b8160008151811061046157610461610c3e565b6020026020010181905250336001600160a01b031663468721a78560008585604051602401610491929190610d11565b60408051601f198184030181529181526020820180516001600160e01b031663579374b960e11b1790525160e085901b6001600160e01b03191681526104df93929190600090600401610d36565b6020604051808303816000875af11580156104fe573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105229190610d9a565b5050505050565b600080610540898961053a8a6110d4565b89610a16565b915061054f8585858c86610878565b9050600061056360a0890160808a01610b5b565b6001600160a01b031614610603576001600160a01b03891663641f776e8361059160a08b0160808c01610b5b565b6040516001600160e01b031960e085901b16815260048101929092526001600160a01b031660248201526044016020604051808303816000875af11580156105dd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106019190610d9a565b505b60005b61061360a0890189611198565b905081101561086b57600061062b60a08a018a611198565b8381811061063b5761063b610c3e565b9050610160020180360381019061065291906111e1565b6060810151815160408084015190516001600160a01b0390921660248301526001600160801b03166044820152919250339163468721a7919060009060640160408051601f198184030181529181526020820180516001600160e01b031663095ea7b360e01b1790525160e085901b6001600160e01b03191681526106df93929190600090600401610d36565b6020604051808303816000875af11580156106fe573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107229190610d9a565b50600060405180610100016040528083602001516001600160a01b03168152602001856001600160a01b0316815260200183604001516001600160801b0316815260200183606001516001600160a01b031681526020018360800151151581526020018360a00151151581526020018360c0015181526020018360e001518152509050336001600160a01b031663468721a783600001516000846040516024016107cc91906111fe565b60408051601f198184030181529181526020820180516001600160e01b03166353b1572760e01b1790525160e085901b6001600160e01b031916815261081a93929190600090600401610d36565b6020604051808303816000875af1158015610839573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061085d9190610d9a565b508260010192505050610606565b5097509795505050505050565b604051638a54c52f60e01b81526001600160a01b0385811660048301526024820185905246604483015283811660648301526084820183905260009190871690638a54c52f9060a4016020604051808303816000875af11580156108e0573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061090491906112c0565b9695505050505050565b6060816000036109355750506040805180820190915260018152600360fc1b602082015290565b8160005b811561095f5780610949816112f3565b91506109589050600a83611322565b9150610939565b6000816001600160401b0381111561097957610979610ca3565b6040519080825280601f01601f1916602001820160405280156109a3576020820181803683370190505b5090505b8415610a0e576109b8600183611336565b91506109c5600a8661134f565b6109d0906030611363565b60f81b8183815181106109e5576109e5610c3e565b60200101906001600160f81b031916908160001a905350610a07600a86611322565b94506109a7565b949350505050565b6020820151825160608401516040808601519051635829492f60e11b81526000946001600160a01b038a169463b052925e94610a5c948b948a9283929091600401611376565b6020604051808303816000875af1158015610a7b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a9f9190610c8a565b95945050505050565b600060208284031215610aba57600080fd5b81356001600160401b03811115610ad057600080fd5b82016101008185031215610ae357600080fd5b9392505050565b6000815180845260005b81811015610b1057602081850181015186830182015201610af4565b506000602082860101526020601f19601f83011685010191505092915050565b602081526000610ae36020830184610aea565b6001600160a01b0381168114610b5857600080fd5b50565b600060208284031215610b6d57600080fd5b8135610ae381610b43565b6000808335601e19843603018112610b8f57600080fd5b8301803591506001600160401b03821115610ba957600080fd5b602001915036819003821315610bbe57600080fd5b9250929050565b8035610bd081610b43565b919050565b6000823560be19833603018112610beb57600080fd5b9190910192915050565b6000808335601e19843603018112610c0c57600080fd5b8301803591506001600160401b03821115610c2657600080fd5b6020019150600581901b3603821315610bbe57600080fd5b634e487b7160e01b600052603260045260246000fd5b6001600160a01b0384168152606060208201819052600090610c7890830185610aea565b82810360408401526109048185610aea565b600060208284031215610c9c57600080fd5b5051919050565b634e487b7160e01b600052604160045260246000fd5b600082825180855260208086019550808260051b84010181860160005b84811015610d0457601f19868403018952610cf2838351610aea565b98840198925090830190600101610cd6565b5090979650505050505050565b604081526000610d246040830185610cb9565b8281036020840152610a9f8185610cb9565b60018060a01b0385168152836020820152608060408201526000610d5d6080830185610aea565b905060028310610d7d57634e487b7160e01b600052602160045260246000fd5b82606083015295945050505050565b8015158114610b5857600080fd5b600060208284031215610dac57600080fd5b8151610ae381610d8c565b60405160c081016001600160401b0381118282101715610dd957610dd9610ca3565b60405290565b604051601f8201601f191681016001600160401b0381118282101715610e0757610e07610ca3565b604052919050565b803563ffffffff81168114610bd057600080fd5b600082601f830112610e3457600080fd5b81356001600160401b03811115610e4d57610e4d610ca3565b610e60601f8201601f1916602001610ddf565b818152846020838601011115610e7557600080fd5b816020850160208301376000918101602001919091529392505050565b8035610bd081610d8c565b80356001600160801b0381168114610bd057600080fd5b803564ffffffffff81168114610bd057600080fd5b600060608284031215610edb57600080fd5b604051606081018181106001600160401b0382111715610efd57610efd610ca3565b604052905080610f0c83610eb4565b8152610f1a60208401610eb4565b6020820152610f2b60408401610eb4565b60408201525092915050565b600060408284031215610f4957600080fd5b604051604081018181106001600160401b0382111715610f6b57610f6b610ca3565b6040529050808235610f7c81610b43565b8152602092830135920191909152919050565b60006101608284031215610fa257600080fd5b60405161010081018181106001600160401b0382111715610fc557610fc5610ca3565b604052905080610fd483610bc5565b8152610fe260208401610bc5565b6020820152610ff360408401610e9d565b604082015261100460608401610bc5565b606082015261101560808401610e92565b608082015261102660a08401610e92565b60a08201526110388460c08501610ec9565b60c082015261104b846101208501610f37565b60e08201525092915050565b600082601f83011261106857600080fd5b813560206001600160401b0382111561108357611083610ca3565b611091818360051b01610ddf565b82815261016092830285018201928282019190878511156110b157600080fd5b8387015b85811015610d04576110c78982610f8f565b84529284019281016110b5565b600060c082360312156110e657600080fd5b6110ee610db7565b6110f783610e0f565b815260208301356001600160401b038082111561111357600080fd5b61111f36838701610e23565b6020840152604085013591508082111561113857600080fd5b61114436838701610e23565b604084015261115560608601610e92565b606084015261116660808601610bc5565b608084015260a085013591508082111561117f57600080fd5b5061118c36828601611057565b60a08301525092915050565b6000808335601e198436030181126111af57600080fd5b8301803591506001600160401b038211156111c957600080fd5b602001915061016081023603821315610bbe57600080fd5b600061016082840312156111f457600080fd5b610ae38383610f8f565b81516001600160a01b0390811682526020808401518216908301526040808401516001600160801b031690830152606080840151909116908201526080808301516101608301916112529084018215159052565b5060a083015161126660a084018215159052565b5060c083015161129960c0840182805164ffffffffff908116835260208083015182169084015260409182015116910152565b5060e0929092015180516001600160a01b0316610120830152602001516101409091015290565b6000602082840312156112d257600080fd5b8151610ae381610b43565b634e487b7160e01b600052601160045260246000fd5b600060018201611305576113056112dd565b5060010190565b634e487b7160e01b600052601260045260246000fd5b6000826113315761133161130c565b500490565b81810381811115611349576113496112dd565b92915050565b60008261135e5761135e61130c565b500690565b80820180821115611349576113496112dd565b87815260e06020820152600061138f60e0830189610aea565b63ffffffff881660408401526001600160a01b0387811660608501528616608084015284151560a084015282810360c08401526113cc8185610aea565b9a995050505050505050505056fea2646970667358221220fcb8ad75991fd171fd33998d718d5f54883d99a48d56657e7e938e34a55d6a2664736f6c63430008130033", - "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100415760003560e01c806313a9589c146100465780638c5f591a14610079578063a3f4df7e1461008e575b600080fd5b6040517f5d0e6ce4fd951366cc55da93f6e79d8b81483109d79676a04bcc2bed6a4b507281526020015b60405180910390f35b61008c610087366004610aa8565b6100ca565b005b6100bd6040518060400160405280601081526020016f0446563656e74486174735f305f315f360841b81525081565b6040516100709190610b30565b7f5d0e6ce4fd951366cc55da93f6e79d8b81483109d79676a04bcc2bed6a4b50726000806101a86100fe6020860186610b5b565b61010b6080870187610b78565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061014d9250505060a0880188610b78565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610192925050506060890160408a01610b5b565b6101a260408a0160208b01610b5b565b88610317565b90925090506101c66101c06080860160608701610b5b565b836103a9565b600061020d6101d86020870187610b5b565b846101e660c0890189610bd5565b856101f760608b0160408c01610b5b565b61020760408c0160208d01610b5b565b8a610529565b50905060005b61022060e0870187610bf5565b905081101561029a576102906102396020880188610b5b565b8361024760e08a018a610bf5565b8581811061025757610257610c3e565b90506020028101906102699190610bd5565b8661027a60608c0160408d01610b5b565b61028a60408d0160208e01610b5b565b8b610529565b5050600101610213565b506102a86020860186610b5b565b6040516329287c1b60e21b8152600481018590523060248201523360448201526001600160a01b03919091169063a4a1f06c90606401600060405180830381600087803b1580156102f857600080fd5b505af115801561030c573d6000803e3d6000fd5b505050505050505050565b600080876001600160a01b0316631a64dfad3089896040518463ffffffff1660e01b815260040161034a93929190610c54565b6020604051808303816000875af1158015610369573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061038d9190610c8a565b915061039c8585858b86610878565b9050965096945050505050565b604080516001808252818301909252600091816020015b60608152602001906001900390816103c057505060408051600180825281830190925291925060009190602082015b60608152602001906001900390816103ef579050509050604051806040016040528060088152602001671d1bdc12185d125960c21b8152508260008151811061043a5761043a610c3e565b602002602001018190525061044e8361090e565b8160008151811061046157610461610c3e565b6020026020010181905250336001600160a01b031663468721a78560008585604051602401610491929190610d11565b60408051601f198184030181529181526020820180516001600160e01b031663579374b960e11b1790525160e085901b6001600160e01b03191681526104df93929190600090600401610d36565b6020604051808303816000875af11580156104fe573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105229190610d9a565b5050505050565b600080610540898961053a8a6110d4565b89610a16565b915061054f8585858c86610878565b9050600061056360a0890160808a01610b5b565b6001600160a01b031614610603576001600160a01b03891663641f776e8361059160a08b0160808c01610b5b565b6040516001600160e01b031960e085901b16815260048101929092526001600160a01b031660248201526044016020604051808303816000875af11580156105dd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106019190610d9a565b505b60005b61061360a0890189611198565b905081101561086b57600061062b60a08a018a611198565b8381811061063b5761063b610c3e565b9050610160020180360381019061065291906111e1565b6060810151815160408084015190516001600160a01b0390921660248301526001600160801b03166044820152919250339163468721a7919060009060640160408051601f198184030181529181526020820180516001600160e01b031663095ea7b360e01b1790525160e085901b6001600160e01b03191681526106df93929190600090600401610d36565b6020604051808303816000875af11580156106fe573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107229190610d9a565b50600060405180610100016040528083602001516001600160a01b03168152602001856001600160a01b0316815260200183604001516001600160801b0316815260200183606001516001600160a01b031681526020018360800151151581526020018360a00151151581526020018360c0015181526020018360e001518152509050336001600160a01b031663468721a783600001516000846040516024016107cc91906111fe565b60408051601f198184030181529181526020820180516001600160e01b03166353b1572760e01b1790525160e085901b6001600160e01b031916815261081a93929190600090600401610d36565b6020604051808303816000875af1158015610839573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061085d9190610d9a565b508260010192505050610606565b5097509795505050505050565b604051638a54c52f60e01b81526001600160a01b0385811660048301526024820185905246604483015283811660648301526084820183905260009190871690638a54c52f9060a4016020604051808303816000875af11580156108e0573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061090491906112c0565b9695505050505050565b6060816000036109355750506040805180820190915260018152600360fc1b602082015290565b8160005b811561095f5780610949816112f3565b91506109589050600a83611322565b9150610939565b6000816001600160401b0381111561097957610979610ca3565b6040519080825280601f01601f1916602001820160405280156109a3576020820181803683370190505b5090505b8415610a0e576109b8600183611336565b91506109c5600a8661134f565b6109d0906030611363565b60f81b8183815181106109e5576109e5610c3e565b60200101906001600160f81b031916908160001a905350610a07600a86611322565b94506109a7565b949350505050565b6020820151825160608401516040808601519051635829492f60e11b81526000946001600160a01b038a169463b052925e94610a5c948b948a9283929091600401611376565b6020604051808303816000875af1158015610a7b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a9f9190610c8a565b95945050505050565b600060208284031215610aba57600080fd5b81356001600160401b03811115610ad057600080fd5b82016101008185031215610ae357600080fd5b9392505050565b6000815180845260005b81811015610b1057602081850181015186830182015201610af4565b506000602082860101526020601f19601f83011685010191505092915050565b602081526000610ae36020830184610aea565b6001600160a01b0381168114610b5857600080fd5b50565b600060208284031215610b6d57600080fd5b8135610ae381610b43565b6000808335601e19843603018112610b8f57600080fd5b8301803591506001600160401b03821115610ba957600080fd5b602001915036819003821315610bbe57600080fd5b9250929050565b8035610bd081610b43565b919050565b6000823560be19833603018112610beb57600080fd5b9190910192915050565b6000808335601e19843603018112610c0c57600080fd5b8301803591506001600160401b03821115610c2657600080fd5b6020019150600581901b3603821315610bbe57600080fd5b634e487b7160e01b600052603260045260246000fd5b6001600160a01b0384168152606060208201819052600090610c7890830185610aea565b82810360408401526109048185610aea565b600060208284031215610c9c57600080fd5b5051919050565b634e487b7160e01b600052604160045260246000fd5b600082825180855260208086019550808260051b84010181860160005b84811015610d0457601f19868403018952610cf2838351610aea565b98840198925090830190600101610cd6565b5090979650505050505050565b604081526000610d246040830185610cb9565b8281036020840152610a9f8185610cb9565b60018060a01b0385168152836020820152608060408201526000610d5d6080830185610aea565b905060028310610d7d57634e487b7160e01b600052602160045260246000fd5b82606083015295945050505050565b8015158114610b5857600080fd5b600060208284031215610dac57600080fd5b8151610ae381610d8c565b60405160c081016001600160401b0381118282101715610dd957610dd9610ca3565b60405290565b604051601f8201601f191681016001600160401b0381118282101715610e0757610e07610ca3565b604052919050565b803563ffffffff81168114610bd057600080fd5b600082601f830112610e3457600080fd5b81356001600160401b03811115610e4d57610e4d610ca3565b610e60601f8201601f1916602001610ddf565b818152846020838601011115610e7557600080fd5b816020850160208301376000918101602001919091529392505050565b8035610bd081610d8c565b80356001600160801b0381168114610bd057600080fd5b803564ffffffffff81168114610bd057600080fd5b600060608284031215610edb57600080fd5b604051606081018181106001600160401b0382111715610efd57610efd610ca3565b604052905080610f0c83610eb4565b8152610f1a60208401610eb4565b6020820152610f2b60408401610eb4565b60408201525092915050565b600060408284031215610f4957600080fd5b604051604081018181106001600160401b0382111715610f6b57610f6b610ca3565b6040529050808235610f7c81610b43565b8152602092830135920191909152919050565b60006101608284031215610fa257600080fd5b60405161010081018181106001600160401b0382111715610fc557610fc5610ca3565b604052905080610fd483610bc5565b8152610fe260208401610bc5565b6020820152610ff360408401610e9d565b604082015261100460608401610bc5565b606082015261101560808401610e92565b608082015261102660a08401610e92565b60a08201526110388460c08501610ec9565b60c082015261104b846101208501610f37565b60e08201525092915050565b600082601f83011261106857600080fd5b813560206001600160401b0382111561108357611083610ca3565b611091818360051b01610ddf565b82815261016092830285018201928282019190878511156110b157600080fd5b8387015b85811015610d04576110c78982610f8f565b84529284019281016110b5565b600060c082360312156110e657600080fd5b6110ee610db7565b6110f783610e0f565b815260208301356001600160401b038082111561111357600080fd5b61111f36838701610e23565b6020840152604085013591508082111561113857600080fd5b61114436838701610e23565b604084015261115560608601610e92565b606084015261116660808601610bc5565b608084015260a085013591508082111561117f57600080fd5b5061118c36828601611057565b60a08301525092915050565b6000808335601e198436030181126111af57600080fd5b8301803591506001600160401b038211156111c957600080fd5b602001915061016081023603821315610bbe57600080fd5b600061016082840312156111f457600080fd5b610ae38383610f8f565b81516001600160a01b0390811682526020808401518216908301526040808401516001600160801b031690830152606080840151909116908201526080808301516101608301916112529084018215159052565b5060a083015161126660a084018215159052565b5060c083015161129960c0840182805164ffffffffff908116835260208083015182169084015260409182015116910152565b5060e0929092015180516001600160a01b0316610120830152602001516101409091015290565b6000602082840312156112d257600080fd5b8151610ae381610b43565b634e487b7160e01b600052601160045260246000fd5b600060018201611305576113056112dd565b5060010190565b634e487b7160e01b600052601260045260246000fd5b6000826113315761133161130c565b500490565b81810381811115611349576113496112dd565b92915050565b60008261135e5761135e61130c565b500690565b80820180821115611349576113496112dd565b87815260e06020820152600061138f60e0830189610aea565b63ffffffff881660408401526001600160a01b0387811660608501528616608084015284151560a084015282810360c08401526113cc8185610aea565b9a995050505050505050505056fea2646970667358221220fcb8ad75991fd171fd33998d718d5f54883d99a48d56657e7e938e34a55d6a2664736f6c63430008130033", + "numDeployments": 4, + "solcInputHash": "4754a2f0c9d6a191a066af246491b62a", + "metadata": "{\"compiler\":{\"version\":\"0.8.19+commit.7dd6d404\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"NAME\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"contract IHats\",\"name\":\"hatsProtocol\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"hatsAccountImplementation\",\"type\":\"address\"},{\"internalType\":\"contract IERC6551Registry\",\"name\":\"registry\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"keyValuePairs\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"topHatDetails\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"topHatImageURI\",\"type\":\"string\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"maxSupply\",\"type\":\"uint32\"},{\"internalType\":\"string\",\"name\":\"details\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"imageURI\",\"type\":\"string\"},{\"internalType\":\"bool\",\"name\":\"isMutable\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"wearer\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"contract ISablierV2LockupLinear\",\"name\":\"sablier\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint128\",\"name\":\"totalAmount\",\"type\":\"uint128\"},{\"internalType\":\"address\",\"name\":\"asset\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"cancelable\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"transferable\",\"type\":\"bool\"},{\"components\":[{\"internalType\":\"uint40\",\"name\":\"start\",\"type\":\"uint40\"},{\"internalType\":\"uint40\",\"name\":\"cliff\",\"type\":\"uint40\"},{\"internalType\":\"uint40\",\"name\":\"end\",\"type\":\"uint40\"}],\"internalType\":\"struct LockupLinear.Timestamps\",\"name\":\"timestamps\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"fee\",\"type\":\"uint256\"}],\"internalType\":\"struct LockupLinear.Broker\",\"name\":\"broker\",\"type\":\"tuple\"}],\"internalType\":\"struct DecentHats_0_1_0.SablierStreamParams[]\",\"name\":\"sablierParams\",\"type\":\"tuple[]\"}],\"internalType\":\"struct DecentHats_0_1_0.Hat\",\"name\":\"adminHat\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"maxSupply\",\"type\":\"uint32\"},{\"internalType\":\"string\",\"name\":\"details\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"imageURI\",\"type\":\"string\"},{\"internalType\":\"bool\",\"name\":\"isMutable\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"wearer\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"contract ISablierV2LockupLinear\",\"name\":\"sablier\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint128\",\"name\":\"totalAmount\",\"type\":\"uint128\"},{\"internalType\":\"address\",\"name\":\"asset\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"cancelable\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"transferable\",\"type\":\"bool\"},{\"components\":[{\"internalType\":\"uint40\",\"name\":\"start\",\"type\":\"uint40\"},{\"internalType\":\"uint40\",\"name\":\"cliff\",\"type\":\"uint40\"},{\"internalType\":\"uint40\",\"name\":\"end\",\"type\":\"uint40\"}],\"internalType\":\"struct LockupLinear.Timestamps\",\"name\":\"timestamps\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"fee\",\"type\":\"uint256\"}],\"internalType\":\"struct LockupLinear.Broker\",\"name\":\"broker\",\"type\":\"tuple\"}],\"internalType\":\"struct DecentHats_0_1_0.SablierStreamParams[]\",\"name\":\"sablierParams\",\"type\":\"tuple[]\"}],\"internalType\":\"struct DecentHats_0_1_0.Hat[]\",\"name\":\"hats\",\"type\":\"tuple[]\"}],\"internalType\":\"struct DecentHats_0_1_0.CreateTreeParams\",\"name\":\"params\",\"type\":\"tuple\"}],\"name\":\"createAndDeclareTree\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract IHats\",\"name\":\"hatsProtocol\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"adminHatId\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"maxSupply\",\"type\":\"uint32\"},{\"internalType\":\"string\",\"name\":\"details\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"imageURI\",\"type\":\"string\"},{\"internalType\":\"bool\",\"name\":\"isMutable\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"wearer\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"contract ISablierV2LockupLinear\",\"name\":\"sablier\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint128\",\"name\":\"totalAmount\",\"type\":\"uint128\"},{\"internalType\":\"address\",\"name\":\"asset\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"cancelable\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"transferable\",\"type\":\"bool\"},{\"components\":[{\"internalType\":\"uint40\",\"name\":\"start\",\"type\":\"uint40\"},{\"internalType\":\"uint40\",\"name\":\"cliff\",\"type\":\"uint40\"},{\"internalType\":\"uint40\",\"name\":\"end\",\"type\":\"uint40\"}],\"internalType\":\"struct LockupLinear.Timestamps\",\"name\":\"timestamps\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"fee\",\"type\":\"uint256\"}],\"internalType\":\"struct LockupLinear.Broker\",\"name\":\"broker\",\"type\":\"tuple\"}],\"internalType\":\"struct DecentHats_0_1_0.SablierStreamParams[]\",\"name\":\"sablierParams\",\"type\":\"tuple[]\"}],\"internalType\":\"struct DecentHats_0_1_0.Hat\",\"name\":\"hat\",\"type\":\"tuple\"},{\"internalType\":\"uint256\",\"name\":\"topHatId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"topHatAccount\",\"type\":\"address\"},{\"internalType\":\"contract IERC6551Registry\",\"name\":\"registry\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"hatsAccountImplementation\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"salt\",\"type\":\"bytes32\"}],\"name\":\"createRoleHat\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"hatId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"accountAddress\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getSalt\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"salt\",\"type\":\"bytes32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"createAndDeclareTree((address,address,address,address,string,string,(uint32,string,string,bool,address,(address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256))[]),(uint32,string,string,bool,address,(address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256))[])[]))\":{\"details\":\"In order for a Safe to seamlessly create roles even if it has never previously created a role and thus has no hat tree, we defer the creation of the hat tree and its setup to this contract. This way, in a single tx block, the resulting topHatId of the newly created hat can be used to create an admin hat and any other hats needed. We also make use of `KeyValuePairs` to associate the topHatId with the Safe.\"},\"createRoleHat(address,uint256,(uint32,string,string,bool,address,(address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256))[]),uint256,address,address,address,bytes32)\":{\"details\":\"Role hat creation, minting, smart account creation and stream creation are handled here in order to avoid a race condition where not more than one active proposal to create a new role can exist at a time. See: https://github.com/decentdao/decent-interface/issues/2402\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"createAndDeclareTree((address,address,address,address,string,string,(uint32,string,string,bool,address,(address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256))[]),(uint32,string,string,bool,address,(address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256))[])[]))\":{\"notice\":\"For a safe without any roles previously created on it, this function should be called. It sets up the top hat and admin hat, as well as any other hats and their streams that are provided. This contract should be enabled a module on the Safe for which the role(s) are to be created, and disabled after.\"},\"createRoleHat(address,uint256,(uint32,string,string,bool,address,(address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256))[]),uint256,address,address,address,bytes32)\":{\"notice\":\"Creates a new role hat and any streams on it. This contract should be enabled a module on the Safe for which the role is to be created, and disable after. In order for the module to be able to create hats on behalf of the Safe, the Safe must first transfer its top hat to this contract. This function transfers the top hat back to the Safe after creating the role hat. The function simply calls `createHatAndAccountAndMintAndStreams` and then transfers the top hat back to the Safe.\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/DecentHats_0_1_0.sol\":\"DecentHats_0_1_0\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\":{\"content\":\"// SPDX-License-Identifier: LGPL-3.0-only\\npragma solidity >=0.7.0 <0.9.0;\\n\\n/// @title Enum - Collection of enums\\n/// @author Richard Meissner - \\ncontract Enum {\\n enum Operation {Call, DelegateCall}\\n}\\n\",\"keccak256\":\"0x473e45b1a5cc47be494b0e123c9127f0c11c1e0992a321ae5a644c0bfdb2c14f\",\"license\":\"LGPL-3.0-only\"},\"@gnosis.pm/zodiac/contracts/interfaces/IAvatar.sol\":{\"content\":\"// SPDX-License-Identifier: LGPL-3.0-only\\n\\n/// @title Zodiac Avatar - A contract that manages modules that can execute transactions via this contract.\\npragma solidity >=0.7.0 <0.9.0;\\n\\nimport \\\"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\\\";\\n\\ninterface IAvatar {\\n event EnabledModule(address module);\\n event DisabledModule(address module);\\n event ExecutionFromModuleSuccess(address indexed module);\\n event ExecutionFromModuleFailure(address indexed module);\\n\\n /// @dev Enables a module on the avatar.\\n /// @notice Can only be called by the avatar.\\n /// @notice Modules should be stored as a linked list.\\n /// @notice Must emit EnabledModule(address module) if successful.\\n /// @param module Module to be enabled.\\n function enableModule(address module) external;\\n\\n /// @dev Disables a module on the avatar.\\n /// @notice Can only be called by the avatar.\\n /// @notice Must emit DisabledModule(address module) if successful.\\n /// @param prevModule Address that pointed to the module to be removed in the linked list\\n /// @param module Module to be removed.\\n function disableModule(address prevModule, address module) external;\\n\\n /// @dev Allows a Module to execute a transaction.\\n /// @notice Can only be called by an enabled module.\\n /// @notice Must emit ExecutionFromModuleSuccess(address module) if successful.\\n /// @notice Must emit ExecutionFromModuleFailure(address module) if unsuccessful.\\n /// @param to Destination address of module transaction.\\n /// @param value Ether value of module transaction.\\n /// @param data Data payload of module transaction.\\n /// @param operation Operation type of module transaction: 0 == call, 1 == delegate call.\\n function execTransactionFromModule(\\n address to,\\n uint256 value,\\n bytes memory data,\\n Enum.Operation operation\\n ) external returns (bool success);\\n\\n /// @dev Allows a Module to execute a transaction and return data\\n /// @notice Can only be called by an enabled module.\\n /// @notice Must emit ExecutionFromModuleSuccess(address module) if successful.\\n /// @notice Must emit ExecutionFromModuleFailure(address module) if unsuccessful.\\n /// @param to Destination address of module transaction.\\n /// @param value Ether value of module transaction.\\n /// @param data Data payload of module transaction.\\n /// @param operation Operation type of module transaction: 0 == call, 1 == delegate call.\\n function execTransactionFromModuleReturnData(\\n address to,\\n uint256 value,\\n bytes memory data,\\n Enum.Operation operation\\n ) external returns (bool success, bytes memory returnData);\\n\\n /// @dev Returns if an module is enabled\\n /// @return True if the module is enabled\\n function isModuleEnabled(address module) external view returns (bool);\\n\\n /// @dev Returns array of modules.\\n /// @param start Start of the page.\\n /// @param pageSize Maximum number of modules that should be returned.\\n /// @return array Array of modules.\\n /// @return next Start of the next page.\\n function getModulesPaginated(address start, uint256 pageSize)\\n external\\n view\\n returns (address[] memory array, address next);\\n}\\n\",\"keccak256\":\"0xcd5508ffe596eef8fbccfd5fc4f10a34397773547ce64e212d48b5212865ec1f\",\"license\":\"LGPL-3.0-only\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20 {\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `to`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address to, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `from` to `to` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(\\n address from,\\n address to,\\n uint256 amount\\n ) external returns (bool);\\n}\\n\",\"keccak256\":\"0x9750c6b834f7b43000631af5cc30001c5f547b3ceb3635488f140f60e897ea6b\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Strings.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev String operations.\\n */\\nlibrary Strings {\\n bytes16 private constant _HEX_SYMBOLS = \\\"0123456789abcdef\\\";\\n uint8 private constant _ADDRESS_LENGTH = 20;\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\\n */\\n function toString(uint256 value) internal pure returns (string memory) {\\n // Inspired by OraclizeAPI's implementation - MIT licence\\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\\n\\n if (value == 0) {\\n return \\\"0\\\";\\n }\\n uint256 temp = value;\\n uint256 digits;\\n while (temp != 0) {\\n digits++;\\n temp /= 10;\\n }\\n bytes memory buffer = new bytes(digits);\\n while (value != 0) {\\n digits -= 1;\\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\\n value /= 10;\\n }\\n return string(buffer);\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\\n */\\n function toHexString(uint256 value) internal pure returns (string memory) {\\n if (value == 0) {\\n return \\\"0x00\\\";\\n }\\n uint256 temp = value;\\n uint256 length = 0;\\n while (temp != 0) {\\n length++;\\n temp >>= 8;\\n }\\n return toHexString(value, length);\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\\n */\\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\\n bytes memory buffer = new bytes(2 * length + 2);\\n buffer[0] = \\\"0\\\";\\n buffer[1] = \\\"x\\\";\\n for (uint256 i = 2 * length + 1; i > 1; --i) {\\n buffer[i] = _HEX_SYMBOLS[value & 0xf];\\n value >>= 4;\\n }\\n require(value == 0, \\\"Strings: hex length insufficient\\\");\\n return string(buffer);\\n }\\n\\n /**\\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\\n */\\n function toHexString(address addr) internal pure returns (string memory) {\\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\\n }\\n}\\n\",\"keccak256\":\"0xaf159a8b1923ad2a26d516089bceca9bdeaeacd04be50983ea00ba63070f08a3\",\"license\":\"MIT\"},\"contracts/DecentHats_0_1_0.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity =0.8.19;\\n\\nimport {Enum} from \\\"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\\\";\\nimport {IAvatar} from \\\"@gnosis.pm/zodiac/contracts/interfaces/IAvatar.sol\\\";\\nimport {Strings} from \\\"@openzeppelin/contracts/utils/Strings.sol\\\";\\nimport {IERC20} from \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\nimport {IERC6551Registry} from \\\"./interfaces/IERC6551Registry.sol\\\";\\nimport {IHats} from \\\"./interfaces/hats/IHats.sol\\\";\\nimport {ISablierV2LockupLinear} from \\\"./interfaces/sablier/ISablierV2LockupLinear.sol\\\";\\nimport {LockupLinear} from \\\"./interfaces/sablier/LockupLinear.sol\\\";\\n\\ncontract DecentHats_0_1_0 {\\n string public constant NAME = \\\"DecentHats_0_1_0\\\";\\n\\n struct SablierStreamParams {\\n ISablierV2LockupLinear sablier;\\n address sender;\\n uint128 totalAmount;\\n address asset;\\n bool cancelable;\\n bool transferable;\\n LockupLinear.Timestamps timestamps;\\n LockupLinear.Broker broker;\\n }\\n\\n struct Hat {\\n uint32 maxSupply;\\n string details;\\n string imageURI;\\n bool isMutable;\\n address wearer;\\n SablierStreamParams[] sablierParams; // Optional Sablier stream parameters\\n }\\n\\n struct CreateTreeParams {\\n IHats hatsProtocol;\\n address hatsAccountImplementation;\\n IERC6551Registry registry;\\n address keyValuePairs;\\n string topHatDetails;\\n string topHatImageURI;\\n Hat adminHat;\\n Hat[] hats;\\n }\\n\\n function getSalt() public pure returns (bytes32 salt) {\\n return\\n 0x5d0e6ce4fd951366cc55da93f6e79d8b81483109d79676a04bcc2bed6a4b5072;\\n }\\n\\n function declareSafeHatTree(\\n address _keyValuePairs,\\n uint256 topHatId\\n ) internal {\\n string[] memory keys = new string[](1);\\n string[] memory values = new string[](1);\\n keys[0] = \\\"topHatId\\\";\\n values[0] = Strings.toString(topHatId);\\n\\n IAvatar(msg.sender).execTransactionFromModule(\\n _keyValuePairs,\\n 0,\\n abi.encodeWithSignature(\\n \\\"updateValues(string[],string[])\\\",\\n keys,\\n values\\n ),\\n Enum.Operation.Call\\n );\\n }\\n\\n function createHat(\\n IHats _hatsProtocol,\\n uint256 adminHatId,\\n Hat memory _hat,\\n address topHatAccount\\n ) internal returns (uint256) {\\n return\\n _hatsProtocol.createHat(\\n adminHatId,\\n _hat.details,\\n _hat.maxSupply,\\n topHatAccount,\\n topHatAccount,\\n _hat.isMutable,\\n _hat.imageURI\\n );\\n }\\n\\n function createAccount(\\n IERC6551Registry _registry,\\n address _hatsAccountImplementation,\\n bytes32 salt,\\n address protocolAddress,\\n uint256 hatId\\n ) internal returns (address) {\\n return\\n _registry.createAccount(\\n _hatsAccountImplementation,\\n salt,\\n block.chainid,\\n protocolAddress,\\n hatId\\n );\\n }\\n\\n function createTopHatAndAccount(\\n IHats _hatsProtocol,\\n string memory _topHatDetails,\\n string memory _topHatImageURI,\\n IERC6551Registry _registry,\\n address _hatsAccountImplementation,\\n bytes32 salt\\n ) internal returns (uint256 topHatId, address topHatAccount) {\\n topHatId = _hatsProtocol.mintTopHat(\\n address(this),\\n _topHatDetails,\\n _topHatImageURI\\n );\\n\\n topHatAccount = createAccount(\\n _registry,\\n _hatsAccountImplementation,\\n salt,\\n address(_hatsProtocol),\\n topHatId\\n );\\n }\\n\\n function createHatAndAccountAndMintAndStreams(\\n IHats hatsProtocol,\\n uint256 adminHatId,\\n Hat calldata hat,\\n address topHatAccount,\\n IERC6551Registry registry,\\n address hatsAccountImplementation,\\n bytes32 salt\\n ) internal returns (uint256 hatId, address accountAddress) {\\n hatId = createHat(hatsProtocol, adminHatId, hat, topHatAccount);\\n\\n accountAddress = createAccount(\\n registry,\\n hatsAccountImplementation,\\n salt,\\n address(hatsProtocol),\\n hatId\\n );\\n\\n if (hat.wearer != address(0)) {\\n hatsProtocol.mintHat(hatId, hat.wearer);\\n }\\n\\n for (uint256 i = 0; i < hat.sablierParams.length; ) {\\n SablierStreamParams memory sablierParams = hat.sablierParams[i];\\n\\n // Approve tokens for Sablier\\n IAvatar(msg.sender).execTransactionFromModule(\\n sablierParams.asset,\\n 0,\\n abi.encodeWithSignature(\\n \\\"approve(address,uint256)\\\",\\n address(sablierParams.sablier),\\n sablierParams.totalAmount\\n ),\\n Enum.Operation.Call\\n );\\n\\n LockupLinear.CreateWithTimestamps memory params = LockupLinear\\n .CreateWithTimestamps({\\n sender: sablierParams.sender,\\n recipient: accountAddress,\\n totalAmount: sablierParams.totalAmount,\\n asset: IERC20(sablierParams.asset),\\n cancelable: sablierParams.cancelable,\\n transferable: sablierParams.transferable,\\n timestamps: sablierParams.timestamps,\\n broker: sablierParams.broker\\n });\\n\\n // Proxy the Sablier call through IAvatar\\n IAvatar(msg.sender).execTransactionFromModule(\\n address(sablierParams.sablier),\\n 0,\\n abi.encodeWithSignature(\\n \\\"createWithTimestamps((address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256)))\\\",\\n params\\n ),\\n Enum.Operation.Call\\n );\\n\\n unchecked {\\n ++i;\\n }\\n }\\n }\\n\\n /**\\n * Creates a new role hat and any streams on it.\\n *\\n * This contract should be enabled a module on the Safe for which the role is to be created, and disable after.\\n * In order for the module to be able to create hats on behalf of the Safe, the Safe must first\\n * transfer its top hat to this contract. This function transfers the top hat back to the Safe after\\n * creating the role hat.\\n *\\n * The function simply calls `createHatAndAccountAndMintAndStreams` and then transfers the top hat back to the Safe.\\n *\\n * @dev Role hat creation, minting, smart account creation and stream creation are handled here in order\\n * to avoid a race condition where not more than one active proposal to create a new role can exist at a time.\\n * See: https://github.com/decentdao/decent-interface/issues/2402\\n */\\n function createRoleHat(\\n IHats hatsProtocol,\\n uint256 adminHatId,\\n Hat calldata hat,\\n uint256 topHatId,\\n address topHatAccount,\\n IERC6551Registry registry,\\n address hatsAccountImplementation,\\n bytes32 salt\\n ) public returns (uint256 hatId, address accountAddress) {\\n (hatId, accountAddress) = createHatAndAccountAndMintAndStreams(\\n hatsProtocol,\\n adminHatId,\\n hat,\\n topHatAccount,\\n registry,\\n hatsAccountImplementation,\\n salt\\n );\\n\\n hatsProtocol.transferHat(topHatId, address(this), msg.sender);\\n }\\n\\n /**\\n * For a safe without any roles previously created on it, this function should be called. It sets up the\\n * top hat and admin hat, as well as any other hats and their streams that are provided.\\n *\\n * This contract should be enabled a module on the Safe for which the role(s) are to be created, and disabled after.\\n *\\n * @dev In order for a Safe to seamlessly create roles even if it has never previously created a role and thus has\\n * no hat tree, we defer the creation of the hat tree and its setup to this contract. This way, in a single tx block,\\n * the resulting topHatId of the newly created hat can be used to create an admin hat and any other hats needed.\\n * We also make use of `KeyValuePairs` to associate the topHatId with the Safe.\\n */\\n function createAndDeclareTree(CreateTreeParams calldata params) public {\\n bytes32 salt = getSalt();\\n\\n (uint256 topHatId, address topHatAccount) = createTopHatAndAccount(\\n params.hatsProtocol,\\n params.topHatDetails,\\n params.topHatImageURI,\\n params.registry,\\n params.hatsAccountImplementation,\\n salt\\n );\\n\\n declareSafeHatTree(params.keyValuePairs, topHatId);\\n\\n (uint256 adminHatId, ) = createHatAndAccountAndMintAndStreams(\\n params.hatsProtocol,\\n topHatId,\\n params.adminHat,\\n topHatAccount,\\n params.registry,\\n params.hatsAccountImplementation,\\n salt\\n );\\n\\n for (uint256 i = 0; i < params.hats.length; ) {\\n createHatAndAccountAndMintAndStreams(\\n params.hatsProtocol,\\n adminHatId,\\n params.hats[i],\\n topHatAccount,\\n params.registry,\\n params.hatsAccountImplementation,\\n salt\\n );\\n\\n unchecked {\\n ++i;\\n }\\n }\\n\\n params.hatsProtocol.transferHat(topHatId, address(this), msg.sender);\\n }\\n}\\n\",\"keccak256\":\"0x1886fc2edf8c34e58f6a95d33139d7513aa4b581a2c323af6394485752137e20\",\"license\":\"MIT\"},\"contracts/interfaces/IERC6551Registry.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.4;\\n\\ninterface IERC6551Registry {\\n /**\\n * @dev Creates a token bound account for a non-fungible token.\\n *\\n * If account has already been created, returns the account address without calling create2.\\n *\\n * Emits ERC6551AccountCreated event.\\n *\\n * @return account The address of the token bound account\\n */\\n function createAccount(\\n address implementation,\\n bytes32 salt,\\n uint256 chainId,\\n address tokenContract,\\n uint256 tokenId\\n ) external returns (address account);\\n}\\n\",\"keccak256\":\"0x64c52de8a8e68398e61dd8b42dda8e9af8cf6abf93bb85629c322440991ea568\",\"license\":\"MIT\"},\"contracts/interfaces/hats/IHats.sol\":{\"content\":\"// SPDX-License-Identifier: AGPL-3.0\\n// Copyright (C) 2023 Haberdasher Labs\\n//\\n// This program is free software: you can redistribute it and/or modify\\n// it under the terms of the GNU Affero General Public License as published by\\n// the Free Software Foundation, either version 3 of the License, or\\n// (at your option) any later version.\\n//\\n// This program is distributed in the hope that it will be useful,\\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\\n// GNU Affero General Public License for more details.\\n//\\n// You should have received a copy of the GNU Affero General Public License\\n// along with this program. If not, see .\\n\\npragma solidity >=0.8.13;\\n\\ninterface IHats {\\n function mintTopHat(\\n address _target,\\n string memory _details,\\n string memory _imageURI\\n ) external returns (uint256 topHatId);\\n\\n function createHat(\\n uint256 _admin,\\n string calldata _details,\\n uint32 _maxSupply,\\n address _eligibility,\\n address _toggle,\\n bool _mutable,\\n string calldata _imageURI\\n ) external returns (uint256 newHatId);\\n\\n function mintHat(\\n uint256 _hatId,\\n address _wearer\\n ) external returns (bool success);\\n\\n function transferHat(uint256 _hatId, address _from, address _to) external;\\n}\\n\",\"keccak256\":\"0x8e35022f5c0fcf0059033abec78ec890f0cf3bbac09d6d24051cff9679239511\",\"license\":\"AGPL-3.0\"},\"contracts/interfaces/sablier/ISablierV2LockupLinear.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport {LockupLinear} from \\\"./LockupLinear.sol\\\";\\nimport {IERC20} from \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\n\\ninterface ISablierV2LockupLinear {\\n function createWithTimestamps(\\n LockupLinear.CreateWithTimestamps calldata params\\n ) external returns (uint256 streamId);\\n}\\n\",\"keccak256\":\"0xf4899637eb2e6c76c35e2d201e56e162a50e6bc7b5b9156e00866f0703ad07ca\",\"license\":\"MIT\"},\"contracts/interfaces/sablier/LockupLinear.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport {IERC20} from \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\n\\nlibrary LockupLinear {\\n struct CreateWithTimestamps {\\n address sender;\\n address recipient;\\n uint128 totalAmount;\\n IERC20 asset;\\n bool cancelable;\\n bool transferable;\\n Timestamps timestamps;\\n Broker broker;\\n }\\n\\n struct Timestamps {\\n uint40 start;\\n uint40 cliff;\\n uint40 end;\\n }\\n\\n struct Broker {\\n address account;\\n uint256 fee;\\n }\\n}\\n\",\"keccak256\":\"0x497fdb52b5e1a5a7e0711a9f7d5fb036eb668ccb92ea908ee088f56ee08a4ce8\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x608060405234801561001057600080fd5b5061158a806100206000396000f3fe608060405234801561001057600080fd5b506004361061004c5760003560e01c806313a9589c146100515780636592b2ac146100845780638c5f591a146100b4578063a3f4df7e146100c9575b600080fd5b6040517f5d0e6ce4fd951366cc55da93f6e79d8b81483109d79676a04bcc2bed6a4b507281526020015b60405180910390f35b610097610092366004610b95565b610105565b604080519283526001600160a01b0390911660208301520161007b565b6100c76100c2366004610c40565b61018f565b005b6100f86040518060400160405280601081526020016f0446563656e74486174735f305f315f360841b81525081565b60405161007b9190610cc8565b6000806101178a8a8a898989896103dc565b6040516329287c1b60e21b8152600481018a905230602482015233604482015291935091506001600160a01b038b169063a4a1f06c90606401600060405180830381600087803b15801561016a57600080fd5b505af115801561017e573d6000803e3d6000fd5b505050509850989650505050505050565b7f5d0e6ce4fd951366cc55da93f6e79d8b81483109d79676a04bcc2bed6a4b507260008061026d6101c36020860186610cdb565b6101d06080870187610cf8565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506102129250505060a0880188610cf8565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610257925050506060890160408a01610cdb565b61026760408a0160208b01610cdb565b8861072b565b909250905061028b6102856080860160608701610cdb565b836107bd565b60006102d261029d6020870187610cdb565b846102ab60c0890189610d45565b856102bc60608b0160408c01610cdb565b6102cc60408c0160208d01610cdb565b8a6103dc565b50905060005b6102e560e0870187610d65565b905081101561035f576103556102fe6020880188610cdb565b8361030c60e08a018a610d65565b8581811061031c5761031c610dae565b905060200281019061032e9190610d45565b8661033f60608c0160408d01610cdb565b61034f60408d0160208e01610cdb565b8b6103dc565b50506001016102d8565b5061036d6020860186610cdb565b6040516329287c1b60e21b8152600481018590523060248201523360448201526001600160a01b03919091169063a4a1f06c90606401600060405180830381600087803b1580156103bd57600080fd5b505af11580156103d1573d6000803e3d6000fd5b505050505050505050565b6000806103f389896103ed8a611112565b8961093d565b91506104028585858c866109cf565b9050600061041660a0890160808a01610cdb565b6001600160a01b0316146104b6576001600160a01b03891663641f776e8361044460a08b0160808c01610cdb565b6040516001600160e01b031960e085901b16815260048101929092526001600160a01b031660248201526044016020604051808303816000875af1158015610490573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104b491906111d6565b505b60005b6104c660a08901896111f3565b905081101561071e5760006104de60a08a018a6111f3565b838181106104ee576104ee610dae565b90506101600201803603810190610505919061123c565b6060810151815160408084015190516001600160a01b0390921660248301526001600160801b03166044820152919250339163468721a7919060009060640160408051601f198184030181529181526020820180516001600160e01b031663095ea7b360e01b1790525160e085901b6001600160e01b031916815261059293929190600090600401611259565b6020604051808303816000875af11580156105b1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105d591906111d6565b50600060405180610100016040528083602001516001600160a01b03168152602001856001600160a01b0316815260200183604001516001600160801b0316815260200183606001516001600160a01b031681526020018360800151151581526020018360a00151151581526020018360c0015181526020018360e001518152509050336001600160a01b031663468721a7836000015160008460405160240161067f91906112af565b60408051601f198184030181529181526020820180516001600160e01b03166353b1572760e01b1790525160e085901b6001600160e01b03191681526106cd93929190600090600401611259565b6020604051808303816000875af11580156106ec573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061071091906111d6565b5082600101925050506104b9565b5097509795505050505050565b600080876001600160a01b0316631a64dfad3089896040518463ffffffff1660e01b815260040161075e93929190611371565b6020604051808303816000875af115801561077d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107a191906113a7565b91506107b08585858b866109cf565b9050965096945050505050565b604080516001808252818301909252600091816020015b60608152602001906001900390816107d457505060408051600180825281830190925291925060009190602082015b6060815260200190600190039081610803579050509050604051806040016040528060088152602001671d1bdc12185d125960c21b8152508260008151811061084e5761084e610dae565b602002602001018190525061086283610a65565b8160008151811061087557610875610dae565b6020026020010181905250336001600160a01b031663468721a785600085856040516024016108a5929190611415565b60408051601f198184030181529181526020820180516001600160e01b031663579374b960e11b1790525160e085901b6001600160e01b03191681526108f393929190600090600401611259565b6020604051808303816000875af1158015610912573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061093691906111d6565b5050505050565b6020820151825160608401516040808601519051635829492f60e11b81526000946001600160a01b038a169463b052925e94610983948b948a928392909160040161143a565b6020604051808303816000875af11580156109a2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109c691906113a7565b95945050505050565b604051638a54c52f60e01b81526001600160a01b0385811660048301526024820185905246604483015283811660648301526084820183905260009190871690638a54c52f9060a4016020604051808303816000875af1158015610a37573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a5b919061149e565b9695505050505050565b606081600003610a8c5750506040805180820190915260018152600360fc1b602082015290565b8160005b8115610ab65780610aa0816114d1565b9150610aaf9050600a83611500565b9150610a90565b6000816001600160401b03811115610ad057610ad0610dc4565b6040519080825280601f01601f191660200182016040528015610afa576020820181803683370190505b5090505b8415610b6557610b0f600183611514565b9150610b1c600a8661152d565b610b27906030611541565b60f81b818381518110610b3c57610b3c610dae565b60200101906001600160f81b031916908160001a905350610b5e600a86611500565b9450610afe565b949350505050565b6001600160a01b0381168114610b8257600080fd5b50565b8035610b9081610b6d565b919050565b600080600080600080600080610100898b031215610bb257600080fd5b8835610bbd81610b6d565b97506020890135965060408901356001600160401b03811115610bdf57600080fd5b890160c0818c031215610bf157600080fd5b9550606089013594506080890135610c0881610b6d565b935060a0890135610c1881610b6d565b925060c0890135610c2881610b6d565b8092505060e089013590509295985092959890939650565b600060208284031215610c5257600080fd5b81356001600160401b03811115610c6857600080fd5b82016101008185031215610c7b57600080fd5b9392505050565b6000815180845260005b81811015610ca857602081850181015186830182015201610c8c565b506000602082860101526020601f19601f83011685010191505092915050565b602081526000610c7b6020830184610c82565b600060208284031215610ced57600080fd5b8135610c7b81610b6d565b6000808335601e19843603018112610d0f57600080fd5b8301803591506001600160401b03821115610d2957600080fd5b602001915036819003821315610d3e57600080fd5b9250929050565b6000823560be19833603018112610d5b57600080fd5b9190910192915050565b6000808335601e19843603018112610d7c57600080fd5b8301803591506001600160401b03821115610d9657600080fd5b6020019150600581901b3603821315610d3e57600080fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b60405160c081016001600160401b0381118282101715610dfc57610dfc610dc4565b60405290565b604051601f8201601f191681016001600160401b0381118282101715610e2a57610e2a610dc4565b604052919050565b803563ffffffff81168114610b9057600080fd5b600082601f830112610e5757600080fd5b81356001600160401b03811115610e7057610e70610dc4565b610e83601f8201601f1916602001610e02565b818152846020838601011115610e9857600080fd5b816020850160208301376000918101602001919091529392505050565b8015158114610b8257600080fd5b8035610b9081610eb5565b80356001600160801b0381168114610b9057600080fd5b803564ffffffffff81168114610b9057600080fd5b600060608284031215610f0c57600080fd5b604051606081018181106001600160401b0382111715610f2e57610f2e610dc4565b604052905080610f3d83610ee5565b8152610f4b60208401610ee5565b6020820152610f5c60408401610ee5565b60408201525092915050565b600060408284031215610f7a57600080fd5b604051604081018181106001600160401b0382111715610f9c57610f9c610dc4565b6040529050808235610fad81610b6d565b8152602092830135920191909152919050565b60006101608284031215610fd357600080fd5b60405161010081018181106001600160401b0382111715610ff657610ff6610dc4565b60405290508061100583610b85565b815261101360208401610b85565b602082015261102460408401610ece565b604082015261103560608401610b85565b606082015261104660808401610ec3565b608082015261105760a08401610ec3565b60a08201526110698460c08501610efa565b60c082015261107c846101208501610f68565b60e08201525092915050565b600082601f83011261109957600080fd5b813560206001600160401b038211156110b4576110b4610dc4565b6110c2818360051b01610e02565b82815261016092830285018201928282019190878511156110e257600080fd5b8387015b85811015611105576110f88982610fc0565b84529284019281016110e6565b5090979650505050505050565b600060c0823603121561112457600080fd5b61112c610dda565b61113583610e32565b815260208301356001600160401b038082111561115157600080fd5b61115d36838701610e46565b6020840152604085013591508082111561117657600080fd5b61118236838701610e46565b604084015261119360608601610ec3565b60608401526111a460808601610b85565b608084015260a08501359150808211156111bd57600080fd5b506111ca36828601611088565b60a08301525092915050565b6000602082840312156111e857600080fd5b8151610c7b81610eb5565b6000808335601e1984360301811261120a57600080fd5b8301803591506001600160401b0382111561122457600080fd5b602001915061016081023603821315610d3e57600080fd5b6000610160828403121561124f57600080fd5b610c7b8383610fc0565b60018060a01b03851681528360208201526080604082015260006112806080830185610c82565b9050600283106112a057634e487b7160e01b600052602160045260246000fd5b82606083015295945050505050565b81516001600160a01b0390811682526020808401518216908301526040808401516001600160801b031690830152606080840151909116908201526080808301516101608301916113039084018215159052565b5060a083015161131760a084018215159052565b5060c083015161134a60c0840182805164ffffffffff908116835260208083015182169084015260409182015116910152565b5060e0929092015180516001600160a01b0316610120830152602001516101409091015290565b6001600160a01b038416815260606020820181905260009061139590830185610c82565b8281036040840152610a5b8185610c82565b6000602082840312156113b957600080fd5b5051919050565b600081518084526020808501808196508360051b8101915082860160005b858110156114085782840389526113f6848351610c82565b988501989350908401906001016113de565b5091979650505050505050565b60408152600061142860408301856113c0565b82810360208401526109c681856113c0565b87815260e06020820152600061145360e0830189610c82565b63ffffffff881660408401526001600160a01b0387811660608501528616608084015284151560a084015282810360c08401526114908185610c82565b9a9950505050505050505050565b6000602082840312156114b057600080fd5b8151610c7b81610b6d565b634e487b7160e01b600052601160045260246000fd5b6000600182016114e3576114e36114bb565b5060010190565b634e487b7160e01b600052601260045260246000fd5b60008261150f5761150f6114ea565b500490565b81810381811115611527576115276114bb565b92915050565b60008261153c5761153c6114ea565b500690565b80820180821115611527576115276114bb56fea26469706673582212208431b5cb9e9defda60834dc065f918f11d92dcbf19aba7475b779059a216011d64736f6c63430008130033", + "deployedBytecode": "0x608060405234801561001057600080fd5b506004361061004c5760003560e01c806313a9589c146100515780636592b2ac146100845780638c5f591a146100b4578063a3f4df7e146100c9575b600080fd5b6040517f5d0e6ce4fd951366cc55da93f6e79d8b81483109d79676a04bcc2bed6a4b507281526020015b60405180910390f35b610097610092366004610b95565b610105565b604080519283526001600160a01b0390911660208301520161007b565b6100c76100c2366004610c40565b61018f565b005b6100f86040518060400160405280601081526020016f0446563656e74486174735f305f315f360841b81525081565b60405161007b9190610cc8565b6000806101178a8a8a898989896103dc565b6040516329287c1b60e21b8152600481018a905230602482015233604482015291935091506001600160a01b038b169063a4a1f06c90606401600060405180830381600087803b15801561016a57600080fd5b505af115801561017e573d6000803e3d6000fd5b505050509850989650505050505050565b7f5d0e6ce4fd951366cc55da93f6e79d8b81483109d79676a04bcc2bed6a4b507260008061026d6101c36020860186610cdb565b6101d06080870187610cf8565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506102129250505060a0880188610cf8565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610257925050506060890160408a01610cdb565b61026760408a0160208b01610cdb565b8861072b565b909250905061028b6102856080860160608701610cdb565b836107bd565b60006102d261029d6020870187610cdb565b846102ab60c0890189610d45565b856102bc60608b0160408c01610cdb565b6102cc60408c0160208d01610cdb565b8a6103dc565b50905060005b6102e560e0870187610d65565b905081101561035f576103556102fe6020880188610cdb565b8361030c60e08a018a610d65565b8581811061031c5761031c610dae565b905060200281019061032e9190610d45565b8661033f60608c0160408d01610cdb565b61034f60408d0160208e01610cdb565b8b6103dc565b50506001016102d8565b5061036d6020860186610cdb565b6040516329287c1b60e21b8152600481018590523060248201523360448201526001600160a01b03919091169063a4a1f06c90606401600060405180830381600087803b1580156103bd57600080fd5b505af11580156103d1573d6000803e3d6000fd5b505050505050505050565b6000806103f389896103ed8a611112565b8961093d565b91506104028585858c866109cf565b9050600061041660a0890160808a01610cdb565b6001600160a01b0316146104b6576001600160a01b03891663641f776e8361044460a08b0160808c01610cdb565b6040516001600160e01b031960e085901b16815260048101929092526001600160a01b031660248201526044016020604051808303816000875af1158015610490573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104b491906111d6565b505b60005b6104c660a08901896111f3565b905081101561071e5760006104de60a08a018a6111f3565b838181106104ee576104ee610dae565b90506101600201803603810190610505919061123c565b6060810151815160408084015190516001600160a01b0390921660248301526001600160801b03166044820152919250339163468721a7919060009060640160408051601f198184030181529181526020820180516001600160e01b031663095ea7b360e01b1790525160e085901b6001600160e01b031916815261059293929190600090600401611259565b6020604051808303816000875af11580156105b1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105d591906111d6565b50600060405180610100016040528083602001516001600160a01b03168152602001856001600160a01b0316815260200183604001516001600160801b0316815260200183606001516001600160a01b031681526020018360800151151581526020018360a00151151581526020018360c0015181526020018360e001518152509050336001600160a01b031663468721a7836000015160008460405160240161067f91906112af565b60408051601f198184030181529181526020820180516001600160e01b03166353b1572760e01b1790525160e085901b6001600160e01b03191681526106cd93929190600090600401611259565b6020604051808303816000875af11580156106ec573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061071091906111d6565b5082600101925050506104b9565b5097509795505050505050565b600080876001600160a01b0316631a64dfad3089896040518463ffffffff1660e01b815260040161075e93929190611371565b6020604051808303816000875af115801561077d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107a191906113a7565b91506107b08585858b866109cf565b9050965096945050505050565b604080516001808252818301909252600091816020015b60608152602001906001900390816107d457505060408051600180825281830190925291925060009190602082015b6060815260200190600190039081610803579050509050604051806040016040528060088152602001671d1bdc12185d125960c21b8152508260008151811061084e5761084e610dae565b602002602001018190525061086283610a65565b8160008151811061087557610875610dae565b6020026020010181905250336001600160a01b031663468721a785600085856040516024016108a5929190611415565b60408051601f198184030181529181526020820180516001600160e01b031663579374b960e11b1790525160e085901b6001600160e01b03191681526108f393929190600090600401611259565b6020604051808303816000875af1158015610912573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061093691906111d6565b5050505050565b6020820151825160608401516040808601519051635829492f60e11b81526000946001600160a01b038a169463b052925e94610983948b948a928392909160040161143a565b6020604051808303816000875af11580156109a2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109c691906113a7565b95945050505050565b604051638a54c52f60e01b81526001600160a01b0385811660048301526024820185905246604483015283811660648301526084820183905260009190871690638a54c52f9060a4016020604051808303816000875af1158015610a37573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a5b919061149e565b9695505050505050565b606081600003610a8c5750506040805180820190915260018152600360fc1b602082015290565b8160005b8115610ab65780610aa0816114d1565b9150610aaf9050600a83611500565b9150610a90565b6000816001600160401b03811115610ad057610ad0610dc4565b6040519080825280601f01601f191660200182016040528015610afa576020820181803683370190505b5090505b8415610b6557610b0f600183611514565b9150610b1c600a8661152d565b610b27906030611541565b60f81b818381518110610b3c57610b3c610dae565b60200101906001600160f81b031916908160001a905350610b5e600a86611500565b9450610afe565b949350505050565b6001600160a01b0381168114610b8257600080fd5b50565b8035610b9081610b6d565b919050565b600080600080600080600080610100898b031215610bb257600080fd5b8835610bbd81610b6d565b97506020890135965060408901356001600160401b03811115610bdf57600080fd5b890160c0818c031215610bf157600080fd5b9550606089013594506080890135610c0881610b6d565b935060a0890135610c1881610b6d565b925060c0890135610c2881610b6d565b8092505060e089013590509295985092959890939650565b600060208284031215610c5257600080fd5b81356001600160401b03811115610c6857600080fd5b82016101008185031215610c7b57600080fd5b9392505050565b6000815180845260005b81811015610ca857602081850181015186830182015201610c8c565b506000602082860101526020601f19601f83011685010191505092915050565b602081526000610c7b6020830184610c82565b600060208284031215610ced57600080fd5b8135610c7b81610b6d565b6000808335601e19843603018112610d0f57600080fd5b8301803591506001600160401b03821115610d2957600080fd5b602001915036819003821315610d3e57600080fd5b9250929050565b6000823560be19833603018112610d5b57600080fd5b9190910192915050565b6000808335601e19843603018112610d7c57600080fd5b8301803591506001600160401b03821115610d9657600080fd5b6020019150600581901b3603821315610d3e57600080fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b60405160c081016001600160401b0381118282101715610dfc57610dfc610dc4565b60405290565b604051601f8201601f191681016001600160401b0381118282101715610e2a57610e2a610dc4565b604052919050565b803563ffffffff81168114610b9057600080fd5b600082601f830112610e5757600080fd5b81356001600160401b03811115610e7057610e70610dc4565b610e83601f8201601f1916602001610e02565b818152846020838601011115610e9857600080fd5b816020850160208301376000918101602001919091529392505050565b8015158114610b8257600080fd5b8035610b9081610eb5565b80356001600160801b0381168114610b9057600080fd5b803564ffffffffff81168114610b9057600080fd5b600060608284031215610f0c57600080fd5b604051606081018181106001600160401b0382111715610f2e57610f2e610dc4565b604052905080610f3d83610ee5565b8152610f4b60208401610ee5565b6020820152610f5c60408401610ee5565b60408201525092915050565b600060408284031215610f7a57600080fd5b604051604081018181106001600160401b0382111715610f9c57610f9c610dc4565b6040529050808235610fad81610b6d565b8152602092830135920191909152919050565b60006101608284031215610fd357600080fd5b60405161010081018181106001600160401b0382111715610ff657610ff6610dc4565b60405290508061100583610b85565b815261101360208401610b85565b602082015261102460408401610ece565b604082015261103560608401610b85565b606082015261104660808401610ec3565b608082015261105760a08401610ec3565b60a08201526110698460c08501610efa565b60c082015261107c846101208501610f68565b60e08201525092915050565b600082601f83011261109957600080fd5b813560206001600160401b038211156110b4576110b4610dc4565b6110c2818360051b01610e02565b82815261016092830285018201928282019190878511156110e257600080fd5b8387015b85811015611105576110f88982610fc0565b84529284019281016110e6565b5090979650505050505050565b600060c0823603121561112457600080fd5b61112c610dda565b61113583610e32565b815260208301356001600160401b038082111561115157600080fd5b61115d36838701610e46565b6020840152604085013591508082111561117657600080fd5b61118236838701610e46565b604084015261119360608601610ec3565b60608401526111a460808601610b85565b608084015260a08501359150808211156111bd57600080fd5b506111ca36828601611088565b60a08301525092915050565b6000602082840312156111e857600080fd5b8151610c7b81610eb5565b6000808335601e1984360301811261120a57600080fd5b8301803591506001600160401b0382111561122457600080fd5b602001915061016081023603821315610d3e57600080fd5b6000610160828403121561124f57600080fd5b610c7b8383610fc0565b60018060a01b03851681528360208201526080604082015260006112806080830185610c82565b9050600283106112a057634e487b7160e01b600052602160045260246000fd5b82606083015295945050505050565b81516001600160a01b0390811682526020808401518216908301526040808401516001600160801b031690830152606080840151909116908201526080808301516101608301916113039084018215159052565b5060a083015161131760a084018215159052565b5060c083015161134a60c0840182805164ffffffffff908116835260208083015182169084015260409182015116910152565b5060e0929092015180516001600160a01b0316610120830152602001516101409091015290565b6001600160a01b038416815260606020820181905260009061139590830185610c82565b8281036040840152610a5b8185610c82565b6000602082840312156113b957600080fd5b5051919050565b600081518084526020808501808196508360051b8101915082860160005b858110156114085782840389526113f6848351610c82565b988501989350908401906001016113de565b5091979650505050505050565b60408152600061142860408301856113c0565b82810360208401526109c681856113c0565b87815260e06020820152600061145360e0830189610c82565b63ffffffff881660408401526001600160a01b0387811660608501528616608084015284151560a084015282810360c08401526114908185610c82565b9a9950505050505050505050565b6000602082840312156114b057600080fd5b8151610c7b81610b6d565b634e487b7160e01b600052601160045260246000fd5b6000600182016114e3576114e36114bb565b5060010190565b634e487b7160e01b600052601260045260246000fd5b60008261150f5761150f6114ea565b500490565b81810381811115611527576115276114bb565b92915050565b60008261153c5761153c6114ea565b500690565b80820180821115611527576115276114bb56fea26469706673582212208431b5cb9e9defda60834dc065f918f11d92dcbf19aba7475b779059a216011d64736f6c63430008130033", "devdoc": { "kind": "dev", - "methods": {}, + "methods": { + "createAndDeclareTree((address,address,address,address,string,string,(uint32,string,string,bool,address,(address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256))[]),(uint32,string,string,bool,address,(address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256))[])[]))": { + "details": "In order for a Safe to seamlessly create roles even if it has never previously created a role and thus has no hat tree, we defer the creation of the hat tree and its setup to this contract. This way, in a single tx block, the resulting topHatId of the newly created hat can be used to create an admin hat and any other hats needed. We also make use of `KeyValuePairs` to associate the topHatId with the Safe." + }, + "createRoleHat(address,uint256,(uint32,string,string,bool,address,(address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256))[]),uint256,address,address,address,bytes32)": { + "details": "Role hat creation, minting, smart account creation and stream creation are handled here in order to avoid a race condition where not more than one active proposal to create a new role can exist at a time. See: https://github.com/decentdao/decent-interface/issues/2402" + } + }, "version": 1 }, "userdoc": { "kind": "user", - "methods": {}, + "methods": { + "createAndDeclareTree((address,address,address,address,string,string,(uint32,string,string,bool,address,(address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256))[]),(uint32,string,string,bool,address,(address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256))[])[]))": { + "notice": "For a safe without any roles previously created on it, this function should be called. It sets up the top hat and admin hat, as well as any other hats and their streams that are provided. This contract should be enabled a module on the Safe for which the role(s) are to be created, and disabled after." + }, + "createRoleHat(address,uint256,(uint32,string,string,bool,address,(address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256))[]),uint256,address,address,address,bytes32)": { + "notice": "Creates a new role hat and any streams on it. This contract should be enabled a module on the Safe for which the role is to be created, and disable after. In order for the module to be able to create hats on behalf of the Safe, the Safe must first transfer its top hat to this contract. This function transfers the top hat back to the Safe after creating the role hat. The function simply calls `createHatAndAccountAndMintAndStreams` and then transfers the top hat back to the Safe." + } + }, "version": 1 }, "storageLayout": { diff --git a/deployments/mainnet/solcInputs/4754a2f0c9d6a191a066af246491b62a.json b/deployments/mainnet/solcInputs/4754a2f0c9d6a191a066af246491b62a.json new file mode 100644 index 00000000..87cba363 --- /dev/null +++ b/deployments/mainnet/solcInputs/4754a2f0c9d6a191a066af246491b62a.json @@ -0,0 +1,59 @@ +{ + "language": "Solidity", + "sources": { + "@gnosis.pm/safe-contracts/contracts/common/Enum.sol": { + "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\n\n/// @title Enum - Collection of enums\n/// @author Richard Meissner - \ncontract Enum {\n enum Operation {Call, DelegateCall}\n}\n" + }, + "@gnosis.pm/zodiac/contracts/interfaces/IAvatar.sol": { + "content": "// SPDX-License-Identifier: LGPL-3.0-only\n\n/// @title Zodiac Avatar - A contract that manages modules that can execute transactions via this contract.\npragma solidity >=0.7.0 <0.9.0;\n\nimport \"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\";\n\ninterface IAvatar {\n event EnabledModule(address module);\n event DisabledModule(address module);\n event ExecutionFromModuleSuccess(address indexed module);\n event ExecutionFromModuleFailure(address indexed module);\n\n /// @dev Enables a module on the avatar.\n /// @notice Can only be called by the avatar.\n /// @notice Modules should be stored as a linked list.\n /// @notice Must emit EnabledModule(address module) if successful.\n /// @param module Module to be enabled.\n function enableModule(address module) external;\n\n /// @dev Disables a module on the avatar.\n /// @notice Can only be called by the avatar.\n /// @notice Must emit DisabledModule(address module) if successful.\n /// @param prevModule Address that pointed to the module to be removed in the linked list\n /// @param module Module to be removed.\n function disableModule(address prevModule, address module) external;\n\n /// @dev Allows a Module to execute a transaction.\n /// @notice Can only be called by an enabled module.\n /// @notice Must emit ExecutionFromModuleSuccess(address module) if successful.\n /// @notice Must emit ExecutionFromModuleFailure(address module) if unsuccessful.\n /// @param to Destination address of module transaction.\n /// @param value Ether value of module transaction.\n /// @param data Data payload of module transaction.\n /// @param operation Operation type of module transaction: 0 == call, 1 == delegate call.\n function execTransactionFromModule(\n address to,\n uint256 value,\n bytes memory data,\n Enum.Operation operation\n ) external returns (bool success);\n\n /// @dev Allows a Module to execute a transaction and return data\n /// @notice Can only be called by an enabled module.\n /// @notice Must emit ExecutionFromModuleSuccess(address module) if successful.\n /// @notice Must emit ExecutionFromModuleFailure(address module) if unsuccessful.\n /// @param to Destination address of module transaction.\n /// @param value Ether value of module transaction.\n /// @param data Data payload of module transaction.\n /// @param operation Operation type of module transaction: 0 == call, 1 == delegate call.\n function execTransactionFromModuleReturnData(\n address to,\n uint256 value,\n bytes memory data,\n Enum.Operation operation\n ) external returns (bool success, bytes memory returnData);\n\n /// @dev Returns if an module is enabled\n /// @return True if the module is enabled\n function isModuleEnabled(address module) external view returns (bool);\n\n /// @dev Returns array of modules.\n /// @param start Start of the page.\n /// @param pageSize Maximum number of modules that should be returned.\n /// @return array Array of modules.\n /// @return next Start of the next page.\n function getModulesPaginated(address start, uint256 pageSize)\n external\n view\n returns (address[] memory array, address next);\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/IERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20 {\n /**\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\n * another (`to`).\n *\n * Note that `value` may be zero.\n */\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n /**\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n * a call to {approve}. `value` is the new allowance.\n */\n event Approval(address indexed owner, address indexed spender, uint256 value);\n\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by `account`.\n */\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * @dev Moves `amount` tokens from the caller's account to `to`.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transfer(address to, uint256 amount) external returns (bool);\n\n /**\n * @dev Returns the remaining number of tokens that `spender` will be\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\n * zero by default.\n *\n * This value changes when {approve} or {transferFrom} are called.\n */\n function allowance(address owner, address spender) external view returns (uint256);\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\n * that someone may use both the old and the new allowance by unfortunate\n * transaction ordering. One possible solution to mitigate this race\n * condition is to first reduce the spender's allowance to 0 and set the\n * desired value afterwards:\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n *\n * Emits an {Approval} event.\n */\n function approve(address spender, uint256 amount) external returns (bool);\n\n /**\n * @dev Moves `amount` tokens from `from` to `to` using the\n * allowance mechanism. `amount` is then deducted from the caller's\n * allowance.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(\n address from,\n address to,\n uint256 amount\n ) external returns (bool);\n}\n" + }, + "@openzeppelin/contracts/utils/Strings.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n uint8 private constant _ADDRESS_LENGTH = 20;\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp >>= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i > 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value & 0xf];\n value >>= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n\n /**\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\n */\n function toHexString(address addr) internal pure returns (string memory) {\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\n }\n}\n" + }, + "contracts/DecentHats_0_1_0.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity =0.8.19;\n\nimport {Enum} from \"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\";\nimport {IAvatar} from \"@gnosis.pm/zodiac/contracts/interfaces/IAvatar.sol\";\nimport {Strings} from \"@openzeppelin/contracts/utils/Strings.sol\";\nimport {IERC20} from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport {IERC6551Registry} from \"./interfaces/IERC6551Registry.sol\";\nimport {IHats} from \"./interfaces/hats/IHats.sol\";\nimport {ISablierV2LockupLinear} from \"./interfaces/sablier/ISablierV2LockupLinear.sol\";\nimport {LockupLinear} from \"./interfaces/sablier/LockupLinear.sol\";\n\ncontract DecentHats_0_1_0 {\n string public constant NAME = \"DecentHats_0_1_0\";\n\n struct SablierStreamParams {\n ISablierV2LockupLinear sablier;\n address sender;\n uint128 totalAmount;\n address asset;\n bool cancelable;\n bool transferable;\n LockupLinear.Timestamps timestamps;\n LockupLinear.Broker broker;\n }\n\n struct Hat {\n uint32 maxSupply;\n string details;\n string imageURI;\n bool isMutable;\n address wearer;\n SablierStreamParams[] sablierParams; // Optional Sablier stream parameters\n }\n\n struct CreateTreeParams {\n IHats hatsProtocol;\n address hatsAccountImplementation;\n IERC6551Registry registry;\n address keyValuePairs;\n string topHatDetails;\n string topHatImageURI;\n Hat adminHat;\n Hat[] hats;\n }\n\n function getSalt() public pure returns (bytes32 salt) {\n return\n 0x5d0e6ce4fd951366cc55da93f6e79d8b81483109d79676a04bcc2bed6a4b5072;\n }\n\n function declareSafeHatTree(\n address _keyValuePairs,\n uint256 topHatId\n ) internal {\n string[] memory keys = new string[](1);\n string[] memory values = new string[](1);\n keys[0] = \"topHatId\";\n values[0] = Strings.toString(topHatId);\n\n IAvatar(msg.sender).execTransactionFromModule(\n _keyValuePairs,\n 0,\n abi.encodeWithSignature(\n \"updateValues(string[],string[])\",\n keys,\n values\n ),\n Enum.Operation.Call\n );\n }\n\n function createHat(\n IHats _hatsProtocol,\n uint256 adminHatId,\n Hat memory _hat,\n address topHatAccount\n ) internal returns (uint256) {\n return\n _hatsProtocol.createHat(\n adminHatId,\n _hat.details,\n _hat.maxSupply,\n topHatAccount,\n topHatAccount,\n _hat.isMutable,\n _hat.imageURI\n );\n }\n\n function createAccount(\n IERC6551Registry _registry,\n address _hatsAccountImplementation,\n bytes32 salt,\n address protocolAddress,\n uint256 hatId\n ) internal returns (address) {\n return\n _registry.createAccount(\n _hatsAccountImplementation,\n salt,\n block.chainid,\n protocolAddress,\n hatId\n );\n }\n\n function createTopHatAndAccount(\n IHats _hatsProtocol,\n string memory _topHatDetails,\n string memory _topHatImageURI,\n IERC6551Registry _registry,\n address _hatsAccountImplementation,\n bytes32 salt\n ) internal returns (uint256 topHatId, address topHatAccount) {\n topHatId = _hatsProtocol.mintTopHat(\n address(this),\n _topHatDetails,\n _topHatImageURI\n );\n\n topHatAccount = createAccount(\n _registry,\n _hatsAccountImplementation,\n salt,\n address(_hatsProtocol),\n topHatId\n );\n }\n\n function createHatAndAccountAndMintAndStreams(\n IHats hatsProtocol,\n uint256 adminHatId,\n Hat calldata hat,\n address topHatAccount,\n IERC6551Registry registry,\n address hatsAccountImplementation,\n bytes32 salt\n ) internal returns (uint256 hatId, address accountAddress) {\n hatId = createHat(hatsProtocol, adminHatId, hat, topHatAccount);\n\n accountAddress = createAccount(\n registry,\n hatsAccountImplementation,\n salt,\n address(hatsProtocol),\n hatId\n );\n\n if (hat.wearer != address(0)) {\n hatsProtocol.mintHat(hatId, hat.wearer);\n }\n\n for (uint256 i = 0; i < hat.sablierParams.length; ) {\n SablierStreamParams memory sablierParams = hat.sablierParams[i];\n\n // Approve tokens for Sablier\n IAvatar(msg.sender).execTransactionFromModule(\n sablierParams.asset,\n 0,\n abi.encodeWithSignature(\n \"approve(address,uint256)\",\n address(sablierParams.sablier),\n sablierParams.totalAmount\n ),\n Enum.Operation.Call\n );\n\n LockupLinear.CreateWithTimestamps memory params = LockupLinear\n .CreateWithTimestamps({\n sender: sablierParams.sender,\n recipient: accountAddress,\n totalAmount: sablierParams.totalAmount,\n asset: IERC20(sablierParams.asset),\n cancelable: sablierParams.cancelable,\n transferable: sablierParams.transferable,\n timestamps: sablierParams.timestamps,\n broker: sablierParams.broker\n });\n\n // Proxy the Sablier call through IAvatar\n IAvatar(msg.sender).execTransactionFromModule(\n address(sablierParams.sablier),\n 0,\n abi.encodeWithSignature(\n \"createWithTimestamps((address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256)))\",\n params\n ),\n Enum.Operation.Call\n );\n\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * Creates a new role hat and any streams on it.\n *\n * This contract should be enabled a module on the Safe for which the role is to be created, and disable after.\n * In order for the module to be able to create hats on behalf of the Safe, the Safe must first\n * transfer its top hat to this contract. This function transfers the top hat back to the Safe after\n * creating the role hat.\n *\n * The function simply calls `createHatAndAccountAndMintAndStreams` and then transfers the top hat back to the Safe.\n *\n * @dev Role hat creation, minting, smart account creation and stream creation are handled here in order\n * to avoid a race condition where not more than one active proposal to create a new role can exist at a time.\n * See: https://github.com/decentdao/decent-interface/issues/2402\n */\n function createRoleHat(\n IHats hatsProtocol,\n uint256 adminHatId,\n Hat calldata hat,\n uint256 topHatId,\n address topHatAccount,\n IERC6551Registry registry,\n address hatsAccountImplementation,\n bytes32 salt\n ) public returns (uint256 hatId, address accountAddress) {\n (hatId, accountAddress) = createHatAndAccountAndMintAndStreams(\n hatsProtocol,\n adminHatId,\n hat,\n topHatAccount,\n registry,\n hatsAccountImplementation,\n salt\n );\n\n hatsProtocol.transferHat(topHatId, address(this), msg.sender);\n }\n\n /**\n * For a safe without any roles previously created on it, this function should be called. It sets up the\n * top hat and admin hat, as well as any other hats and their streams that are provided.\n *\n * This contract should be enabled a module on the Safe for which the role(s) are to be created, and disabled after.\n *\n * @dev In order for a Safe to seamlessly create roles even if it has never previously created a role and thus has\n * no hat tree, we defer the creation of the hat tree and its setup to this contract. This way, in a single tx block,\n * the resulting topHatId of the newly created hat can be used to create an admin hat and any other hats needed.\n * We also make use of `KeyValuePairs` to associate the topHatId with the Safe.\n */\n function createAndDeclareTree(CreateTreeParams calldata params) public {\n bytes32 salt = getSalt();\n\n (uint256 topHatId, address topHatAccount) = createTopHatAndAccount(\n params.hatsProtocol,\n params.topHatDetails,\n params.topHatImageURI,\n params.registry,\n params.hatsAccountImplementation,\n salt\n );\n\n declareSafeHatTree(params.keyValuePairs, topHatId);\n\n (uint256 adminHatId, ) = createHatAndAccountAndMintAndStreams(\n params.hatsProtocol,\n topHatId,\n params.adminHat,\n topHatAccount,\n params.registry,\n params.hatsAccountImplementation,\n salt\n );\n\n for (uint256 i = 0; i < params.hats.length; ) {\n createHatAndAccountAndMintAndStreams(\n params.hatsProtocol,\n adminHatId,\n params.hats[i],\n topHatAccount,\n params.registry,\n params.hatsAccountImplementation,\n salt\n );\n\n unchecked {\n ++i;\n }\n }\n\n params.hatsProtocol.transferHat(topHatId, address(this), msg.sender);\n }\n}\n" + }, + "contracts/interfaces/hats/IHats.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0\n// Copyright (C) 2023 Haberdasher Labs\n//\n// This program is free software: you can redistribute it and/or modify\n// it under the terms of the GNU Affero General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU Affero General Public License for more details.\n//\n// You should have received a copy of the GNU Affero General Public License\n// along with this program. If not, see .\n\npragma solidity >=0.8.13;\n\ninterface IHats {\n function mintTopHat(\n address _target,\n string memory _details,\n string memory _imageURI\n ) external returns (uint256 topHatId);\n\n function createHat(\n uint256 _admin,\n string calldata _details,\n uint32 _maxSupply,\n address _eligibility,\n address _toggle,\n bool _mutable,\n string calldata _imageURI\n ) external returns (uint256 newHatId);\n\n function mintHat(\n uint256 _hatId,\n address _wearer\n ) external returns (bool success);\n\n function transferHat(uint256 _hatId, address _from, address _to) external;\n}\n" + }, + "contracts/interfaces/IERC6551Registry.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.4;\n\ninterface IERC6551Registry {\n /**\n * @dev Creates a token bound account for a non-fungible token.\n *\n * If account has already been created, returns the account address without calling create2.\n *\n * Emits ERC6551AccountCreated event.\n *\n * @return account The address of the token bound account\n */\n function createAccount(\n address implementation,\n bytes32 salt,\n uint256 chainId,\n address tokenContract,\n uint256 tokenId\n ) external returns (address account);\n}\n" + }, + "contracts/interfaces/sablier/ISablierV2LockupLinear.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport {LockupLinear} from \"./LockupLinear.sol\";\nimport {IERC20} from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\n\ninterface ISablierV2LockupLinear {\n function createWithTimestamps(\n LockupLinear.CreateWithTimestamps calldata params\n ) external returns (uint256 streamId);\n}\n" + }, + "contracts/interfaces/sablier/LockupLinear.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport {IERC20} from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\n\nlibrary LockupLinear {\n struct CreateWithTimestamps {\n address sender;\n address recipient;\n uint128 totalAmount;\n IERC20 asset;\n bool cancelable;\n bool transferable;\n Timestamps timestamps;\n Broker broker;\n }\n\n struct Timestamps {\n uint40 start;\n uint40 cliff;\n uint40 end;\n }\n\n struct Broker {\n address account;\n uint256 fee;\n }\n}\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200 + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers", + "metadata", + "devdoc", + "userdoc", + "storageLayout", + "evm.gasEstimates" + ], + "": [ + "ast" + ] + } + }, + "metadata": { + "useLiteralContent": true + } + } +} \ No newline at end of file diff --git a/deployments/optimism/DecentHats_0_1_0.json b/deployments/optimism/DecentHats_0_1_0.json index 905e0851..06cee265 100644 --- a/deployments/optimism/DecentHats_0_1_0.json +++ b/deployments/optimism/DecentHats_0_1_0.json @@ -1,5 +1,5 @@ { - "address": "0x00b089E0A6fdE24cf8978994c7BcD24fc1D79825", + "address": "0x2A8Bf5E47FDcceA8Ab31A995C25198996D5ac514", "abi": [ { "inputs": [], @@ -275,6 +275,168 @@ "stateMutability": "nonpayable", "type": "function" }, + { + "inputs": [ + { + "internalType": "contract IHats", + "name": "hatsProtocol", + "type": "address" + }, + { + "internalType": "uint256", + "name": "adminHatId", + "type": "uint256" + }, + { + "components": [ + { + "internalType": "uint32", + "name": "maxSupply", + "type": "uint32" + }, + { + "internalType": "string", + "name": "details", + "type": "string" + }, + { + "internalType": "string", + "name": "imageURI", + "type": "string" + }, + { + "internalType": "bool", + "name": "isMutable", + "type": "bool" + }, + { + "internalType": "address", + "name": "wearer", + "type": "address" + }, + { + "components": [ + { + "internalType": "contract ISablierV2LockupLinear", + "name": "sablier", + "type": "address" + }, + { + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "internalType": "uint128", + "name": "totalAmount", + "type": "uint128" + }, + { + "internalType": "address", + "name": "asset", + "type": "address" + }, + { + "internalType": "bool", + "name": "cancelable", + "type": "bool" + }, + { + "internalType": "bool", + "name": "transferable", + "type": "bool" + }, + { + "components": [ + { + "internalType": "uint40", + "name": "start", + "type": "uint40" + }, + { + "internalType": "uint40", + "name": "cliff", + "type": "uint40" + }, + { + "internalType": "uint40", + "name": "end", + "type": "uint40" + } + ], + "internalType": "struct LockupLinear.Timestamps", + "name": "timestamps", + "type": "tuple" + }, + { + "components": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "uint256", + "name": "fee", + "type": "uint256" + } + ], + "internalType": "struct LockupLinear.Broker", + "name": "broker", + "type": "tuple" + } + ], + "internalType": "struct DecentHats_0_1_0.SablierStreamParams[]", + "name": "sablierParams", + "type": "tuple[]" + } + ], + "internalType": "struct DecentHats_0_1_0.Hat", + "name": "hat", + "type": "tuple" + }, + { + "internalType": "uint256", + "name": "topHatId", + "type": "uint256" + }, + { + "internalType": "address", + "name": "topHatAccount", + "type": "address" + }, + { + "internalType": "contract IERC6551Registry", + "name": "registry", + "type": "address" + }, + { + "internalType": "address", + "name": "hatsAccountImplementation", + "type": "address" + }, + { + "internalType": "bytes32", + "name": "salt", + "type": "bytes32" + } + ], + "name": "createRoleHat", + "outputs": [ + { + "internalType": "uint256", + "name": "hatId", + "type": "uint256" + }, + { + "internalType": "address", + "name": "accountAddress", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, { "inputs": [], "name": "getSalt", @@ -289,36 +451,50 @@ "type": "function" } ], - "transactionHash": "0x838e49f34e0c5da270a3ee8945c11b664f1cc242cb6b3c794464795333813910", + "transactionHash": "0x57c929ca92770fd06f0a51d038d29bfbf8790582f290fefb712c9b5a867aee84", "receipt": { "to": null, "from": "0xb5Ca125166C1987A35EDD550E16846Fa1e1D9bB3", - "contractAddress": "0x00b089E0A6fdE24cf8978994c7BcD24fc1D79825", - "transactionIndex": 12, - "gasUsed": "1162443", + "contractAddress": "0x2A8Bf5E47FDcceA8Ab31A995C25198996D5ac514", + "transactionIndex": 24, + "gasUsed": "1243979", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x4673e4ee1835f9085310f9f34eb7da3086eba765920c7de3c35d4b6870f668c6", - "transactionHash": "0x838e49f34e0c5da270a3ee8945c11b664f1cc242cb6b3c794464795333813910", + "blockHash": "0x7b3f0fd56bbfa019a8edb17cd23803cc2fdb06712a35d74474c06b09828d73c6", + "transactionHash": "0x57c929ca92770fd06f0a51d038d29bfbf8790582f290fefb712c9b5a867aee84", "logs": [], - "blockNumber": 126497749, - "cumulativeGasUsed": "2827783", + "blockNumber": 127133402, + "cumulativeGasUsed": "7388287", "status": 1, "byzantium": true }, "args": [], - "numDeployments": 3, - "solcInputHash": "6ceb8d75a501322d052845dbe517017d", - "metadata": "{\"compiler\":{\"version\":\"0.8.19+commit.7dd6d404\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"NAME\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"contract IHats\",\"name\":\"hatsProtocol\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"hatsAccountImplementation\",\"type\":\"address\"},{\"internalType\":\"contract IERC6551Registry\",\"name\":\"registry\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"keyValuePairs\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"topHatDetails\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"topHatImageURI\",\"type\":\"string\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"maxSupply\",\"type\":\"uint32\"},{\"internalType\":\"string\",\"name\":\"details\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"imageURI\",\"type\":\"string\"},{\"internalType\":\"bool\",\"name\":\"isMutable\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"wearer\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"contract ISablierV2LockupLinear\",\"name\":\"sablier\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint128\",\"name\":\"totalAmount\",\"type\":\"uint128\"},{\"internalType\":\"address\",\"name\":\"asset\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"cancelable\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"transferable\",\"type\":\"bool\"},{\"components\":[{\"internalType\":\"uint40\",\"name\":\"start\",\"type\":\"uint40\"},{\"internalType\":\"uint40\",\"name\":\"cliff\",\"type\":\"uint40\"},{\"internalType\":\"uint40\",\"name\":\"end\",\"type\":\"uint40\"}],\"internalType\":\"struct LockupLinear.Timestamps\",\"name\":\"timestamps\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"fee\",\"type\":\"uint256\"}],\"internalType\":\"struct LockupLinear.Broker\",\"name\":\"broker\",\"type\":\"tuple\"}],\"internalType\":\"struct DecentHats_0_1_0.SablierStreamParams[]\",\"name\":\"sablierParams\",\"type\":\"tuple[]\"}],\"internalType\":\"struct DecentHats_0_1_0.Hat\",\"name\":\"adminHat\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"maxSupply\",\"type\":\"uint32\"},{\"internalType\":\"string\",\"name\":\"details\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"imageURI\",\"type\":\"string\"},{\"internalType\":\"bool\",\"name\":\"isMutable\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"wearer\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"contract ISablierV2LockupLinear\",\"name\":\"sablier\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint128\",\"name\":\"totalAmount\",\"type\":\"uint128\"},{\"internalType\":\"address\",\"name\":\"asset\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"cancelable\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"transferable\",\"type\":\"bool\"},{\"components\":[{\"internalType\":\"uint40\",\"name\":\"start\",\"type\":\"uint40\"},{\"internalType\":\"uint40\",\"name\":\"cliff\",\"type\":\"uint40\"},{\"internalType\":\"uint40\",\"name\":\"end\",\"type\":\"uint40\"}],\"internalType\":\"struct LockupLinear.Timestamps\",\"name\":\"timestamps\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"fee\",\"type\":\"uint256\"}],\"internalType\":\"struct LockupLinear.Broker\",\"name\":\"broker\",\"type\":\"tuple\"}],\"internalType\":\"struct DecentHats_0_1_0.SablierStreamParams[]\",\"name\":\"sablierParams\",\"type\":\"tuple[]\"}],\"internalType\":\"struct DecentHats_0_1_0.Hat[]\",\"name\":\"hats\",\"type\":\"tuple[]\"}],\"internalType\":\"struct DecentHats_0_1_0.CreateTreeParams\",\"name\":\"params\",\"type\":\"tuple\"}],\"name\":\"createAndDeclareTree\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getSalt\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"salt\",\"type\":\"bytes32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/DecentHats_0_1_0.sol\":\"DecentHats_0_1_0\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\":{\"content\":\"// SPDX-License-Identifier: LGPL-3.0-only\\npragma solidity >=0.7.0 <0.9.0;\\n\\n/// @title Enum - Collection of enums\\n/// @author Richard Meissner - \\ncontract Enum {\\n enum Operation {Call, DelegateCall}\\n}\\n\",\"keccak256\":\"0x473e45b1a5cc47be494b0e123c9127f0c11c1e0992a321ae5a644c0bfdb2c14f\",\"license\":\"LGPL-3.0-only\"},\"@gnosis.pm/zodiac/contracts/interfaces/IAvatar.sol\":{\"content\":\"// SPDX-License-Identifier: LGPL-3.0-only\\n\\n/// @title Zodiac Avatar - A contract that manages modules that can execute transactions via this contract.\\npragma solidity >=0.7.0 <0.9.0;\\n\\nimport \\\"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\\\";\\n\\ninterface IAvatar {\\n event EnabledModule(address module);\\n event DisabledModule(address module);\\n event ExecutionFromModuleSuccess(address indexed module);\\n event ExecutionFromModuleFailure(address indexed module);\\n\\n /// @dev Enables a module on the avatar.\\n /// @notice Can only be called by the avatar.\\n /// @notice Modules should be stored as a linked list.\\n /// @notice Must emit EnabledModule(address module) if successful.\\n /// @param module Module to be enabled.\\n function enableModule(address module) external;\\n\\n /// @dev Disables a module on the avatar.\\n /// @notice Can only be called by the avatar.\\n /// @notice Must emit DisabledModule(address module) if successful.\\n /// @param prevModule Address that pointed to the module to be removed in the linked list\\n /// @param module Module to be removed.\\n function disableModule(address prevModule, address module) external;\\n\\n /// @dev Allows a Module to execute a transaction.\\n /// @notice Can only be called by an enabled module.\\n /// @notice Must emit ExecutionFromModuleSuccess(address module) if successful.\\n /// @notice Must emit ExecutionFromModuleFailure(address module) if unsuccessful.\\n /// @param to Destination address of module transaction.\\n /// @param value Ether value of module transaction.\\n /// @param data Data payload of module transaction.\\n /// @param operation Operation type of module transaction: 0 == call, 1 == delegate call.\\n function execTransactionFromModule(\\n address to,\\n uint256 value,\\n bytes memory data,\\n Enum.Operation operation\\n ) external returns (bool success);\\n\\n /// @dev Allows a Module to execute a transaction and return data\\n /// @notice Can only be called by an enabled module.\\n /// @notice Must emit ExecutionFromModuleSuccess(address module) if successful.\\n /// @notice Must emit ExecutionFromModuleFailure(address module) if unsuccessful.\\n /// @param to Destination address of module transaction.\\n /// @param value Ether value of module transaction.\\n /// @param data Data payload of module transaction.\\n /// @param operation Operation type of module transaction: 0 == call, 1 == delegate call.\\n function execTransactionFromModuleReturnData(\\n address to,\\n uint256 value,\\n bytes memory data,\\n Enum.Operation operation\\n ) external returns (bool success, bytes memory returnData);\\n\\n /// @dev Returns if an module is enabled\\n /// @return True if the module is enabled\\n function isModuleEnabled(address module) external view returns (bool);\\n\\n /// @dev Returns array of modules.\\n /// @param start Start of the page.\\n /// @param pageSize Maximum number of modules that should be returned.\\n /// @return array Array of modules.\\n /// @return next Start of the next page.\\n function getModulesPaginated(address start, uint256 pageSize)\\n external\\n view\\n returns (address[] memory array, address next);\\n}\\n\",\"keccak256\":\"0xcd5508ffe596eef8fbccfd5fc4f10a34397773547ce64e212d48b5212865ec1f\",\"license\":\"LGPL-3.0-only\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20 {\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `to`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address to, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `from` to `to` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(\\n address from,\\n address to,\\n uint256 amount\\n ) external returns (bool);\\n}\\n\",\"keccak256\":\"0x9750c6b834f7b43000631af5cc30001c5f547b3ceb3635488f140f60e897ea6b\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Strings.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev String operations.\\n */\\nlibrary Strings {\\n bytes16 private constant _HEX_SYMBOLS = \\\"0123456789abcdef\\\";\\n uint8 private constant _ADDRESS_LENGTH = 20;\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\\n */\\n function toString(uint256 value) internal pure returns (string memory) {\\n // Inspired by OraclizeAPI's implementation - MIT licence\\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\\n\\n if (value == 0) {\\n return \\\"0\\\";\\n }\\n uint256 temp = value;\\n uint256 digits;\\n while (temp != 0) {\\n digits++;\\n temp /= 10;\\n }\\n bytes memory buffer = new bytes(digits);\\n while (value != 0) {\\n digits -= 1;\\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\\n value /= 10;\\n }\\n return string(buffer);\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\\n */\\n function toHexString(uint256 value) internal pure returns (string memory) {\\n if (value == 0) {\\n return \\\"0x00\\\";\\n }\\n uint256 temp = value;\\n uint256 length = 0;\\n while (temp != 0) {\\n length++;\\n temp >>= 8;\\n }\\n return toHexString(value, length);\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\\n */\\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\\n bytes memory buffer = new bytes(2 * length + 2);\\n buffer[0] = \\\"0\\\";\\n buffer[1] = \\\"x\\\";\\n for (uint256 i = 2 * length + 1; i > 1; --i) {\\n buffer[i] = _HEX_SYMBOLS[value & 0xf];\\n value >>= 4;\\n }\\n require(value == 0, \\\"Strings: hex length insufficient\\\");\\n return string(buffer);\\n }\\n\\n /**\\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\\n */\\n function toHexString(address addr) internal pure returns (string memory) {\\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\\n }\\n}\\n\",\"keccak256\":\"0xaf159a8b1923ad2a26d516089bceca9bdeaeacd04be50983ea00ba63070f08a3\",\"license\":\"MIT\"},\"contracts/DecentHats_0_1_0.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity =0.8.19;\\n\\nimport {Enum} from \\\"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\\\";\\nimport {IAvatar} from \\\"@gnosis.pm/zodiac/contracts/interfaces/IAvatar.sol\\\";\\nimport {Strings} from \\\"@openzeppelin/contracts/utils/Strings.sol\\\";\\nimport {IERC20} from \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\nimport {IERC6551Registry} from \\\"./interfaces/IERC6551Registry.sol\\\";\\nimport {IHats} from \\\"./interfaces/hats/IHats.sol\\\";\\nimport {ISablierV2LockupLinear} from \\\"./interfaces/sablier/ISablierV2LockupLinear.sol\\\";\\nimport {LockupLinear} from \\\"./interfaces/sablier/LockupLinear.sol\\\";\\n\\ncontract DecentHats_0_1_0 {\\n string public constant NAME = \\\"DecentHats_0_1_0\\\";\\n\\n struct SablierStreamParams {\\n ISablierV2LockupLinear sablier;\\n address sender;\\n uint128 totalAmount;\\n address asset;\\n bool cancelable;\\n bool transferable;\\n LockupLinear.Timestamps timestamps;\\n LockupLinear.Broker broker;\\n }\\n\\n struct Hat {\\n uint32 maxSupply;\\n string details;\\n string imageURI;\\n bool isMutable;\\n address wearer;\\n SablierStreamParams[] sablierParams; // Optional Sablier stream parameters\\n }\\n\\n struct CreateTreeParams {\\n IHats hatsProtocol;\\n address hatsAccountImplementation;\\n IERC6551Registry registry;\\n address keyValuePairs;\\n string topHatDetails;\\n string topHatImageURI;\\n Hat adminHat;\\n Hat[] hats;\\n }\\n\\n function getSalt() public pure returns (bytes32 salt) {\\n return\\n 0x5d0e6ce4fd951366cc55da93f6e79d8b81483109d79676a04bcc2bed6a4b5072;\\n }\\n\\n function updateKeyValuePairs(\\n address _keyValuePairs,\\n uint256 topHatId\\n ) internal {\\n string[] memory keys = new string[](1);\\n string[] memory values = new string[](1);\\n keys[0] = \\\"topHatId\\\";\\n values[0] = Strings.toString(topHatId);\\n\\n IAvatar(msg.sender).execTransactionFromModule(\\n _keyValuePairs,\\n 0,\\n abi.encodeWithSignature(\\n \\\"updateValues(string[],string[])\\\",\\n keys,\\n values\\n ),\\n Enum.Operation.Call\\n );\\n }\\n\\n function createHat(\\n IHats _hatsProtocol,\\n uint256 adminHatId,\\n Hat memory _hat,\\n address topHatAccount\\n ) internal returns (uint256) {\\n return\\n _hatsProtocol.createHat(\\n adminHatId,\\n _hat.details,\\n _hat.maxSupply,\\n topHatAccount,\\n topHatAccount,\\n _hat.isMutable,\\n _hat.imageURI\\n );\\n }\\n\\n function createAccount(\\n IERC6551Registry _registry,\\n address _hatsAccountImplementation,\\n bytes32 salt,\\n address protocolAddress,\\n uint256 hatId\\n ) internal returns (address) {\\n return\\n _registry.createAccount(\\n _hatsAccountImplementation,\\n salt,\\n block.chainid,\\n protocolAddress,\\n hatId\\n );\\n }\\n\\n function createTopHatAndAccount(\\n IHats _hatsProtocol,\\n string memory _topHatDetails,\\n string memory _topHatImageURI,\\n IERC6551Registry _registry,\\n address _hatsAccountImplementation,\\n bytes32 salt\\n ) internal returns (uint256 topHatId, address topHatAccount) {\\n topHatId = _hatsProtocol.mintTopHat(\\n address(this),\\n _topHatDetails,\\n _topHatImageURI\\n );\\n\\n topHatAccount = createAccount(\\n _registry,\\n _hatsAccountImplementation,\\n salt,\\n address(_hatsProtocol),\\n topHatId\\n );\\n }\\n\\n function createHatAndAccountAndMintAndStreams(\\n IHats hatsProtocol,\\n uint256 adminHatId,\\n Hat calldata hat,\\n address topHatAccount,\\n IERC6551Registry registry,\\n address hatsAccountImplementation,\\n bytes32 salt\\n ) internal returns (uint256 hatId, address accountAddress) {\\n hatId = createHat(hatsProtocol, adminHatId, hat, topHatAccount);\\n\\n accountAddress = createAccount(\\n registry,\\n hatsAccountImplementation,\\n salt,\\n address(hatsProtocol),\\n hatId\\n );\\n\\n if (hat.wearer != address(0)) {\\n hatsProtocol.mintHat(hatId, hat.wearer);\\n }\\n\\n for (uint256 i = 0; i < hat.sablierParams.length; ) {\\n SablierStreamParams memory sablierParams = hat.sablierParams[i];\\n\\n // Approve tokens for Sablier\\n IAvatar(msg.sender).execTransactionFromModule(\\n sablierParams.asset,\\n 0,\\n abi.encodeWithSignature(\\n \\\"approve(address,uint256)\\\",\\n address(sablierParams.sablier),\\n sablierParams.totalAmount\\n ),\\n Enum.Operation.Call\\n );\\n\\n LockupLinear.CreateWithTimestamps memory params = LockupLinear\\n .CreateWithTimestamps({\\n sender: sablierParams.sender,\\n recipient: accountAddress,\\n totalAmount: sablierParams.totalAmount,\\n asset: IERC20(sablierParams.asset),\\n cancelable: sablierParams.cancelable,\\n transferable: sablierParams.transferable,\\n timestamps: sablierParams.timestamps,\\n broker: sablierParams.broker\\n });\\n\\n // Proxy the Sablier call through IAvatar\\n IAvatar(msg.sender).execTransactionFromModule(\\n address(sablierParams.sablier),\\n 0,\\n abi.encodeWithSignature(\\n \\\"createWithTimestamps((address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256)))\\\",\\n params\\n ),\\n Enum.Operation.Call\\n );\\n\\n unchecked {\\n ++i;\\n }\\n }\\n }\\n\\n function createAndDeclareTree(CreateTreeParams calldata params) public {\\n bytes32 salt = getSalt();\\n\\n (uint256 topHatId, address topHatAccount) = createTopHatAndAccount(\\n params.hatsProtocol,\\n params.topHatDetails,\\n params.topHatImageURI,\\n params.registry,\\n params.hatsAccountImplementation,\\n salt\\n );\\n\\n updateKeyValuePairs(params.keyValuePairs, topHatId);\\n\\n (uint256 adminHatId, ) = createHatAndAccountAndMintAndStreams(\\n params.hatsProtocol,\\n topHatId,\\n params.adminHat,\\n topHatAccount,\\n params.registry,\\n params.hatsAccountImplementation,\\n salt\\n );\\n\\n for (uint256 i = 0; i < params.hats.length; ) {\\n createHatAndAccountAndMintAndStreams(\\n params.hatsProtocol,\\n adminHatId,\\n params.hats[i],\\n topHatAccount,\\n params.registry,\\n params.hatsAccountImplementation,\\n salt\\n );\\n\\n unchecked {\\n ++i;\\n }\\n }\\n\\n params.hatsProtocol.transferHat(topHatId, address(this), msg.sender);\\n }\\n}\\n\",\"keccak256\":\"0xcf4e6d62ca64f62b8eb638805a8a4e715aea8fc201f3dea9a522edc1034599f1\",\"license\":\"MIT\"},\"contracts/interfaces/IERC6551Registry.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.4;\\n\\ninterface IERC6551Registry {\\n /**\\n * @dev Creates a token bound account for a non-fungible token.\\n *\\n * If account has already been created, returns the account address without calling create2.\\n *\\n * Emits ERC6551AccountCreated event.\\n *\\n * @return account The address of the token bound account\\n */\\n function createAccount(\\n address implementation,\\n bytes32 salt,\\n uint256 chainId,\\n address tokenContract,\\n uint256 tokenId\\n ) external returns (address account);\\n}\\n\",\"keccak256\":\"0x64c52de8a8e68398e61dd8b42dda8e9af8cf6abf93bb85629c322440991ea568\",\"license\":\"MIT\"},\"contracts/interfaces/hats/IHats.sol\":{\"content\":\"// SPDX-License-Identifier: AGPL-3.0\\n// Copyright (C) 2023 Haberdasher Labs\\n//\\n// This program is free software: you can redistribute it and/or modify\\n// it under the terms of the GNU Affero General Public License as published by\\n// the Free Software Foundation, either version 3 of the License, or\\n// (at your option) any later version.\\n//\\n// This program is distributed in the hope that it will be useful,\\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\\n// GNU Affero General Public License for more details.\\n//\\n// You should have received a copy of the GNU Affero General Public License\\n// along with this program. If not, see .\\n\\npragma solidity >=0.8.13;\\n\\ninterface IHats {\\n function mintTopHat(\\n address _target,\\n string memory _details,\\n string memory _imageURI\\n ) external returns (uint256 topHatId);\\n\\n function createHat(\\n uint256 _admin,\\n string calldata _details,\\n uint32 _maxSupply,\\n address _eligibility,\\n address _toggle,\\n bool _mutable,\\n string calldata _imageURI\\n ) external returns (uint256 newHatId);\\n\\n function mintHat(\\n uint256 _hatId,\\n address _wearer\\n ) external returns (bool success);\\n\\n function transferHat(uint256 _hatId, address _from, address _to) external;\\n}\\n\",\"keccak256\":\"0x8e35022f5c0fcf0059033abec78ec890f0cf3bbac09d6d24051cff9679239511\",\"license\":\"AGPL-3.0\"},\"contracts/interfaces/sablier/ISablierV2LockupLinear.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport {LockupLinear} from \\\"./LockupLinear.sol\\\";\\nimport {IERC20} from \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\n\\ninterface ISablierV2LockupLinear {\\n function createWithTimestamps(\\n LockupLinear.CreateWithTimestamps calldata params\\n ) external returns (uint256 streamId);\\n}\\n\",\"keccak256\":\"0xf4899637eb2e6c76c35e2d201e56e162a50e6bc7b5b9156e00866f0703ad07ca\",\"license\":\"MIT\"},\"contracts/interfaces/sablier/LockupLinear.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport {IERC20} from \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\n\\nlibrary LockupLinear {\\n struct CreateWithTimestamps {\\n address sender;\\n address recipient;\\n uint128 totalAmount;\\n IERC20 asset;\\n bool cancelable;\\n bool transferable;\\n Timestamps timestamps;\\n Broker broker;\\n }\\n\\n struct Timestamps {\\n uint40 start;\\n uint40 cliff;\\n uint40 end;\\n }\\n\\n struct Broker {\\n address account;\\n uint256 fee;\\n }\\n}\\n\",\"keccak256\":\"0x497fdb52b5e1a5a7e0711a9f7d5fb036eb668ccb92ea908ee088f56ee08a4ce8\",\"license\":\"MIT\"}},\"version\":1}", - "bytecode": "0x608060405234801561001057600080fd5b50611410806100206000396000f3fe608060405234801561001057600080fd5b50600436106100415760003560e01c806313a9589c146100465780638c5f591a14610079578063a3f4df7e1461008e575b600080fd5b6040517f5d0e6ce4fd951366cc55da93f6e79d8b81483109d79676a04bcc2bed6a4b507281526020015b60405180910390f35b61008c610087366004610aa8565b6100ca565b005b6100bd6040518060400160405280601081526020016f0446563656e74486174735f305f315f360841b81525081565b6040516100709190610b30565b7f5d0e6ce4fd951366cc55da93f6e79d8b81483109d79676a04bcc2bed6a4b50726000806101a86100fe6020860186610b5b565b61010b6080870187610b78565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061014d9250505060a0880188610b78565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610192925050506060890160408a01610b5b565b6101a260408a0160208b01610b5b565b88610317565b90925090506101c66101c06080860160608701610b5b565b836103a9565b600061020d6101d86020870187610b5b565b846101e660c0890189610bd5565b856101f760608b0160408c01610b5b565b61020760408c0160208d01610b5b565b8a610529565b50905060005b61022060e0870187610bf5565b905081101561029a576102906102396020880188610b5b565b8361024760e08a018a610bf5565b8581811061025757610257610c3e565b90506020028101906102699190610bd5565b8661027a60608c0160408d01610b5b565b61028a60408d0160208e01610b5b565b8b610529565b5050600101610213565b506102a86020860186610b5b565b6040516329287c1b60e21b8152600481018590523060248201523360448201526001600160a01b03919091169063a4a1f06c90606401600060405180830381600087803b1580156102f857600080fd5b505af115801561030c573d6000803e3d6000fd5b505050505050505050565b600080876001600160a01b0316631a64dfad3089896040518463ffffffff1660e01b815260040161034a93929190610c54565b6020604051808303816000875af1158015610369573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061038d9190610c8a565b915061039c8585858b86610878565b9050965096945050505050565b604080516001808252818301909252600091816020015b60608152602001906001900390816103c057505060408051600180825281830190925291925060009190602082015b60608152602001906001900390816103ef579050509050604051806040016040528060088152602001671d1bdc12185d125960c21b8152508260008151811061043a5761043a610c3e565b602002602001018190525061044e8361090e565b8160008151811061046157610461610c3e565b6020026020010181905250336001600160a01b031663468721a78560008585604051602401610491929190610d11565b60408051601f198184030181529181526020820180516001600160e01b031663579374b960e11b1790525160e085901b6001600160e01b03191681526104df93929190600090600401610d36565b6020604051808303816000875af11580156104fe573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105229190610d9a565b5050505050565b600080610540898961053a8a6110d4565b89610a16565b915061054f8585858c86610878565b9050600061056360a0890160808a01610b5b565b6001600160a01b031614610603576001600160a01b03891663641f776e8361059160a08b0160808c01610b5b565b6040516001600160e01b031960e085901b16815260048101929092526001600160a01b031660248201526044016020604051808303816000875af11580156105dd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106019190610d9a565b505b60005b61061360a0890189611198565b905081101561086b57600061062b60a08a018a611198565b8381811061063b5761063b610c3e565b9050610160020180360381019061065291906111e1565b6060810151815160408084015190516001600160a01b0390921660248301526001600160801b03166044820152919250339163468721a7919060009060640160408051601f198184030181529181526020820180516001600160e01b031663095ea7b360e01b1790525160e085901b6001600160e01b03191681526106df93929190600090600401610d36565b6020604051808303816000875af11580156106fe573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107229190610d9a565b50600060405180610100016040528083602001516001600160a01b03168152602001856001600160a01b0316815260200183604001516001600160801b0316815260200183606001516001600160a01b031681526020018360800151151581526020018360a00151151581526020018360c0015181526020018360e001518152509050336001600160a01b031663468721a783600001516000846040516024016107cc91906111fe565b60408051601f198184030181529181526020820180516001600160e01b03166353b1572760e01b1790525160e085901b6001600160e01b031916815261081a93929190600090600401610d36565b6020604051808303816000875af1158015610839573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061085d9190610d9a565b508260010192505050610606565b5097509795505050505050565b604051638a54c52f60e01b81526001600160a01b0385811660048301526024820185905246604483015283811660648301526084820183905260009190871690638a54c52f9060a4016020604051808303816000875af11580156108e0573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061090491906112c0565b9695505050505050565b6060816000036109355750506040805180820190915260018152600360fc1b602082015290565b8160005b811561095f5780610949816112f3565b91506109589050600a83611322565b9150610939565b6000816001600160401b0381111561097957610979610ca3565b6040519080825280601f01601f1916602001820160405280156109a3576020820181803683370190505b5090505b8415610a0e576109b8600183611336565b91506109c5600a8661134f565b6109d0906030611363565b60f81b8183815181106109e5576109e5610c3e565b60200101906001600160f81b031916908160001a905350610a07600a86611322565b94506109a7565b949350505050565b6020820151825160608401516040808601519051635829492f60e11b81526000946001600160a01b038a169463b052925e94610a5c948b948a9283929091600401611376565b6020604051808303816000875af1158015610a7b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a9f9190610c8a565b95945050505050565b600060208284031215610aba57600080fd5b81356001600160401b03811115610ad057600080fd5b82016101008185031215610ae357600080fd5b9392505050565b6000815180845260005b81811015610b1057602081850181015186830182015201610af4565b506000602082860101526020601f19601f83011685010191505092915050565b602081526000610ae36020830184610aea565b6001600160a01b0381168114610b5857600080fd5b50565b600060208284031215610b6d57600080fd5b8135610ae381610b43565b6000808335601e19843603018112610b8f57600080fd5b8301803591506001600160401b03821115610ba957600080fd5b602001915036819003821315610bbe57600080fd5b9250929050565b8035610bd081610b43565b919050565b6000823560be19833603018112610beb57600080fd5b9190910192915050565b6000808335601e19843603018112610c0c57600080fd5b8301803591506001600160401b03821115610c2657600080fd5b6020019150600581901b3603821315610bbe57600080fd5b634e487b7160e01b600052603260045260246000fd5b6001600160a01b0384168152606060208201819052600090610c7890830185610aea565b82810360408401526109048185610aea565b600060208284031215610c9c57600080fd5b5051919050565b634e487b7160e01b600052604160045260246000fd5b600082825180855260208086019550808260051b84010181860160005b84811015610d0457601f19868403018952610cf2838351610aea565b98840198925090830190600101610cd6565b5090979650505050505050565b604081526000610d246040830185610cb9565b8281036020840152610a9f8185610cb9565b60018060a01b0385168152836020820152608060408201526000610d5d6080830185610aea565b905060028310610d7d57634e487b7160e01b600052602160045260246000fd5b82606083015295945050505050565b8015158114610b5857600080fd5b600060208284031215610dac57600080fd5b8151610ae381610d8c565b60405160c081016001600160401b0381118282101715610dd957610dd9610ca3565b60405290565b604051601f8201601f191681016001600160401b0381118282101715610e0757610e07610ca3565b604052919050565b803563ffffffff81168114610bd057600080fd5b600082601f830112610e3457600080fd5b81356001600160401b03811115610e4d57610e4d610ca3565b610e60601f8201601f1916602001610ddf565b818152846020838601011115610e7557600080fd5b816020850160208301376000918101602001919091529392505050565b8035610bd081610d8c565b80356001600160801b0381168114610bd057600080fd5b803564ffffffffff81168114610bd057600080fd5b600060608284031215610edb57600080fd5b604051606081018181106001600160401b0382111715610efd57610efd610ca3565b604052905080610f0c83610eb4565b8152610f1a60208401610eb4565b6020820152610f2b60408401610eb4565b60408201525092915050565b600060408284031215610f4957600080fd5b604051604081018181106001600160401b0382111715610f6b57610f6b610ca3565b6040529050808235610f7c81610b43565b8152602092830135920191909152919050565b60006101608284031215610fa257600080fd5b60405161010081018181106001600160401b0382111715610fc557610fc5610ca3565b604052905080610fd483610bc5565b8152610fe260208401610bc5565b6020820152610ff360408401610e9d565b604082015261100460608401610bc5565b606082015261101560808401610e92565b608082015261102660a08401610e92565b60a08201526110388460c08501610ec9565b60c082015261104b846101208501610f37565b60e08201525092915050565b600082601f83011261106857600080fd5b813560206001600160401b0382111561108357611083610ca3565b611091818360051b01610ddf565b82815261016092830285018201928282019190878511156110b157600080fd5b8387015b85811015610d04576110c78982610f8f565b84529284019281016110b5565b600060c082360312156110e657600080fd5b6110ee610db7565b6110f783610e0f565b815260208301356001600160401b038082111561111357600080fd5b61111f36838701610e23565b6020840152604085013591508082111561113857600080fd5b61114436838701610e23565b604084015261115560608601610e92565b606084015261116660808601610bc5565b608084015260a085013591508082111561117f57600080fd5b5061118c36828601611057565b60a08301525092915050565b6000808335601e198436030181126111af57600080fd5b8301803591506001600160401b038211156111c957600080fd5b602001915061016081023603821315610bbe57600080fd5b600061016082840312156111f457600080fd5b610ae38383610f8f565b81516001600160a01b0390811682526020808401518216908301526040808401516001600160801b031690830152606080840151909116908201526080808301516101608301916112529084018215159052565b5060a083015161126660a084018215159052565b5060c083015161129960c0840182805164ffffffffff908116835260208083015182169084015260409182015116910152565b5060e0929092015180516001600160a01b0316610120830152602001516101409091015290565b6000602082840312156112d257600080fd5b8151610ae381610b43565b634e487b7160e01b600052601160045260246000fd5b600060018201611305576113056112dd565b5060010190565b634e487b7160e01b600052601260045260246000fd5b6000826113315761133161130c565b500490565b81810381811115611349576113496112dd565b92915050565b60008261135e5761135e61130c565b500690565b80820180821115611349576113496112dd565b87815260e06020820152600061138f60e0830189610aea565b63ffffffff881660408401526001600160a01b0387811660608501528616608084015284151560a084015282810360c08401526113cc8185610aea565b9a995050505050505050505056fea2646970667358221220fcb8ad75991fd171fd33998d718d5f54883d99a48d56657e7e938e34a55d6a2664736f6c63430008130033", - "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100415760003560e01c806313a9589c146100465780638c5f591a14610079578063a3f4df7e1461008e575b600080fd5b6040517f5d0e6ce4fd951366cc55da93f6e79d8b81483109d79676a04bcc2bed6a4b507281526020015b60405180910390f35b61008c610087366004610aa8565b6100ca565b005b6100bd6040518060400160405280601081526020016f0446563656e74486174735f305f315f360841b81525081565b6040516100709190610b30565b7f5d0e6ce4fd951366cc55da93f6e79d8b81483109d79676a04bcc2bed6a4b50726000806101a86100fe6020860186610b5b565b61010b6080870187610b78565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061014d9250505060a0880188610b78565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610192925050506060890160408a01610b5b565b6101a260408a0160208b01610b5b565b88610317565b90925090506101c66101c06080860160608701610b5b565b836103a9565b600061020d6101d86020870187610b5b565b846101e660c0890189610bd5565b856101f760608b0160408c01610b5b565b61020760408c0160208d01610b5b565b8a610529565b50905060005b61022060e0870187610bf5565b905081101561029a576102906102396020880188610b5b565b8361024760e08a018a610bf5565b8581811061025757610257610c3e565b90506020028101906102699190610bd5565b8661027a60608c0160408d01610b5b565b61028a60408d0160208e01610b5b565b8b610529565b5050600101610213565b506102a86020860186610b5b565b6040516329287c1b60e21b8152600481018590523060248201523360448201526001600160a01b03919091169063a4a1f06c90606401600060405180830381600087803b1580156102f857600080fd5b505af115801561030c573d6000803e3d6000fd5b505050505050505050565b600080876001600160a01b0316631a64dfad3089896040518463ffffffff1660e01b815260040161034a93929190610c54565b6020604051808303816000875af1158015610369573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061038d9190610c8a565b915061039c8585858b86610878565b9050965096945050505050565b604080516001808252818301909252600091816020015b60608152602001906001900390816103c057505060408051600180825281830190925291925060009190602082015b60608152602001906001900390816103ef579050509050604051806040016040528060088152602001671d1bdc12185d125960c21b8152508260008151811061043a5761043a610c3e565b602002602001018190525061044e8361090e565b8160008151811061046157610461610c3e565b6020026020010181905250336001600160a01b031663468721a78560008585604051602401610491929190610d11565b60408051601f198184030181529181526020820180516001600160e01b031663579374b960e11b1790525160e085901b6001600160e01b03191681526104df93929190600090600401610d36565b6020604051808303816000875af11580156104fe573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105229190610d9a565b5050505050565b600080610540898961053a8a6110d4565b89610a16565b915061054f8585858c86610878565b9050600061056360a0890160808a01610b5b565b6001600160a01b031614610603576001600160a01b03891663641f776e8361059160a08b0160808c01610b5b565b6040516001600160e01b031960e085901b16815260048101929092526001600160a01b031660248201526044016020604051808303816000875af11580156105dd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106019190610d9a565b505b60005b61061360a0890189611198565b905081101561086b57600061062b60a08a018a611198565b8381811061063b5761063b610c3e565b9050610160020180360381019061065291906111e1565b6060810151815160408084015190516001600160a01b0390921660248301526001600160801b03166044820152919250339163468721a7919060009060640160408051601f198184030181529181526020820180516001600160e01b031663095ea7b360e01b1790525160e085901b6001600160e01b03191681526106df93929190600090600401610d36565b6020604051808303816000875af11580156106fe573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107229190610d9a565b50600060405180610100016040528083602001516001600160a01b03168152602001856001600160a01b0316815260200183604001516001600160801b0316815260200183606001516001600160a01b031681526020018360800151151581526020018360a00151151581526020018360c0015181526020018360e001518152509050336001600160a01b031663468721a783600001516000846040516024016107cc91906111fe565b60408051601f198184030181529181526020820180516001600160e01b03166353b1572760e01b1790525160e085901b6001600160e01b031916815261081a93929190600090600401610d36565b6020604051808303816000875af1158015610839573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061085d9190610d9a565b508260010192505050610606565b5097509795505050505050565b604051638a54c52f60e01b81526001600160a01b0385811660048301526024820185905246604483015283811660648301526084820183905260009190871690638a54c52f9060a4016020604051808303816000875af11580156108e0573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061090491906112c0565b9695505050505050565b6060816000036109355750506040805180820190915260018152600360fc1b602082015290565b8160005b811561095f5780610949816112f3565b91506109589050600a83611322565b9150610939565b6000816001600160401b0381111561097957610979610ca3565b6040519080825280601f01601f1916602001820160405280156109a3576020820181803683370190505b5090505b8415610a0e576109b8600183611336565b91506109c5600a8661134f565b6109d0906030611363565b60f81b8183815181106109e5576109e5610c3e565b60200101906001600160f81b031916908160001a905350610a07600a86611322565b94506109a7565b949350505050565b6020820151825160608401516040808601519051635829492f60e11b81526000946001600160a01b038a169463b052925e94610a5c948b948a9283929091600401611376565b6020604051808303816000875af1158015610a7b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a9f9190610c8a565b95945050505050565b600060208284031215610aba57600080fd5b81356001600160401b03811115610ad057600080fd5b82016101008185031215610ae357600080fd5b9392505050565b6000815180845260005b81811015610b1057602081850181015186830182015201610af4565b506000602082860101526020601f19601f83011685010191505092915050565b602081526000610ae36020830184610aea565b6001600160a01b0381168114610b5857600080fd5b50565b600060208284031215610b6d57600080fd5b8135610ae381610b43565b6000808335601e19843603018112610b8f57600080fd5b8301803591506001600160401b03821115610ba957600080fd5b602001915036819003821315610bbe57600080fd5b9250929050565b8035610bd081610b43565b919050565b6000823560be19833603018112610beb57600080fd5b9190910192915050565b6000808335601e19843603018112610c0c57600080fd5b8301803591506001600160401b03821115610c2657600080fd5b6020019150600581901b3603821315610bbe57600080fd5b634e487b7160e01b600052603260045260246000fd5b6001600160a01b0384168152606060208201819052600090610c7890830185610aea565b82810360408401526109048185610aea565b600060208284031215610c9c57600080fd5b5051919050565b634e487b7160e01b600052604160045260246000fd5b600082825180855260208086019550808260051b84010181860160005b84811015610d0457601f19868403018952610cf2838351610aea565b98840198925090830190600101610cd6565b5090979650505050505050565b604081526000610d246040830185610cb9565b8281036020840152610a9f8185610cb9565b60018060a01b0385168152836020820152608060408201526000610d5d6080830185610aea565b905060028310610d7d57634e487b7160e01b600052602160045260246000fd5b82606083015295945050505050565b8015158114610b5857600080fd5b600060208284031215610dac57600080fd5b8151610ae381610d8c565b60405160c081016001600160401b0381118282101715610dd957610dd9610ca3565b60405290565b604051601f8201601f191681016001600160401b0381118282101715610e0757610e07610ca3565b604052919050565b803563ffffffff81168114610bd057600080fd5b600082601f830112610e3457600080fd5b81356001600160401b03811115610e4d57610e4d610ca3565b610e60601f8201601f1916602001610ddf565b818152846020838601011115610e7557600080fd5b816020850160208301376000918101602001919091529392505050565b8035610bd081610d8c565b80356001600160801b0381168114610bd057600080fd5b803564ffffffffff81168114610bd057600080fd5b600060608284031215610edb57600080fd5b604051606081018181106001600160401b0382111715610efd57610efd610ca3565b604052905080610f0c83610eb4565b8152610f1a60208401610eb4565b6020820152610f2b60408401610eb4565b60408201525092915050565b600060408284031215610f4957600080fd5b604051604081018181106001600160401b0382111715610f6b57610f6b610ca3565b6040529050808235610f7c81610b43565b8152602092830135920191909152919050565b60006101608284031215610fa257600080fd5b60405161010081018181106001600160401b0382111715610fc557610fc5610ca3565b604052905080610fd483610bc5565b8152610fe260208401610bc5565b6020820152610ff360408401610e9d565b604082015261100460608401610bc5565b606082015261101560808401610e92565b608082015261102660a08401610e92565b60a08201526110388460c08501610ec9565b60c082015261104b846101208501610f37565b60e08201525092915050565b600082601f83011261106857600080fd5b813560206001600160401b0382111561108357611083610ca3565b611091818360051b01610ddf565b82815261016092830285018201928282019190878511156110b157600080fd5b8387015b85811015610d04576110c78982610f8f565b84529284019281016110b5565b600060c082360312156110e657600080fd5b6110ee610db7565b6110f783610e0f565b815260208301356001600160401b038082111561111357600080fd5b61111f36838701610e23565b6020840152604085013591508082111561113857600080fd5b61114436838701610e23565b604084015261115560608601610e92565b606084015261116660808601610bc5565b608084015260a085013591508082111561117f57600080fd5b5061118c36828601611057565b60a08301525092915050565b6000808335601e198436030181126111af57600080fd5b8301803591506001600160401b038211156111c957600080fd5b602001915061016081023603821315610bbe57600080fd5b600061016082840312156111f457600080fd5b610ae38383610f8f565b81516001600160a01b0390811682526020808401518216908301526040808401516001600160801b031690830152606080840151909116908201526080808301516101608301916112529084018215159052565b5060a083015161126660a084018215159052565b5060c083015161129960c0840182805164ffffffffff908116835260208083015182169084015260409182015116910152565b5060e0929092015180516001600160a01b0316610120830152602001516101409091015290565b6000602082840312156112d257600080fd5b8151610ae381610b43565b634e487b7160e01b600052601160045260246000fd5b600060018201611305576113056112dd565b5060010190565b634e487b7160e01b600052601260045260246000fd5b6000826113315761133161130c565b500490565b81810381811115611349576113496112dd565b92915050565b60008261135e5761135e61130c565b500690565b80820180821115611349576113496112dd565b87815260e06020820152600061138f60e0830189610aea565b63ffffffff881660408401526001600160a01b0387811660608501528616608084015284151560a084015282810360c08401526113cc8185610aea565b9a995050505050505050505056fea2646970667358221220fcb8ad75991fd171fd33998d718d5f54883d99a48d56657e7e938e34a55d6a2664736f6c63430008130033", + "numDeployments": 4, + "solcInputHash": "4754a2f0c9d6a191a066af246491b62a", + "metadata": "{\"compiler\":{\"version\":\"0.8.19+commit.7dd6d404\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"NAME\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"contract IHats\",\"name\":\"hatsProtocol\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"hatsAccountImplementation\",\"type\":\"address\"},{\"internalType\":\"contract IERC6551Registry\",\"name\":\"registry\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"keyValuePairs\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"topHatDetails\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"topHatImageURI\",\"type\":\"string\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"maxSupply\",\"type\":\"uint32\"},{\"internalType\":\"string\",\"name\":\"details\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"imageURI\",\"type\":\"string\"},{\"internalType\":\"bool\",\"name\":\"isMutable\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"wearer\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"contract ISablierV2LockupLinear\",\"name\":\"sablier\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint128\",\"name\":\"totalAmount\",\"type\":\"uint128\"},{\"internalType\":\"address\",\"name\":\"asset\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"cancelable\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"transferable\",\"type\":\"bool\"},{\"components\":[{\"internalType\":\"uint40\",\"name\":\"start\",\"type\":\"uint40\"},{\"internalType\":\"uint40\",\"name\":\"cliff\",\"type\":\"uint40\"},{\"internalType\":\"uint40\",\"name\":\"end\",\"type\":\"uint40\"}],\"internalType\":\"struct LockupLinear.Timestamps\",\"name\":\"timestamps\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"fee\",\"type\":\"uint256\"}],\"internalType\":\"struct LockupLinear.Broker\",\"name\":\"broker\",\"type\":\"tuple\"}],\"internalType\":\"struct DecentHats_0_1_0.SablierStreamParams[]\",\"name\":\"sablierParams\",\"type\":\"tuple[]\"}],\"internalType\":\"struct DecentHats_0_1_0.Hat\",\"name\":\"adminHat\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"maxSupply\",\"type\":\"uint32\"},{\"internalType\":\"string\",\"name\":\"details\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"imageURI\",\"type\":\"string\"},{\"internalType\":\"bool\",\"name\":\"isMutable\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"wearer\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"contract ISablierV2LockupLinear\",\"name\":\"sablier\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint128\",\"name\":\"totalAmount\",\"type\":\"uint128\"},{\"internalType\":\"address\",\"name\":\"asset\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"cancelable\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"transferable\",\"type\":\"bool\"},{\"components\":[{\"internalType\":\"uint40\",\"name\":\"start\",\"type\":\"uint40\"},{\"internalType\":\"uint40\",\"name\":\"cliff\",\"type\":\"uint40\"},{\"internalType\":\"uint40\",\"name\":\"end\",\"type\":\"uint40\"}],\"internalType\":\"struct LockupLinear.Timestamps\",\"name\":\"timestamps\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"fee\",\"type\":\"uint256\"}],\"internalType\":\"struct LockupLinear.Broker\",\"name\":\"broker\",\"type\":\"tuple\"}],\"internalType\":\"struct DecentHats_0_1_0.SablierStreamParams[]\",\"name\":\"sablierParams\",\"type\":\"tuple[]\"}],\"internalType\":\"struct DecentHats_0_1_0.Hat[]\",\"name\":\"hats\",\"type\":\"tuple[]\"}],\"internalType\":\"struct DecentHats_0_1_0.CreateTreeParams\",\"name\":\"params\",\"type\":\"tuple\"}],\"name\":\"createAndDeclareTree\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract IHats\",\"name\":\"hatsProtocol\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"adminHatId\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"maxSupply\",\"type\":\"uint32\"},{\"internalType\":\"string\",\"name\":\"details\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"imageURI\",\"type\":\"string\"},{\"internalType\":\"bool\",\"name\":\"isMutable\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"wearer\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"contract ISablierV2LockupLinear\",\"name\":\"sablier\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint128\",\"name\":\"totalAmount\",\"type\":\"uint128\"},{\"internalType\":\"address\",\"name\":\"asset\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"cancelable\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"transferable\",\"type\":\"bool\"},{\"components\":[{\"internalType\":\"uint40\",\"name\":\"start\",\"type\":\"uint40\"},{\"internalType\":\"uint40\",\"name\":\"cliff\",\"type\":\"uint40\"},{\"internalType\":\"uint40\",\"name\":\"end\",\"type\":\"uint40\"}],\"internalType\":\"struct LockupLinear.Timestamps\",\"name\":\"timestamps\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"fee\",\"type\":\"uint256\"}],\"internalType\":\"struct LockupLinear.Broker\",\"name\":\"broker\",\"type\":\"tuple\"}],\"internalType\":\"struct DecentHats_0_1_0.SablierStreamParams[]\",\"name\":\"sablierParams\",\"type\":\"tuple[]\"}],\"internalType\":\"struct DecentHats_0_1_0.Hat\",\"name\":\"hat\",\"type\":\"tuple\"},{\"internalType\":\"uint256\",\"name\":\"topHatId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"topHatAccount\",\"type\":\"address\"},{\"internalType\":\"contract IERC6551Registry\",\"name\":\"registry\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"hatsAccountImplementation\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"salt\",\"type\":\"bytes32\"}],\"name\":\"createRoleHat\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"hatId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"accountAddress\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getSalt\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"salt\",\"type\":\"bytes32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"createAndDeclareTree((address,address,address,address,string,string,(uint32,string,string,bool,address,(address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256))[]),(uint32,string,string,bool,address,(address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256))[])[]))\":{\"details\":\"In order for a Safe to seamlessly create roles even if it has never previously created a role and thus has no hat tree, we defer the creation of the hat tree and its setup to this contract. This way, in a single tx block, the resulting topHatId of the newly created hat can be used to create an admin hat and any other hats needed. We also make use of `KeyValuePairs` to associate the topHatId with the Safe.\"},\"createRoleHat(address,uint256,(uint32,string,string,bool,address,(address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256))[]),uint256,address,address,address,bytes32)\":{\"details\":\"Role hat creation, minting, smart account creation and stream creation are handled here in order to avoid a race condition where not more than one active proposal to create a new role can exist at a time. See: https://github.com/decentdao/decent-interface/issues/2402\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"createAndDeclareTree((address,address,address,address,string,string,(uint32,string,string,bool,address,(address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256))[]),(uint32,string,string,bool,address,(address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256))[])[]))\":{\"notice\":\"For a safe without any roles previously created on it, this function should be called. It sets up the top hat and admin hat, as well as any other hats and their streams that are provided. This contract should be enabled a module on the Safe for which the role(s) are to be created, and disabled after.\"},\"createRoleHat(address,uint256,(uint32,string,string,bool,address,(address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256))[]),uint256,address,address,address,bytes32)\":{\"notice\":\"Creates a new role hat and any streams on it. This contract should be enabled a module on the Safe for which the role is to be created, and disable after. In order for the module to be able to create hats on behalf of the Safe, the Safe must first transfer its top hat to this contract. This function transfers the top hat back to the Safe after creating the role hat. The function simply calls `createHatAndAccountAndMintAndStreams` and then transfers the top hat back to the Safe.\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/DecentHats_0_1_0.sol\":\"DecentHats_0_1_0\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\":{\"content\":\"// SPDX-License-Identifier: LGPL-3.0-only\\npragma solidity >=0.7.0 <0.9.0;\\n\\n/// @title Enum - Collection of enums\\n/// @author Richard Meissner - \\ncontract Enum {\\n enum Operation {Call, DelegateCall}\\n}\\n\",\"keccak256\":\"0x473e45b1a5cc47be494b0e123c9127f0c11c1e0992a321ae5a644c0bfdb2c14f\",\"license\":\"LGPL-3.0-only\"},\"@gnosis.pm/zodiac/contracts/interfaces/IAvatar.sol\":{\"content\":\"// SPDX-License-Identifier: LGPL-3.0-only\\n\\n/// @title Zodiac Avatar - A contract that manages modules that can execute transactions via this contract.\\npragma solidity >=0.7.0 <0.9.0;\\n\\nimport \\\"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\\\";\\n\\ninterface IAvatar {\\n event EnabledModule(address module);\\n event DisabledModule(address module);\\n event ExecutionFromModuleSuccess(address indexed module);\\n event ExecutionFromModuleFailure(address indexed module);\\n\\n /// @dev Enables a module on the avatar.\\n /// @notice Can only be called by the avatar.\\n /// @notice Modules should be stored as a linked list.\\n /// @notice Must emit EnabledModule(address module) if successful.\\n /// @param module Module to be enabled.\\n function enableModule(address module) external;\\n\\n /// @dev Disables a module on the avatar.\\n /// @notice Can only be called by the avatar.\\n /// @notice Must emit DisabledModule(address module) if successful.\\n /// @param prevModule Address that pointed to the module to be removed in the linked list\\n /// @param module Module to be removed.\\n function disableModule(address prevModule, address module) external;\\n\\n /// @dev Allows a Module to execute a transaction.\\n /// @notice Can only be called by an enabled module.\\n /// @notice Must emit ExecutionFromModuleSuccess(address module) if successful.\\n /// @notice Must emit ExecutionFromModuleFailure(address module) if unsuccessful.\\n /// @param to Destination address of module transaction.\\n /// @param value Ether value of module transaction.\\n /// @param data Data payload of module transaction.\\n /// @param operation Operation type of module transaction: 0 == call, 1 == delegate call.\\n function execTransactionFromModule(\\n address to,\\n uint256 value,\\n bytes memory data,\\n Enum.Operation operation\\n ) external returns (bool success);\\n\\n /// @dev Allows a Module to execute a transaction and return data\\n /// @notice Can only be called by an enabled module.\\n /// @notice Must emit ExecutionFromModuleSuccess(address module) if successful.\\n /// @notice Must emit ExecutionFromModuleFailure(address module) if unsuccessful.\\n /// @param to Destination address of module transaction.\\n /// @param value Ether value of module transaction.\\n /// @param data Data payload of module transaction.\\n /// @param operation Operation type of module transaction: 0 == call, 1 == delegate call.\\n function execTransactionFromModuleReturnData(\\n address to,\\n uint256 value,\\n bytes memory data,\\n Enum.Operation operation\\n ) external returns (bool success, bytes memory returnData);\\n\\n /// @dev Returns if an module is enabled\\n /// @return True if the module is enabled\\n function isModuleEnabled(address module) external view returns (bool);\\n\\n /// @dev Returns array of modules.\\n /// @param start Start of the page.\\n /// @param pageSize Maximum number of modules that should be returned.\\n /// @return array Array of modules.\\n /// @return next Start of the next page.\\n function getModulesPaginated(address start, uint256 pageSize)\\n external\\n view\\n returns (address[] memory array, address next);\\n}\\n\",\"keccak256\":\"0xcd5508ffe596eef8fbccfd5fc4f10a34397773547ce64e212d48b5212865ec1f\",\"license\":\"LGPL-3.0-only\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20 {\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `to`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address to, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `from` to `to` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(\\n address from,\\n address to,\\n uint256 amount\\n ) external returns (bool);\\n}\\n\",\"keccak256\":\"0x9750c6b834f7b43000631af5cc30001c5f547b3ceb3635488f140f60e897ea6b\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Strings.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev String operations.\\n */\\nlibrary Strings {\\n bytes16 private constant _HEX_SYMBOLS = \\\"0123456789abcdef\\\";\\n uint8 private constant _ADDRESS_LENGTH = 20;\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\\n */\\n function toString(uint256 value) internal pure returns (string memory) {\\n // Inspired by OraclizeAPI's implementation - MIT licence\\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\\n\\n if (value == 0) {\\n return \\\"0\\\";\\n }\\n uint256 temp = value;\\n uint256 digits;\\n while (temp != 0) {\\n digits++;\\n temp /= 10;\\n }\\n bytes memory buffer = new bytes(digits);\\n while (value != 0) {\\n digits -= 1;\\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\\n value /= 10;\\n }\\n return string(buffer);\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\\n */\\n function toHexString(uint256 value) internal pure returns (string memory) {\\n if (value == 0) {\\n return \\\"0x00\\\";\\n }\\n uint256 temp = value;\\n uint256 length = 0;\\n while (temp != 0) {\\n length++;\\n temp >>= 8;\\n }\\n return toHexString(value, length);\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\\n */\\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\\n bytes memory buffer = new bytes(2 * length + 2);\\n buffer[0] = \\\"0\\\";\\n buffer[1] = \\\"x\\\";\\n for (uint256 i = 2 * length + 1; i > 1; --i) {\\n buffer[i] = _HEX_SYMBOLS[value & 0xf];\\n value >>= 4;\\n }\\n require(value == 0, \\\"Strings: hex length insufficient\\\");\\n return string(buffer);\\n }\\n\\n /**\\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\\n */\\n function toHexString(address addr) internal pure returns (string memory) {\\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\\n }\\n}\\n\",\"keccak256\":\"0xaf159a8b1923ad2a26d516089bceca9bdeaeacd04be50983ea00ba63070f08a3\",\"license\":\"MIT\"},\"contracts/DecentHats_0_1_0.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity =0.8.19;\\n\\nimport {Enum} from \\\"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\\\";\\nimport {IAvatar} from \\\"@gnosis.pm/zodiac/contracts/interfaces/IAvatar.sol\\\";\\nimport {Strings} from \\\"@openzeppelin/contracts/utils/Strings.sol\\\";\\nimport {IERC20} from \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\nimport {IERC6551Registry} from \\\"./interfaces/IERC6551Registry.sol\\\";\\nimport {IHats} from \\\"./interfaces/hats/IHats.sol\\\";\\nimport {ISablierV2LockupLinear} from \\\"./interfaces/sablier/ISablierV2LockupLinear.sol\\\";\\nimport {LockupLinear} from \\\"./interfaces/sablier/LockupLinear.sol\\\";\\n\\ncontract DecentHats_0_1_0 {\\n string public constant NAME = \\\"DecentHats_0_1_0\\\";\\n\\n struct SablierStreamParams {\\n ISablierV2LockupLinear sablier;\\n address sender;\\n uint128 totalAmount;\\n address asset;\\n bool cancelable;\\n bool transferable;\\n LockupLinear.Timestamps timestamps;\\n LockupLinear.Broker broker;\\n }\\n\\n struct Hat {\\n uint32 maxSupply;\\n string details;\\n string imageURI;\\n bool isMutable;\\n address wearer;\\n SablierStreamParams[] sablierParams; // Optional Sablier stream parameters\\n }\\n\\n struct CreateTreeParams {\\n IHats hatsProtocol;\\n address hatsAccountImplementation;\\n IERC6551Registry registry;\\n address keyValuePairs;\\n string topHatDetails;\\n string topHatImageURI;\\n Hat adminHat;\\n Hat[] hats;\\n }\\n\\n function getSalt() public pure returns (bytes32 salt) {\\n return\\n 0x5d0e6ce4fd951366cc55da93f6e79d8b81483109d79676a04bcc2bed6a4b5072;\\n }\\n\\n function declareSafeHatTree(\\n address _keyValuePairs,\\n uint256 topHatId\\n ) internal {\\n string[] memory keys = new string[](1);\\n string[] memory values = new string[](1);\\n keys[0] = \\\"topHatId\\\";\\n values[0] = Strings.toString(topHatId);\\n\\n IAvatar(msg.sender).execTransactionFromModule(\\n _keyValuePairs,\\n 0,\\n abi.encodeWithSignature(\\n \\\"updateValues(string[],string[])\\\",\\n keys,\\n values\\n ),\\n Enum.Operation.Call\\n );\\n }\\n\\n function createHat(\\n IHats _hatsProtocol,\\n uint256 adminHatId,\\n Hat memory _hat,\\n address topHatAccount\\n ) internal returns (uint256) {\\n return\\n _hatsProtocol.createHat(\\n adminHatId,\\n _hat.details,\\n _hat.maxSupply,\\n topHatAccount,\\n topHatAccount,\\n _hat.isMutable,\\n _hat.imageURI\\n );\\n }\\n\\n function createAccount(\\n IERC6551Registry _registry,\\n address _hatsAccountImplementation,\\n bytes32 salt,\\n address protocolAddress,\\n uint256 hatId\\n ) internal returns (address) {\\n return\\n _registry.createAccount(\\n _hatsAccountImplementation,\\n salt,\\n block.chainid,\\n protocolAddress,\\n hatId\\n );\\n }\\n\\n function createTopHatAndAccount(\\n IHats _hatsProtocol,\\n string memory _topHatDetails,\\n string memory _topHatImageURI,\\n IERC6551Registry _registry,\\n address _hatsAccountImplementation,\\n bytes32 salt\\n ) internal returns (uint256 topHatId, address topHatAccount) {\\n topHatId = _hatsProtocol.mintTopHat(\\n address(this),\\n _topHatDetails,\\n _topHatImageURI\\n );\\n\\n topHatAccount = createAccount(\\n _registry,\\n _hatsAccountImplementation,\\n salt,\\n address(_hatsProtocol),\\n topHatId\\n );\\n }\\n\\n function createHatAndAccountAndMintAndStreams(\\n IHats hatsProtocol,\\n uint256 adminHatId,\\n Hat calldata hat,\\n address topHatAccount,\\n IERC6551Registry registry,\\n address hatsAccountImplementation,\\n bytes32 salt\\n ) internal returns (uint256 hatId, address accountAddress) {\\n hatId = createHat(hatsProtocol, adminHatId, hat, topHatAccount);\\n\\n accountAddress = createAccount(\\n registry,\\n hatsAccountImplementation,\\n salt,\\n address(hatsProtocol),\\n hatId\\n );\\n\\n if (hat.wearer != address(0)) {\\n hatsProtocol.mintHat(hatId, hat.wearer);\\n }\\n\\n for (uint256 i = 0; i < hat.sablierParams.length; ) {\\n SablierStreamParams memory sablierParams = hat.sablierParams[i];\\n\\n // Approve tokens for Sablier\\n IAvatar(msg.sender).execTransactionFromModule(\\n sablierParams.asset,\\n 0,\\n abi.encodeWithSignature(\\n \\\"approve(address,uint256)\\\",\\n address(sablierParams.sablier),\\n sablierParams.totalAmount\\n ),\\n Enum.Operation.Call\\n );\\n\\n LockupLinear.CreateWithTimestamps memory params = LockupLinear\\n .CreateWithTimestamps({\\n sender: sablierParams.sender,\\n recipient: accountAddress,\\n totalAmount: sablierParams.totalAmount,\\n asset: IERC20(sablierParams.asset),\\n cancelable: sablierParams.cancelable,\\n transferable: sablierParams.transferable,\\n timestamps: sablierParams.timestamps,\\n broker: sablierParams.broker\\n });\\n\\n // Proxy the Sablier call through IAvatar\\n IAvatar(msg.sender).execTransactionFromModule(\\n address(sablierParams.sablier),\\n 0,\\n abi.encodeWithSignature(\\n \\\"createWithTimestamps((address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256)))\\\",\\n params\\n ),\\n Enum.Operation.Call\\n );\\n\\n unchecked {\\n ++i;\\n }\\n }\\n }\\n\\n /**\\n * Creates a new role hat and any streams on it.\\n *\\n * This contract should be enabled a module on the Safe for which the role is to be created, and disable after.\\n * In order for the module to be able to create hats on behalf of the Safe, the Safe must first\\n * transfer its top hat to this contract. This function transfers the top hat back to the Safe after\\n * creating the role hat.\\n *\\n * The function simply calls `createHatAndAccountAndMintAndStreams` and then transfers the top hat back to the Safe.\\n *\\n * @dev Role hat creation, minting, smart account creation and stream creation are handled here in order\\n * to avoid a race condition where not more than one active proposal to create a new role can exist at a time.\\n * See: https://github.com/decentdao/decent-interface/issues/2402\\n */\\n function createRoleHat(\\n IHats hatsProtocol,\\n uint256 adminHatId,\\n Hat calldata hat,\\n uint256 topHatId,\\n address topHatAccount,\\n IERC6551Registry registry,\\n address hatsAccountImplementation,\\n bytes32 salt\\n ) public returns (uint256 hatId, address accountAddress) {\\n (hatId, accountAddress) = createHatAndAccountAndMintAndStreams(\\n hatsProtocol,\\n adminHatId,\\n hat,\\n topHatAccount,\\n registry,\\n hatsAccountImplementation,\\n salt\\n );\\n\\n hatsProtocol.transferHat(topHatId, address(this), msg.sender);\\n }\\n\\n /**\\n * For a safe without any roles previously created on it, this function should be called. It sets up the\\n * top hat and admin hat, as well as any other hats and their streams that are provided.\\n *\\n * This contract should be enabled a module on the Safe for which the role(s) are to be created, and disabled after.\\n *\\n * @dev In order for a Safe to seamlessly create roles even if it has never previously created a role and thus has\\n * no hat tree, we defer the creation of the hat tree and its setup to this contract. This way, in a single tx block,\\n * the resulting topHatId of the newly created hat can be used to create an admin hat and any other hats needed.\\n * We also make use of `KeyValuePairs` to associate the topHatId with the Safe.\\n */\\n function createAndDeclareTree(CreateTreeParams calldata params) public {\\n bytes32 salt = getSalt();\\n\\n (uint256 topHatId, address topHatAccount) = createTopHatAndAccount(\\n params.hatsProtocol,\\n params.topHatDetails,\\n params.topHatImageURI,\\n params.registry,\\n params.hatsAccountImplementation,\\n salt\\n );\\n\\n declareSafeHatTree(params.keyValuePairs, topHatId);\\n\\n (uint256 adminHatId, ) = createHatAndAccountAndMintAndStreams(\\n params.hatsProtocol,\\n topHatId,\\n params.adminHat,\\n topHatAccount,\\n params.registry,\\n params.hatsAccountImplementation,\\n salt\\n );\\n\\n for (uint256 i = 0; i < params.hats.length; ) {\\n createHatAndAccountAndMintAndStreams(\\n params.hatsProtocol,\\n adminHatId,\\n params.hats[i],\\n topHatAccount,\\n params.registry,\\n params.hatsAccountImplementation,\\n salt\\n );\\n\\n unchecked {\\n ++i;\\n }\\n }\\n\\n params.hatsProtocol.transferHat(topHatId, address(this), msg.sender);\\n }\\n}\\n\",\"keccak256\":\"0x1886fc2edf8c34e58f6a95d33139d7513aa4b581a2c323af6394485752137e20\",\"license\":\"MIT\"},\"contracts/interfaces/IERC6551Registry.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.4;\\n\\ninterface IERC6551Registry {\\n /**\\n * @dev Creates a token bound account for a non-fungible token.\\n *\\n * If account has already been created, returns the account address without calling create2.\\n *\\n * Emits ERC6551AccountCreated event.\\n *\\n * @return account The address of the token bound account\\n */\\n function createAccount(\\n address implementation,\\n bytes32 salt,\\n uint256 chainId,\\n address tokenContract,\\n uint256 tokenId\\n ) external returns (address account);\\n}\\n\",\"keccak256\":\"0x64c52de8a8e68398e61dd8b42dda8e9af8cf6abf93bb85629c322440991ea568\",\"license\":\"MIT\"},\"contracts/interfaces/hats/IHats.sol\":{\"content\":\"// SPDX-License-Identifier: AGPL-3.0\\n// Copyright (C) 2023 Haberdasher Labs\\n//\\n// This program is free software: you can redistribute it and/or modify\\n// it under the terms of the GNU Affero General Public License as published by\\n// the Free Software Foundation, either version 3 of the License, or\\n// (at your option) any later version.\\n//\\n// This program is distributed in the hope that it will be useful,\\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\\n// GNU Affero General Public License for more details.\\n//\\n// You should have received a copy of the GNU Affero General Public License\\n// along with this program. If not, see .\\n\\npragma solidity >=0.8.13;\\n\\ninterface IHats {\\n function mintTopHat(\\n address _target,\\n string memory _details,\\n string memory _imageURI\\n ) external returns (uint256 topHatId);\\n\\n function createHat(\\n uint256 _admin,\\n string calldata _details,\\n uint32 _maxSupply,\\n address _eligibility,\\n address _toggle,\\n bool _mutable,\\n string calldata _imageURI\\n ) external returns (uint256 newHatId);\\n\\n function mintHat(\\n uint256 _hatId,\\n address _wearer\\n ) external returns (bool success);\\n\\n function transferHat(uint256 _hatId, address _from, address _to) external;\\n}\\n\",\"keccak256\":\"0x8e35022f5c0fcf0059033abec78ec890f0cf3bbac09d6d24051cff9679239511\",\"license\":\"AGPL-3.0\"},\"contracts/interfaces/sablier/ISablierV2LockupLinear.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport {LockupLinear} from \\\"./LockupLinear.sol\\\";\\nimport {IERC20} from \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\n\\ninterface ISablierV2LockupLinear {\\n function createWithTimestamps(\\n LockupLinear.CreateWithTimestamps calldata params\\n ) external returns (uint256 streamId);\\n}\\n\",\"keccak256\":\"0xf4899637eb2e6c76c35e2d201e56e162a50e6bc7b5b9156e00866f0703ad07ca\",\"license\":\"MIT\"},\"contracts/interfaces/sablier/LockupLinear.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport {IERC20} from \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\n\\nlibrary LockupLinear {\\n struct CreateWithTimestamps {\\n address sender;\\n address recipient;\\n uint128 totalAmount;\\n IERC20 asset;\\n bool cancelable;\\n bool transferable;\\n Timestamps timestamps;\\n Broker broker;\\n }\\n\\n struct Timestamps {\\n uint40 start;\\n uint40 cliff;\\n uint40 end;\\n }\\n\\n struct Broker {\\n address account;\\n uint256 fee;\\n }\\n}\\n\",\"keccak256\":\"0x497fdb52b5e1a5a7e0711a9f7d5fb036eb668ccb92ea908ee088f56ee08a4ce8\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x608060405234801561001057600080fd5b5061158a806100206000396000f3fe608060405234801561001057600080fd5b506004361061004c5760003560e01c806313a9589c146100515780636592b2ac146100845780638c5f591a146100b4578063a3f4df7e146100c9575b600080fd5b6040517f5d0e6ce4fd951366cc55da93f6e79d8b81483109d79676a04bcc2bed6a4b507281526020015b60405180910390f35b610097610092366004610b95565b610105565b604080519283526001600160a01b0390911660208301520161007b565b6100c76100c2366004610c40565b61018f565b005b6100f86040518060400160405280601081526020016f0446563656e74486174735f305f315f360841b81525081565b60405161007b9190610cc8565b6000806101178a8a8a898989896103dc565b6040516329287c1b60e21b8152600481018a905230602482015233604482015291935091506001600160a01b038b169063a4a1f06c90606401600060405180830381600087803b15801561016a57600080fd5b505af115801561017e573d6000803e3d6000fd5b505050509850989650505050505050565b7f5d0e6ce4fd951366cc55da93f6e79d8b81483109d79676a04bcc2bed6a4b507260008061026d6101c36020860186610cdb565b6101d06080870187610cf8565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506102129250505060a0880188610cf8565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610257925050506060890160408a01610cdb565b61026760408a0160208b01610cdb565b8861072b565b909250905061028b6102856080860160608701610cdb565b836107bd565b60006102d261029d6020870187610cdb565b846102ab60c0890189610d45565b856102bc60608b0160408c01610cdb565b6102cc60408c0160208d01610cdb565b8a6103dc565b50905060005b6102e560e0870187610d65565b905081101561035f576103556102fe6020880188610cdb565b8361030c60e08a018a610d65565b8581811061031c5761031c610dae565b905060200281019061032e9190610d45565b8661033f60608c0160408d01610cdb565b61034f60408d0160208e01610cdb565b8b6103dc565b50506001016102d8565b5061036d6020860186610cdb565b6040516329287c1b60e21b8152600481018590523060248201523360448201526001600160a01b03919091169063a4a1f06c90606401600060405180830381600087803b1580156103bd57600080fd5b505af11580156103d1573d6000803e3d6000fd5b505050505050505050565b6000806103f389896103ed8a611112565b8961093d565b91506104028585858c866109cf565b9050600061041660a0890160808a01610cdb565b6001600160a01b0316146104b6576001600160a01b03891663641f776e8361044460a08b0160808c01610cdb565b6040516001600160e01b031960e085901b16815260048101929092526001600160a01b031660248201526044016020604051808303816000875af1158015610490573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104b491906111d6565b505b60005b6104c660a08901896111f3565b905081101561071e5760006104de60a08a018a6111f3565b838181106104ee576104ee610dae565b90506101600201803603810190610505919061123c565b6060810151815160408084015190516001600160a01b0390921660248301526001600160801b03166044820152919250339163468721a7919060009060640160408051601f198184030181529181526020820180516001600160e01b031663095ea7b360e01b1790525160e085901b6001600160e01b031916815261059293929190600090600401611259565b6020604051808303816000875af11580156105b1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105d591906111d6565b50600060405180610100016040528083602001516001600160a01b03168152602001856001600160a01b0316815260200183604001516001600160801b0316815260200183606001516001600160a01b031681526020018360800151151581526020018360a00151151581526020018360c0015181526020018360e001518152509050336001600160a01b031663468721a7836000015160008460405160240161067f91906112af565b60408051601f198184030181529181526020820180516001600160e01b03166353b1572760e01b1790525160e085901b6001600160e01b03191681526106cd93929190600090600401611259565b6020604051808303816000875af11580156106ec573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061071091906111d6565b5082600101925050506104b9565b5097509795505050505050565b600080876001600160a01b0316631a64dfad3089896040518463ffffffff1660e01b815260040161075e93929190611371565b6020604051808303816000875af115801561077d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107a191906113a7565b91506107b08585858b866109cf565b9050965096945050505050565b604080516001808252818301909252600091816020015b60608152602001906001900390816107d457505060408051600180825281830190925291925060009190602082015b6060815260200190600190039081610803579050509050604051806040016040528060088152602001671d1bdc12185d125960c21b8152508260008151811061084e5761084e610dae565b602002602001018190525061086283610a65565b8160008151811061087557610875610dae565b6020026020010181905250336001600160a01b031663468721a785600085856040516024016108a5929190611415565b60408051601f198184030181529181526020820180516001600160e01b031663579374b960e11b1790525160e085901b6001600160e01b03191681526108f393929190600090600401611259565b6020604051808303816000875af1158015610912573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061093691906111d6565b5050505050565b6020820151825160608401516040808601519051635829492f60e11b81526000946001600160a01b038a169463b052925e94610983948b948a928392909160040161143a565b6020604051808303816000875af11580156109a2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109c691906113a7565b95945050505050565b604051638a54c52f60e01b81526001600160a01b0385811660048301526024820185905246604483015283811660648301526084820183905260009190871690638a54c52f9060a4016020604051808303816000875af1158015610a37573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a5b919061149e565b9695505050505050565b606081600003610a8c5750506040805180820190915260018152600360fc1b602082015290565b8160005b8115610ab65780610aa0816114d1565b9150610aaf9050600a83611500565b9150610a90565b6000816001600160401b03811115610ad057610ad0610dc4565b6040519080825280601f01601f191660200182016040528015610afa576020820181803683370190505b5090505b8415610b6557610b0f600183611514565b9150610b1c600a8661152d565b610b27906030611541565b60f81b818381518110610b3c57610b3c610dae565b60200101906001600160f81b031916908160001a905350610b5e600a86611500565b9450610afe565b949350505050565b6001600160a01b0381168114610b8257600080fd5b50565b8035610b9081610b6d565b919050565b600080600080600080600080610100898b031215610bb257600080fd5b8835610bbd81610b6d565b97506020890135965060408901356001600160401b03811115610bdf57600080fd5b890160c0818c031215610bf157600080fd5b9550606089013594506080890135610c0881610b6d565b935060a0890135610c1881610b6d565b925060c0890135610c2881610b6d565b8092505060e089013590509295985092959890939650565b600060208284031215610c5257600080fd5b81356001600160401b03811115610c6857600080fd5b82016101008185031215610c7b57600080fd5b9392505050565b6000815180845260005b81811015610ca857602081850181015186830182015201610c8c565b506000602082860101526020601f19601f83011685010191505092915050565b602081526000610c7b6020830184610c82565b600060208284031215610ced57600080fd5b8135610c7b81610b6d565b6000808335601e19843603018112610d0f57600080fd5b8301803591506001600160401b03821115610d2957600080fd5b602001915036819003821315610d3e57600080fd5b9250929050565b6000823560be19833603018112610d5b57600080fd5b9190910192915050565b6000808335601e19843603018112610d7c57600080fd5b8301803591506001600160401b03821115610d9657600080fd5b6020019150600581901b3603821315610d3e57600080fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b60405160c081016001600160401b0381118282101715610dfc57610dfc610dc4565b60405290565b604051601f8201601f191681016001600160401b0381118282101715610e2a57610e2a610dc4565b604052919050565b803563ffffffff81168114610b9057600080fd5b600082601f830112610e5757600080fd5b81356001600160401b03811115610e7057610e70610dc4565b610e83601f8201601f1916602001610e02565b818152846020838601011115610e9857600080fd5b816020850160208301376000918101602001919091529392505050565b8015158114610b8257600080fd5b8035610b9081610eb5565b80356001600160801b0381168114610b9057600080fd5b803564ffffffffff81168114610b9057600080fd5b600060608284031215610f0c57600080fd5b604051606081018181106001600160401b0382111715610f2e57610f2e610dc4565b604052905080610f3d83610ee5565b8152610f4b60208401610ee5565b6020820152610f5c60408401610ee5565b60408201525092915050565b600060408284031215610f7a57600080fd5b604051604081018181106001600160401b0382111715610f9c57610f9c610dc4565b6040529050808235610fad81610b6d565b8152602092830135920191909152919050565b60006101608284031215610fd357600080fd5b60405161010081018181106001600160401b0382111715610ff657610ff6610dc4565b60405290508061100583610b85565b815261101360208401610b85565b602082015261102460408401610ece565b604082015261103560608401610b85565b606082015261104660808401610ec3565b608082015261105760a08401610ec3565b60a08201526110698460c08501610efa565b60c082015261107c846101208501610f68565b60e08201525092915050565b600082601f83011261109957600080fd5b813560206001600160401b038211156110b4576110b4610dc4565b6110c2818360051b01610e02565b82815261016092830285018201928282019190878511156110e257600080fd5b8387015b85811015611105576110f88982610fc0565b84529284019281016110e6565b5090979650505050505050565b600060c0823603121561112457600080fd5b61112c610dda565b61113583610e32565b815260208301356001600160401b038082111561115157600080fd5b61115d36838701610e46565b6020840152604085013591508082111561117657600080fd5b61118236838701610e46565b604084015261119360608601610ec3565b60608401526111a460808601610b85565b608084015260a08501359150808211156111bd57600080fd5b506111ca36828601611088565b60a08301525092915050565b6000602082840312156111e857600080fd5b8151610c7b81610eb5565b6000808335601e1984360301811261120a57600080fd5b8301803591506001600160401b0382111561122457600080fd5b602001915061016081023603821315610d3e57600080fd5b6000610160828403121561124f57600080fd5b610c7b8383610fc0565b60018060a01b03851681528360208201526080604082015260006112806080830185610c82565b9050600283106112a057634e487b7160e01b600052602160045260246000fd5b82606083015295945050505050565b81516001600160a01b0390811682526020808401518216908301526040808401516001600160801b031690830152606080840151909116908201526080808301516101608301916113039084018215159052565b5060a083015161131760a084018215159052565b5060c083015161134a60c0840182805164ffffffffff908116835260208083015182169084015260409182015116910152565b5060e0929092015180516001600160a01b0316610120830152602001516101409091015290565b6001600160a01b038416815260606020820181905260009061139590830185610c82565b8281036040840152610a5b8185610c82565b6000602082840312156113b957600080fd5b5051919050565b600081518084526020808501808196508360051b8101915082860160005b858110156114085782840389526113f6848351610c82565b988501989350908401906001016113de565b5091979650505050505050565b60408152600061142860408301856113c0565b82810360208401526109c681856113c0565b87815260e06020820152600061145360e0830189610c82565b63ffffffff881660408401526001600160a01b0387811660608501528616608084015284151560a084015282810360c08401526114908185610c82565b9a9950505050505050505050565b6000602082840312156114b057600080fd5b8151610c7b81610b6d565b634e487b7160e01b600052601160045260246000fd5b6000600182016114e3576114e36114bb565b5060010190565b634e487b7160e01b600052601260045260246000fd5b60008261150f5761150f6114ea565b500490565b81810381811115611527576115276114bb565b92915050565b60008261153c5761153c6114ea565b500690565b80820180821115611527576115276114bb56fea26469706673582212208431b5cb9e9defda60834dc065f918f11d92dcbf19aba7475b779059a216011d64736f6c63430008130033", + "deployedBytecode": "0x608060405234801561001057600080fd5b506004361061004c5760003560e01c806313a9589c146100515780636592b2ac146100845780638c5f591a146100b4578063a3f4df7e146100c9575b600080fd5b6040517f5d0e6ce4fd951366cc55da93f6e79d8b81483109d79676a04bcc2bed6a4b507281526020015b60405180910390f35b610097610092366004610b95565b610105565b604080519283526001600160a01b0390911660208301520161007b565b6100c76100c2366004610c40565b61018f565b005b6100f86040518060400160405280601081526020016f0446563656e74486174735f305f315f360841b81525081565b60405161007b9190610cc8565b6000806101178a8a8a898989896103dc565b6040516329287c1b60e21b8152600481018a905230602482015233604482015291935091506001600160a01b038b169063a4a1f06c90606401600060405180830381600087803b15801561016a57600080fd5b505af115801561017e573d6000803e3d6000fd5b505050509850989650505050505050565b7f5d0e6ce4fd951366cc55da93f6e79d8b81483109d79676a04bcc2bed6a4b507260008061026d6101c36020860186610cdb565b6101d06080870187610cf8565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506102129250505060a0880188610cf8565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610257925050506060890160408a01610cdb565b61026760408a0160208b01610cdb565b8861072b565b909250905061028b6102856080860160608701610cdb565b836107bd565b60006102d261029d6020870187610cdb565b846102ab60c0890189610d45565b856102bc60608b0160408c01610cdb565b6102cc60408c0160208d01610cdb565b8a6103dc565b50905060005b6102e560e0870187610d65565b905081101561035f576103556102fe6020880188610cdb565b8361030c60e08a018a610d65565b8581811061031c5761031c610dae565b905060200281019061032e9190610d45565b8661033f60608c0160408d01610cdb565b61034f60408d0160208e01610cdb565b8b6103dc565b50506001016102d8565b5061036d6020860186610cdb565b6040516329287c1b60e21b8152600481018590523060248201523360448201526001600160a01b03919091169063a4a1f06c90606401600060405180830381600087803b1580156103bd57600080fd5b505af11580156103d1573d6000803e3d6000fd5b505050505050505050565b6000806103f389896103ed8a611112565b8961093d565b91506104028585858c866109cf565b9050600061041660a0890160808a01610cdb565b6001600160a01b0316146104b6576001600160a01b03891663641f776e8361044460a08b0160808c01610cdb565b6040516001600160e01b031960e085901b16815260048101929092526001600160a01b031660248201526044016020604051808303816000875af1158015610490573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104b491906111d6565b505b60005b6104c660a08901896111f3565b905081101561071e5760006104de60a08a018a6111f3565b838181106104ee576104ee610dae565b90506101600201803603810190610505919061123c565b6060810151815160408084015190516001600160a01b0390921660248301526001600160801b03166044820152919250339163468721a7919060009060640160408051601f198184030181529181526020820180516001600160e01b031663095ea7b360e01b1790525160e085901b6001600160e01b031916815261059293929190600090600401611259565b6020604051808303816000875af11580156105b1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105d591906111d6565b50600060405180610100016040528083602001516001600160a01b03168152602001856001600160a01b0316815260200183604001516001600160801b0316815260200183606001516001600160a01b031681526020018360800151151581526020018360a00151151581526020018360c0015181526020018360e001518152509050336001600160a01b031663468721a7836000015160008460405160240161067f91906112af565b60408051601f198184030181529181526020820180516001600160e01b03166353b1572760e01b1790525160e085901b6001600160e01b03191681526106cd93929190600090600401611259565b6020604051808303816000875af11580156106ec573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061071091906111d6565b5082600101925050506104b9565b5097509795505050505050565b600080876001600160a01b0316631a64dfad3089896040518463ffffffff1660e01b815260040161075e93929190611371565b6020604051808303816000875af115801561077d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107a191906113a7565b91506107b08585858b866109cf565b9050965096945050505050565b604080516001808252818301909252600091816020015b60608152602001906001900390816107d457505060408051600180825281830190925291925060009190602082015b6060815260200190600190039081610803579050509050604051806040016040528060088152602001671d1bdc12185d125960c21b8152508260008151811061084e5761084e610dae565b602002602001018190525061086283610a65565b8160008151811061087557610875610dae565b6020026020010181905250336001600160a01b031663468721a785600085856040516024016108a5929190611415565b60408051601f198184030181529181526020820180516001600160e01b031663579374b960e11b1790525160e085901b6001600160e01b03191681526108f393929190600090600401611259565b6020604051808303816000875af1158015610912573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061093691906111d6565b5050505050565b6020820151825160608401516040808601519051635829492f60e11b81526000946001600160a01b038a169463b052925e94610983948b948a928392909160040161143a565b6020604051808303816000875af11580156109a2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109c691906113a7565b95945050505050565b604051638a54c52f60e01b81526001600160a01b0385811660048301526024820185905246604483015283811660648301526084820183905260009190871690638a54c52f9060a4016020604051808303816000875af1158015610a37573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a5b919061149e565b9695505050505050565b606081600003610a8c5750506040805180820190915260018152600360fc1b602082015290565b8160005b8115610ab65780610aa0816114d1565b9150610aaf9050600a83611500565b9150610a90565b6000816001600160401b03811115610ad057610ad0610dc4565b6040519080825280601f01601f191660200182016040528015610afa576020820181803683370190505b5090505b8415610b6557610b0f600183611514565b9150610b1c600a8661152d565b610b27906030611541565b60f81b818381518110610b3c57610b3c610dae565b60200101906001600160f81b031916908160001a905350610b5e600a86611500565b9450610afe565b949350505050565b6001600160a01b0381168114610b8257600080fd5b50565b8035610b9081610b6d565b919050565b600080600080600080600080610100898b031215610bb257600080fd5b8835610bbd81610b6d565b97506020890135965060408901356001600160401b03811115610bdf57600080fd5b890160c0818c031215610bf157600080fd5b9550606089013594506080890135610c0881610b6d565b935060a0890135610c1881610b6d565b925060c0890135610c2881610b6d565b8092505060e089013590509295985092959890939650565b600060208284031215610c5257600080fd5b81356001600160401b03811115610c6857600080fd5b82016101008185031215610c7b57600080fd5b9392505050565b6000815180845260005b81811015610ca857602081850181015186830182015201610c8c565b506000602082860101526020601f19601f83011685010191505092915050565b602081526000610c7b6020830184610c82565b600060208284031215610ced57600080fd5b8135610c7b81610b6d565b6000808335601e19843603018112610d0f57600080fd5b8301803591506001600160401b03821115610d2957600080fd5b602001915036819003821315610d3e57600080fd5b9250929050565b6000823560be19833603018112610d5b57600080fd5b9190910192915050565b6000808335601e19843603018112610d7c57600080fd5b8301803591506001600160401b03821115610d9657600080fd5b6020019150600581901b3603821315610d3e57600080fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b60405160c081016001600160401b0381118282101715610dfc57610dfc610dc4565b60405290565b604051601f8201601f191681016001600160401b0381118282101715610e2a57610e2a610dc4565b604052919050565b803563ffffffff81168114610b9057600080fd5b600082601f830112610e5757600080fd5b81356001600160401b03811115610e7057610e70610dc4565b610e83601f8201601f1916602001610e02565b818152846020838601011115610e9857600080fd5b816020850160208301376000918101602001919091529392505050565b8015158114610b8257600080fd5b8035610b9081610eb5565b80356001600160801b0381168114610b9057600080fd5b803564ffffffffff81168114610b9057600080fd5b600060608284031215610f0c57600080fd5b604051606081018181106001600160401b0382111715610f2e57610f2e610dc4565b604052905080610f3d83610ee5565b8152610f4b60208401610ee5565b6020820152610f5c60408401610ee5565b60408201525092915050565b600060408284031215610f7a57600080fd5b604051604081018181106001600160401b0382111715610f9c57610f9c610dc4565b6040529050808235610fad81610b6d565b8152602092830135920191909152919050565b60006101608284031215610fd357600080fd5b60405161010081018181106001600160401b0382111715610ff657610ff6610dc4565b60405290508061100583610b85565b815261101360208401610b85565b602082015261102460408401610ece565b604082015261103560608401610b85565b606082015261104660808401610ec3565b608082015261105760a08401610ec3565b60a08201526110698460c08501610efa565b60c082015261107c846101208501610f68565b60e08201525092915050565b600082601f83011261109957600080fd5b813560206001600160401b038211156110b4576110b4610dc4565b6110c2818360051b01610e02565b82815261016092830285018201928282019190878511156110e257600080fd5b8387015b85811015611105576110f88982610fc0565b84529284019281016110e6565b5090979650505050505050565b600060c0823603121561112457600080fd5b61112c610dda565b61113583610e32565b815260208301356001600160401b038082111561115157600080fd5b61115d36838701610e46565b6020840152604085013591508082111561117657600080fd5b61118236838701610e46565b604084015261119360608601610ec3565b60608401526111a460808601610b85565b608084015260a08501359150808211156111bd57600080fd5b506111ca36828601611088565b60a08301525092915050565b6000602082840312156111e857600080fd5b8151610c7b81610eb5565b6000808335601e1984360301811261120a57600080fd5b8301803591506001600160401b0382111561122457600080fd5b602001915061016081023603821315610d3e57600080fd5b6000610160828403121561124f57600080fd5b610c7b8383610fc0565b60018060a01b03851681528360208201526080604082015260006112806080830185610c82565b9050600283106112a057634e487b7160e01b600052602160045260246000fd5b82606083015295945050505050565b81516001600160a01b0390811682526020808401518216908301526040808401516001600160801b031690830152606080840151909116908201526080808301516101608301916113039084018215159052565b5060a083015161131760a084018215159052565b5060c083015161134a60c0840182805164ffffffffff908116835260208083015182169084015260409182015116910152565b5060e0929092015180516001600160a01b0316610120830152602001516101409091015290565b6001600160a01b038416815260606020820181905260009061139590830185610c82565b8281036040840152610a5b8185610c82565b6000602082840312156113b957600080fd5b5051919050565b600081518084526020808501808196508360051b8101915082860160005b858110156114085782840389526113f6848351610c82565b988501989350908401906001016113de565b5091979650505050505050565b60408152600061142860408301856113c0565b82810360208401526109c681856113c0565b87815260e06020820152600061145360e0830189610c82565b63ffffffff881660408401526001600160a01b0387811660608501528616608084015284151560a084015282810360c08401526114908185610c82565b9a9950505050505050505050565b6000602082840312156114b057600080fd5b8151610c7b81610b6d565b634e487b7160e01b600052601160045260246000fd5b6000600182016114e3576114e36114bb565b5060010190565b634e487b7160e01b600052601260045260246000fd5b60008261150f5761150f6114ea565b500490565b81810381811115611527576115276114bb565b92915050565b60008261153c5761153c6114ea565b500690565b80820180821115611527576115276114bb56fea26469706673582212208431b5cb9e9defda60834dc065f918f11d92dcbf19aba7475b779059a216011d64736f6c63430008130033", "devdoc": { "kind": "dev", - "methods": {}, + "methods": { + "createAndDeclareTree((address,address,address,address,string,string,(uint32,string,string,bool,address,(address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256))[]),(uint32,string,string,bool,address,(address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256))[])[]))": { + "details": "In order for a Safe to seamlessly create roles even if it has never previously created a role and thus has no hat tree, we defer the creation of the hat tree and its setup to this contract. This way, in a single tx block, the resulting topHatId of the newly created hat can be used to create an admin hat and any other hats needed. We also make use of `KeyValuePairs` to associate the topHatId with the Safe." + }, + "createRoleHat(address,uint256,(uint32,string,string,bool,address,(address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256))[]),uint256,address,address,address,bytes32)": { + "details": "Role hat creation, minting, smart account creation and stream creation are handled here in order to avoid a race condition where not more than one active proposal to create a new role can exist at a time. See: https://github.com/decentdao/decent-interface/issues/2402" + } + }, "version": 1 }, "userdoc": { "kind": "user", - "methods": {}, + "methods": { + "createAndDeclareTree((address,address,address,address,string,string,(uint32,string,string,bool,address,(address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256))[]),(uint32,string,string,bool,address,(address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256))[])[]))": { + "notice": "For a safe without any roles previously created on it, this function should be called. It sets up the top hat and admin hat, as well as any other hats and their streams that are provided. This contract should be enabled a module on the Safe for which the role(s) are to be created, and disabled after." + }, + "createRoleHat(address,uint256,(uint32,string,string,bool,address,(address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256))[]),uint256,address,address,address,bytes32)": { + "notice": "Creates a new role hat and any streams on it. This contract should be enabled a module on the Safe for which the role is to be created, and disable after. In order for the module to be able to create hats on behalf of the Safe, the Safe must first transfer its top hat to this contract. This function transfers the top hat back to the Safe after creating the role hat. The function simply calls `createHatAndAccountAndMintAndStreams` and then transfers the top hat back to the Safe." + } + }, "version": 1 }, "storageLayout": { diff --git a/deployments/optimism/solcInputs/4754a2f0c9d6a191a066af246491b62a.json b/deployments/optimism/solcInputs/4754a2f0c9d6a191a066af246491b62a.json new file mode 100644 index 00000000..87cba363 --- /dev/null +++ b/deployments/optimism/solcInputs/4754a2f0c9d6a191a066af246491b62a.json @@ -0,0 +1,59 @@ +{ + "language": "Solidity", + "sources": { + "@gnosis.pm/safe-contracts/contracts/common/Enum.sol": { + "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\n\n/// @title Enum - Collection of enums\n/// @author Richard Meissner - \ncontract Enum {\n enum Operation {Call, DelegateCall}\n}\n" + }, + "@gnosis.pm/zodiac/contracts/interfaces/IAvatar.sol": { + "content": "// SPDX-License-Identifier: LGPL-3.0-only\n\n/// @title Zodiac Avatar - A contract that manages modules that can execute transactions via this contract.\npragma solidity >=0.7.0 <0.9.0;\n\nimport \"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\";\n\ninterface IAvatar {\n event EnabledModule(address module);\n event DisabledModule(address module);\n event ExecutionFromModuleSuccess(address indexed module);\n event ExecutionFromModuleFailure(address indexed module);\n\n /// @dev Enables a module on the avatar.\n /// @notice Can only be called by the avatar.\n /// @notice Modules should be stored as a linked list.\n /// @notice Must emit EnabledModule(address module) if successful.\n /// @param module Module to be enabled.\n function enableModule(address module) external;\n\n /// @dev Disables a module on the avatar.\n /// @notice Can only be called by the avatar.\n /// @notice Must emit DisabledModule(address module) if successful.\n /// @param prevModule Address that pointed to the module to be removed in the linked list\n /// @param module Module to be removed.\n function disableModule(address prevModule, address module) external;\n\n /// @dev Allows a Module to execute a transaction.\n /// @notice Can only be called by an enabled module.\n /// @notice Must emit ExecutionFromModuleSuccess(address module) if successful.\n /// @notice Must emit ExecutionFromModuleFailure(address module) if unsuccessful.\n /// @param to Destination address of module transaction.\n /// @param value Ether value of module transaction.\n /// @param data Data payload of module transaction.\n /// @param operation Operation type of module transaction: 0 == call, 1 == delegate call.\n function execTransactionFromModule(\n address to,\n uint256 value,\n bytes memory data,\n Enum.Operation operation\n ) external returns (bool success);\n\n /// @dev Allows a Module to execute a transaction and return data\n /// @notice Can only be called by an enabled module.\n /// @notice Must emit ExecutionFromModuleSuccess(address module) if successful.\n /// @notice Must emit ExecutionFromModuleFailure(address module) if unsuccessful.\n /// @param to Destination address of module transaction.\n /// @param value Ether value of module transaction.\n /// @param data Data payload of module transaction.\n /// @param operation Operation type of module transaction: 0 == call, 1 == delegate call.\n function execTransactionFromModuleReturnData(\n address to,\n uint256 value,\n bytes memory data,\n Enum.Operation operation\n ) external returns (bool success, bytes memory returnData);\n\n /// @dev Returns if an module is enabled\n /// @return True if the module is enabled\n function isModuleEnabled(address module) external view returns (bool);\n\n /// @dev Returns array of modules.\n /// @param start Start of the page.\n /// @param pageSize Maximum number of modules that should be returned.\n /// @return array Array of modules.\n /// @return next Start of the next page.\n function getModulesPaginated(address start, uint256 pageSize)\n external\n view\n returns (address[] memory array, address next);\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/IERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20 {\n /**\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\n * another (`to`).\n *\n * Note that `value` may be zero.\n */\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n /**\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n * a call to {approve}. `value` is the new allowance.\n */\n event Approval(address indexed owner, address indexed spender, uint256 value);\n\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by `account`.\n */\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * @dev Moves `amount` tokens from the caller's account to `to`.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transfer(address to, uint256 amount) external returns (bool);\n\n /**\n * @dev Returns the remaining number of tokens that `spender` will be\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\n * zero by default.\n *\n * This value changes when {approve} or {transferFrom} are called.\n */\n function allowance(address owner, address spender) external view returns (uint256);\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\n * that someone may use both the old and the new allowance by unfortunate\n * transaction ordering. One possible solution to mitigate this race\n * condition is to first reduce the spender's allowance to 0 and set the\n * desired value afterwards:\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n *\n * Emits an {Approval} event.\n */\n function approve(address spender, uint256 amount) external returns (bool);\n\n /**\n * @dev Moves `amount` tokens from `from` to `to` using the\n * allowance mechanism. `amount` is then deducted from the caller's\n * allowance.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(\n address from,\n address to,\n uint256 amount\n ) external returns (bool);\n}\n" + }, + "@openzeppelin/contracts/utils/Strings.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n uint8 private constant _ADDRESS_LENGTH = 20;\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp >>= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i > 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value & 0xf];\n value >>= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n\n /**\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\n */\n function toHexString(address addr) internal pure returns (string memory) {\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\n }\n}\n" + }, + "contracts/DecentHats_0_1_0.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity =0.8.19;\n\nimport {Enum} from \"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\";\nimport {IAvatar} from \"@gnosis.pm/zodiac/contracts/interfaces/IAvatar.sol\";\nimport {Strings} from \"@openzeppelin/contracts/utils/Strings.sol\";\nimport {IERC20} from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport {IERC6551Registry} from \"./interfaces/IERC6551Registry.sol\";\nimport {IHats} from \"./interfaces/hats/IHats.sol\";\nimport {ISablierV2LockupLinear} from \"./interfaces/sablier/ISablierV2LockupLinear.sol\";\nimport {LockupLinear} from \"./interfaces/sablier/LockupLinear.sol\";\n\ncontract DecentHats_0_1_0 {\n string public constant NAME = \"DecentHats_0_1_0\";\n\n struct SablierStreamParams {\n ISablierV2LockupLinear sablier;\n address sender;\n uint128 totalAmount;\n address asset;\n bool cancelable;\n bool transferable;\n LockupLinear.Timestamps timestamps;\n LockupLinear.Broker broker;\n }\n\n struct Hat {\n uint32 maxSupply;\n string details;\n string imageURI;\n bool isMutable;\n address wearer;\n SablierStreamParams[] sablierParams; // Optional Sablier stream parameters\n }\n\n struct CreateTreeParams {\n IHats hatsProtocol;\n address hatsAccountImplementation;\n IERC6551Registry registry;\n address keyValuePairs;\n string topHatDetails;\n string topHatImageURI;\n Hat adminHat;\n Hat[] hats;\n }\n\n function getSalt() public pure returns (bytes32 salt) {\n return\n 0x5d0e6ce4fd951366cc55da93f6e79d8b81483109d79676a04bcc2bed6a4b5072;\n }\n\n function declareSafeHatTree(\n address _keyValuePairs,\n uint256 topHatId\n ) internal {\n string[] memory keys = new string[](1);\n string[] memory values = new string[](1);\n keys[0] = \"topHatId\";\n values[0] = Strings.toString(topHatId);\n\n IAvatar(msg.sender).execTransactionFromModule(\n _keyValuePairs,\n 0,\n abi.encodeWithSignature(\n \"updateValues(string[],string[])\",\n keys,\n values\n ),\n Enum.Operation.Call\n );\n }\n\n function createHat(\n IHats _hatsProtocol,\n uint256 adminHatId,\n Hat memory _hat,\n address topHatAccount\n ) internal returns (uint256) {\n return\n _hatsProtocol.createHat(\n adminHatId,\n _hat.details,\n _hat.maxSupply,\n topHatAccount,\n topHatAccount,\n _hat.isMutable,\n _hat.imageURI\n );\n }\n\n function createAccount(\n IERC6551Registry _registry,\n address _hatsAccountImplementation,\n bytes32 salt,\n address protocolAddress,\n uint256 hatId\n ) internal returns (address) {\n return\n _registry.createAccount(\n _hatsAccountImplementation,\n salt,\n block.chainid,\n protocolAddress,\n hatId\n );\n }\n\n function createTopHatAndAccount(\n IHats _hatsProtocol,\n string memory _topHatDetails,\n string memory _topHatImageURI,\n IERC6551Registry _registry,\n address _hatsAccountImplementation,\n bytes32 salt\n ) internal returns (uint256 topHatId, address topHatAccount) {\n topHatId = _hatsProtocol.mintTopHat(\n address(this),\n _topHatDetails,\n _topHatImageURI\n );\n\n topHatAccount = createAccount(\n _registry,\n _hatsAccountImplementation,\n salt,\n address(_hatsProtocol),\n topHatId\n );\n }\n\n function createHatAndAccountAndMintAndStreams(\n IHats hatsProtocol,\n uint256 adminHatId,\n Hat calldata hat,\n address topHatAccount,\n IERC6551Registry registry,\n address hatsAccountImplementation,\n bytes32 salt\n ) internal returns (uint256 hatId, address accountAddress) {\n hatId = createHat(hatsProtocol, adminHatId, hat, topHatAccount);\n\n accountAddress = createAccount(\n registry,\n hatsAccountImplementation,\n salt,\n address(hatsProtocol),\n hatId\n );\n\n if (hat.wearer != address(0)) {\n hatsProtocol.mintHat(hatId, hat.wearer);\n }\n\n for (uint256 i = 0; i < hat.sablierParams.length; ) {\n SablierStreamParams memory sablierParams = hat.sablierParams[i];\n\n // Approve tokens for Sablier\n IAvatar(msg.sender).execTransactionFromModule(\n sablierParams.asset,\n 0,\n abi.encodeWithSignature(\n \"approve(address,uint256)\",\n address(sablierParams.sablier),\n sablierParams.totalAmount\n ),\n Enum.Operation.Call\n );\n\n LockupLinear.CreateWithTimestamps memory params = LockupLinear\n .CreateWithTimestamps({\n sender: sablierParams.sender,\n recipient: accountAddress,\n totalAmount: sablierParams.totalAmount,\n asset: IERC20(sablierParams.asset),\n cancelable: sablierParams.cancelable,\n transferable: sablierParams.transferable,\n timestamps: sablierParams.timestamps,\n broker: sablierParams.broker\n });\n\n // Proxy the Sablier call through IAvatar\n IAvatar(msg.sender).execTransactionFromModule(\n address(sablierParams.sablier),\n 0,\n abi.encodeWithSignature(\n \"createWithTimestamps((address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256)))\",\n params\n ),\n Enum.Operation.Call\n );\n\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * Creates a new role hat and any streams on it.\n *\n * This contract should be enabled a module on the Safe for which the role is to be created, and disable after.\n * In order for the module to be able to create hats on behalf of the Safe, the Safe must first\n * transfer its top hat to this contract. This function transfers the top hat back to the Safe after\n * creating the role hat.\n *\n * The function simply calls `createHatAndAccountAndMintAndStreams` and then transfers the top hat back to the Safe.\n *\n * @dev Role hat creation, minting, smart account creation and stream creation are handled here in order\n * to avoid a race condition where not more than one active proposal to create a new role can exist at a time.\n * See: https://github.com/decentdao/decent-interface/issues/2402\n */\n function createRoleHat(\n IHats hatsProtocol,\n uint256 adminHatId,\n Hat calldata hat,\n uint256 topHatId,\n address topHatAccount,\n IERC6551Registry registry,\n address hatsAccountImplementation,\n bytes32 salt\n ) public returns (uint256 hatId, address accountAddress) {\n (hatId, accountAddress) = createHatAndAccountAndMintAndStreams(\n hatsProtocol,\n adminHatId,\n hat,\n topHatAccount,\n registry,\n hatsAccountImplementation,\n salt\n );\n\n hatsProtocol.transferHat(topHatId, address(this), msg.sender);\n }\n\n /**\n * For a safe without any roles previously created on it, this function should be called. It sets up the\n * top hat and admin hat, as well as any other hats and their streams that are provided.\n *\n * This contract should be enabled a module on the Safe for which the role(s) are to be created, and disabled after.\n *\n * @dev In order for a Safe to seamlessly create roles even if it has never previously created a role and thus has\n * no hat tree, we defer the creation of the hat tree and its setup to this contract. This way, in a single tx block,\n * the resulting topHatId of the newly created hat can be used to create an admin hat and any other hats needed.\n * We also make use of `KeyValuePairs` to associate the topHatId with the Safe.\n */\n function createAndDeclareTree(CreateTreeParams calldata params) public {\n bytes32 salt = getSalt();\n\n (uint256 topHatId, address topHatAccount) = createTopHatAndAccount(\n params.hatsProtocol,\n params.topHatDetails,\n params.topHatImageURI,\n params.registry,\n params.hatsAccountImplementation,\n salt\n );\n\n declareSafeHatTree(params.keyValuePairs, topHatId);\n\n (uint256 adminHatId, ) = createHatAndAccountAndMintAndStreams(\n params.hatsProtocol,\n topHatId,\n params.adminHat,\n topHatAccount,\n params.registry,\n params.hatsAccountImplementation,\n salt\n );\n\n for (uint256 i = 0; i < params.hats.length; ) {\n createHatAndAccountAndMintAndStreams(\n params.hatsProtocol,\n adminHatId,\n params.hats[i],\n topHatAccount,\n params.registry,\n params.hatsAccountImplementation,\n salt\n );\n\n unchecked {\n ++i;\n }\n }\n\n params.hatsProtocol.transferHat(topHatId, address(this), msg.sender);\n }\n}\n" + }, + "contracts/interfaces/hats/IHats.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0\n// Copyright (C) 2023 Haberdasher Labs\n//\n// This program is free software: you can redistribute it and/or modify\n// it under the terms of the GNU Affero General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU Affero General Public License for more details.\n//\n// You should have received a copy of the GNU Affero General Public License\n// along with this program. If not, see .\n\npragma solidity >=0.8.13;\n\ninterface IHats {\n function mintTopHat(\n address _target,\n string memory _details,\n string memory _imageURI\n ) external returns (uint256 topHatId);\n\n function createHat(\n uint256 _admin,\n string calldata _details,\n uint32 _maxSupply,\n address _eligibility,\n address _toggle,\n bool _mutable,\n string calldata _imageURI\n ) external returns (uint256 newHatId);\n\n function mintHat(\n uint256 _hatId,\n address _wearer\n ) external returns (bool success);\n\n function transferHat(uint256 _hatId, address _from, address _to) external;\n}\n" + }, + "contracts/interfaces/IERC6551Registry.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.4;\n\ninterface IERC6551Registry {\n /**\n * @dev Creates a token bound account for a non-fungible token.\n *\n * If account has already been created, returns the account address without calling create2.\n *\n * Emits ERC6551AccountCreated event.\n *\n * @return account The address of the token bound account\n */\n function createAccount(\n address implementation,\n bytes32 salt,\n uint256 chainId,\n address tokenContract,\n uint256 tokenId\n ) external returns (address account);\n}\n" + }, + "contracts/interfaces/sablier/ISablierV2LockupLinear.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport {LockupLinear} from \"./LockupLinear.sol\";\nimport {IERC20} from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\n\ninterface ISablierV2LockupLinear {\n function createWithTimestamps(\n LockupLinear.CreateWithTimestamps calldata params\n ) external returns (uint256 streamId);\n}\n" + }, + "contracts/interfaces/sablier/LockupLinear.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport {IERC20} from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\n\nlibrary LockupLinear {\n struct CreateWithTimestamps {\n address sender;\n address recipient;\n uint128 totalAmount;\n IERC20 asset;\n bool cancelable;\n bool transferable;\n Timestamps timestamps;\n Broker broker;\n }\n\n struct Timestamps {\n uint40 start;\n uint40 cliff;\n uint40 end;\n }\n\n struct Broker {\n address account;\n uint256 fee;\n }\n}\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200 + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers", + "metadata", + "devdoc", + "userdoc", + "storageLayout", + "evm.gasEstimates" + ], + "": [ + "ast" + ] + } + }, + "metadata": { + "useLiteralContent": true + } + } +} \ No newline at end of file diff --git a/deployments/polygon/DecentHats_0_1_0.json b/deployments/polygon/DecentHats_0_1_0.json index 430c2ee9..4f31841f 100644 --- a/deployments/polygon/DecentHats_0_1_0.json +++ b/deployments/polygon/DecentHats_0_1_0.json @@ -1,5 +1,5 @@ { - "address": "0xF45EAc866BAD509B0CD233869b61be8b0BC6dBd8", + "address": "0xD16368a8b709cBAfd47c480607a843144Bcd27Dc", "abi": [ { "inputs": [], @@ -275,6 +275,168 @@ "stateMutability": "nonpayable", "type": "function" }, + { + "inputs": [ + { + "internalType": "contract IHats", + "name": "hatsProtocol", + "type": "address" + }, + { + "internalType": "uint256", + "name": "adminHatId", + "type": "uint256" + }, + { + "components": [ + { + "internalType": "uint32", + "name": "maxSupply", + "type": "uint32" + }, + { + "internalType": "string", + "name": "details", + "type": "string" + }, + { + "internalType": "string", + "name": "imageURI", + "type": "string" + }, + { + "internalType": "bool", + "name": "isMutable", + "type": "bool" + }, + { + "internalType": "address", + "name": "wearer", + "type": "address" + }, + { + "components": [ + { + "internalType": "contract ISablierV2LockupLinear", + "name": "sablier", + "type": "address" + }, + { + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "internalType": "uint128", + "name": "totalAmount", + "type": "uint128" + }, + { + "internalType": "address", + "name": "asset", + "type": "address" + }, + { + "internalType": "bool", + "name": "cancelable", + "type": "bool" + }, + { + "internalType": "bool", + "name": "transferable", + "type": "bool" + }, + { + "components": [ + { + "internalType": "uint40", + "name": "start", + "type": "uint40" + }, + { + "internalType": "uint40", + "name": "cliff", + "type": "uint40" + }, + { + "internalType": "uint40", + "name": "end", + "type": "uint40" + } + ], + "internalType": "struct LockupLinear.Timestamps", + "name": "timestamps", + "type": "tuple" + }, + { + "components": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "uint256", + "name": "fee", + "type": "uint256" + } + ], + "internalType": "struct LockupLinear.Broker", + "name": "broker", + "type": "tuple" + } + ], + "internalType": "struct DecentHats_0_1_0.SablierStreamParams[]", + "name": "sablierParams", + "type": "tuple[]" + } + ], + "internalType": "struct DecentHats_0_1_0.Hat", + "name": "hat", + "type": "tuple" + }, + { + "internalType": "uint256", + "name": "topHatId", + "type": "uint256" + }, + { + "internalType": "address", + "name": "topHatAccount", + "type": "address" + }, + { + "internalType": "contract IERC6551Registry", + "name": "registry", + "type": "address" + }, + { + "internalType": "address", + "name": "hatsAccountImplementation", + "type": "address" + }, + { + "internalType": "bytes32", + "name": "salt", + "type": "bytes32" + } + ], + "name": "createRoleHat", + "outputs": [ + { + "internalType": "uint256", + "name": "hatId", + "type": "uint256" + }, + { + "internalType": "address", + "name": "accountAddress", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, { "inputs": [], "name": "getSalt", @@ -289,52 +451,66 @@ "type": "function" } ], - "transactionHash": "0x40e81b75cc595e623f572f1eb7880ded1189d5ac88f08b2f0cfa06d7e17504cf", + "transactionHash": "0x4ba462f0850e0d219a04185af6fdd7106e48b60e7edadb407e7afb66ec337f8a", "receipt": { "to": null, "from": "0xb5Ca125166C1987A35EDD550E16846Fa1e1D9bB3", - "contractAddress": "0xF45EAc866BAD509B0CD233869b61be8b0BC6dBd8", - "transactionIndex": 9, - "gasUsed": "1162443", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000800000000000400000000100000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000100000000000004000000000000000000001000000000000000000000000000000100004000000000000000000200000000000000000000000000000000000000000000000100000", - "blockHash": "0x7d22d6e543e1e0df7018ad856b6b90ec9d58b64b8b0ffc66abc8ad4d4c2ac537", - "transactionHash": "0x40e81b75cc595e623f572f1eb7880ded1189d5ac88f08b2f0cfa06d7e17504cf", + "contractAddress": "0xD16368a8b709cBAfd47c480607a843144Bcd27Dc", + "transactionIndex": 40, + "gasUsed": "1243979", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000800000000000000000000100000000000000000000000000000000000000000000000000000000000080000000000000000040000000040000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000100000000000004000000000000000000001000000000000000000000000000000120004000000000000000000200000000000000000000000000000000000000000000000100000", + "blockHash": "0xd9e72f56a6a5a78cf740fa9f15bee4930ed50fcf55b112b8f6165202a874477c", + "transactionHash": "0x4ba462f0850e0d219a04185af6fdd7106e48b60e7edadb407e7afb66ec337f8a", "logs": [ { - "transactionIndex": 9, - "blockNumber": 62879901, - "transactionHash": "0x40e81b75cc595e623f572f1eb7880ded1189d5ac88f08b2f0cfa06d7e17504cf", + "transactionIndex": 40, + "blockNumber": 63474684, + "transactionHash": "0x4ba462f0850e0d219a04185af6fdd7106e48b60e7edadb407e7afb66ec337f8a", "address": "0x0000000000000000000000000000000000001010", "topics": [ "0x4dfe1bbbcf077ddc3e01291eea2d5c70c2b422b415d95645b9adcfd678cb1d63", "0x0000000000000000000000000000000000000000000000000000000000001010", "0x000000000000000000000000b5ca125166c1987a35edd550e16846fa1e1d9bb3", - "0x0000000000000000000000007c7379531b2aee82e4ca06d4175d13b9cbeafd49" + "0x0000000000000000000000009ead03f7136fc6b4bdb0780b00a1c14ae5a8b6d0" ], - "data": "0x00000000000000000000000000000000000000000000000001084f16858b800000000000000000000000000000000000000000000000000034103173616baf340000000000000000000000000000000000000000000339407dbafe9f1de83cf40000000000000000000000000000000000000000000000003307e25cdbe02f340000000000000000000000000000000000000000000339407ec34db5a373bcf4", - "logIndex": 91, - "blockHash": "0x7d22d6e543e1e0df7018ad856b6b90ec9d58b64b8b0ffc66abc8ad4d4c2ac537" + "data": "0x00000000000000000000000000000000000000000000000000bcc837b2df4d5a0000000000000000000000000000000000000000000000003307e25cd9ef8900000000000000000000000000000000000000000000000b962f1502731c562a88000000000000000000000000000000000000000000000000324b1a2527103ba6000000000000000000000000000000000000000000000b962fd1caaacf3577e2", + "logIndex": 247, + "blockHash": "0xd9e72f56a6a5a78cf740fa9f15bee4930ed50fcf55b112b8f6165202a874477c" } ], - "blockNumber": 62879901, - "cumulativeGasUsed": "3502682", + "blockNumber": 63474684, + "cumulativeGasUsed": "9341874", "status": 1, "byzantium": true }, "args": [], - "numDeployments": 3, - "solcInputHash": "6ceb8d75a501322d052845dbe517017d", - "metadata": "{\"compiler\":{\"version\":\"0.8.19+commit.7dd6d404\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"NAME\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"contract IHats\",\"name\":\"hatsProtocol\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"hatsAccountImplementation\",\"type\":\"address\"},{\"internalType\":\"contract IERC6551Registry\",\"name\":\"registry\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"keyValuePairs\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"topHatDetails\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"topHatImageURI\",\"type\":\"string\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"maxSupply\",\"type\":\"uint32\"},{\"internalType\":\"string\",\"name\":\"details\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"imageURI\",\"type\":\"string\"},{\"internalType\":\"bool\",\"name\":\"isMutable\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"wearer\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"contract ISablierV2LockupLinear\",\"name\":\"sablier\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint128\",\"name\":\"totalAmount\",\"type\":\"uint128\"},{\"internalType\":\"address\",\"name\":\"asset\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"cancelable\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"transferable\",\"type\":\"bool\"},{\"components\":[{\"internalType\":\"uint40\",\"name\":\"start\",\"type\":\"uint40\"},{\"internalType\":\"uint40\",\"name\":\"cliff\",\"type\":\"uint40\"},{\"internalType\":\"uint40\",\"name\":\"end\",\"type\":\"uint40\"}],\"internalType\":\"struct LockupLinear.Timestamps\",\"name\":\"timestamps\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"fee\",\"type\":\"uint256\"}],\"internalType\":\"struct LockupLinear.Broker\",\"name\":\"broker\",\"type\":\"tuple\"}],\"internalType\":\"struct DecentHats_0_1_0.SablierStreamParams[]\",\"name\":\"sablierParams\",\"type\":\"tuple[]\"}],\"internalType\":\"struct DecentHats_0_1_0.Hat\",\"name\":\"adminHat\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"maxSupply\",\"type\":\"uint32\"},{\"internalType\":\"string\",\"name\":\"details\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"imageURI\",\"type\":\"string\"},{\"internalType\":\"bool\",\"name\":\"isMutable\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"wearer\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"contract ISablierV2LockupLinear\",\"name\":\"sablier\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint128\",\"name\":\"totalAmount\",\"type\":\"uint128\"},{\"internalType\":\"address\",\"name\":\"asset\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"cancelable\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"transferable\",\"type\":\"bool\"},{\"components\":[{\"internalType\":\"uint40\",\"name\":\"start\",\"type\":\"uint40\"},{\"internalType\":\"uint40\",\"name\":\"cliff\",\"type\":\"uint40\"},{\"internalType\":\"uint40\",\"name\":\"end\",\"type\":\"uint40\"}],\"internalType\":\"struct LockupLinear.Timestamps\",\"name\":\"timestamps\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"fee\",\"type\":\"uint256\"}],\"internalType\":\"struct LockupLinear.Broker\",\"name\":\"broker\",\"type\":\"tuple\"}],\"internalType\":\"struct DecentHats_0_1_0.SablierStreamParams[]\",\"name\":\"sablierParams\",\"type\":\"tuple[]\"}],\"internalType\":\"struct DecentHats_0_1_0.Hat[]\",\"name\":\"hats\",\"type\":\"tuple[]\"}],\"internalType\":\"struct DecentHats_0_1_0.CreateTreeParams\",\"name\":\"params\",\"type\":\"tuple\"}],\"name\":\"createAndDeclareTree\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getSalt\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"salt\",\"type\":\"bytes32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/DecentHats_0_1_0.sol\":\"DecentHats_0_1_0\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\":{\"content\":\"// SPDX-License-Identifier: LGPL-3.0-only\\npragma solidity >=0.7.0 <0.9.0;\\n\\n/// @title Enum - Collection of enums\\n/// @author Richard Meissner - \\ncontract Enum {\\n enum Operation {Call, DelegateCall}\\n}\\n\",\"keccak256\":\"0x473e45b1a5cc47be494b0e123c9127f0c11c1e0992a321ae5a644c0bfdb2c14f\",\"license\":\"LGPL-3.0-only\"},\"@gnosis.pm/zodiac/contracts/interfaces/IAvatar.sol\":{\"content\":\"// SPDX-License-Identifier: LGPL-3.0-only\\n\\n/// @title Zodiac Avatar - A contract that manages modules that can execute transactions via this contract.\\npragma solidity >=0.7.0 <0.9.0;\\n\\nimport \\\"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\\\";\\n\\ninterface IAvatar {\\n event EnabledModule(address module);\\n event DisabledModule(address module);\\n event ExecutionFromModuleSuccess(address indexed module);\\n event ExecutionFromModuleFailure(address indexed module);\\n\\n /// @dev Enables a module on the avatar.\\n /// @notice Can only be called by the avatar.\\n /// @notice Modules should be stored as a linked list.\\n /// @notice Must emit EnabledModule(address module) if successful.\\n /// @param module Module to be enabled.\\n function enableModule(address module) external;\\n\\n /// @dev Disables a module on the avatar.\\n /// @notice Can only be called by the avatar.\\n /// @notice Must emit DisabledModule(address module) if successful.\\n /// @param prevModule Address that pointed to the module to be removed in the linked list\\n /// @param module Module to be removed.\\n function disableModule(address prevModule, address module) external;\\n\\n /// @dev Allows a Module to execute a transaction.\\n /// @notice Can only be called by an enabled module.\\n /// @notice Must emit ExecutionFromModuleSuccess(address module) if successful.\\n /// @notice Must emit ExecutionFromModuleFailure(address module) if unsuccessful.\\n /// @param to Destination address of module transaction.\\n /// @param value Ether value of module transaction.\\n /// @param data Data payload of module transaction.\\n /// @param operation Operation type of module transaction: 0 == call, 1 == delegate call.\\n function execTransactionFromModule(\\n address to,\\n uint256 value,\\n bytes memory data,\\n Enum.Operation operation\\n ) external returns (bool success);\\n\\n /// @dev Allows a Module to execute a transaction and return data\\n /// @notice Can only be called by an enabled module.\\n /// @notice Must emit ExecutionFromModuleSuccess(address module) if successful.\\n /// @notice Must emit ExecutionFromModuleFailure(address module) if unsuccessful.\\n /// @param to Destination address of module transaction.\\n /// @param value Ether value of module transaction.\\n /// @param data Data payload of module transaction.\\n /// @param operation Operation type of module transaction: 0 == call, 1 == delegate call.\\n function execTransactionFromModuleReturnData(\\n address to,\\n uint256 value,\\n bytes memory data,\\n Enum.Operation operation\\n ) external returns (bool success, bytes memory returnData);\\n\\n /// @dev Returns if an module is enabled\\n /// @return True if the module is enabled\\n function isModuleEnabled(address module) external view returns (bool);\\n\\n /// @dev Returns array of modules.\\n /// @param start Start of the page.\\n /// @param pageSize Maximum number of modules that should be returned.\\n /// @return array Array of modules.\\n /// @return next Start of the next page.\\n function getModulesPaginated(address start, uint256 pageSize)\\n external\\n view\\n returns (address[] memory array, address next);\\n}\\n\",\"keccak256\":\"0xcd5508ffe596eef8fbccfd5fc4f10a34397773547ce64e212d48b5212865ec1f\",\"license\":\"LGPL-3.0-only\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20 {\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `to`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address to, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `from` to `to` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(\\n address from,\\n address to,\\n uint256 amount\\n ) external returns (bool);\\n}\\n\",\"keccak256\":\"0x9750c6b834f7b43000631af5cc30001c5f547b3ceb3635488f140f60e897ea6b\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Strings.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev String operations.\\n */\\nlibrary Strings {\\n bytes16 private constant _HEX_SYMBOLS = \\\"0123456789abcdef\\\";\\n uint8 private constant _ADDRESS_LENGTH = 20;\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\\n */\\n function toString(uint256 value) internal pure returns (string memory) {\\n // Inspired by OraclizeAPI's implementation - MIT licence\\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\\n\\n if (value == 0) {\\n return \\\"0\\\";\\n }\\n uint256 temp = value;\\n uint256 digits;\\n while (temp != 0) {\\n digits++;\\n temp /= 10;\\n }\\n bytes memory buffer = new bytes(digits);\\n while (value != 0) {\\n digits -= 1;\\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\\n value /= 10;\\n }\\n return string(buffer);\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\\n */\\n function toHexString(uint256 value) internal pure returns (string memory) {\\n if (value == 0) {\\n return \\\"0x00\\\";\\n }\\n uint256 temp = value;\\n uint256 length = 0;\\n while (temp != 0) {\\n length++;\\n temp >>= 8;\\n }\\n return toHexString(value, length);\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\\n */\\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\\n bytes memory buffer = new bytes(2 * length + 2);\\n buffer[0] = \\\"0\\\";\\n buffer[1] = \\\"x\\\";\\n for (uint256 i = 2 * length + 1; i > 1; --i) {\\n buffer[i] = _HEX_SYMBOLS[value & 0xf];\\n value >>= 4;\\n }\\n require(value == 0, \\\"Strings: hex length insufficient\\\");\\n return string(buffer);\\n }\\n\\n /**\\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\\n */\\n function toHexString(address addr) internal pure returns (string memory) {\\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\\n }\\n}\\n\",\"keccak256\":\"0xaf159a8b1923ad2a26d516089bceca9bdeaeacd04be50983ea00ba63070f08a3\",\"license\":\"MIT\"},\"contracts/DecentHats_0_1_0.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity =0.8.19;\\n\\nimport {Enum} from \\\"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\\\";\\nimport {IAvatar} from \\\"@gnosis.pm/zodiac/contracts/interfaces/IAvatar.sol\\\";\\nimport {Strings} from \\\"@openzeppelin/contracts/utils/Strings.sol\\\";\\nimport {IERC20} from \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\nimport {IERC6551Registry} from \\\"./interfaces/IERC6551Registry.sol\\\";\\nimport {IHats} from \\\"./interfaces/hats/IHats.sol\\\";\\nimport {ISablierV2LockupLinear} from \\\"./interfaces/sablier/ISablierV2LockupLinear.sol\\\";\\nimport {LockupLinear} from \\\"./interfaces/sablier/LockupLinear.sol\\\";\\n\\ncontract DecentHats_0_1_0 {\\n string public constant NAME = \\\"DecentHats_0_1_0\\\";\\n\\n struct SablierStreamParams {\\n ISablierV2LockupLinear sablier;\\n address sender;\\n uint128 totalAmount;\\n address asset;\\n bool cancelable;\\n bool transferable;\\n LockupLinear.Timestamps timestamps;\\n LockupLinear.Broker broker;\\n }\\n\\n struct Hat {\\n uint32 maxSupply;\\n string details;\\n string imageURI;\\n bool isMutable;\\n address wearer;\\n SablierStreamParams[] sablierParams; // Optional Sablier stream parameters\\n }\\n\\n struct CreateTreeParams {\\n IHats hatsProtocol;\\n address hatsAccountImplementation;\\n IERC6551Registry registry;\\n address keyValuePairs;\\n string topHatDetails;\\n string topHatImageURI;\\n Hat adminHat;\\n Hat[] hats;\\n }\\n\\n function getSalt() public pure returns (bytes32 salt) {\\n return\\n 0x5d0e6ce4fd951366cc55da93f6e79d8b81483109d79676a04bcc2bed6a4b5072;\\n }\\n\\n function updateKeyValuePairs(\\n address _keyValuePairs,\\n uint256 topHatId\\n ) internal {\\n string[] memory keys = new string[](1);\\n string[] memory values = new string[](1);\\n keys[0] = \\\"topHatId\\\";\\n values[0] = Strings.toString(topHatId);\\n\\n IAvatar(msg.sender).execTransactionFromModule(\\n _keyValuePairs,\\n 0,\\n abi.encodeWithSignature(\\n \\\"updateValues(string[],string[])\\\",\\n keys,\\n values\\n ),\\n Enum.Operation.Call\\n );\\n }\\n\\n function createHat(\\n IHats _hatsProtocol,\\n uint256 adminHatId,\\n Hat memory _hat,\\n address topHatAccount\\n ) internal returns (uint256) {\\n return\\n _hatsProtocol.createHat(\\n adminHatId,\\n _hat.details,\\n _hat.maxSupply,\\n topHatAccount,\\n topHatAccount,\\n _hat.isMutable,\\n _hat.imageURI\\n );\\n }\\n\\n function createAccount(\\n IERC6551Registry _registry,\\n address _hatsAccountImplementation,\\n bytes32 salt,\\n address protocolAddress,\\n uint256 hatId\\n ) internal returns (address) {\\n return\\n _registry.createAccount(\\n _hatsAccountImplementation,\\n salt,\\n block.chainid,\\n protocolAddress,\\n hatId\\n );\\n }\\n\\n function createTopHatAndAccount(\\n IHats _hatsProtocol,\\n string memory _topHatDetails,\\n string memory _topHatImageURI,\\n IERC6551Registry _registry,\\n address _hatsAccountImplementation,\\n bytes32 salt\\n ) internal returns (uint256 topHatId, address topHatAccount) {\\n topHatId = _hatsProtocol.mintTopHat(\\n address(this),\\n _topHatDetails,\\n _topHatImageURI\\n );\\n\\n topHatAccount = createAccount(\\n _registry,\\n _hatsAccountImplementation,\\n salt,\\n address(_hatsProtocol),\\n topHatId\\n );\\n }\\n\\n function createHatAndAccountAndMintAndStreams(\\n IHats hatsProtocol,\\n uint256 adminHatId,\\n Hat calldata hat,\\n address topHatAccount,\\n IERC6551Registry registry,\\n address hatsAccountImplementation,\\n bytes32 salt\\n ) internal returns (uint256 hatId, address accountAddress) {\\n hatId = createHat(hatsProtocol, adminHatId, hat, topHatAccount);\\n\\n accountAddress = createAccount(\\n registry,\\n hatsAccountImplementation,\\n salt,\\n address(hatsProtocol),\\n hatId\\n );\\n\\n if (hat.wearer != address(0)) {\\n hatsProtocol.mintHat(hatId, hat.wearer);\\n }\\n\\n for (uint256 i = 0; i < hat.sablierParams.length; ) {\\n SablierStreamParams memory sablierParams = hat.sablierParams[i];\\n\\n // Approve tokens for Sablier\\n IAvatar(msg.sender).execTransactionFromModule(\\n sablierParams.asset,\\n 0,\\n abi.encodeWithSignature(\\n \\\"approve(address,uint256)\\\",\\n address(sablierParams.sablier),\\n sablierParams.totalAmount\\n ),\\n Enum.Operation.Call\\n );\\n\\n LockupLinear.CreateWithTimestamps memory params = LockupLinear\\n .CreateWithTimestamps({\\n sender: sablierParams.sender,\\n recipient: accountAddress,\\n totalAmount: sablierParams.totalAmount,\\n asset: IERC20(sablierParams.asset),\\n cancelable: sablierParams.cancelable,\\n transferable: sablierParams.transferable,\\n timestamps: sablierParams.timestamps,\\n broker: sablierParams.broker\\n });\\n\\n // Proxy the Sablier call through IAvatar\\n IAvatar(msg.sender).execTransactionFromModule(\\n address(sablierParams.sablier),\\n 0,\\n abi.encodeWithSignature(\\n \\\"createWithTimestamps((address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256)))\\\",\\n params\\n ),\\n Enum.Operation.Call\\n );\\n\\n unchecked {\\n ++i;\\n }\\n }\\n }\\n\\n function createAndDeclareTree(CreateTreeParams calldata params) public {\\n bytes32 salt = getSalt();\\n\\n (uint256 topHatId, address topHatAccount) = createTopHatAndAccount(\\n params.hatsProtocol,\\n params.topHatDetails,\\n params.topHatImageURI,\\n params.registry,\\n params.hatsAccountImplementation,\\n salt\\n );\\n\\n updateKeyValuePairs(params.keyValuePairs, topHatId);\\n\\n (uint256 adminHatId, ) = createHatAndAccountAndMintAndStreams(\\n params.hatsProtocol,\\n topHatId,\\n params.adminHat,\\n topHatAccount,\\n params.registry,\\n params.hatsAccountImplementation,\\n salt\\n );\\n\\n for (uint256 i = 0; i < params.hats.length; ) {\\n createHatAndAccountAndMintAndStreams(\\n params.hatsProtocol,\\n adminHatId,\\n params.hats[i],\\n topHatAccount,\\n params.registry,\\n params.hatsAccountImplementation,\\n salt\\n );\\n\\n unchecked {\\n ++i;\\n }\\n }\\n\\n params.hatsProtocol.transferHat(topHatId, address(this), msg.sender);\\n }\\n}\\n\",\"keccak256\":\"0xcf4e6d62ca64f62b8eb638805a8a4e715aea8fc201f3dea9a522edc1034599f1\",\"license\":\"MIT\"},\"contracts/interfaces/IERC6551Registry.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.4;\\n\\ninterface IERC6551Registry {\\n /**\\n * @dev Creates a token bound account for a non-fungible token.\\n *\\n * If account has already been created, returns the account address without calling create2.\\n *\\n * Emits ERC6551AccountCreated event.\\n *\\n * @return account The address of the token bound account\\n */\\n function createAccount(\\n address implementation,\\n bytes32 salt,\\n uint256 chainId,\\n address tokenContract,\\n uint256 tokenId\\n ) external returns (address account);\\n}\\n\",\"keccak256\":\"0x64c52de8a8e68398e61dd8b42dda8e9af8cf6abf93bb85629c322440991ea568\",\"license\":\"MIT\"},\"contracts/interfaces/hats/IHats.sol\":{\"content\":\"// SPDX-License-Identifier: AGPL-3.0\\n// Copyright (C) 2023 Haberdasher Labs\\n//\\n// This program is free software: you can redistribute it and/or modify\\n// it under the terms of the GNU Affero General Public License as published by\\n// the Free Software Foundation, either version 3 of the License, or\\n// (at your option) any later version.\\n//\\n// This program is distributed in the hope that it will be useful,\\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\\n// GNU Affero General Public License for more details.\\n//\\n// You should have received a copy of the GNU Affero General Public License\\n// along with this program. If not, see .\\n\\npragma solidity >=0.8.13;\\n\\ninterface IHats {\\n function mintTopHat(\\n address _target,\\n string memory _details,\\n string memory _imageURI\\n ) external returns (uint256 topHatId);\\n\\n function createHat(\\n uint256 _admin,\\n string calldata _details,\\n uint32 _maxSupply,\\n address _eligibility,\\n address _toggle,\\n bool _mutable,\\n string calldata _imageURI\\n ) external returns (uint256 newHatId);\\n\\n function mintHat(\\n uint256 _hatId,\\n address _wearer\\n ) external returns (bool success);\\n\\n function transferHat(uint256 _hatId, address _from, address _to) external;\\n}\\n\",\"keccak256\":\"0x8e35022f5c0fcf0059033abec78ec890f0cf3bbac09d6d24051cff9679239511\",\"license\":\"AGPL-3.0\"},\"contracts/interfaces/sablier/ISablierV2LockupLinear.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport {LockupLinear} from \\\"./LockupLinear.sol\\\";\\nimport {IERC20} from \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\n\\ninterface ISablierV2LockupLinear {\\n function createWithTimestamps(\\n LockupLinear.CreateWithTimestamps calldata params\\n ) external returns (uint256 streamId);\\n}\\n\",\"keccak256\":\"0xf4899637eb2e6c76c35e2d201e56e162a50e6bc7b5b9156e00866f0703ad07ca\",\"license\":\"MIT\"},\"contracts/interfaces/sablier/LockupLinear.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport {IERC20} from \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\n\\nlibrary LockupLinear {\\n struct CreateWithTimestamps {\\n address sender;\\n address recipient;\\n uint128 totalAmount;\\n IERC20 asset;\\n bool cancelable;\\n bool transferable;\\n Timestamps timestamps;\\n Broker broker;\\n }\\n\\n struct Timestamps {\\n uint40 start;\\n uint40 cliff;\\n uint40 end;\\n }\\n\\n struct Broker {\\n address account;\\n uint256 fee;\\n }\\n}\\n\",\"keccak256\":\"0x497fdb52b5e1a5a7e0711a9f7d5fb036eb668ccb92ea908ee088f56ee08a4ce8\",\"license\":\"MIT\"}},\"version\":1}", - "bytecode": "0x608060405234801561001057600080fd5b50611410806100206000396000f3fe608060405234801561001057600080fd5b50600436106100415760003560e01c806313a9589c146100465780638c5f591a14610079578063a3f4df7e1461008e575b600080fd5b6040517f5d0e6ce4fd951366cc55da93f6e79d8b81483109d79676a04bcc2bed6a4b507281526020015b60405180910390f35b61008c610087366004610aa8565b6100ca565b005b6100bd6040518060400160405280601081526020016f0446563656e74486174735f305f315f360841b81525081565b6040516100709190610b30565b7f5d0e6ce4fd951366cc55da93f6e79d8b81483109d79676a04bcc2bed6a4b50726000806101a86100fe6020860186610b5b565b61010b6080870187610b78565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061014d9250505060a0880188610b78565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610192925050506060890160408a01610b5b565b6101a260408a0160208b01610b5b565b88610317565b90925090506101c66101c06080860160608701610b5b565b836103a9565b600061020d6101d86020870187610b5b565b846101e660c0890189610bd5565b856101f760608b0160408c01610b5b565b61020760408c0160208d01610b5b565b8a610529565b50905060005b61022060e0870187610bf5565b905081101561029a576102906102396020880188610b5b565b8361024760e08a018a610bf5565b8581811061025757610257610c3e565b90506020028101906102699190610bd5565b8661027a60608c0160408d01610b5b565b61028a60408d0160208e01610b5b565b8b610529565b5050600101610213565b506102a86020860186610b5b565b6040516329287c1b60e21b8152600481018590523060248201523360448201526001600160a01b03919091169063a4a1f06c90606401600060405180830381600087803b1580156102f857600080fd5b505af115801561030c573d6000803e3d6000fd5b505050505050505050565b600080876001600160a01b0316631a64dfad3089896040518463ffffffff1660e01b815260040161034a93929190610c54565b6020604051808303816000875af1158015610369573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061038d9190610c8a565b915061039c8585858b86610878565b9050965096945050505050565b604080516001808252818301909252600091816020015b60608152602001906001900390816103c057505060408051600180825281830190925291925060009190602082015b60608152602001906001900390816103ef579050509050604051806040016040528060088152602001671d1bdc12185d125960c21b8152508260008151811061043a5761043a610c3e565b602002602001018190525061044e8361090e565b8160008151811061046157610461610c3e565b6020026020010181905250336001600160a01b031663468721a78560008585604051602401610491929190610d11565b60408051601f198184030181529181526020820180516001600160e01b031663579374b960e11b1790525160e085901b6001600160e01b03191681526104df93929190600090600401610d36565b6020604051808303816000875af11580156104fe573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105229190610d9a565b5050505050565b600080610540898961053a8a6110d4565b89610a16565b915061054f8585858c86610878565b9050600061056360a0890160808a01610b5b565b6001600160a01b031614610603576001600160a01b03891663641f776e8361059160a08b0160808c01610b5b565b6040516001600160e01b031960e085901b16815260048101929092526001600160a01b031660248201526044016020604051808303816000875af11580156105dd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106019190610d9a565b505b60005b61061360a0890189611198565b905081101561086b57600061062b60a08a018a611198565b8381811061063b5761063b610c3e565b9050610160020180360381019061065291906111e1565b6060810151815160408084015190516001600160a01b0390921660248301526001600160801b03166044820152919250339163468721a7919060009060640160408051601f198184030181529181526020820180516001600160e01b031663095ea7b360e01b1790525160e085901b6001600160e01b03191681526106df93929190600090600401610d36565b6020604051808303816000875af11580156106fe573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107229190610d9a565b50600060405180610100016040528083602001516001600160a01b03168152602001856001600160a01b0316815260200183604001516001600160801b0316815260200183606001516001600160a01b031681526020018360800151151581526020018360a00151151581526020018360c0015181526020018360e001518152509050336001600160a01b031663468721a783600001516000846040516024016107cc91906111fe565b60408051601f198184030181529181526020820180516001600160e01b03166353b1572760e01b1790525160e085901b6001600160e01b031916815261081a93929190600090600401610d36565b6020604051808303816000875af1158015610839573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061085d9190610d9a565b508260010192505050610606565b5097509795505050505050565b604051638a54c52f60e01b81526001600160a01b0385811660048301526024820185905246604483015283811660648301526084820183905260009190871690638a54c52f9060a4016020604051808303816000875af11580156108e0573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061090491906112c0565b9695505050505050565b6060816000036109355750506040805180820190915260018152600360fc1b602082015290565b8160005b811561095f5780610949816112f3565b91506109589050600a83611322565b9150610939565b6000816001600160401b0381111561097957610979610ca3565b6040519080825280601f01601f1916602001820160405280156109a3576020820181803683370190505b5090505b8415610a0e576109b8600183611336565b91506109c5600a8661134f565b6109d0906030611363565b60f81b8183815181106109e5576109e5610c3e565b60200101906001600160f81b031916908160001a905350610a07600a86611322565b94506109a7565b949350505050565b6020820151825160608401516040808601519051635829492f60e11b81526000946001600160a01b038a169463b052925e94610a5c948b948a9283929091600401611376565b6020604051808303816000875af1158015610a7b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a9f9190610c8a565b95945050505050565b600060208284031215610aba57600080fd5b81356001600160401b03811115610ad057600080fd5b82016101008185031215610ae357600080fd5b9392505050565b6000815180845260005b81811015610b1057602081850181015186830182015201610af4565b506000602082860101526020601f19601f83011685010191505092915050565b602081526000610ae36020830184610aea565b6001600160a01b0381168114610b5857600080fd5b50565b600060208284031215610b6d57600080fd5b8135610ae381610b43565b6000808335601e19843603018112610b8f57600080fd5b8301803591506001600160401b03821115610ba957600080fd5b602001915036819003821315610bbe57600080fd5b9250929050565b8035610bd081610b43565b919050565b6000823560be19833603018112610beb57600080fd5b9190910192915050565b6000808335601e19843603018112610c0c57600080fd5b8301803591506001600160401b03821115610c2657600080fd5b6020019150600581901b3603821315610bbe57600080fd5b634e487b7160e01b600052603260045260246000fd5b6001600160a01b0384168152606060208201819052600090610c7890830185610aea565b82810360408401526109048185610aea565b600060208284031215610c9c57600080fd5b5051919050565b634e487b7160e01b600052604160045260246000fd5b600082825180855260208086019550808260051b84010181860160005b84811015610d0457601f19868403018952610cf2838351610aea565b98840198925090830190600101610cd6565b5090979650505050505050565b604081526000610d246040830185610cb9565b8281036020840152610a9f8185610cb9565b60018060a01b0385168152836020820152608060408201526000610d5d6080830185610aea565b905060028310610d7d57634e487b7160e01b600052602160045260246000fd5b82606083015295945050505050565b8015158114610b5857600080fd5b600060208284031215610dac57600080fd5b8151610ae381610d8c565b60405160c081016001600160401b0381118282101715610dd957610dd9610ca3565b60405290565b604051601f8201601f191681016001600160401b0381118282101715610e0757610e07610ca3565b604052919050565b803563ffffffff81168114610bd057600080fd5b600082601f830112610e3457600080fd5b81356001600160401b03811115610e4d57610e4d610ca3565b610e60601f8201601f1916602001610ddf565b818152846020838601011115610e7557600080fd5b816020850160208301376000918101602001919091529392505050565b8035610bd081610d8c565b80356001600160801b0381168114610bd057600080fd5b803564ffffffffff81168114610bd057600080fd5b600060608284031215610edb57600080fd5b604051606081018181106001600160401b0382111715610efd57610efd610ca3565b604052905080610f0c83610eb4565b8152610f1a60208401610eb4565b6020820152610f2b60408401610eb4565b60408201525092915050565b600060408284031215610f4957600080fd5b604051604081018181106001600160401b0382111715610f6b57610f6b610ca3565b6040529050808235610f7c81610b43565b8152602092830135920191909152919050565b60006101608284031215610fa257600080fd5b60405161010081018181106001600160401b0382111715610fc557610fc5610ca3565b604052905080610fd483610bc5565b8152610fe260208401610bc5565b6020820152610ff360408401610e9d565b604082015261100460608401610bc5565b606082015261101560808401610e92565b608082015261102660a08401610e92565b60a08201526110388460c08501610ec9565b60c082015261104b846101208501610f37565b60e08201525092915050565b600082601f83011261106857600080fd5b813560206001600160401b0382111561108357611083610ca3565b611091818360051b01610ddf565b82815261016092830285018201928282019190878511156110b157600080fd5b8387015b85811015610d04576110c78982610f8f565b84529284019281016110b5565b600060c082360312156110e657600080fd5b6110ee610db7565b6110f783610e0f565b815260208301356001600160401b038082111561111357600080fd5b61111f36838701610e23565b6020840152604085013591508082111561113857600080fd5b61114436838701610e23565b604084015261115560608601610e92565b606084015261116660808601610bc5565b608084015260a085013591508082111561117f57600080fd5b5061118c36828601611057565b60a08301525092915050565b6000808335601e198436030181126111af57600080fd5b8301803591506001600160401b038211156111c957600080fd5b602001915061016081023603821315610bbe57600080fd5b600061016082840312156111f457600080fd5b610ae38383610f8f565b81516001600160a01b0390811682526020808401518216908301526040808401516001600160801b031690830152606080840151909116908201526080808301516101608301916112529084018215159052565b5060a083015161126660a084018215159052565b5060c083015161129960c0840182805164ffffffffff908116835260208083015182169084015260409182015116910152565b5060e0929092015180516001600160a01b0316610120830152602001516101409091015290565b6000602082840312156112d257600080fd5b8151610ae381610b43565b634e487b7160e01b600052601160045260246000fd5b600060018201611305576113056112dd565b5060010190565b634e487b7160e01b600052601260045260246000fd5b6000826113315761133161130c565b500490565b81810381811115611349576113496112dd565b92915050565b60008261135e5761135e61130c565b500690565b80820180821115611349576113496112dd565b87815260e06020820152600061138f60e0830189610aea565b63ffffffff881660408401526001600160a01b0387811660608501528616608084015284151560a084015282810360c08401526113cc8185610aea565b9a995050505050505050505056fea2646970667358221220fcb8ad75991fd171fd33998d718d5f54883d99a48d56657e7e938e34a55d6a2664736f6c63430008130033", - "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100415760003560e01c806313a9589c146100465780638c5f591a14610079578063a3f4df7e1461008e575b600080fd5b6040517f5d0e6ce4fd951366cc55da93f6e79d8b81483109d79676a04bcc2bed6a4b507281526020015b60405180910390f35b61008c610087366004610aa8565b6100ca565b005b6100bd6040518060400160405280601081526020016f0446563656e74486174735f305f315f360841b81525081565b6040516100709190610b30565b7f5d0e6ce4fd951366cc55da93f6e79d8b81483109d79676a04bcc2bed6a4b50726000806101a86100fe6020860186610b5b565b61010b6080870187610b78565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061014d9250505060a0880188610b78565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610192925050506060890160408a01610b5b565b6101a260408a0160208b01610b5b565b88610317565b90925090506101c66101c06080860160608701610b5b565b836103a9565b600061020d6101d86020870187610b5b565b846101e660c0890189610bd5565b856101f760608b0160408c01610b5b565b61020760408c0160208d01610b5b565b8a610529565b50905060005b61022060e0870187610bf5565b905081101561029a576102906102396020880188610b5b565b8361024760e08a018a610bf5565b8581811061025757610257610c3e565b90506020028101906102699190610bd5565b8661027a60608c0160408d01610b5b565b61028a60408d0160208e01610b5b565b8b610529565b5050600101610213565b506102a86020860186610b5b565b6040516329287c1b60e21b8152600481018590523060248201523360448201526001600160a01b03919091169063a4a1f06c90606401600060405180830381600087803b1580156102f857600080fd5b505af115801561030c573d6000803e3d6000fd5b505050505050505050565b600080876001600160a01b0316631a64dfad3089896040518463ffffffff1660e01b815260040161034a93929190610c54565b6020604051808303816000875af1158015610369573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061038d9190610c8a565b915061039c8585858b86610878565b9050965096945050505050565b604080516001808252818301909252600091816020015b60608152602001906001900390816103c057505060408051600180825281830190925291925060009190602082015b60608152602001906001900390816103ef579050509050604051806040016040528060088152602001671d1bdc12185d125960c21b8152508260008151811061043a5761043a610c3e565b602002602001018190525061044e8361090e565b8160008151811061046157610461610c3e565b6020026020010181905250336001600160a01b031663468721a78560008585604051602401610491929190610d11565b60408051601f198184030181529181526020820180516001600160e01b031663579374b960e11b1790525160e085901b6001600160e01b03191681526104df93929190600090600401610d36565b6020604051808303816000875af11580156104fe573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105229190610d9a565b5050505050565b600080610540898961053a8a6110d4565b89610a16565b915061054f8585858c86610878565b9050600061056360a0890160808a01610b5b565b6001600160a01b031614610603576001600160a01b03891663641f776e8361059160a08b0160808c01610b5b565b6040516001600160e01b031960e085901b16815260048101929092526001600160a01b031660248201526044016020604051808303816000875af11580156105dd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106019190610d9a565b505b60005b61061360a0890189611198565b905081101561086b57600061062b60a08a018a611198565b8381811061063b5761063b610c3e565b9050610160020180360381019061065291906111e1565b6060810151815160408084015190516001600160a01b0390921660248301526001600160801b03166044820152919250339163468721a7919060009060640160408051601f198184030181529181526020820180516001600160e01b031663095ea7b360e01b1790525160e085901b6001600160e01b03191681526106df93929190600090600401610d36565b6020604051808303816000875af11580156106fe573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107229190610d9a565b50600060405180610100016040528083602001516001600160a01b03168152602001856001600160a01b0316815260200183604001516001600160801b0316815260200183606001516001600160a01b031681526020018360800151151581526020018360a00151151581526020018360c0015181526020018360e001518152509050336001600160a01b031663468721a783600001516000846040516024016107cc91906111fe565b60408051601f198184030181529181526020820180516001600160e01b03166353b1572760e01b1790525160e085901b6001600160e01b031916815261081a93929190600090600401610d36565b6020604051808303816000875af1158015610839573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061085d9190610d9a565b508260010192505050610606565b5097509795505050505050565b604051638a54c52f60e01b81526001600160a01b0385811660048301526024820185905246604483015283811660648301526084820183905260009190871690638a54c52f9060a4016020604051808303816000875af11580156108e0573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061090491906112c0565b9695505050505050565b6060816000036109355750506040805180820190915260018152600360fc1b602082015290565b8160005b811561095f5780610949816112f3565b91506109589050600a83611322565b9150610939565b6000816001600160401b0381111561097957610979610ca3565b6040519080825280601f01601f1916602001820160405280156109a3576020820181803683370190505b5090505b8415610a0e576109b8600183611336565b91506109c5600a8661134f565b6109d0906030611363565b60f81b8183815181106109e5576109e5610c3e565b60200101906001600160f81b031916908160001a905350610a07600a86611322565b94506109a7565b949350505050565b6020820151825160608401516040808601519051635829492f60e11b81526000946001600160a01b038a169463b052925e94610a5c948b948a9283929091600401611376565b6020604051808303816000875af1158015610a7b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a9f9190610c8a565b95945050505050565b600060208284031215610aba57600080fd5b81356001600160401b03811115610ad057600080fd5b82016101008185031215610ae357600080fd5b9392505050565b6000815180845260005b81811015610b1057602081850181015186830182015201610af4565b506000602082860101526020601f19601f83011685010191505092915050565b602081526000610ae36020830184610aea565b6001600160a01b0381168114610b5857600080fd5b50565b600060208284031215610b6d57600080fd5b8135610ae381610b43565b6000808335601e19843603018112610b8f57600080fd5b8301803591506001600160401b03821115610ba957600080fd5b602001915036819003821315610bbe57600080fd5b9250929050565b8035610bd081610b43565b919050565b6000823560be19833603018112610beb57600080fd5b9190910192915050565b6000808335601e19843603018112610c0c57600080fd5b8301803591506001600160401b03821115610c2657600080fd5b6020019150600581901b3603821315610bbe57600080fd5b634e487b7160e01b600052603260045260246000fd5b6001600160a01b0384168152606060208201819052600090610c7890830185610aea565b82810360408401526109048185610aea565b600060208284031215610c9c57600080fd5b5051919050565b634e487b7160e01b600052604160045260246000fd5b600082825180855260208086019550808260051b84010181860160005b84811015610d0457601f19868403018952610cf2838351610aea565b98840198925090830190600101610cd6565b5090979650505050505050565b604081526000610d246040830185610cb9565b8281036020840152610a9f8185610cb9565b60018060a01b0385168152836020820152608060408201526000610d5d6080830185610aea565b905060028310610d7d57634e487b7160e01b600052602160045260246000fd5b82606083015295945050505050565b8015158114610b5857600080fd5b600060208284031215610dac57600080fd5b8151610ae381610d8c565b60405160c081016001600160401b0381118282101715610dd957610dd9610ca3565b60405290565b604051601f8201601f191681016001600160401b0381118282101715610e0757610e07610ca3565b604052919050565b803563ffffffff81168114610bd057600080fd5b600082601f830112610e3457600080fd5b81356001600160401b03811115610e4d57610e4d610ca3565b610e60601f8201601f1916602001610ddf565b818152846020838601011115610e7557600080fd5b816020850160208301376000918101602001919091529392505050565b8035610bd081610d8c565b80356001600160801b0381168114610bd057600080fd5b803564ffffffffff81168114610bd057600080fd5b600060608284031215610edb57600080fd5b604051606081018181106001600160401b0382111715610efd57610efd610ca3565b604052905080610f0c83610eb4565b8152610f1a60208401610eb4565b6020820152610f2b60408401610eb4565b60408201525092915050565b600060408284031215610f4957600080fd5b604051604081018181106001600160401b0382111715610f6b57610f6b610ca3565b6040529050808235610f7c81610b43565b8152602092830135920191909152919050565b60006101608284031215610fa257600080fd5b60405161010081018181106001600160401b0382111715610fc557610fc5610ca3565b604052905080610fd483610bc5565b8152610fe260208401610bc5565b6020820152610ff360408401610e9d565b604082015261100460608401610bc5565b606082015261101560808401610e92565b608082015261102660a08401610e92565b60a08201526110388460c08501610ec9565b60c082015261104b846101208501610f37565b60e08201525092915050565b600082601f83011261106857600080fd5b813560206001600160401b0382111561108357611083610ca3565b611091818360051b01610ddf565b82815261016092830285018201928282019190878511156110b157600080fd5b8387015b85811015610d04576110c78982610f8f565b84529284019281016110b5565b600060c082360312156110e657600080fd5b6110ee610db7565b6110f783610e0f565b815260208301356001600160401b038082111561111357600080fd5b61111f36838701610e23565b6020840152604085013591508082111561113857600080fd5b61114436838701610e23565b604084015261115560608601610e92565b606084015261116660808601610bc5565b608084015260a085013591508082111561117f57600080fd5b5061118c36828601611057565b60a08301525092915050565b6000808335601e198436030181126111af57600080fd5b8301803591506001600160401b038211156111c957600080fd5b602001915061016081023603821315610bbe57600080fd5b600061016082840312156111f457600080fd5b610ae38383610f8f565b81516001600160a01b0390811682526020808401518216908301526040808401516001600160801b031690830152606080840151909116908201526080808301516101608301916112529084018215159052565b5060a083015161126660a084018215159052565b5060c083015161129960c0840182805164ffffffffff908116835260208083015182169084015260409182015116910152565b5060e0929092015180516001600160a01b0316610120830152602001516101409091015290565b6000602082840312156112d257600080fd5b8151610ae381610b43565b634e487b7160e01b600052601160045260246000fd5b600060018201611305576113056112dd565b5060010190565b634e487b7160e01b600052601260045260246000fd5b6000826113315761133161130c565b500490565b81810381811115611349576113496112dd565b92915050565b60008261135e5761135e61130c565b500690565b80820180821115611349576113496112dd565b87815260e06020820152600061138f60e0830189610aea565b63ffffffff881660408401526001600160a01b0387811660608501528616608084015284151560a084015282810360c08401526113cc8185610aea565b9a995050505050505050505056fea2646970667358221220fcb8ad75991fd171fd33998d718d5f54883d99a48d56657e7e938e34a55d6a2664736f6c63430008130033", + "numDeployments": 4, + "solcInputHash": "4754a2f0c9d6a191a066af246491b62a", + "metadata": "{\"compiler\":{\"version\":\"0.8.19+commit.7dd6d404\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"NAME\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"contract IHats\",\"name\":\"hatsProtocol\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"hatsAccountImplementation\",\"type\":\"address\"},{\"internalType\":\"contract IERC6551Registry\",\"name\":\"registry\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"keyValuePairs\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"topHatDetails\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"topHatImageURI\",\"type\":\"string\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"maxSupply\",\"type\":\"uint32\"},{\"internalType\":\"string\",\"name\":\"details\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"imageURI\",\"type\":\"string\"},{\"internalType\":\"bool\",\"name\":\"isMutable\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"wearer\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"contract ISablierV2LockupLinear\",\"name\":\"sablier\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint128\",\"name\":\"totalAmount\",\"type\":\"uint128\"},{\"internalType\":\"address\",\"name\":\"asset\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"cancelable\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"transferable\",\"type\":\"bool\"},{\"components\":[{\"internalType\":\"uint40\",\"name\":\"start\",\"type\":\"uint40\"},{\"internalType\":\"uint40\",\"name\":\"cliff\",\"type\":\"uint40\"},{\"internalType\":\"uint40\",\"name\":\"end\",\"type\":\"uint40\"}],\"internalType\":\"struct LockupLinear.Timestamps\",\"name\":\"timestamps\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"fee\",\"type\":\"uint256\"}],\"internalType\":\"struct LockupLinear.Broker\",\"name\":\"broker\",\"type\":\"tuple\"}],\"internalType\":\"struct DecentHats_0_1_0.SablierStreamParams[]\",\"name\":\"sablierParams\",\"type\":\"tuple[]\"}],\"internalType\":\"struct DecentHats_0_1_0.Hat\",\"name\":\"adminHat\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"maxSupply\",\"type\":\"uint32\"},{\"internalType\":\"string\",\"name\":\"details\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"imageURI\",\"type\":\"string\"},{\"internalType\":\"bool\",\"name\":\"isMutable\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"wearer\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"contract ISablierV2LockupLinear\",\"name\":\"sablier\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint128\",\"name\":\"totalAmount\",\"type\":\"uint128\"},{\"internalType\":\"address\",\"name\":\"asset\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"cancelable\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"transferable\",\"type\":\"bool\"},{\"components\":[{\"internalType\":\"uint40\",\"name\":\"start\",\"type\":\"uint40\"},{\"internalType\":\"uint40\",\"name\":\"cliff\",\"type\":\"uint40\"},{\"internalType\":\"uint40\",\"name\":\"end\",\"type\":\"uint40\"}],\"internalType\":\"struct LockupLinear.Timestamps\",\"name\":\"timestamps\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"fee\",\"type\":\"uint256\"}],\"internalType\":\"struct LockupLinear.Broker\",\"name\":\"broker\",\"type\":\"tuple\"}],\"internalType\":\"struct DecentHats_0_1_0.SablierStreamParams[]\",\"name\":\"sablierParams\",\"type\":\"tuple[]\"}],\"internalType\":\"struct DecentHats_0_1_0.Hat[]\",\"name\":\"hats\",\"type\":\"tuple[]\"}],\"internalType\":\"struct DecentHats_0_1_0.CreateTreeParams\",\"name\":\"params\",\"type\":\"tuple\"}],\"name\":\"createAndDeclareTree\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract IHats\",\"name\":\"hatsProtocol\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"adminHatId\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"maxSupply\",\"type\":\"uint32\"},{\"internalType\":\"string\",\"name\":\"details\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"imageURI\",\"type\":\"string\"},{\"internalType\":\"bool\",\"name\":\"isMutable\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"wearer\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"contract ISablierV2LockupLinear\",\"name\":\"sablier\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint128\",\"name\":\"totalAmount\",\"type\":\"uint128\"},{\"internalType\":\"address\",\"name\":\"asset\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"cancelable\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"transferable\",\"type\":\"bool\"},{\"components\":[{\"internalType\":\"uint40\",\"name\":\"start\",\"type\":\"uint40\"},{\"internalType\":\"uint40\",\"name\":\"cliff\",\"type\":\"uint40\"},{\"internalType\":\"uint40\",\"name\":\"end\",\"type\":\"uint40\"}],\"internalType\":\"struct LockupLinear.Timestamps\",\"name\":\"timestamps\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"fee\",\"type\":\"uint256\"}],\"internalType\":\"struct LockupLinear.Broker\",\"name\":\"broker\",\"type\":\"tuple\"}],\"internalType\":\"struct DecentHats_0_1_0.SablierStreamParams[]\",\"name\":\"sablierParams\",\"type\":\"tuple[]\"}],\"internalType\":\"struct DecentHats_0_1_0.Hat\",\"name\":\"hat\",\"type\":\"tuple\"},{\"internalType\":\"uint256\",\"name\":\"topHatId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"topHatAccount\",\"type\":\"address\"},{\"internalType\":\"contract IERC6551Registry\",\"name\":\"registry\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"hatsAccountImplementation\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"salt\",\"type\":\"bytes32\"}],\"name\":\"createRoleHat\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"hatId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"accountAddress\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getSalt\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"salt\",\"type\":\"bytes32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"createAndDeclareTree((address,address,address,address,string,string,(uint32,string,string,bool,address,(address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256))[]),(uint32,string,string,bool,address,(address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256))[])[]))\":{\"details\":\"In order for a Safe to seamlessly create roles even if it has never previously created a role and thus has no hat tree, we defer the creation of the hat tree and its setup to this contract. This way, in a single tx block, the resulting topHatId of the newly created hat can be used to create an admin hat and any other hats needed. We also make use of `KeyValuePairs` to associate the topHatId with the Safe.\"},\"createRoleHat(address,uint256,(uint32,string,string,bool,address,(address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256))[]),uint256,address,address,address,bytes32)\":{\"details\":\"Role hat creation, minting, smart account creation and stream creation are handled here in order to avoid a race condition where not more than one active proposal to create a new role can exist at a time. See: https://github.com/decentdao/decent-interface/issues/2402\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"createAndDeclareTree((address,address,address,address,string,string,(uint32,string,string,bool,address,(address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256))[]),(uint32,string,string,bool,address,(address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256))[])[]))\":{\"notice\":\"For a safe without any roles previously created on it, this function should be called. It sets up the top hat and admin hat, as well as any other hats and their streams that are provided. This contract should be enabled a module on the Safe for which the role(s) are to be created, and disabled after.\"},\"createRoleHat(address,uint256,(uint32,string,string,bool,address,(address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256))[]),uint256,address,address,address,bytes32)\":{\"notice\":\"Creates a new role hat and any streams on it. This contract should be enabled a module on the Safe for which the role is to be created, and disable after. In order for the module to be able to create hats on behalf of the Safe, the Safe must first transfer its top hat to this contract. This function transfers the top hat back to the Safe after creating the role hat. The function simply calls `createHatAndAccountAndMintAndStreams` and then transfers the top hat back to the Safe.\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/DecentHats_0_1_0.sol\":\"DecentHats_0_1_0\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\":{\"content\":\"// SPDX-License-Identifier: LGPL-3.0-only\\npragma solidity >=0.7.0 <0.9.0;\\n\\n/// @title Enum - Collection of enums\\n/// @author Richard Meissner - \\ncontract Enum {\\n enum Operation {Call, DelegateCall}\\n}\\n\",\"keccak256\":\"0x473e45b1a5cc47be494b0e123c9127f0c11c1e0992a321ae5a644c0bfdb2c14f\",\"license\":\"LGPL-3.0-only\"},\"@gnosis.pm/zodiac/contracts/interfaces/IAvatar.sol\":{\"content\":\"// SPDX-License-Identifier: LGPL-3.0-only\\n\\n/// @title Zodiac Avatar - A contract that manages modules that can execute transactions via this contract.\\npragma solidity >=0.7.0 <0.9.0;\\n\\nimport \\\"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\\\";\\n\\ninterface IAvatar {\\n event EnabledModule(address module);\\n event DisabledModule(address module);\\n event ExecutionFromModuleSuccess(address indexed module);\\n event ExecutionFromModuleFailure(address indexed module);\\n\\n /// @dev Enables a module on the avatar.\\n /// @notice Can only be called by the avatar.\\n /// @notice Modules should be stored as a linked list.\\n /// @notice Must emit EnabledModule(address module) if successful.\\n /// @param module Module to be enabled.\\n function enableModule(address module) external;\\n\\n /// @dev Disables a module on the avatar.\\n /// @notice Can only be called by the avatar.\\n /// @notice Must emit DisabledModule(address module) if successful.\\n /// @param prevModule Address that pointed to the module to be removed in the linked list\\n /// @param module Module to be removed.\\n function disableModule(address prevModule, address module) external;\\n\\n /// @dev Allows a Module to execute a transaction.\\n /// @notice Can only be called by an enabled module.\\n /// @notice Must emit ExecutionFromModuleSuccess(address module) if successful.\\n /// @notice Must emit ExecutionFromModuleFailure(address module) if unsuccessful.\\n /// @param to Destination address of module transaction.\\n /// @param value Ether value of module transaction.\\n /// @param data Data payload of module transaction.\\n /// @param operation Operation type of module transaction: 0 == call, 1 == delegate call.\\n function execTransactionFromModule(\\n address to,\\n uint256 value,\\n bytes memory data,\\n Enum.Operation operation\\n ) external returns (bool success);\\n\\n /// @dev Allows a Module to execute a transaction and return data\\n /// @notice Can only be called by an enabled module.\\n /// @notice Must emit ExecutionFromModuleSuccess(address module) if successful.\\n /// @notice Must emit ExecutionFromModuleFailure(address module) if unsuccessful.\\n /// @param to Destination address of module transaction.\\n /// @param value Ether value of module transaction.\\n /// @param data Data payload of module transaction.\\n /// @param operation Operation type of module transaction: 0 == call, 1 == delegate call.\\n function execTransactionFromModuleReturnData(\\n address to,\\n uint256 value,\\n bytes memory data,\\n Enum.Operation operation\\n ) external returns (bool success, bytes memory returnData);\\n\\n /// @dev Returns if an module is enabled\\n /// @return True if the module is enabled\\n function isModuleEnabled(address module) external view returns (bool);\\n\\n /// @dev Returns array of modules.\\n /// @param start Start of the page.\\n /// @param pageSize Maximum number of modules that should be returned.\\n /// @return array Array of modules.\\n /// @return next Start of the next page.\\n function getModulesPaginated(address start, uint256 pageSize)\\n external\\n view\\n returns (address[] memory array, address next);\\n}\\n\",\"keccak256\":\"0xcd5508ffe596eef8fbccfd5fc4f10a34397773547ce64e212d48b5212865ec1f\",\"license\":\"LGPL-3.0-only\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20 {\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `to`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address to, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `from` to `to` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(\\n address from,\\n address to,\\n uint256 amount\\n ) external returns (bool);\\n}\\n\",\"keccak256\":\"0x9750c6b834f7b43000631af5cc30001c5f547b3ceb3635488f140f60e897ea6b\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Strings.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev String operations.\\n */\\nlibrary Strings {\\n bytes16 private constant _HEX_SYMBOLS = \\\"0123456789abcdef\\\";\\n uint8 private constant _ADDRESS_LENGTH = 20;\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\\n */\\n function toString(uint256 value) internal pure returns (string memory) {\\n // Inspired by OraclizeAPI's implementation - MIT licence\\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\\n\\n if (value == 0) {\\n return \\\"0\\\";\\n }\\n uint256 temp = value;\\n uint256 digits;\\n while (temp != 0) {\\n digits++;\\n temp /= 10;\\n }\\n bytes memory buffer = new bytes(digits);\\n while (value != 0) {\\n digits -= 1;\\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\\n value /= 10;\\n }\\n return string(buffer);\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\\n */\\n function toHexString(uint256 value) internal pure returns (string memory) {\\n if (value == 0) {\\n return \\\"0x00\\\";\\n }\\n uint256 temp = value;\\n uint256 length = 0;\\n while (temp != 0) {\\n length++;\\n temp >>= 8;\\n }\\n return toHexString(value, length);\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\\n */\\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\\n bytes memory buffer = new bytes(2 * length + 2);\\n buffer[0] = \\\"0\\\";\\n buffer[1] = \\\"x\\\";\\n for (uint256 i = 2 * length + 1; i > 1; --i) {\\n buffer[i] = _HEX_SYMBOLS[value & 0xf];\\n value >>= 4;\\n }\\n require(value == 0, \\\"Strings: hex length insufficient\\\");\\n return string(buffer);\\n }\\n\\n /**\\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\\n */\\n function toHexString(address addr) internal pure returns (string memory) {\\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\\n }\\n}\\n\",\"keccak256\":\"0xaf159a8b1923ad2a26d516089bceca9bdeaeacd04be50983ea00ba63070f08a3\",\"license\":\"MIT\"},\"contracts/DecentHats_0_1_0.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity =0.8.19;\\n\\nimport {Enum} from \\\"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\\\";\\nimport {IAvatar} from \\\"@gnosis.pm/zodiac/contracts/interfaces/IAvatar.sol\\\";\\nimport {Strings} from \\\"@openzeppelin/contracts/utils/Strings.sol\\\";\\nimport {IERC20} from \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\nimport {IERC6551Registry} from \\\"./interfaces/IERC6551Registry.sol\\\";\\nimport {IHats} from \\\"./interfaces/hats/IHats.sol\\\";\\nimport {ISablierV2LockupLinear} from \\\"./interfaces/sablier/ISablierV2LockupLinear.sol\\\";\\nimport {LockupLinear} from \\\"./interfaces/sablier/LockupLinear.sol\\\";\\n\\ncontract DecentHats_0_1_0 {\\n string public constant NAME = \\\"DecentHats_0_1_0\\\";\\n\\n struct SablierStreamParams {\\n ISablierV2LockupLinear sablier;\\n address sender;\\n uint128 totalAmount;\\n address asset;\\n bool cancelable;\\n bool transferable;\\n LockupLinear.Timestamps timestamps;\\n LockupLinear.Broker broker;\\n }\\n\\n struct Hat {\\n uint32 maxSupply;\\n string details;\\n string imageURI;\\n bool isMutable;\\n address wearer;\\n SablierStreamParams[] sablierParams; // Optional Sablier stream parameters\\n }\\n\\n struct CreateTreeParams {\\n IHats hatsProtocol;\\n address hatsAccountImplementation;\\n IERC6551Registry registry;\\n address keyValuePairs;\\n string topHatDetails;\\n string topHatImageURI;\\n Hat adminHat;\\n Hat[] hats;\\n }\\n\\n function getSalt() public pure returns (bytes32 salt) {\\n return\\n 0x5d0e6ce4fd951366cc55da93f6e79d8b81483109d79676a04bcc2bed6a4b5072;\\n }\\n\\n function declareSafeHatTree(\\n address _keyValuePairs,\\n uint256 topHatId\\n ) internal {\\n string[] memory keys = new string[](1);\\n string[] memory values = new string[](1);\\n keys[0] = \\\"topHatId\\\";\\n values[0] = Strings.toString(topHatId);\\n\\n IAvatar(msg.sender).execTransactionFromModule(\\n _keyValuePairs,\\n 0,\\n abi.encodeWithSignature(\\n \\\"updateValues(string[],string[])\\\",\\n keys,\\n values\\n ),\\n Enum.Operation.Call\\n );\\n }\\n\\n function createHat(\\n IHats _hatsProtocol,\\n uint256 adminHatId,\\n Hat memory _hat,\\n address topHatAccount\\n ) internal returns (uint256) {\\n return\\n _hatsProtocol.createHat(\\n adminHatId,\\n _hat.details,\\n _hat.maxSupply,\\n topHatAccount,\\n topHatAccount,\\n _hat.isMutable,\\n _hat.imageURI\\n );\\n }\\n\\n function createAccount(\\n IERC6551Registry _registry,\\n address _hatsAccountImplementation,\\n bytes32 salt,\\n address protocolAddress,\\n uint256 hatId\\n ) internal returns (address) {\\n return\\n _registry.createAccount(\\n _hatsAccountImplementation,\\n salt,\\n block.chainid,\\n protocolAddress,\\n hatId\\n );\\n }\\n\\n function createTopHatAndAccount(\\n IHats _hatsProtocol,\\n string memory _topHatDetails,\\n string memory _topHatImageURI,\\n IERC6551Registry _registry,\\n address _hatsAccountImplementation,\\n bytes32 salt\\n ) internal returns (uint256 topHatId, address topHatAccount) {\\n topHatId = _hatsProtocol.mintTopHat(\\n address(this),\\n _topHatDetails,\\n _topHatImageURI\\n );\\n\\n topHatAccount = createAccount(\\n _registry,\\n _hatsAccountImplementation,\\n salt,\\n address(_hatsProtocol),\\n topHatId\\n );\\n }\\n\\n function createHatAndAccountAndMintAndStreams(\\n IHats hatsProtocol,\\n uint256 adminHatId,\\n Hat calldata hat,\\n address topHatAccount,\\n IERC6551Registry registry,\\n address hatsAccountImplementation,\\n bytes32 salt\\n ) internal returns (uint256 hatId, address accountAddress) {\\n hatId = createHat(hatsProtocol, adminHatId, hat, topHatAccount);\\n\\n accountAddress = createAccount(\\n registry,\\n hatsAccountImplementation,\\n salt,\\n address(hatsProtocol),\\n hatId\\n );\\n\\n if (hat.wearer != address(0)) {\\n hatsProtocol.mintHat(hatId, hat.wearer);\\n }\\n\\n for (uint256 i = 0; i < hat.sablierParams.length; ) {\\n SablierStreamParams memory sablierParams = hat.sablierParams[i];\\n\\n // Approve tokens for Sablier\\n IAvatar(msg.sender).execTransactionFromModule(\\n sablierParams.asset,\\n 0,\\n abi.encodeWithSignature(\\n \\\"approve(address,uint256)\\\",\\n address(sablierParams.sablier),\\n sablierParams.totalAmount\\n ),\\n Enum.Operation.Call\\n );\\n\\n LockupLinear.CreateWithTimestamps memory params = LockupLinear\\n .CreateWithTimestamps({\\n sender: sablierParams.sender,\\n recipient: accountAddress,\\n totalAmount: sablierParams.totalAmount,\\n asset: IERC20(sablierParams.asset),\\n cancelable: sablierParams.cancelable,\\n transferable: sablierParams.transferable,\\n timestamps: sablierParams.timestamps,\\n broker: sablierParams.broker\\n });\\n\\n // Proxy the Sablier call through IAvatar\\n IAvatar(msg.sender).execTransactionFromModule(\\n address(sablierParams.sablier),\\n 0,\\n abi.encodeWithSignature(\\n \\\"createWithTimestamps((address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256)))\\\",\\n params\\n ),\\n Enum.Operation.Call\\n );\\n\\n unchecked {\\n ++i;\\n }\\n }\\n }\\n\\n /**\\n * Creates a new role hat and any streams on it.\\n *\\n * This contract should be enabled a module on the Safe for which the role is to be created, and disable after.\\n * In order for the module to be able to create hats on behalf of the Safe, the Safe must first\\n * transfer its top hat to this contract. This function transfers the top hat back to the Safe after\\n * creating the role hat.\\n *\\n * The function simply calls `createHatAndAccountAndMintAndStreams` and then transfers the top hat back to the Safe.\\n *\\n * @dev Role hat creation, minting, smart account creation and stream creation are handled here in order\\n * to avoid a race condition where not more than one active proposal to create a new role can exist at a time.\\n * See: https://github.com/decentdao/decent-interface/issues/2402\\n */\\n function createRoleHat(\\n IHats hatsProtocol,\\n uint256 adminHatId,\\n Hat calldata hat,\\n uint256 topHatId,\\n address topHatAccount,\\n IERC6551Registry registry,\\n address hatsAccountImplementation,\\n bytes32 salt\\n ) public returns (uint256 hatId, address accountAddress) {\\n (hatId, accountAddress) = createHatAndAccountAndMintAndStreams(\\n hatsProtocol,\\n adminHatId,\\n hat,\\n topHatAccount,\\n registry,\\n hatsAccountImplementation,\\n salt\\n );\\n\\n hatsProtocol.transferHat(topHatId, address(this), msg.sender);\\n }\\n\\n /**\\n * For a safe without any roles previously created on it, this function should be called. It sets up the\\n * top hat and admin hat, as well as any other hats and their streams that are provided.\\n *\\n * This contract should be enabled a module on the Safe for which the role(s) are to be created, and disabled after.\\n *\\n * @dev In order for a Safe to seamlessly create roles even if it has never previously created a role and thus has\\n * no hat tree, we defer the creation of the hat tree and its setup to this contract. This way, in a single tx block,\\n * the resulting topHatId of the newly created hat can be used to create an admin hat and any other hats needed.\\n * We also make use of `KeyValuePairs` to associate the topHatId with the Safe.\\n */\\n function createAndDeclareTree(CreateTreeParams calldata params) public {\\n bytes32 salt = getSalt();\\n\\n (uint256 topHatId, address topHatAccount) = createTopHatAndAccount(\\n params.hatsProtocol,\\n params.topHatDetails,\\n params.topHatImageURI,\\n params.registry,\\n params.hatsAccountImplementation,\\n salt\\n );\\n\\n declareSafeHatTree(params.keyValuePairs, topHatId);\\n\\n (uint256 adminHatId, ) = createHatAndAccountAndMintAndStreams(\\n params.hatsProtocol,\\n topHatId,\\n params.adminHat,\\n topHatAccount,\\n params.registry,\\n params.hatsAccountImplementation,\\n salt\\n );\\n\\n for (uint256 i = 0; i < params.hats.length; ) {\\n createHatAndAccountAndMintAndStreams(\\n params.hatsProtocol,\\n adminHatId,\\n params.hats[i],\\n topHatAccount,\\n params.registry,\\n params.hatsAccountImplementation,\\n salt\\n );\\n\\n unchecked {\\n ++i;\\n }\\n }\\n\\n params.hatsProtocol.transferHat(topHatId, address(this), msg.sender);\\n }\\n}\\n\",\"keccak256\":\"0x1886fc2edf8c34e58f6a95d33139d7513aa4b581a2c323af6394485752137e20\",\"license\":\"MIT\"},\"contracts/interfaces/IERC6551Registry.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.4;\\n\\ninterface IERC6551Registry {\\n /**\\n * @dev Creates a token bound account for a non-fungible token.\\n *\\n * If account has already been created, returns the account address without calling create2.\\n *\\n * Emits ERC6551AccountCreated event.\\n *\\n * @return account The address of the token bound account\\n */\\n function createAccount(\\n address implementation,\\n bytes32 salt,\\n uint256 chainId,\\n address tokenContract,\\n uint256 tokenId\\n ) external returns (address account);\\n}\\n\",\"keccak256\":\"0x64c52de8a8e68398e61dd8b42dda8e9af8cf6abf93bb85629c322440991ea568\",\"license\":\"MIT\"},\"contracts/interfaces/hats/IHats.sol\":{\"content\":\"// SPDX-License-Identifier: AGPL-3.0\\n// Copyright (C) 2023 Haberdasher Labs\\n//\\n// This program is free software: you can redistribute it and/or modify\\n// it under the terms of the GNU Affero General Public License as published by\\n// the Free Software Foundation, either version 3 of the License, or\\n// (at your option) any later version.\\n//\\n// This program is distributed in the hope that it will be useful,\\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\\n// GNU Affero General Public License for more details.\\n//\\n// You should have received a copy of the GNU Affero General Public License\\n// along with this program. If not, see .\\n\\npragma solidity >=0.8.13;\\n\\ninterface IHats {\\n function mintTopHat(\\n address _target,\\n string memory _details,\\n string memory _imageURI\\n ) external returns (uint256 topHatId);\\n\\n function createHat(\\n uint256 _admin,\\n string calldata _details,\\n uint32 _maxSupply,\\n address _eligibility,\\n address _toggle,\\n bool _mutable,\\n string calldata _imageURI\\n ) external returns (uint256 newHatId);\\n\\n function mintHat(\\n uint256 _hatId,\\n address _wearer\\n ) external returns (bool success);\\n\\n function transferHat(uint256 _hatId, address _from, address _to) external;\\n}\\n\",\"keccak256\":\"0x8e35022f5c0fcf0059033abec78ec890f0cf3bbac09d6d24051cff9679239511\",\"license\":\"AGPL-3.0\"},\"contracts/interfaces/sablier/ISablierV2LockupLinear.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport {LockupLinear} from \\\"./LockupLinear.sol\\\";\\nimport {IERC20} from \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\n\\ninterface ISablierV2LockupLinear {\\n function createWithTimestamps(\\n LockupLinear.CreateWithTimestamps calldata params\\n ) external returns (uint256 streamId);\\n}\\n\",\"keccak256\":\"0xf4899637eb2e6c76c35e2d201e56e162a50e6bc7b5b9156e00866f0703ad07ca\",\"license\":\"MIT\"},\"contracts/interfaces/sablier/LockupLinear.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport {IERC20} from \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\n\\nlibrary LockupLinear {\\n struct CreateWithTimestamps {\\n address sender;\\n address recipient;\\n uint128 totalAmount;\\n IERC20 asset;\\n bool cancelable;\\n bool transferable;\\n Timestamps timestamps;\\n Broker broker;\\n }\\n\\n struct Timestamps {\\n uint40 start;\\n uint40 cliff;\\n uint40 end;\\n }\\n\\n struct Broker {\\n address account;\\n uint256 fee;\\n }\\n}\\n\",\"keccak256\":\"0x497fdb52b5e1a5a7e0711a9f7d5fb036eb668ccb92ea908ee088f56ee08a4ce8\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x608060405234801561001057600080fd5b5061158a806100206000396000f3fe608060405234801561001057600080fd5b506004361061004c5760003560e01c806313a9589c146100515780636592b2ac146100845780638c5f591a146100b4578063a3f4df7e146100c9575b600080fd5b6040517f5d0e6ce4fd951366cc55da93f6e79d8b81483109d79676a04bcc2bed6a4b507281526020015b60405180910390f35b610097610092366004610b95565b610105565b604080519283526001600160a01b0390911660208301520161007b565b6100c76100c2366004610c40565b61018f565b005b6100f86040518060400160405280601081526020016f0446563656e74486174735f305f315f360841b81525081565b60405161007b9190610cc8565b6000806101178a8a8a898989896103dc565b6040516329287c1b60e21b8152600481018a905230602482015233604482015291935091506001600160a01b038b169063a4a1f06c90606401600060405180830381600087803b15801561016a57600080fd5b505af115801561017e573d6000803e3d6000fd5b505050509850989650505050505050565b7f5d0e6ce4fd951366cc55da93f6e79d8b81483109d79676a04bcc2bed6a4b507260008061026d6101c36020860186610cdb565b6101d06080870187610cf8565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506102129250505060a0880188610cf8565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610257925050506060890160408a01610cdb565b61026760408a0160208b01610cdb565b8861072b565b909250905061028b6102856080860160608701610cdb565b836107bd565b60006102d261029d6020870187610cdb565b846102ab60c0890189610d45565b856102bc60608b0160408c01610cdb565b6102cc60408c0160208d01610cdb565b8a6103dc565b50905060005b6102e560e0870187610d65565b905081101561035f576103556102fe6020880188610cdb565b8361030c60e08a018a610d65565b8581811061031c5761031c610dae565b905060200281019061032e9190610d45565b8661033f60608c0160408d01610cdb565b61034f60408d0160208e01610cdb565b8b6103dc565b50506001016102d8565b5061036d6020860186610cdb565b6040516329287c1b60e21b8152600481018590523060248201523360448201526001600160a01b03919091169063a4a1f06c90606401600060405180830381600087803b1580156103bd57600080fd5b505af11580156103d1573d6000803e3d6000fd5b505050505050505050565b6000806103f389896103ed8a611112565b8961093d565b91506104028585858c866109cf565b9050600061041660a0890160808a01610cdb565b6001600160a01b0316146104b6576001600160a01b03891663641f776e8361044460a08b0160808c01610cdb565b6040516001600160e01b031960e085901b16815260048101929092526001600160a01b031660248201526044016020604051808303816000875af1158015610490573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104b491906111d6565b505b60005b6104c660a08901896111f3565b905081101561071e5760006104de60a08a018a6111f3565b838181106104ee576104ee610dae565b90506101600201803603810190610505919061123c565b6060810151815160408084015190516001600160a01b0390921660248301526001600160801b03166044820152919250339163468721a7919060009060640160408051601f198184030181529181526020820180516001600160e01b031663095ea7b360e01b1790525160e085901b6001600160e01b031916815261059293929190600090600401611259565b6020604051808303816000875af11580156105b1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105d591906111d6565b50600060405180610100016040528083602001516001600160a01b03168152602001856001600160a01b0316815260200183604001516001600160801b0316815260200183606001516001600160a01b031681526020018360800151151581526020018360a00151151581526020018360c0015181526020018360e001518152509050336001600160a01b031663468721a7836000015160008460405160240161067f91906112af565b60408051601f198184030181529181526020820180516001600160e01b03166353b1572760e01b1790525160e085901b6001600160e01b03191681526106cd93929190600090600401611259565b6020604051808303816000875af11580156106ec573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061071091906111d6565b5082600101925050506104b9565b5097509795505050505050565b600080876001600160a01b0316631a64dfad3089896040518463ffffffff1660e01b815260040161075e93929190611371565b6020604051808303816000875af115801561077d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107a191906113a7565b91506107b08585858b866109cf565b9050965096945050505050565b604080516001808252818301909252600091816020015b60608152602001906001900390816107d457505060408051600180825281830190925291925060009190602082015b6060815260200190600190039081610803579050509050604051806040016040528060088152602001671d1bdc12185d125960c21b8152508260008151811061084e5761084e610dae565b602002602001018190525061086283610a65565b8160008151811061087557610875610dae565b6020026020010181905250336001600160a01b031663468721a785600085856040516024016108a5929190611415565b60408051601f198184030181529181526020820180516001600160e01b031663579374b960e11b1790525160e085901b6001600160e01b03191681526108f393929190600090600401611259565b6020604051808303816000875af1158015610912573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061093691906111d6565b5050505050565b6020820151825160608401516040808601519051635829492f60e11b81526000946001600160a01b038a169463b052925e94610983948b948a928392909160040161143a565b6020604051808303816000875af11580156109a2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109c691906113a7565b95945050505050565b604051638a54c52f60e01b81526001600160a01b0385811660048301526024820185905246604483015283811660648301526084820183905260009190871690638a54c52f9060a4016020604051808303816000875af1158015610a37573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a5b919061149e565b9695505050505050565b606081600003610a8c5750506040805180820190915260018152600360fc1b602082015290565b8160005b8115610ab65780610aa0816114d1565b9150610aaf9050600a83611500565b9150610a90565b6000816001600160401b03811115610ad057610ad0610dc4565b6040519080825280601f01601f191660200182016040528015610afa576020820181803683370190505b5090505b8415610b6557610b0f600183611514565b9150610b1c600a8661152d565b610b27906030611541565b60f81b818381518110610b3c57610b3c610dae565b60200101906001600160f81b031916908160001a905350610b5e600a86611500565b9450610afe565b949350505050565b6001600160a01b0381168114610b8257600080fd5b50565b8035610b9081610b6d565b919050565b600080600080600080600080610100898b031215610bb257600080fd5b8835610bbd81610b6d565b97506020890135965060408901356001600160401b03811115610bdf57600080fd5b890160c0818c031215610bf157600080fd5b9550606089013594506080890135610c0881610b6d565b935060a0890135610c1881610b6d565b925060c0890135610c2881610b6d565b8092505060e089013590509295985092959890939650565b600060208284031215610c5257600080fd5b81356001600160401b03811115610c6857600080fd5b82016101008185031215610c7b57600080fd5b9392505050565b6000815180845260005b81811015610ca857602081850181015186830182015201610c8c565b506000602082860101526020601f19601f83011685010191505092915050565b602081526000610c7b6020830184610c82565b600060208284031215610ced57600080fd5b8135610c7b81610b6d565b6000808335601e19843603018112610d0f57600080fd5b8301803591506001600160401b03821115610d2957600080fd5b602001915036819003821315610d3e57600080fd5b9250929050565b6000823560be19833603018112610d5b57600080fd5b9190910192915050565b6000808335601e19843603018112610d7c57600080fd5b8301803591506001600160401b03821115610d9657600080fd5b6020019150600581901b3603821315610d3e57600080fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b60405160c081016001600160401b0381118282101715610dfc57610dfc610dc4565b60405290565b604051601f8201601f191681016001600160401b0381118282101715610e2a57610e2a610dc4565b604052919050565b803563ffffffff81168114610b9057600080fd5b600082601f830112610e5757600080fd5b81356001600160401b03811115610e7057610e70610dc4565b610e83601f8201601f1916602001610e02565b818152846020838601011115610e9857600080fd5b816020850160208301376000918101602001919091529392505050565b8015158114610b8257600080fd5b8035610b9081610eb5565b80356001600160801b0381168114610b9057600080fd5b803564ffffffffff81168114610b9057600080fd5b600060608284031215610f0c57600080fd5b604051606081018181106001600160401b0382111715610f2e57610f2e610dc4565b604052905080610f3d83610ee5565b8152610f4b60208401610ee5565b6020820152610f5c60408401610ee5565b60408201525092915050565b600060408284031215610f7a57600080fd5b604051604081018181106001600160401b0382111715610f9c57610f9c610dc4565b6040529050808235610fad81610b6d565b8152602092830135920191909152919050565b60006101608284031215610fd357600080fd5b60405161010081018181106001600160401b0382111715610ff657610ff6610dc4565b60405290508061100583610b85565b815261101360208401610b85565b602082015261102460408401610ece565b604082015261103560608401610b85565b606082015261104660808401610ec3565b608082015261105760a08401610ec3565b60a08201526110698460c08501610efa565b60c082015261107c846101208501610f68565b60e08201525092915050565b600082601f83011261109957600080fd5b813560206001600160401b038211156110b4576110b4610dc4565b6110c2818360051b01610e02565b82815261016092830285018201928282019190878511156110e257600080fd5b8387015b85811015611105576110f88982610fc0565b84529284019281016110e6565b5090979650505050505050565b600060c0823603121561112457600080fd5b61112c610dda565b61113583610e32565b815260208301356001600160401b038082111561115157600080fd5b61115d36838701610e46565b6020840152604085013591508082111561117657600080fd5b61118236838701610e46565b604084015261119360608601610ec3565b60608401526111a460808601610b85565b608084015260a08501359150808211156111bd57600080fd5b506111ca36828601611088565b60a08301525092915050565b6000602082840312156111e857600080fd5b8151610c7b81610eb5565b6000808335601e1984360301811261120a57600080fd5b8301803591506001600160401b0382111561122457600080fd5b602001915061016081023603821315610d3e57600080fd5b6000610160828403121561124f57600080fd5b610c7b8383610fc0565b60018060a01b03851681528360208201526080604082015260006112806080830185610c82565b9050600283106112a057634e487b7160e01b600052602160045260246000fd5b82606083015295945050505050565b81516001600160a01b0390811682526020808401518216908301526040808401516001600160801b031690830152606080840151909116908201526080808301516101608301916113039084018215159052565b5060a083015161131760a084018215159052565b5060c083015161134a60c0840182805164ffffffffff908116835260208083015182169084015260409182015116910152565b5060e0929092015180516001600160a01b0316610120830152602001516101409091015290565b6001600160a01b038416815260606020820181905260009061139590830185610c82565b8281036040840152610a5b8185610c82565b6000602082840312156113b957600080fd5b5051919050565b600081518084526020808501808196508360051b8101915082860160005b858110156114085782840389526113f6848351610c82565b988501989350908401906001016113de565b5091979650505050505050565b60408152600061142860408301856113c0565b82810360208401526109c681856113c0565b87815260e06020820152600061145360e0830189610c82565b63ffffffff881660408401526001600160a01b0387811660608501528616608084015284151560a084015282810360c08401526114908185610c82565b9a9950505050505050505050565b6000602082840312156114b057600080fd5b8151610c7b81610b6d565b634e487b7160e01b600052601160045260246000fd5b6000600182016114e3576114e36114bb565b5060010190565b634e487b7160e01b600052601260045260246000fd5b60008261150f5761150f6114ea565b500490565b81810381811115611527576115276114bb565b92915050565b60008261153c5761153c6114ea565b500690565b80820180821115611527576115276114bb56fea26469706673582212208431b5cb9e9defda60834dc065f918f11d92dcbf19aba7475b779059a216011d64736f6c63430008130033", + "deployedBytecode": "0x608060405234801561001057600080fd5b506004361061004c5760003560e01c806313a9589c146100515780636592b2ac146100845780638c5f591a146100b4578063a3f4df7e146100c9575b600080fd5b6040517f5d0e6ce4fd951366cc55da93f6e79d8b81483109d79676a04bcc2bed6a4b507281526020015b60405180910390f35b610097610092366004610b95565b610105565b604080519283526001600160a01b0390911660208301520161007b565b6100c76100c2366004610c40565b61018f565b005b6100f86040518060400160405280601081526020016f0446563656e74486174735f305f315f360841b81525081565b60405161007b9190610cc8565b6000806101178a8a8a898989896103dc565b6040516329287c1b60e21b8152600481018a905230602482015233604482015291935091506001600160a01b038b169063a4a1f06c90606401600060405180830381600087803b15801561016a57600080fd5b505af115801561017e573d6000803e3d6000fd5b505050509850989650505050505050565b7f5d0e6ce4fd951366cc55da93f6e79d8b81483109d79676a04bcc2bed6a4b507260008061026d6101c36020860186610cdb565b6101d06080870187610cf8565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506102129250505060a0880188610cf8565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610257925050506060890160408a01610cdb565b61026760408a0160208b01610cdb565b8861072b565b909250905061028b6102856080860160608701610cdb565b836107bd565b60006102d261029d6020870187610cdb565b846102ab60c0890189610d45565b856102bc60608b0160408c01610cdb565b6102cc60408c0160208d01610cdb565b8a6103dc565b50905060005b6102e560e0870187610d65565b905081101561035f576103556102fe6020880188610cdb565b8361030c60e08a018a610d65565b8581811061031c5761031c610dae565b905060200281019061032e9190610d45565b8661033f60608c0160408d01610cdb565b61034f60408d0160208e01610cdb565b8b6103dc565b50506001016102d8565b5061036d6020860186610cdb565b6040516329287c1b60e21b8152600481018590523060248201523360448201526001600160a01b03919091169063a4a1f06c90606401600060405180830381600087803b1580156103bd57600080fd5b505af11580156103d1573d6000803e3d6000fd5b505050505050505050565b6000806103f389896103ed8a611112565b8961093d565b91506104028585858c866109cf565b9050600061041660a0890160808a01610cdb565b6001600160a01b0316146104b6576001600160a01b03891663641f776e8361044460a08b0160808c01610cdb565b6040516001600160e01b031960e085901b16815260048101929092526001600160a01b031660248201526044016020604051808303816000875af1158015610490573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104b491906111d6565b505b60005b6104c660a08901896111f3565b905081101561071e5760006104de60a08a018a6111f3565b838181106104ee576104ee610dae565b90506101600201803603810190610505919061123c565b6060810151815160408084015190516001600160a01b0390921660248301526001600160801b03166044820152919250339163468721a7919060009060640160408051601f198184030181529181526020820180516001600160e01b031663095ea7b360e01b1790525160e085901b6001600160e01b031916815261059293929190600090600401611259565b6020604051808303816000875af11580156105b1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105d591906111d6565b50600060405180610100016040528083602001516001600160a01b03168152602001856001600160a01b0316815260200183604001516001600160801b0316815260200183606001516001600160a01b031681526020018360800151151581526020018360a00151151581526020018360c0015181526020018360e001518152509050336001600160a01b031663468721a7836000015160008460405160240161067f91906112af565b60408051601f198184030181529181526020820180516001600160e01b03166353b1572760e01b1790525160e085901b6001600160e01b03191681526106cd93929190600090600401611259565b6020604051808303816000875af11580156106ec573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061071091906111d6565b5082600101925050506104b9565b5097509795505050505050565b600080876001600160a01b0316631a64dfad3089896040518463ffffffff1660e01b815260040161075e93929190611371565b6020604051808303816000875af115801561077d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107a191906113a7565b91506107b08585858b866109cf565b9050965096945050505050565b604080516001808252818301909252600091816020015b60608152602001906001900390816107d457505060408051600180825281830190925291925060009190602082015b6060815260200190600190039081610803579050509050604051806040016040528060088152602001671d1bdc12185d125960c21b8152508260008151811061084e5761084e610dae565b602002602001018190525061086283610a65565b8160008151811061087557610875610dae565b6020026020010181905250336001600160a01b031663468721a785600085856040516024016108a5929190611415565b60408051601f198184030181529181526020820180516001600160e01b031663579374b960e11b1790525160e085901b6001600160e01b03191681526108f393929190600090600401611259565b6020604051808303816000875af1158015610912573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061093691906111d6565b5050505050565b6020820151825160608401516040808601519051635829492f60e11b81526000946001600160a01b038a169463b052925e94610983948b948a928392909160040161143a565b6020604051808303816000875af11580156109a2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109c691906113a7565b95945050505050565b604051638a54c52f60e01b81526001600160a01b0385811660048301526024820185905246604483015283811660648301526084820183905260009190871690638a54c52f9060a4016020604051808303816000875af1158015610a37573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a5b919061149e565b9695505050505050565b606081600003610a8c5750506040805180820190915260018152600360fc1b602082015290565b8160005b8115610ab65780610aa0816114d1565b9150610aaf9050600a83611500565b9150610a90565b6000816001600160401b03811115610ad057610ad0610dc4565b6040519080825280601f01601f191660200182016040528015610afa576020820181803683370190505b5090505b8415610b6557610b0f600183611514565b9150610b1c600a8661152d565b610b27906030611541565b60f81b818381518110610b3c57610b3c610dae565b60200101906001600160f81b031916908160001a905350610b5e600a86611500565b9450610afe565b949350505050565b6001600160a01b0381168114610b8257600080fd5b50565b8035610b9081610b6d565b919050565b600080600080600080600080610100898b031215610bb257600080fd5b8835610bbd81610b6d565b97506020890135965060408901356001600160401b03811115610bdf57600080fd5b890160c0818c031215610bf157600080fd5b9550606089013594506080890135610c0881610b6d565b935060a0890135610c1881610b6d565b925060c0890135610c2881610b6d565b8092505060e089013590509295985092959890939650565b600060208284031215610c5257600080fd5b81356001600160401b03811115610c6857600080fd5b82016101008185031215610c7b57600080fd5b9392505050565b6000815180845260005b81811015610ca857602081850181015186830182015201610c8c565b506000602082860101526020601f19601f83011685010191505092915050565b602081526000610c7b6020830184610c82565b600060208284031215610ced57600080fd5b8135610c7b81610b6d565b6000808335601e19843603018112610d0f57600080fd5b8301803591506001600160401b03821115610d2957600080fd5b602001915036819003821315610d3e57600080fd5b9250929050565b6000823560be19833603018112610d5b57600080fd5b9190910192915050565b6000808335601e19843603018112610d7c57600080fd5b8301803591506001600160401b03821115610d9657600080fd5b6020019150600581901b3603821315610d3e57600080fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b60405160c081016001600160401b0381118282101715610dfc57610dfc610dc4565b60405290565b604051601f8201601f191681016001600160401b0381118282101715610e2a57610e2a610dc4565b604052919050565b803563ffffffff81168114610b9057600080fd5b600082601f830112610e5757600080fd5b81356001600160401b03811115610e7057610e70610dc4565b610e83601f8201601f1916602001610e02565b818152846020838601011115610e9857600080fd5b816020850160208301376000918101602001919091529392505050565b8015158114610b8257600080fd5b8035610b9081610eb5565b80356001600160801b0381168114610b9057600080fd5b803564ffffffffff81168114610b9057600080fd5b600060608284031215610f0c57600080fd5b604051606081018181106001600160401b0382111715610f2e57610f2e610dc4565b604052905080610f3d83610ee5565b8152610f4b60208401610ee5565b6020820152610f5c60408401610ee5565b60408201525092915050565b600060408284031215610f7a57600080fd5b604051604081018181106001600160401b0382111715610f9c57610f9c610dc4565b6040529050808235610fad81610b6d565b8152602092830135920191909152919050565b60006101608284031215610fd357600080fd5b60405161010081018181106001600160401b0382111715610ff657610ff6610dc4565b60405290508061100583610b85565b815261101360208401610b85565b602082015261102460408401610ece565b604082015261103560608401610b85565b606082015261104660808401610ec3565b608082015261105760a08401610ec3565b60a08201526110698460c08501610efa565b60c082015261107c846101208501610f68565b60e08201525092915050565b600082601f83011261109957600080fd5b813560206001600160401b038211156110b4576110b4610dc4565b6110c2818360051b01610e02565b82815261016092830285018201928282019190878511156110e257600080fd5b8387015b85811015611105576110f88982610fc0565b84529284019281016110e6565b5090979650505050505050565b600060c0823603121561112457600080fd5b61112c610dda565b61113583610e32565b815260208301356001600160401b038082111561115157600080fd5b61115d36838701610e46565b6020840152604085013591508082111561117657600080fd5b61118236838701610e46565b604084015261119360608601610ec3565b60608401526111a460808601610b85565b608084015260a08501359150808211156111bd57600080fd5b506111ca36828601611088565b60a08301525092915050565b6000602082840312156111e857600080fd5b8151610c7b81610eb5565b6000808335601e1984360301811261120a57600080fd5b8301803591506001600160401b0382111561122457600080fd5b602001915061016081023603821315610d3e57600080fd5b6000610160828403121561124f57600080fd5b610c7b8383610fc0565b60018060a01b03851681528360208201526080604082015260006112806080830185610c82565b9050600283106112a057634e487b7160e01b600052602160045260246000fd5b82606083015295945050505050565b81516001600160a01b0390811682526020808401518216908301526040808401516001600160801b031690830152606080840151909116908201526080808301516101608301916113039084018215159052565b5060a083015161131760a084018215159052565b5060c083015161134a60c0840182805164ffffffffff908116835260208083015182169084015260409182015116910152565b5060e0929092015180516001600160a01b0316610120830152602001516101409091015290565b6001600160a01b038416815260606020820181905260009061139590830185610c82565b8281036040840152610a5b8185610c82565b6000602082840312156113b957600080fd5b5051919050565b600081518084526020808501808196508360051b8101915082860160005b858110156114085782840389526113f6848351610c82565b988501989350908401906001016113de565b5091979650505050505050565b60408152600061142860408301856113c0565b82810360208401526109c681856113c0565b87815260e06020820152600061145360e0830189610c82565b63ffffffff881660408401526001600160a01b0387811660608501528616608084015284151560a084015282810360c08401526114908185610c82565b9a9950505050505050505050565b6000602082840312156114b057600080fd5b8151610c7b81610b6d565b634e487b7160e01b600052601160045260246000fd5b6000600182016114e3576114e36114bb565b5060010190565b634e487b7160e01b600052601260045260246000fd5b60008261150f5761150f6114ea565b500490565b81810381811115611527576115276114bb565b92915050565b60008261153c5761153c6114ea565b500690565b80820180821115611527576115276114bb56fea26469706673582212208431b5cb9e9defda60834dc065f918f11d92dcbf19aba7475b779059a216011d64736f6c63430008130033", "devdoc": { "kind": "dev", - "methods": {}, + "methods": { + "createAndDeclareTree((address,address,address,address,string,string,(uint32,string,string,bool,address,(address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256))[]),(uint32,string,string,bool,address,(address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256))[])[]))": { + "details": "In order for a Safe to seamlessly create roles even if it has never previously created a role and thus has no hat tree, we defer the creation of the hat tree and its setup to this contract. This way, in a single tx block, the resulting topHatId of the newly created hat can be used to create an admin hat and any other hats needed. We also make use of `KeyValuePairs` to associate the topHatId with the Safe." + }, + "createRoleHat(address,uint256,(uint32,string,string,bool,address,(address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256))[]),uint256,address,address,address,bytes32)": { + "details": "Role hat creation, minting, smart account creation and stream creation are handled here in order to avoid a race condition where not more than one active proposal to create a new role can exist at a time. See: https://github.com/decentdao/decent-interface/issues/2402" + } + }, "version": 1 }, "userdoc": { "kind": "user", - "methods": {}, + "methods": { + "createAndDeclareTree((address,address,address,address,string,string,(uint32,string,string,bool,address,(address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256))[]),(uint32,string,string,bool,address,(address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256))[])[]))": { + "notice": "For a safe without any roles previously created on it, this function should be called. It sets up the top hat and admin hat, as well as any other hats and their streams that are provided. This contract should be enabled a module on the Safe for which the role(s) are to be created, and disabled after." + }, + "createRoleHat(address,uint256,(uint32,string,string,bool,address,(address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256))[]),uint256,address,address,address,bytes32)": { + "notice": "Creates a new role hat and any streams on it. This contract should be enabled a module on the Safe for which the role is to be created, and disable after. In order for the module to be able to create hats on behalf of the Safe, the Safe must first transfer its top hat to this contract. This function transfers the top hat back to the Safe after creating the role hat. The function simply calls `createHatAndAccountAndMintAndStreams` and then transfers the top hat back to the Safe." + } + }, "version": 1 }, "storageLayout": { diff --git a/deployments/polygon/solcInputs/4754a2f0c9d6a191a066af246491b62a.json b/deployments/polygon/solcInputs/4754a2f0c9d6a191a066af246491b62a.json new file mode 100644 index 00000000..87cba363 --- /dev/null +++ b/deployments/polygon/solcInputs/4754a2f0c9d6a191a066af246491b62a.json @@ -0,0 +1,59 @@ +{ + "language": "Solidity", + "sources": { + "@gnosis.pm/safe-contracts/contracts/common/Enum.sol": { + "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\n\n/// @title Enum - Collection of enums\n/// @author Richard Meissner - \ncontract Enum {\n enum Operation {Call, DelegateCall}\n}\n" + }, + "@gnosis.pm/zodiac/contracts/interfaces/IAvatar.sol": { + "content": "// SPDX-License-Identifier: LGPL-3.0-only\n\n/// @title Zodiac Avatar - A contract that manages modules that can execute transactions via this contract.\npragma solidity >=0.7.0 <0.9.0;\n\nimport \"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\";\n\ninterface IAvatar {\n event EnabledModule(address module);\n event DisabledModule(address module);\n event ExecutionFromModuleSuccess(address indexed module);\n event ExecutionFromModuleFailure(address indexed module);\n\n /// @dev Enables a module on the avatar.\n /// @notice Can only be called by the avatar.\n /// @notice Modules should be stored as a linked list.\n /// @notice Must emit EnabledModule(address module) if successful.\n /// @param module Module to be enabled.\n function enableModule(address module) external;\n\n /// @dev Disables a module on the avatar.\n /// @notice Can only be called by the avatar.\n /// @notice Must emit DisabledModule(address module) if successful.\n /// @param prevModule Address that pointed to the module to be removed in the linked list\n /// @param module Module to be removed.\n function disableModule(address prevModule, address module) external;\n\n /// @dev Allows a Module to execute a transaction.\n /// @notice Can only be called by an enabled module.\n /// @notice Must emit ExecutionFromModuleSuccess(address module) if successful.\n /// @notice Must emit ExecutionFromModuleFailure(address module) if unsuccessful.\n /// @param to Destination address of module transaction.\n /// @param value Ether value of module transaction.\n /// @param data Data payload of module transaction.\n /// @param operation Operation type of module transaction: 0 == call, 1 == delegate call.\n function execTransactionFromModule(\n address to,\n uint256 value,\n bytes memory data,\n Enum.Operation operation\n ) external returns (bool success);\n\n /// @dev Allows a Module to execute a transaction and return data\n /// @notice Can only be called by an enabled module.\n /// @notice Must emit ExecutionFromModuleSuccess(address module) if successful.\n /// @notice Must emit ExecutionFromModuleFailure(address module) if unsuccessful.\n /// @param to Destination address of module transaction.\n /// @param value Ether value of module transaction.\n /// @param data Data payload of module transaction.\n /// @param operation Operation type of module transaction: 0 == call, 1 == delegate call.\n function execTransactionFromModuleReturnData(\n address to,\n uint256 value,\n bytes memory data,\n Enum.Operation operation\n ) external returns (bool success, bytes memory returnData);\n\n /// @dev Returns if an module is enabled\n /// @return True if the module is enabled\n function isModuleEnabled(address module) external view returns (bool);\n\n /// @dev Returns array of modules.\n /// @param start Start of the page.\n /// @param pageSize Maximum number of modules that should be returned.\n /// @return array Array of modules.\n /// @return next Start of the next page.\n function getModulesPaginated(address start, uint256 pageSize)\n external\n view\n returns (address[] memory array, address next);\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/IERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20 {\n /**\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\n * another (`to`).\n *\n * Note that `value` may be zero.\n */\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n /**\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n * a call to {approve}. `value` is the new allowance.\n */\n event Approval(address indexed owner, address indexed spender, uint256 value);\n\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by `account`.\n */\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * @dev Moves `amount` tokens from the caller's account to `to`.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transfer(address to, uint256 amount) external returns (bool);\n\n /**\n * @dev Returns the remaining number of tokens that `spender` will be\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\n * zero by default.\n *\n * This value changes when {approve} or {transferFrom} are called.\n */\n function allowance(address owner, address spender) external view returns (uint256);\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\n * that someone may use both the old and the new allowance by unfortunate\n * transaction ordering. One possible solution to mitigate this race\n * condition is to first reduce the spender's allowance to 0 and set the\n * desired value afterwards:\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n *\n * Emits an {Approval} event.\n */\n function approve(address spender, uint256 amount) external returns (bool);\n\n /**\n * @dev Moves `amount` tokens from `from` to `to` using the\n * allowance mechanism. `amount` is then deducted from the caller's\n * allowance.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(\n address from,\n address to,\n uint256 amount\n ) external returns (bool);\n}\n" + }, + "@openzeppelin/contracts/utils/Strings.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n uint8 private constant _ADDRESS_LENGTH = 20;\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp >>= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i > 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value & 0xf];\n value >>= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n\n /**\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\n */\n function toHexString(address addr) internal pure returns (string memory) {\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\n }\n}\n" + }, + "contracts/DecentHats_0_1_0.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity =0.8.19;\n\nimport {Enum} from \"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\";\nimport {IAvatar} from \"@gnosis.pm/zodiac/contracts/interfaces/IAvatar.sol\";\nimport {Strings} from \"@openzeppelin/contracts/utils/Strings.sol\";\nimport {IERC20} from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport {IERC6551Registry} from \"./interfaces/IERC6551Registry.sol\";\nimport {IHats} from \"./interfaces/hats/IHats.sol\";\nimport {ISablierV2LockupLinear} from \"./interfaces/sablier/ISablierV2LockupLinear.sol\";\nimport {LockupLinear} from \"./interfaces/sablier/LockupLinear.sol\";\n\ncontract DecentHats_0_1_0 {\n string public constant NAME = \"DecentHats_0_1_0\";\n\n struct SablierStreamParams {\n ISablierV2LockupLinear sablier;\n address sender;\n uint128 totalAmount;\n address asset;\n bool cancelable;\n bool transferable;\n LockupLinear.Timestamps timestamps;\n LockupLinear.Broker broker;\n }\n\n struct Hat {\n uint32 maxSupply;\n string details;\n string imageURI;\n bool isMutable;\n address wearer;\n SablierStreamParams[] sablierParams; // Optional Sablier stream parameters\n }\n\n struct CreateTreeParams {\n IHats hatsProtocol;\n address hatsAccountImplementation;\n IERC6551Registry registry;\n address keyValuePairs;\n string topHatDetails;\n string topHatImageURI;\n Hat adminHat;\n Hat[] hats;\n }\n\n function getSalt() public pure returns (bytes32 salt) {\n return\n 0x5d0e6ce4fd951366cc55da93f6e79d8b81483109d79676a04bcc2bed6a4b5072;\n }\n\n function declareSafeHatTree(\n address _keyValuePairs,\n uint256 topHatId\n ) internal {\n string[] memory keys = new string[](1);\n string[] memory values = new string[](1);\n keys[0] = \"topHatId\";\n values[0] = Strings.toString(topHatId);\n\n IAvatar(msg.sender).execTransactionFromModule(\n _keyValuePairs,\n 0,\n abi.encodeWithSignature(\n \"updateValues(string[],string[])\",\n keys,\n values\n ),\n Enum.Operation.Call\n );\n }\n\n function createHat(\n IHats _hatsProtocol,\n uint256 adminHatId,\n Hat memory _hat,\n address topHatAccount\n ) internal returns (uint256) {\n return\n _hatsProtocol.createHat(\n adminHatId,\n _hat.details,\n _hat.maxSupply,\n topHatAccount,\n topHatAccount,\n _hat.isMutable,\n _hat.imageURI\n );\n }\n\n function createAccount(\n IERC6551Registry _registry,\n address _hatsAccountImplementation,\n bytes32 salt,\n address protocolAddress,\n uint256 hatId\n ) internal returns (address) {\n return\n _registry.createAccount(\n _hatsAccountImplementation,\n salt,\n block.chainid,\n protocolAddress,\n hatId\n );\n }\n\n function createTopHatAndAccount(\n IHats _hatsProtocol,\n string memory _topHatDetails,\n string memory _topHatImageURI,\n IERC6551Registry _registry,\n address _hatsAccountImplementation,\n bytes32 salt\n ) internal returns (uint256 topHatId, address topHatAccount) {\n topHatId = _hatsProtocol.mintTopHat(\n address(this),\n _topHatDetails,\n _topHatImageURI\n );\n\n topHatAccount = createAccount(\n _registry,\n _hatsAccountImplementation,\n salt,\n address(_hatsProtocol),\n topHatId\n );\n }\n\n function createHatAndAccountAndMintAndStreams(\n IHats hatsProtocol,\n uint256 adminHatId,\n Hat calldata hat,\n address topHatAccount,\n IERC6551Registry registry,\n address hatsAccountImplementation,\n bytes32 salt\n ) internal returns (uint256 hatId, address accountAddress) {\n hatId = createHat(hatsProtocol, adminHatId, hat, topHatAccount);\n\n accountAddress = createAccount(\n registry,\n hatsAccountImplementation,\n salt,\n address(hatsProtocol),\n hatId\n );\n\n if (hat.wearer != address(0)) {\n hatsProtocol.mintHat(hatId, hat.wearer);\n }\n\n for (uint256 i = 0; i < hat.sablierParams.length; ) {\n SablierStreamParams memory sablierParams = hat.sablierParams[i];\n\n // Approve tokens for Sablier\n IAvatar(msg.sender).execTransactionFromModule(\n sablierParams.asset,\n 0,\n abi.encodeWithSignature(\n \"approve(address,uint256)\",\n address(sablierParams.sablier),\n sablierParams.totalAmount\n ),\n Enum.Operation.Call\n );\n\n LockupLinear.CreateWithTimestamps memory params = LockupLinear\n .CreateWithTimestamps({\n sender: sablierParams.sender,\n recipient: accountAddress,\n totalAmount: sablierParams.totalAmount,\n asset: IERC20(sablierParams.asset),\n cancelable: sablierParams.cancelable,\n transferable: sablierParams.transferable,\n timestamps: sablierParams.timestamps,\n broker: sablierParams.broker\n });\n\n // Proxy the Sablier call through IAvatar\n IAvatar(msg.sender).execTransactionFromModule(\n address(sablierParams.sablier),\n 0,\n abi.encodeWithSignature(\n \"createWithTimestamps((address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256)))\",\n params\n ),\n Enum.Operation.Call\n );\n\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * Creates a new role hat and any streams on it.\n *\n * This contract should be enabled a module on the Safe for which the role is to be created, and disable after.\n * In order for the module to be able to create hats on behalf of the Safe, the Safe must first\n * transfer its top hat to this contract. This function transfers the top hat back to the Safe after\n * creating the role hat.\n *\n * The function simply calls `createHatAndAccountAndMintAndStreams` and then transfers the top hat back to the Safe.\n *\n * @dev Role hat creation, minting, smart account creation and stream creation are handled here in order\n * to avoid a race condition where not more than one active proposal to create a new role can exist at a time.\n * See: https://github.com/decentdao/decent-interface/issues/2402\n */\n function createRoleHat(\n IHats hatsProtocol,\n uint256 adminHatId,\n Hat calldata hat,\n uint256 topHatId,\n address topHatAccount,\n IERC6551Registry registry,\n address hatsAccountImplementation,\n bytes32 salt\n ) public returns (uint256 hatId, address accountAddress) {\n (hatId, accountAddress) = createHatAndAccountAndMintAndStreams(\n hatsProtocol,\n adminHatId,\n hat,\n topHatAccount,\n registry,\n hatsAccountImplementation,\n salt\n );\n\n hatsProtocol.transferHat(topHatId, address(this), msg.sender);\n }\n\n /**\n * For a safe without any roles previously created on it, this function should be called. It sets up the\n * top hat and admin hat, as well as any other hats and their streams that are provided.\n *\n * This contract should be enabled a module on the Safe for which the role(s) are to be created, and disabled after.\n *\n * @dev In order for a Safe to seamlessly create roles even if it has never previously created a role and thus has\n * no hat tree, we defer the creation of the hat tree and its setup to this contract. This way, in a single tx block,\n * the resulting topHatId of the newly created hat can be used to create an admin hat and any other hats needed.\n * We also make use of `KeyValuePairs` to associate the topHatId with the Safe.\n */\n function createAndDeclareTree(CreateTreeParams calldata params) public {\n bytes32 salt = getSalt();\n\n (uint256 topHatId, address topHatAccount) = createTopHatAndAccount(\n params.hatsProtocol,\n params.topHatDetails,\n params.topHatImageURI,\n params.registry,\n params.hatsAccountImplementation,\n salt\n );\n\n declareSafeHatTree(params.keyValuePairs, topHatId);\n\n (uint256 adminHatId, ) = createHatAndAccountAndMintAndStreams(\n params.hatsProtocol,\n topHatId,\n params.adminHat,\n topHatAccount,\n params.registry,\n params.hatsAccountImplementation,\n salt\n );\n\n for (uint256 i = 0; i < params.hats.length; ) {\n createHatAndAccountAndMintAndStreams(\n params.hatsProtocol,\n adminHatId,\n params.hats[i],\n topHatAccount,\n params.registry,\n params.hatsAccountImplementation,\n salt\n );\n\n unchecked {\n ++i;\n }\n }\n\n params.hatsProtocol.transferHat(topHatId, address(this), msg.sender);\n }\n}\n" + }, + "contracts/interfaces/hats/IHats.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0\n// Copyright (C) 2023 Haberdasher Labs\n//\n// This program is free software: you can redistribute it and/or modify\n// it under the terms of the GNU Affero General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU Affero General Public License for more details.\n//\n// You should have received a copy of the GNU Affero General Public License\n// along with this program. If not, see .\n\npragma solidity >=0.8.13;\n\ninterface IHats {\n function mintTopHat(\n address _target,\n string memory _details,\n string memory _imageURI\n ) external returns (uint256 topHatId);\n\n function createHat(\n uint256 _admin,\n string calldata _details,\n uint32 _maxSupply,\n address _eligibility,\n address _toggle,\n bool _mutable,\n string calldata _imageURI\n ) external returns (uint256 newHatId);\n\n function mintHat(\n uint256 _hatId,\n address _wearer\n ) external returns (bool success);\n\n function transferHat(uint256 _hatId, address _from, address _to) external;\n}\n" + }, + "contracts/interfaces/IERC6551Registry.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.4;\n\ninterface IERC6551Registry {\n /**\n * @dev Creates a token bound account for a non-fungible token.\n *\n * If account has already been created, returns the account address without calling create2.\n *\n * Emits ERC6551AccountCreated event.\n *\n * @return account The address of the token bound account\n */\n function createAccount(\n address implementation,\n bytes32 salt,\n uint256 chainId,\n address tokenContract,\n uint256 tokenId\n ) external returns (address account);\n}\n" + }, + "contracts/interfaces/sablier/ISablierV2LockupLinear.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport {LockupLinear} from \"./LockupLinear.sol\";\nimport {IERC20} from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\n\ninterface ISablierV2LockupLinear {\n function createWithTimestamps(\n LockupLinear.CreateWithTimestamps calldata params\n ) external returns (uint256 streamId);\n}\n" + }, + "contracts/interfaces/sablier/LockupLinear.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport {IERC20} from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\n\nlibrary LockupLinear {\n struct CreateWithTimestamps {\n address sender;\n address recipient;\n uint128 totalAmount;\n IERC20 asset;\n bool cancelable;\n bool transferable;\n Timestamps timestamps;\n Broker broker;\n }\n\n struct Timestamps {\n uint40 start;\n uint40 cliff;\n uint40 end;\n }\n\n struct Broker {\n address account;\n uint256 fee;\n }\n}\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200 + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers", + "metadata", + "devdoc", + "userdoc", + "storageLayout", + "evm.gasEstimates" + ], + "": [ + "ast" + ] + } + }, + "metadata": { + "useLiteralContent": true + } + } +} \ No newline at end of file diff --git a/deployments/sepolia/DecentHats_0_1_0.json b/deployments/sepolia/DecentHats_0_1_0.json index d0d70862..fc9fee8b 100644 --- a/deployments/sepolia/DecentHats_0_1_0.json +++ b/deployments/sepolia/DecentHats_0_1_0.json @@ -1,5 +1,5 @@ { - "address": "0x577FcfB0655f24809345E951f188b1929A961E42", + "address": "0x0bEe0a447e6A5bEA8CAA0d8559A681EE16d6caCE", "abi": [ { "inputs": [], @@ -275,6 +275,168 @@ "stateMutability": "nonpayable", "type": "function" }, + { + "inputs": [ + { + "internalType": "contract IHats", + "name": "hatsProtocol", + "type": "address" + }, + { + "internalType": "uint256", + "name": "adminHatId", + "type": "uint256" + }, + { + "components": [ + { + "internalType": "uint32", + "name": "maxSupply", + "type": "uint32" + }, + { + "internalType": "string", + "name": "details", + "type": "string" + }, + { + "internalType": "string", + "name": "imageURI", + "type": "string" + }, + { + "internalType": "bool", + "name": "isMutable", + "type": "bool" + }, + { + "internalType": "address", + "name": "wearer", + "type": "address" + }, + { + "components": [ + { + "internalType": "contract ISablierV2LockupLinear", + "name": "sablier", + "type": "address" + }, + { + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "internalType": "uint128", + "name": "totalAmount", + "type": "uint128" + }, + { + "internalType": "address", + "name": "asset", + "type": "address" + }, + { + "internalType": "bool", + "name": "cancelable", + "type": "bool" + }, + { + "internalType": "bool", + "name": "transferable", + "type": "bool" + }, + { + "components": [ + { + "internalType": "uint40", + "name": "start", + "type": "uint40" + }, + { + "internalType": "uint40", + "name": "cliff", + "type": "uint40" + }, + { + "internalType": "uint40", + "name": "end", + "type": "uint40" + } + ], + "internalType": "struct LockupLinear.Timestamps", + "name": "timestamps", + "type": "tuple" + }, + { + "components": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "uint256", + "name": "fee", + "type": "uint256" + } + ], + "internalType": "struct LockupLinear.Broker", + "name": "broker", + "type": "tuple" + } + ], + "internalType": "struct DecentHats_0_1_0.SablierStreamParams[]", + "name": "sablierParams", + "type": "tuple[]" + } + ], + "internalType": "struct DecentHats_0_1_0.Hat", + "name": "hat", + "type": "tuple" + }, + { + "internalType": "uint256", + "name": "topHatId", + "type": "uint256" + }, + { + "internalType": "address", + "name": "topHatAccount", + "type": "address" + }, + { + "internalType": "contract IERC6551Registry", + "name": "registry", + "type": "address" + }, + { + "internalType": "address", + "name": "hatsAccountImplementation", + "type": "address" + }, + { + "internalType": "bytes32", + "name": "salt", + "type": "bytes32" + } + ], + "name": "createRoleHat", + "outputs": [ + { + "internalType": "uint256", + "name": "hatId", + "type": "uint256" + }, + { + "internalType": "address", + "name": "accountAddress", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, { "inputs": [], "name": "getSalt", @@ -289,36 +451,50 @@ "type": "function" } ], - "transactionHash": "0xa1e9712c6b8c387a4a26483ba80ed4e0d62b9c0546a3971cfacebedcca430271", + "transactionHash": "0xf40bd3ced4aeef501671b0cdb5b38737c085281f0b2147ac8e4aae18667fa1dd", "receipt": { "to": null, - "from": "0xfcf7a2794D066110162ADdcE3085dfd6221D4ddD", - "contractAddress": "0x577FcfB0655f24809345E951f188b1929A961E42", - "transactionIndex": 9, - "gasUsed": "1162443", + "from": "0xeb54d471CFadb8a9fD114C4628c89620b313432f", + "contractAddress": "0x0bEe0a447e6A5bEA8CAA0d8559A681EE16d6caCE", + "transactionIndex": 52, + "gasUsed": "1243979", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x614020dff98bee6b1b1949ba946f7f8d5b1054f3199eb499f979e82889712945", - "transactionHash": "0xa1e9712c6b8c387a4a26483ba80ed4e0d62b9c0546a3971cfacebedcca430271", + "blockHash": "0x348e807031247225bcd356c1719d5ef0ae8dec1556f477af9b569308deddf9f3", + "transactionHash": "0xf40bd3ced4aeef501671b0cdb5b38737c085281f0b2147ac8e4aae18667fa1dd", "logs": [], - "blockNumber": 6852403, - "cumulativeGasUsed": "1938170", + "blockNumber": 6943061, + "cumulativeGasUsed": "5696224", "status": 1, "byzantium": true }, "args": [], - "numDeployments": 5, - "solcInputHash": "6ceb8d75a501322d052845dbe517017d", - "metadata": "{\"compiler\":{\"version\":\"0.8.19+commit.7dd6d404\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"NAME\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"contract IHats\",\"name\":\"hatsProtocol\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"hatsAccountImplementation\",\"type\":\"address\"},{\"internalType\":\"contract IERC6551Registry\",\"name\":\"registry\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"keyValuePairs\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"topHatDetails\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"topHatImageURI\",\"type\":\"string\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"maxSupply\",\"type\":\"uint32\"},{\"internalType\":\"string\",\"name\":\"details\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"imageURI\",\"type\":\"string\"},{\"internalType\":\"bool\",\"name\":\"isMutable\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"wearer\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"contract ISablierV2LockupLinear\",\"name\":\"sablier\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint128\",\"name\":\"totalAmount\",\"type\":\"uint128\"},{\"internalType\":\"address\",\"name\":\"asset\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"cancelable\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"transferable\",\"type\":\"bool\"},{\"components\":[{\"internalType\":\"uint40\",\"name\":\"start\",\"type\":\"uint40\"},{\"internalType\":\"uint40\",\"name\":\"cliff\",\"type\":\"uint40\"},{\"internalType\":\"uint40\",\"name\":\"end\",\"type\":\"uint40\"}],\"internalType\":\"struct LockupLinear.Timestamps\",\"name\":\"timestamps\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"fee\",\"type\":\"uint256\"}],\"internalType\":\"struct LockupLinear.Broker\",\"name\":\"broker\",\"type\":\"tuple\"}],\"internalType\":\"struct DecentHats_0_1_0.SablierStreamParams[]\",\"name\":\"sablierParams\",\"type\":\"tuple[]\"}],\"internalType\":\"struct DecentHats_0_1_0.Hat\",\"name\":\"adminHat\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"maxSupply\",\"type\":\"uint32\"},{\"internalType\":\"string\",\"name\":\"details\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"imageURI\",\"type\":\"string\"},{\"internalType\":\"bool\",\"name\":\"isMutable\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"wearer\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"contract ISablierV2LockupLinear\",\"name\":\"sablier\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint128\",\"name\":\"totalAmount\",\"type\":\"uint128\"},{\"internalType\":\"address\",\"name\":\"asset\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"cancelable\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"transferable\",\"type\":\"bool\"},{\"components\":[{\"internalType\":\"uint40\",\"name\":\"start\",\"type\":\"uint40\"},{\"internalType\":\"uint40\",\"name\":\"cliff\",\"type\":\"uint40\"},{\"internalType\":\"uint40\",\"name\":\"end\",\"type\":\"uint40\"}],\"internalType\":\"struct LockupLinear.Timestamps\",\"name\":\"timestamps\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"fee\",\"type\":\"uint256\"}],\"internalType\":\"struct LockupLinear.Broker\",\"name\":\"broker\",\"type\":\"tuple\"}],\"internalType\":\"struct DecentHats_0_1_0.SablierStreamParams[]\",\"name\":\"sablierParams\",\"type\":\"tuple[]\"}],\"internalType\":\"struct DecentHats_0_1_0.Hat[]\",\"name\":\"hats\",\"type\":\"tuple[]\"}],\"internalType\":\"struct DecentHats_0_1_0.CreateTreeParams\",\"name\":\"params\",\"type\":\"tuple\"}],\"name\":\"createAndDeclareTree\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getSalt\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"salt\",\"type\":\"bytes32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/DecentHats_0_1_0.sol\":\"DecentHats_0_1_0\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\":{\"content\":\"// SPDX-License-Identifier: LGPL-3.0-only\\npragma solidity >=0.7.0 <0.9.0;\\n\\n/// @title Enum - Collection of enums\\n/// @author Richard Meissner - \\ncontract Enum {\\n enum Operation {Call, DelegateCall}\\n}\\n\",\"keccak256\":\"0x473e45b1a5cc47be494b0e123c9127f0c11c1e0992a321ae5a644c0bfdb2c14f\",\"license\":\"LGPL-3.0-only\"},\"@gnosis.pm/zodiac/contracts/interfaces/IAvatar.sol\":{\"content\":\"// SPDX-License-Identifier: LGPL-3.0-only\\n\\n/// @title Zodiac Avatar - A contract that manages modules that can execute transactions via this contract.\\npragma solidity >=0.7.0 <0.9.0;\\n\\nimport \\\"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\\\";\\n\\ninterface IAvatar {\\n event EnabledModule(address module);\\n event DisabledModule(address module);\\n event ExecutionFromModuleSuccess(address indexed module);\\n event ExecutionFromModuleFailure(address indexed module);\\n\\n /// @dev Enables a module on the avatar.\\n /// @notice Can only be called by the avatar.\\n /// @notice Modules should be stored as a linked list.\\n /// @notice Must emit EnabledModule(address module) if successful.\\n /// @param module Module to be enabled.\\n function enableModule(address module) external;\\n\\n /// @dev Disables a module on the avatar.\\n /// @notice Can only be called by the avatar.\\n /// @notice Must emit DisabledModule(address module) if successful.\\n /// @param prevModule Address that pointed to the module to be removed in the linked list\\n /// @param module Module to be removed.\\n function disableModule(address prevModule, address module) external;\\n\\n /// @dev Allows a Module to execute a transaction.\\n /// @notice Can only be called by an enabled module.\\n /// @notice Must emit ExecutionFromModuleSuccess(address module) if successful.\\n /// @notice Must emit ExecutionFromModuleFailure(address module) if unsuccessful.\\n /// @param to Destination address of module transaction.\\n /// @param value Ether value of module transaction.\\n /// @param data Data payload of module transaction.\\n /// @param operation Operation type of module transaction: 0 == call, 1 == delegate call.\\n function execTransactionFromModule(\\n address to,\\n uint256 value,\\n bytes memory data,\\n Enum.Operation operation\\n ) external returns (bool success);\\n\\n /// @dev Allows a Module to execute a transaction and return data\\n /// @notice Can only be called by an enabled module.\\n /// @notice Must emit ExecutionFromModuleSuccess(address module) if successful.\\n /// @notice Must emit ExecutionFromModuleFailure(address module) if unsuccessful.\\n /// @param to Destination address of module transaction.\\n /// @param value Ether value of module transaction.\\n /// @param data Data payload of module transaction.\\n /// @param operation Operation type of module transaction: 0 == call, 1 == delegate call.\\n function execTransactionFromModuleReturnData(\\n address to,\\n uint256 value,\\n bytes memory data,\\n Enum.Operation operation\\n ) external returns (bool success, bytes memory returnData);\\n\\n /// @dev Returns if an module is enabled\\n /// @return True if the module is enabled\\n function isModuleEnabled(address module) external view returns (bool);\\n\\n /// @dev Returns array of modules.\\n /// @param start Start of the page.\\n /// @param pageSize Maximum number of modules that should be returned.\\n /// @return array Array of modules.\\n /// @return next Start of the next page.\\n function getModulesPaginated(address start, uint256 pageSize)\\n external\\n view\\n returns (address[] memory array, address next);\\n}\\n\",\"keccak256\":\"0xcd5508ffe596eef8fbccfd5fc4f10a34397773547ce64e212d48b5212865ec1f\",\"license\":\"LGPL-3.0-only\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20 {\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `to`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address to, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `from` to `to` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(\\n address from,\\n address to,\\n uint256 amount\\n ) external returns (bool);\\n}\\n\",\"keccak256\":\"0x9750c6b834f7b43000631af5cc30001c5f547b3ceb3635488f140f60e897ea6b\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Strings.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev String operations.\\n */\\nlibrary Strings {\\n bytes16 private constant _HEX_SYMBOLS = \\\"0123456789abcdef\\\";\\n uint8 private constant _ADDRESS_LENGTH = 20;\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\\n */\\n function toString(uint256 value) internal pure returns (string memory) {\\n // Inspired by OraclizeAPI's implementation - MIT licence\\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\\n\\n if (value == 0) {\\n return \\\"0\\\";\\n }\\n uint256 temp = value;\\n uint256 digits;\\n while (temp != 0) {\\n digits++;\\n temp /= 10;\\n }\\n bytes memory buffer = new bytes(digits);\\n while (value != 0) {\\n digits -= 1;\\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\\n value /= 10;\\n }\\n return string(buffer);\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\\n */\\n function toHexString(uint256 value) internal pure returns (string memory) {\\n if (value == 0) {\\n return \\\"0x00\\\";\\n }\\n uint256 temp = value;\\n uint256 length = 0;\\n while (temp != 0) {\\n length++;\\n temp >>= 8;\\n }\\n return toHexString(value, length);\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\\n */\\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\\n bytes memory buffer = new bytes(2 * length + 2);\\n buffer[0] = \\\"0\\\";\\n buffer[1] = \\\"x\\\";\\n for (uint256 i = 2 * length + 1; i > 1; --i) {\\n buffer[i] = _HEX_SYMBOLS[value & 0xf];\\n value >>= 4;\\n }\\n require(value == 0, \\\"Strings: hex length insufficient\\\");\\n return string(buffer);\\n }\\n\\n /**\\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\\n */\\n function toHexString(address addr) internal pure returns (string memory) {\\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\\n }\\n}\\n\",\"keccak256\":\"0xaf159a8b1923ad2a26d516089bceca9bdeaeacd04be50983ea00ba63070f08a3\",\"license\":\"MIT\"},\"contracts/DecentHats_0_1_0.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity =0.8.19;\\n\\nimport {Enum} from \\\"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\\\";\\nimport {IAvatar} from \\\"@gnosis.pm/zodiac/contracts/interfaces/IAvatar.sol\\\";\\nimport {Strings} from \\\"@openzeppelin/contracts/utils/Strings.sol\\\";\\nimport {IERC20} from \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\nimport {IERC6551Registry} from \\\"./interfaces/IERC6551Registry.sol\\\";\\nimport {IHats} from \\\"./interfaces/hats/IHats.sol\\\";\\nimport {ISablierV2LockupLinear} from \\\"./interfaces/sablier/ISablierV2LockupLinear.sol\\\";\\nimport {LockupLinear} from \\\"./interfaces/sablier/LockupLinear.sol\\\";\\n\\ncontract DecentHats_0_1_0 {\\n string public constant NAME = \\\"DecentHats_0_1_0\\\";\\n\\n struct SablierStreamParams {\\n ISablierV2LockupLinear sablier;\\n address sender;\\n uint128 totalAmount;\\n address asset;\\n bool cancelable;\\n bool transferable;\\n LockupLinear.Timestamps timestamps;\\n LockupLinear.Broker broker;\\n }\\n\\n struct Hat {\\n uint32 maxSupply;\\n string details;\\n string imageURI;\\n bool isMutable;\\n address wearer;\\n SablierStreamParams[] sablierParams; // Optional Sablier stream parameters\\n }\\n\\n struct CreateTreeParams {\\n IHats hatsProtocol;\\n address hatsAccountImplementation;\\n IERC6551Registry registry;\\n address keyValuePairs;\\n string topHatDetails;\\n string topHatImageURI;\\n Hat adminHat;\\n Hat[] hats;\\n }\\n\\n function getSalt() public pure returns (bytes32 salt) {\\n return\\n 0x5d0e6ce4fd951366cc55da93f6e79d8b81483109d79676a04bcc2bed6a4b5072;\\n }\\n\\n function updateKeyValuePairs(\\n address _keyValuePairs,\\n uint256 topHatId\\n ) internal {\\n string[] memory keys = new string[](1);\\n string[] memory values = new string[](1);\\n keys[0] = \\\"topHatId\\\";\\n values[0] = Strings.toString(topHatId);\\n\\n IAvatar(msg.sender).execTransactionFromModule(\\n _keyValuePairs,\\n 0,\\n abi.encodeWithSignature(\\n \\\"updateValues(string[],string[])\\\",\\n keys,\\n values\\n ),\\n Enum.Operation.Call\\n );\\n }\\n\\n function createHat(\\n IHats _hatsProtocol,\\n uint256 adminHatId,\\n Hat memory _hat,\\n address topHatAccount\\n ) internal returns (uint256) {\\n return\\n _hatsProtocol.createHat(\\n adminHatId,\\n _hat.details,\\n _hat.maxSupply,\\n topHatAccount,\\n topHatAccount,\\n _hat.isMutable,\\n _hat.imageURI\\n );\\n }\\n\\n function createAccount(\\n IERC6551Registry _registry,\\n address _hatsAccountImplementation,\\n bytes32 salt,\\n address protocolAddress,\\n uint256 hatId\\n ) internal returns (address) {\\n return\\n _registry.createAccount(\\n _hatsAccountImplementation,\\n salt,\\n block.chainid,\\n protocolAddress,\\n hatId\\n );\\n }\\n\\n function createTopHatAndAccount(\\n IHats _hatsProtocol,\\n string memory _topHatDetails,\\n string memory _topHatImageURI,\\n IERC6551Registry _registry,\\n address _hatsAccountImplementation,\\n bytes32 salt\\n ) internal returns (uint256 topHatId, address topHatAccount) {\\n topHatId = _hatsProtocol.mintTopHat(\\n address(this),\\n _topHatDetails,\\n _topHatImageURI\\n );\\n\\n topHatAccount = createAccount(\\n _registry,\\n _hatsAccountImplementation,\\n salt,\\n address(_hatsProtocol),\\n topHatId\\n );\\n }\\n\\n function createHatAndAccountAndMintAndStreams(\\n IHats hatsProtocol,\\n uint256 adminHatId,\\n Hat calldata hat,\\n address topHatAccount,\\n IERC6551Registry registry,\\n address hatsAccountImplementation,\\n bytes32 salt\\n ) internal returns (uint256 hatId, address accountAddress) {\\n hatId = createHat(hatsProtocol, adminHatId, hat, topHatAccount);\\n\\n accountAddress = createAccount(\\n registry,\\n hatsAccountImplementation,\\n salt,\\n address(hatsProtocol),\\n hatId\\n );\\n\\n if (hat.wearer != address(0)) {\\n hatsProtocol.mintHat(hatId, hat.wearer);\\n }\\n\\n for (uint256 i = 0; i < hat.sablierParams.length; ) {\\n SablierStreamParams memory sablierParams = hat.sablierParams[i];\\n\\n // Approve tokens for Sablier\\n IAvatar(msg.sender).execTransactionFromModule(\\n sablierParams.asset,\\n 0,\\n abi.encodeWithSignature(\\n \\\"approve(address,uint256)\\\",\\n address(sablierParams.sablier),\\n sablierParams.totalAmount\\n ),\\n Enum.Operation.Call\\n );\\n\\n LockupLinear.CreateWithTimestamps memory params = LockupLinear\\n .CreateWithTimestamps({\\n sender: sablierParams.sender,\\n recipient: accountAddress,\\n totalAmount: sablierParams.totalAmount,\\n asset: IERC20(sablierParams.asset),\\n cancelable: sablierParams.cancelable,\\n transferable: sablierParams.transferable,\\n timestamps: sablierParams.timestamps,\\n broker: sablierParams.broker\\n });\\n\\n // Proxy the Sablier call through IAvatar\\n IAvatar(msg.sender).execTransactionFromModule(\\n address(sablierParams.sablier),\\n 0,\\n abi.encodeWithSignature(\\n \\\"createWithTimestamps((address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256)))\\\",\\n params\\n ),\\n Enum.Operation.Call\\n );\\n\\n unchecked {\\n ++i;\\n }\\n }\\n }\\n\\n function createAndDeclareTree(CreateTreeParams calldata params) public {\\n bytes32 salt = getSalt();\\n\\n (uint256 topHatId, address topHatAccount) = createTopHatAndAccount(\\n params.hatsProtocol,\\n params.topHatDetails,\\n params.topHatImageURI,\\n params.registry,\\n params.hatsAccountImplementation,\\n salt\\n );\\n\\n updateKeyValuePairs(params.keyValuePairs, topHatId);\\n\\n (uint256 adminHatId, ) = createHatAndAccountAndMintAndStreams(\\n params.hatsProtocol,\\n topHatId,\\n params.adminHat,\\n topHatAccount,\\n params.registry,\\n params.hatsAccountImplementation,\\n salt\\n );\\n\\n for (uint256 i = 0; i < params.hats.length; ) {\\n createHatAndAccountAndMintAndStreams(\\n params.hatsProtocol,\\n adminHatId,\\n params.hats[i],\\n topHatAccount,\\n params.registry,\\n params.hatsAccountImplementation,\\n salt\\n );\\n\\n unchecked {\\n ++i;\\n }\\n }\\n\\n params.hatsProtocol.transferHat(topHatId, address(this), msg.sender);\\n }\\n}\\n\",\"keccak256\":\"0xcf4e6d62ca64f62b8eb638805a8a4e715aea8fc201f3dea9a522edc1034599f1\",\"license\":\"MIT\"},\"contracts/interfaces/IERC6551Registry.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.4;\\n\\ninterface IERC6551Registry {\\n /**\\n * @dev Creates a token bound account for a non-fungible token.\\n *\\n * If account has already been created, returns the account address without calling create2.\\n *\\n * Emits ERC6551AccountCreated event.\\n *\\n * @return account The address of the token bound account\\n */\\n function createAccount(\\n address implementation,\\n bytes32 salt,\\n uint256 chainId,\\n address tokenContract,\\n uint256 tokenId\\n ) external returns (address account);\\n}\\n\",\"keccak256\":\"0x64c52de8a8e68398e61dd8b42dda8e9af8cf6abf93bb85629c322440991ea568\",\"license\":\"MIT\"},\"contracts/interfaces/hats/IHats.sol\":{\"content\":\"// SPDX-License-Identifier: AGPL-3.0\\n// Copyright (C) 2023 Haberdasher Labs\\n//\\n// This program is free software: you can redistribute it and/or modify\\n// it under the terms of the GNU Affero General Public License as published by\\n// the Free Software Foundation, either version 3 of the License, or\\n// (at your option) any later version.\\n//\\n// This program is distributed in the hope that it will be useful,\\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\\n// GNU Affero General Public License for more details.\\n//\\n// You should have received a copy of the GNU Affero General Public License\\n// along with this program. If not, see .\\n\\npragma solidity >=0.8.13;\\n\\ninterface IHats {\\n function mintTopHat(\\n address _target,\\n string memory _details,\\n string memory _imageURI\\n ) external returns (uint256 topHatId);\\n\\n function createHat(\\n uint256 _admin,\\n string calldata _details,\\n uint32 _maxSupply,\\n address _eligibility,\\n address _toggle,\\n bool _mutable,\\n string calldata _imageURI\\n ) external returns (uint256 newHatId);\\n\\n function mintHat(\\n uint256 _hatId,\\n address _wearer\\n ) external returns (bool success);\\n\\n function transferHat(uint256 _hatId, address _from, address _to) external;\\n}\\n\",\"keccak256\":\"0x8e35022f5c0fcf0059033abec78ec890f0cf3bbac09d6d24051cff9679239511\",\"license\":\"AGPL-3.0\"},\"contracts/interfaces/sablier/ISablierV2LockupLinear.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport {LockupLinear} from \\\"./LockupLinear.sol\\\";\\nimport {IERC20} from \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\n\\ninterface ISablierV2LockupLinear {\\n function createWithTimestamps(\\n LockupLinear.CreateWithTimestamps calldata params\\n ) external returns (uint256 streamId);\\n}\\n\",\"keccak256\":\"0xf4899637eb2e6c76c35e2d201e56e162a50e6bc7b5b9156e00866f0703ad07ca\",\"license\":\"MIT\"},\"contracts/interfaces/sablier/LockupLinear.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport {IERC20} from \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\n\\nlibrary LockupLinear {\\n struct CreateWithTimestamps {\\n address sender;\\n address recipient;\\n uint128 totalAmount;\\n IERC20 asset;\\n bool cancelable;\\n bool transferable;\\n Timestamps timestamps;\\n Broker broker;\\n }\\n\\n struct Timestamps {\\n uint40 start;\\n uint40 cliff;\\n uint40 end;\\n }\\n\\n struct Broker {\\n address account;\\n uint256 fee;\\n }\\n}\\n\",\"keccak256\":\"0x497fdb52b5e1a5a7e0711a9f7d5fb036eb668ccb92ea908ee088f56ee08a4ce8\",\"license\":\"MIT\"}},\"version\":1}", - "bytecode": "0x608060405234801561001057600080fd5b50611410806100206000396000f3fe608060405234801561001057600080fd5b50600436106100415760003560e01c806313a9589c146100465780638c5f591a14610079578063a3f4df7e1461008e575b600080fd5b6040517f5d0e6ce4fd951366cc55da93f6e79d8b81483109d79676a04bcc2bed6a4b507281526020015b60405180910390f35b61008c610087366004610aa8565b6100ca565b005b6100bd6040518060400160405280601081526020016f0446563656e74486174735f305f315f360841b81525081565b6040516100709190610b30565b7f5d0e6ce4fd951366cc55da93f6e79d8b81483109d79676a04bcc2bed6a4b50726000806101a86100fe6020860186610b5b565b61010b6080870187610b78565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061014d9250505060a0880188610b78565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610192925050506060890160408a01610b5b565b6101a260408a0160208b01610b5b565b88610317565b90925090506101c66101c06080860160608701610b5b565b836103a9565b600061020d6101d86020870187610b5b565b846101e660c0890189610bd5565b856101f760608b0160408c01610b5b565b61020760408c0160208d01610b5b565b8a610529565b50905060005b61022060e0870187610bf5565b905081101561029a576102906102396020880188610b5b565b8361024760e08a018a610bf5565b8581811061025757610257610c3e565b90506020028101906102699190610bd5565b8661027a60608c0160408d01610b5b565b61028a60408d0160208e01610b5b565b8b610529565b5050600101610213565b506102a86020860186610b5b565b6040516329287c1b60e21b8152600481018590523060248201523360448201526001600160a01b03919091169063a4a1f06c90606401600060405180830381600087803b1580156102f857600080fd5b505af115801561030c573d6000803e3d6000fd5b505050505050505050565b600080876001600160a01b0316631a64dfad3089896040518463ffffffff1660e01b815260040161034a93929190610c54565b6020604051808303816000875af1158015610369573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061038d9190610c8a565b915061039c8585858b86610878565b9050965096945050505050565b604080516001808252818301909252600091816020015b60608152602001906001900390816103c057505060408051600180825281830190925291925060009190602082015b60608152602001906001900390816103ef579050509050604051806040016040528060088152602001671d1bdc12185d125960c21b8152508260008151811061043a5761043a610c3e565b602002602001018190525061044e8361090e565b8160008151811061046157610461610c3e565b6020026020010181905250336001600160a01b031663468721a78560008585604051602401610491929190610d11565b60408051601f198184030181529181526020820180516001600160e01b031663579374b960e11b1790525160e085901b6001600160e01b03191681526104df93929190600090600401610d36565b6020604051808303816000875af11580156104fe573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105229190610d9a565b5050505050565b600080610540898961053a8a6110d4565b89610a16565b915061054f8585858c86610878565b9050600061056360a0890160808a01610b5b565b6001600160a01b031614610603576001600160a01b03891663641f776e8361059160a08b0160808c01610b5b565b6040516001600160e01b031960e085901b16815260048101929092526001600160a01b031660248201526044016020604051808303816000875af11580156105dd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106019190610d9a565b505b60005b61061360a0890189611198565b905081101561086b57600061062b60a08a018a611198565b8381811061063b5761063b610c3e565b9050610160020180360381019061065291906111e1565b6060810151815160408084015190516001600160a01b0390921660248301526001600160801b03166044820152919250339163468721a7919060009060640160408051601f198184030181529181526020820180516001600160e01b031663095ea7b360e01b1790525160e085901b6001600160e01b03191681526106df93929190600090600401610d36565b6020604051808303816000875af11580156106fe573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107229190610d9a565b50600060405180610100016040528083602001516001600160a01b03168152602001856001600160a01b0316815260200183604001516001600160801b0316815260200183606001516001600160a01b031681526020018360800151151581526020018360a00151151581526020018360c0015181526020018360e001518152509050336001600160a01b031663468721a783600001516000846040516024016107cc91906111fe565b60408051601f198184030181529181526020820180516001600160e01b03166353b1572760e01b1790525160e085901b6001600160e01b031916815261081a93929190600090600401610d36565b6020604051808303816000875af1158015610839573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061085d9190610d9a565b508260010192505050610606565b5097509795505050505050565b604051638a54c52f60e01b81526001600160a01b0385811660048301526024820185905246604483015283811660648301526084820183905260009190871690638a54c52f9060a4016020604051808303816000875af11580156108e0573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061090491906112c0565b9695505050505050565b6060816000036109355750506040805180820190915260018152600360fc1b602082015290565b8160005b811561095f5780610949816112f3565b91506109589050600a83611322565b9150610939565b6000816001600160401b0381111561097957610979610ca3565b6040519080825280601f01601f1916602001820160405280156109a3576020820181803683370190505b5090505b8415610a0e576109b8600183611336565b91506109c5600a8661134f565b6109d0906030611363565b60f81b8183815181106109e5576109e5610c3e565b60200101906001600160f81b031916908160001a905350610a07600a86611322565b94506109a7565b949350505050565b6020820151825160608401516040808601519051635829492f60e11b81526000946001600160a01b038a169463b052925e94610a5c948b948a9283929091600401611376565b6020604051808303816000875af1158015610a7b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a9f9190610c8a565b95945050505050565b600060208284031215610aba57600080fd5b81356001600160401b03811115610ad057600080fd5b82016101008185031215610ae357600080fd5b9392505050565b6000815180845260005b81811015610b1057602081850181015186830182015201610af4565b506000602082860101526020601f19601f83011685010191505092915050565b602081526000610ae36020830184610aea565b6001600160a01b0381168114610b5857600080fd5b50565b600060208284031215610b6d57600080fd5b8135610ae381610b43565b6000808335601e19843603018112610b8f57600080fd5b8301803591506001600160401b03821115610ba957600080fd5b602001915036819003821315610bbe57600080fd5b9250929050565b8035610bd081610b43565b919050565b6000823560be19833603018112610beb57600080fd5b9190910192915050565b6000808335601e19843603018112610c0c57600080fd5b8301803591506001600160401b03821115610c2657600080fd5b6020019150600581901b3603821315610bbe57600080fd5b634e487b7160e01b600052603260045260246000fd5b6001600160a01b0384168152606060208201819052600090610c7890830185610aea565b82810360408401526109048185610aea565b600060208284031215610c9c57600080fd5b5051919050565b634e487b7160e01b600052604160045260246000fd5b600082825180855260208086019550808260051b84010181860160005b84811015610d0457601f19868403018952610cf2838351610aea565b98840198925090830190600101610cd6565b5090979650505050505050565b604081526000610d246040830185610cb9565b8281036020840152610a9f8185610cb9565b60018060a01b0385168152836020820152608060408201526000610d5d6080830185610aea565b905060028310610d7d57634e487b7160e01b600052602160045260246000fd5b82606083015295945050505050565b8015158114610b5857600080fd5b600060208284031215610dac57600080fd5b8151610ae381610d8c565b60405160c081016001600160401b0381118282101715610dd957610dd9610ca3565b60405290565b604051601f8201601f191681016001600160401b0381118282101715610e0757610e07610ca3565b604052919050565b803563ffffffff81168114610bd057600080fd5b600082601f830112610e3457600080fd5b81356001600160401b03811115610e4d57610e4d610ca3565b610e60601f8201601f1916602001610ddf565b818152846020838601011115610e7557600080fd5b816020850160208301376000918101602001919091529392505050565b8035610bd081610d8c565b80356001600160801b0381168114610bd057600080fd5b803564ffffffffff81168114610bd057600080fd5b600060608284031215610edb57600080fd5b604051606081018181106001600160401b0382111715610efd57610efd610ca3565b604052905080610f0c83610eb4565b8152610f1a60208401610eb4565b6020820152610f2b60408401610eb4565b60408201525092915050565b600060408284031215610f4957600080fd5b604051604081018181106001600160401b0382111715610f6b57610f6b610ca3565b6040529050808235610f7c81610b43565b8152602092830135920191909152919050565b60006101608284031215610fa257600080fd5b60405161010081018181106001600160401b0382111715610fc557610fc5610ca3565b604052905080610fd483610bc5565b8152610fe260208401610bc5565b6020820152610ff360408401610e9d565b604082015261100460608401610bc5565b606082015261101560808401610e92565b608082015261102660a08401610e92565b60a08201526110388460c08501610ec9565b60c082015261104b846101208501610f37565b60e08201525092915050565b600082601f83011261106857600080fd5b813560206001600160401b0382111561108357611083610ca3565b611091818360051b01610ddf565b82815261016092830285018201928282019190878511156110b157600080fd5b8387015b85811015610d04576110c78982610f8f565b84529284019281016110b5565b600060c082360312156110e657600080fd5b6110ee610db7565b6110f783610e0f565b815260208301356001600160401b038082111561111357600080fd5b61111f36838701610e23565b6020840152604085013591508082111561113857600080fd5b61114436838701610e23565b604084015261115560608601610e92565b606084015261116660808601610bc5565b608084015260a085013591508082111561117f57600080fd5b5061118c36828601611057565b60a08301525092915050565b6000808335601e198436030181126111af57600080fd5b8301803591506001600160401b038211156111c957600080fd5b602001915061016081023603821315610bbe57600080fd5b600061016082840312156111f457600080fd5b610ae38383610f8f565b81516001600160a01b0390811682526020808401518216908301526040808401516001600160801b031690830152606080840151909116908201526080808301516101608301916112529084018215159052565b5060a083015161126660a084018215159052565b5060c083015161129960c0840182805164ffffffffff908116835260208083015182169084015260409182015116910152565b5060e0929092015180516001600160a01b0316610120830152602001516101409091015290565b6000602082840312156112d257600080fd5b8151610ae381610b43565b634e487b7160e01b600052601160045260246000fd5b600060018201611305576113056112dd565b5060010190565b634e487b7160e01b600052601260045260246000fd5b6000826113315761133161130c565b500490565b81810381811115611349576113496112dd565b92915050565b60008261135e5761135e61130c565b500690565b80820180821115611349576113496112dd565b87815260e06020820152600061138f60e0830189610aea565b63ffffffff881660408401526001600160a01b0387811660608501528616608084015284151560a084015282810360c08401526113cc8185610aea565b9a995050505050505050505056fea2646970667358221220fcb8ad75991fd171fd33998d718d5f54883d99a48d56657e7e938e34a55d6a2664736f6c63430008130033", - "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100415760003560e01c806313a9589c146100465780638c5f591a14610079578063a3f4df7e1461008e575b600080fd5b6040517f5d0e6ce4fd951366cc55da93f6e79d8b81483109d79676a04bcc2bed6a4b507281526020015b60405180910390f35b61008c610087366004610aa8565b6100ca565b005b6100bd6040518060400160405280601081526020016f0446563656e74486174735f305f315f360841b81525081565b6040516100709190610b30565b7f5d0e6ce4fd951366cc55da93f6e79d8b81483109d79676a04bcc2bed6a4b50726000806101a86100fe6020860186610b5b565b61010b6080870187610b78565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061014d9250505060a0880188610b78565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610192925050506060890160408a01610b5b565b6101a260408a0160208b01610b5b565b88610317565b90925090506101c66101c06080860160608701610b5b565b836103a9565b600061020d6101d86020870187610b5b565b846101e660c0890189610bd5565b856101f760608b0160408c01610b5b565b61020760408c0160208d01610b5b565b8a610529565b50905060005b61022060e0870187610bf5565b905081101561029a576102906102396020880188610b5b565b8361024760e08a018a610bf5565b8581811061025757610257610c3e565b90506020028101906102699190610bd5565b8661027a60608c0160408d01610b5b565b61028a60408d0160208e01610b5b565b8b610529565b5050600101610213565b506102a86020860186610b5b565b6040516329287c1b60e21b8152600481018590523060248201523360448201526001600160a01b03919091169063a4a1f06c90606401600060405180830381600087803b1580156102f857600080fd5b505af115801561030c573d6000803e3d6000fd5b505050505050505050565b600080876001600160a01b0316631a64dfad3089896040518463ffffffff1660e01b815260040161034a93929190610c54565b6020604051808303816000875af1158015610369573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061038d9190610c8a565b915061039c8585858b86610878565b9050965096945050505050565b604080516001808252818301909252600091816020015b60608152602001906001900390816103c057505060408051600180825281830190925291925060009190602082015b60608152602001906001900390816103ef579050509050604051806040016040528060088152602001671d1bdc12185d125960c21b8152508260008151811061043a5761043a610c3e565b602002602001018190525061044e8361090e565b8160008151811061046157610461610c3e565b6020026020010181905250336001600160a01b031663468721a78560008585604051602401610491929190610d11565b60408051601f198184030181529181526020820180516001600160e01b031663579374b960e11b1790525160e085901b6001600160e01b03191681526104df93929190600090600401610d36565b6020604051808303816000875af11580156104fe573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105229190610d9a565b5050505050565b600080610540898961053a8a6110d4565b89610a16565b915061054f8585858c86610878565b9050600061056360a0890160808a01610b5b565b6001600160a01b031614610603576001600160a01b03891663641f776e8361059160a08b0160808c01610b5b565b6040516001600160e01b031960e085901b16815260048101929092526001600160a01b031660248201526044016020604051808303816000875af11580156105dd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106019190610d9a565b505b60005b61061360a0890189611198565b905081101561086b57600061062b60a08a018a611198565b8381811061063b5761063b610c3e565b9050610160020180360381019061065291906111e1565b6060810151815160408084015190516001600160a01b0390921660248301526001600160801b03166044820152919250339163468721a7919060009060640160408051601f198184030181529181526020820180516001600160e01b031663095ea7b360e01b1790525160e085901b6001600160e01b03191681526106df93929190600090600401610d36565b6020604051808303816000875af11580156106fe573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107229190610d9a565b50600060405180610100016040528083602001516001600160a01b03168152602001856001600160a01b0316815260200183604001516001600160801b0316815260200183606001516001600160a01b031681526020018360800151151581526020018360a00151151581526020018360c0015181526020018360e001518152509050336001600160a01b031663468721a783600001516000846040516024016107cc91906111fe565b60408051601f198184030181529181526020820180516001600160e01b03166353b1572760e01b1790525160e085901b6001600160e01b031916815261081a93929190600090600401610d36565b6020604051808303816000875af1158015610839573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061085d9190610d9a565b508260010192505050610606565b5097509795505050505050565b604051638a54c52f60e01b81526001600160a01b0385811660048301526024820185905246604483015283811660648301526084820183905260009190871690638a54c52f9060a4016020604051808303816000875af11580156108e0573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061090491906112c0565b9695505050505050565b6060816000036109355750506040805180820190915260018152600360fc1b602082015290565b8160005b811561095f5780610949816112f3565b91506109589050600a83611322565b9150610939565b6000816001600160401b0381111561097957610979610ca3565b6040519080825280601f01601f1916602001820160405280156109a3576020820181803683370190505b5090505b8415610a0e576109b8600183611336565b91506109c5600a8661134f565b6109d0906030611363565b60f81b8183815181106109e5576109e5610c3e565b60200101906001600160f81b031916908160001a905350610a07600a86611322565b94506109a7565b949350505050565b6020820151825160608401516040808601519051635829492f60e11b81526000946001600160a01b038a169463b052925e94610a5c948b948a9283929091600401611376565b6020604051808303816000875af1158015610a7b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a9f9190610c8a565b95945050505050565b600060208284031215610aba57600080fd5b81356001600160401b03811115610ad057600080fd5b82016101008185031215610ae357600080fd5b9392505050565b6000815180845260005b81811015610b1057602081850181015186830182015201610af4565b506000602082860101526020601f19601f83011685010191505092915050565b602081526000610ae36020830184610aea565b6001600160a01b0381168114610b5857600080fd5b50565b600060208284031215610b6d57600080fd5b8135610ae381610b43565b6000808335601e19843603018112610b8f57600080fd5b8301803591506001600160401b03821115610ba957600080fd5b602001915036819003821315610bbe57600080fd5b9250929050565b8035610bd081610b43565b919050565b6000823560be19833603018112610beb57600080fd5b9190910192915050565b6000808335601e19843603018112610c0c57600080fd5b8301803591506001600160401b03821115610c2657600080fd5b6020019150600581901b3603821315610bbe57600080fd5b634e487b7160e01b600052603260045260246000fd5b6001600160a01b0384168152606060208201819052600090610c7890830185610aea565b82810360408401526109048185610aea565b600060208284031215610c9c57600080fd5b5051919050565b634e487b7160e01b600052604160045260246000fd5b600082825180855260208086019550808260051b84010181860160005b84811015610d0457601f19868403018952610cf2838351610aea565b98840198925090830190600101610cd6565b5090979650505050505050565b604081526000610d246040830185610cb9565b8281036020840152610a9f8185610cb9565b60018060a01b0385168152836020820152608060408201526000610d5d6080830185610aea565b905060028310610d7d57634e487b7160e01b600052602160045260246000fd5b82606083015295945050505050565b8015158114610b5857600080fd5b600060208284031215610dac57600080fd5b8151610ae381610d8c565b60405160c081016001600160401b0381118282101715610dd957610dd9610ca3565b60405290565b604051601f8201601f191681016001600160401b0381118282101715610e0757610e07610ca3565b604052919050565b803563ffffffff81168114610bd057600080fd5b600082601f830112610e3457600080fd5b81356001600160401b03811115610e4d57610e4d610ca3565b610e60601f8201601f1916602001610ddf565b818152846020838601011115610e7557600080fd5b816020850160208301376000918101602001919091529392505050565b8035610bd081610d8c565b80356001600160801b0381168114610bd057600080fd5b803564ffffffffff81168114610bd057600080fd5b600060608284031215610edb57600080fd5b604051606081018181106001600160401b0382111715610efd57610efd610ca3565b604052905080610f0c83610eb4565b8152610f1a60208401610eb4565b6020820152610f2b60408401610eb4565b60408201525092915050565b600060408284031215610f4957600080fd5b604051604081018181106001600160401b0382111715610f6b57610f6b610ca3565b6040529050808235610f7c81610b43565b8152602092830135920191909152919050565b60006101608284031215610fa257600080fd5b60405161010081018181106001600160401b0382111715610fc557610fc5610ca3565b604052905080610fd483610bc5565b8152610fe260208401610bc5565b6020820152610ff360408401610e9d565b604082015261100460608401610bc5565b606082015261101560808401610e92565b608082015261102660a08401610e92565b60a08201526110388460c08501610ec9565b60c082015261104b846101208501610f37565b60e08201525092915050565b600082601f83011261106857600080fd5b813560206001600160401b0382111561108357611083610ca3565b611091818360051b01610ddf565b82815261016092830285018201928282019190878511156110b157600080fd5b8387015b85811015610d04576110c78982610f8f565b84529284019281016110b5565b600060c082360312156110e657600080fd5b6110ee610db7565b6110f783610e0f565b815260208301356001600160401b038082111561111357600080fd5b61111f36838701610e23565b6020840152604085013591508082111561113857600080fd5b61114436838701610e23565b604084015261115560608601610e92565b606084015261116660808601610bc5565b608084015260a085013591508082111561117f57600080fd5b5061118c36828601611057565b60a08301525092915050565b6000808335601e198436030181126111af57600080fd5b8301803591506001600160401b038211156111c957600080fd5b602001915061016081023603821315610bbe57600080fd5b600061016082840312156111f457600080fd5b610ae38383610f8f565b81516001600160a01b0390811682526020808401518216908301526040808401516001600160801b031690830152606080840151909116908201526080808301516101608301916112529084018215159052565b5060a083015161126660a084018215159052565b5060c083015161129960c0840182805164ffffffffff908116835260208083015182169084015260409182015116910152565b5060e0929092015180516001600160a01b0316610120830152602001516101409091015290565b6000602082840312156112d257600080fd5b8151610ae381610b43565b634e487b7160e01b600052601160045260246000fd5b600060018201611305576113056112dd565b5060010190565b634e487b7160e01b600052601260045260246000fd5b6000826113315761133161130c565b500490565b81810381811115611349576113496112dd565b92915050565b60008261135e5761135e61130c565b500690565b80820180821115611349576113496112dd565b87815260e06020820152600061138f60e0830189610aea565b63ffffffff881660408401526001600160a01b0387811660608501528616608084015284151560a084015282810360c08401526113cc8185610aea565b9a995050505050505050505056fea2646970667358221220fcb8ad75991fd171fd33998d718d5f54883d99a48d56657e7e938e34a55d6a2664736f6c63430008130033", + "numDeployments": 6, + "solcInputHash": "4754a2f0c9d6a191a066af246491b62a", + "metadata": "{\"compiler\":{\"version\":\"0.8.19+commit.7dd6d404\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"NAME\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"contract IHats\",\"name\":\"hatsProtocol\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"hatsAccountImplementation\",\"type\":\"address\"},{\"internalType\":\"contract IERC6551Registry\",\"name\":\"registry\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"keyValuePairs\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"topHatDetails\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"topHatImageURI\",\"type\":\"string\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"maxSupply\",\"type\":\"uint32\"},{\"internalType\":\"string\",\"name\":\"details\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"imageURI\",\"type\":\"string\"},{\"internalType\":\"bool\",\"name\":\"isMutable\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"wearer\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"contract ISablierV2LockupLinear\",\"name\":\"sablier\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint128\",\"name\":\"totalAmount\",\"type\":\"uint128\"},{\"internalType\":\"address\",\"name\":\"asset\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"cancelable\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"transferable\",\"type\":\"bool\"},{\"components\":[{\"internalType\":\"uint40\",\"name\":\"start\",\"type\":\"uint40\"},{\"internalType\":\"uint40\",\"name\":\"cliff\",\"type\":\"uint40\"},{\"internalType\":\"uint40\",\"name\":\"end\",\"type\":\"uint40\"}],\"internalType\":\"struct LockupLinear.Timestamps\",\"name\":\"timestamps\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"fee\",\"type\":\"uint256\"}],\"internalType\":\"struct LockupLinear.Broker\",\"name\":\"broker\",\"type\":\"tuple\"}],\"internalType\":\"struct DecentHats_0_1_0.SablierStreamParams[]\",\"name\":\"sablierParams\",\"type\":\"tuple[]\"}],\"internalType\":\"struct DecentHats_0_1_0.Hat\",\"name\":\"adminHat\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"maxSupply\",\"type\":\"uint32\"},{\"internalType\":\"string\",\"name\":\"details\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"imageURI\",\"type\":\"string\"},{\"internalType\":\"bool\",\"name\":\"isMutable\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"wearer\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"contract ISablierV2LockupLinear\",\"name\":\"sablier\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint128\",\"name\":\"totalAmount\",\"type\":\"uint128\"},{\"internalType\":\"address\",\"name\":\"asset\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"cancelable\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"transferable\",\"type\":\"bool\"},{\"components\":[{\"internalType\":\"uint40\",\"name\":\"start\",\"type\":\"uint40\"},{\"internalType\":\"uint40\",\"name\":\"cliff\",\"type\":\"uint40\"},{\"internalType\":\"uint40\",\"name\":\"end\",\"type\":\"uint40\"}],\"internalType\":\"struct LockupLinear.Timestamps\",\"name\":\"timestamps\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"fee\",\"type\":\"uint256\"}],\"internalType\":\"struct LockupLinear.Broker\",\"name\":\"broker\",\"type\":\"tuple\"}],\"internalType\":\"struct DecentHats_0_1_0.SablierStreamParams[]\",\"name\":\"sablierParams\",\"type\":\"tuple[]\"}],\"internalType\":\"struct DecentHats_0_1_0.Hat[]\",\"name\":\"hats\",\"type\":\"tuple[]\"}],\"internalType\":\"struct DecentHats_0_1_0.CreateTreeParams\",\"name\":\"params\",\"type\":\"tuple\"}],\"name\":\"createAndDeclareTree\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"contract IHats\",\"name\":\"hatsProtocol\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"adminHatId\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"uint32\",\"name\":\"maxSupply\",\"type\":\"uint32\"},{\"internalType\":\"string\",\"name\":\"details\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"imageURI\",\"type\":\"string\"},{\"internalType\":\"bool\",\"name\":\"isMutable\",\"type\":\"bool\"},{\"internalType\":\"address\",\"name\":\"wearer\",\"type\":\"address\"},{\"components\":[{\"internalType\":\"contract ISablierV2LockupLinear\",\"name\":\"sablier\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"uint128\",\"name\":\"totalAmount\",\"type\":\"uint128\"},{\"internalType\":\"address\",\"name\":\"asset\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"cancelable\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"transferable\",\"type\":\"bool\"},{\"components\":[{\"internalType\":\"uint40\",\"name\":\"start\",\"type\":\"uint40\"},{\"internalType\":\"uint40\",\"name\":\"cliff\",\"type\":\"uint40\"},{\"internalType\":\"uint40\",\"name\":\"end\",\"type\":\"uint40\"}],\"internalType\":\"struct LockupLinear.Timestamps\",\"name\":\"timestamps\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"fee\",\"type\":\"uint256\"}],\"internalType\":\"struct LockupLinear.Broker\",\"name\":\"broker\",\"type\":\"tuple\"}],\"internalType\":\"struct DecentHats_0_1_0.SablierStreamParams[]\",\"name\":\"sablierParams\",\"type\":\"tuple[]\"}],\"internalType\":\"struct DecentHats_0_1_0.Hat\",\"name\":\"hat\",\"type\":\"tuple\"},{\"internalType\":\"uint256\",\"name\":\"topHatId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"topHatAccount\",\"type\":\"address\"},{\"internalType\":\"contract IERC6551Registry\",\"name\":\"registry\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"hatsAccountImplementation\",\"type\":\"address\"},{\"internalType\":\"bytes32\",\"name\":\"salt\",\"type\":\"bytes32\"}],\"name\":\"createRoleHat\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"hatId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"accountAddress\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getSalt\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"salt\",\"type\":\"bytes32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"createAndDeclareTree((address,address,address,address,string,string,(uint32,string,string,bool,address,(address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256))[]),(uint32,string,string,bool,address,(address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256))[])[]))\":{\"details\":\"In order for a Safe to seamlessly create roles even if it has never previously created a role and thus has no hat tree, we defer the creation of the hat tree and its setup to this contract. This way, in a single tx block, the resulting topHatId of the newly created hat can be used to create an admin hat and any other hats needed. We also make use of `KeyValuePairs` to associate the topHatId with the Safe.\"},\"createRoleHat(address,uint256,(uint32,string,string,bool,address,(address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256))[]),uint256,address,address,address,bytes32)\":{\"details\":\"Role hat creation, minting, smart account creation and stream creation are handled here in order to avoid a race condition where not more than one active proposal to create a new role can exist at a time. See: https://github.com/decentdao/decent-interface/issues/2402\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"createAndDeclareTree((address,address,address,address,string,string,(uint32,string,string,bool,address,(address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256))[]),(uint32,string,string,bool,address,(address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256))[])[]))\":{\"notice\":\"For a safe without any roles previously created on it, this function should be called. It sets up the top hat and admin hat, as well as any other hats and their streams that are provided. This contract should be enabled a module on the Safe for which the role(s) are to be created, and disabled after.\"},\"createRoleHat(address,uint256,(uint32,string,string,bool,address,(address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256))[]),uint256,address,address,address,bytes32)\":{\"notice\":\"Creates a new role hat and any streams on it. This contract should be enabled a module on the Safe for which the role is to be created, and disable after. In order for the module to be able to create hats on behalf of the Safe, the Safe must first transfer its top hat to this contract. This function transfers the top hat back to the Safe after creating the role hat. The function simply calls `createHatAndAccountAndMintAndStreams` and then transfers the top hat back to the Safe.\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/DecentHats_0_1_0.sol\":\"DecentHats_0_1_0\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\":{\"content\":\"// SPDX-License-Identifier: LGPL-3.0-only\\npragma solidity >=0.7.0 <0.9.0;\\n\\n/// @title Enum - Collection of enums\\n/// @author Richard Meissner - \\ncontract Enum {\\n enum Operation {Call, DelegateCall}\\n}\\n\",\"keccak256\":\"0x473e45b1a5cc47be494b0e123c9127f0c11c1e0992a321ae5a644c0bfdb2c14f\",\"license\":\"LGPL-3.0-only\"},\"@gnosis.pm/zodiac/contracts/interfaces/IAvatar.sol\":{\"content\":\"// SPDX-License-Identifier: LGPL-3.0-only\\n\\n/// @title Zodiac Avatar - A contract that manages modules that can execute transactions via this contract.\\npragma solidity >=0.7.0 <0.9.0;\\n\\nimport \\\"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\\\";\\n\\ninterface IAvatar {\\n event EnabledModule(address module);\\n event DisabledModule(address module);\\n event ExecutionFromModuleSuccess(address indexed module);\\n event ExecutionFromModuleFailure(address indexed module);\\n\\n /// @dev Enables a module on the avatar.\\n /// @notice Can only be called by the avatar.\\n /// @notice Modules should be stored as a linked list.\\n /// @notice Must emit EnabledModule(address module) if successful.\\n /// @param module Module to be enabled.\\n function enableModule(address module) external;\\n\\n /// @dev Disables a module on the avatar.\\n /// @notice Can only be called by the avatar.\\n /// @notice Must emit DisabledModule(address module) if successful.\\n /// @param prevModule Address that pointed to the module to be removed in the linked list\\n /// @param module Module to be removed.\\n function disableModule(address prevModule, address module) external;\\n\\n /// @dev Allows a Module to execute a transaction.\\n /// @notice Can only be called by an enabled module.\\n /// @notice Must emit ExecutionFromModuleSuccess(address module) if successful.\\n /// @notice Must emit ExecutionFromModuleFailure(address module) if unsuccessful.\\n /// @param to Destination address of module transaction.\\n /// @param value Ether value of module transaction.\\n /// @param data Data payload of module transaction.\\n /// @param operation Operation type of module transaction: 0 == call, 1 == delegate call.\\n function execTransactionFromModule(\\n address to,\\n uint256 value,\\n bytes memory data,\\n Enum.Operation operation\\n ) external returns (bool success);\\n\\n /// @dev Allows a Module to execute a transaction and return data\\n /// @notice Can only be called by an enabled module.\\n /// @notice Must emit ExecutionFromModuleSuccess(address module) if successful.\\n /// @notice Must emit ExecutionFromModuleFailure(address module) if unsuccessful.\\n /// @param to Destination address of module transaction.\\n /// @param value Ether value of module transaction.\\n /// @param data Data payload of module transaction.\\n /// @param operation Operation type of module transaction: 0 == call, 1 == delegate call.\\n function execTransactionFromModuleReturnData(\\n address to,\\n uint256 value,\\n bytes memory data,\\n Enum.Operation operation\\n ) external returns (bool success, bytes memory returnData);\\n\\n /// @dev Returns if an module is enabled\\n /// @return True if the module is enabled\\n function isModuleEnabled(address module) external view returns (bool);\\n\\n /// @dev Returns array of modules.\\n /// @param start Start of the page.\\n /// @param pageSize Maximum number of modules that should be returned.\\n /// @return array Array of modules.\\n /// @return next Start of the next page.\\n function getModulesPaginated(address start, uint256 pageSize)\\n external\\n view\\n returns (address[] memory array, address next);\\n}\\n\",\"keccak256\":\"0xcd5508ffe596eef8fbccfd5fc4f10a34397773547ce64e212d48b5212865ec1f\",\"license\":\"LGPL-3.0-only\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20 {\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `to`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address to, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `from` to `to` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(\\n address from,\\n address to,\\n uint256 amount\\n ) external returns (bool);\\n}\\n\",\"keccak256\":\"0x9750c6b834f7b43000631af5cc30001c5f547b3ceb3635488f140f60e897ea6b\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Strings.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev String operations.\\n */\\nlibrary Strings {\\n bytes16 private constant _HEX_SYMBOLS = \\\"0123456789abcdef\\\";\\n uint8 private constant _ADDRESS_LENGTH = 20;\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\\n */\\n function toString(uint256 value) internal pure returns (string memory) {\\n // Inspired by OraclizeAPI's implementation - MIT licence\\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\\n\\n if (value == 0) {\\n return \\\"0\\\";\\n }\\n uint256 temp = value;\\n uint256 digits;\\n while (temp != 0) {\\n digits++;\\n temp /= 10;\\n }\\n bytes memory buffer = new bytes(digits);\\n while (value != 0) {\\n digits -= 1;\\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\\n value /= 10;\\n }\\n return string(buffer);\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\\n */\\n function toHexString(uint256 value) internal pure returns (string memory) {\\n if (value == 0) {\\n return \\\"0x00\\\";\\n }\\n uint256 temp = value;\\n uint256 length = 0;\\n while (temp != 0) {\\n length++;\\n temp >>= 8;\\n }\\n return toHexString(value, length);\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\\n */\\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\\n bytes memory buffer = new bytes(2 * length + 2);\\n buffer[0] = \\\"0\\\";\\n buffer[1] = \\\"x\\\";\\n for (uint256 i = 2 * length + 1; i > 1; --i) {\\n buffer[i] = _HEX_SYMBOLS[value & 0xf];\\n value >>= 4;\\n }\\n require(value == 0, \\\"Strings: hex length insufficient\\\");\\n return string(buffer);\\n }\\n\\n /**\\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\\n */\\n function toHexString(address addr) internal pure returns (string memory) {\\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\\n }\\n}\\n\",\"keccak256\":\"0xaf159a8b1923ad2a26d516089bceca9bdeaeacd04be50983ea00ba63070f08a3\",\"license\":\"MIT\"},\"contracts/DecentHats_0_1_0.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity =0.8.19;\\n\\nimport {Enum} from \\\"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\\\";\\nimport {IAvatar} from \\\"@gnosis.pm/zodiac/contracts/interfaces/IAvatar.sol\\\";\\nimport {Strings} from \\\"@openzeppelin/contracts/utils/Strings.sol\\\";\\nimport {IERC20} from \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\nimport {IERC6551Registry} from \\\"./interfaces/IERC6551Registry.sol\\\";\\nimport {IHats} from \\\"./interfaces/hats/IHats.sol\\\";\\nimport {ISablierV2LockupLinear} from \\\"./interfaces/sablier/ISablierV2LockupLinear.sol\\\";\\nimport {LockupLinear} from \\\"./interfaces/sablier/LockupLinear.sol\\\";\\n\\ncontract DecentHats_0_1_0 {\\n string public constant NAME = \\\"DecentHats_0_1_0\\\";\\n\\n struct SablierStreamParams {\\n ISablierV2LockupLinear sablier;\\n address sender;\\n uint128 totalAmount;\\n address asset;\\n bool cancelable;\\n bool transferable;\\n LockupLinear.Timestamps timestamps;\\n LockupLinear.Broker broker;\\n }\\n\\n struct Hat {\\n uint32 maxSupply;\\n string details;\\n string imageURI;\\n bool isMutable;\\n address wearer;\\n SablierStreamParams[] sablierParams; // Optional Sablier stream parameters\\n }\\n\\n struct CreateTreeParams {\\n IHats hatsProtocol;\\n address hatsAccountImplementation;\\n IERC6551Registry registry;\\n address keyValuePairs;\\n string topHatDetails;\\n string topHatImageURI;\\n Hat adminHat;\\n Hat[] hats;\\n }\\n\\n function getSalt() public pure returns (bytes32 salt) {\\n return\\n 0x5d0e6ce4fd951366cc55da93f6e79d8b81483109d79676a04bcc2bed6a4b5072;\\n }\\n\\n function declareSafeHatTree(\\n address _keyValuePairs,\\n uint256 topHatId\\n ) internal {\\n string[] memory keys = new string[](1);\\n string[] memory values = new string[](1);\\n keys[0] = \\\"topHatId\\\";\\n values[0] = Strings.toString(topHatId);\\n\\n IAvatar(msg.sender).execTransactionFromModule(\\n _keyValuePairs,\\n 0,\\n abi.encodeWithSignature(\\n \\\"updateValues(string[],string[])\\\",\\n keys,\\n values\\n ),\\n Enum.Operation.Call\\n );\\n }\\n\\n function createHat(\\n IHats _hatsProtocol,\\n uint256 adminHatId,\\n Hat memory _hat,\\n address topHatAccount\\n ) internal returns (uint256) {\\n return\\n _hatsProtocol.createHat(\\n adminHatId,\\n _hat.details,\\n _hat.maxSupply,\\n topHatAccount,\\n topHatAccount,\\n _hat.isMutable,\\n _hat.imageURI\\n );\\n }\\n\\n function createAccount(\\n IERC6551Registry _registry,\\n address _hatsAccountImplementation,\\n bytes32 salt,\\n address protocolAddress,\\n uint256 hatId\\n ) internal returns (address) {\\n return\\n _registry.createAccount(\\n _hatsAccountImplementation,\\n salt,\\n block.chainid,\\n protocolAddress,\\n hatId\\n );\\n }\\n\\n function createTopHatAndAccount(\\n IHats _hatsProtocol,\\n string memory _topHatDetails,\\n string memory _topHatImageURI,\\n IERC6551Registry _registry,\\n address _hatsAccountImplementation,\\n bytes32 salt\\n ) internal returns (uint256 topHatId, address topHatAccount) {\\n topHatId = _hatsProtocol.mintTopHat(\\n address(this),\\n _topHatDetails,\\n _topHatImageURI\\n );\\n\\n topHatAccount = createAccount(\\n _registry,\\n _hatsAccountImplementation,\\n salt,\\n address(_hatsProtocol),\\n topHatId\\n );\\n }\\n\\n function createHatAndAccountAndMintAndStreams(\\n IHats hatsProtocol,\\n uint256 adminHatId,\\n Hat calldata hat,\\n address topHatAccount,\\n IERC6551Registry registry,\\n address hatsAccountImplementation,\\n bytes32 salt\\n ) internal returns (uint256 hatId, address accountAddress) {\\n hatId = createHat(hatsProtocol, adminHatId, hat, topHatAccount);\\n\\n accountAddress = createAccount(\\n registry,\\n hatsAccountImplementation,\\n salt,\\n address(hatsProtocol),\\n hatId\\n );\\n\\n if (hat.wearer != address(0)) {\\n hatsProtocol.mintHat(hatId, hat.wearer);\\n }\\n\\n for (uint256 i = 0; i < hat.sablierParams.length; ) {\\n SablierStreamParams memory sablierParams = hat.sablierParams[i];\\n\\n // Approve tokens for Sablier\\n IAvatar(msg.sender).execTransactionFromModule(\\n sablierParams.asset,\\n 0,\\n abi.encodeWithSignature(\\n \\\"approve(address,uint256)\\\",\\n address(sablierParams.sablier),\\n sablierParams.totalAmount\\n ),\\n Enum.Operation.Call\\n );\\n\\n LockupLinear.CreateWithTimestamps memory params = LockupLinear\\n .CreateWithTimestamps({\\n sender: sablierParams.sender,\\n recipient: accountAddress,\\n totalAmount: sablierParams.totalAmount,\\n asset: IERC20(sablierParams.asset),\\n cancelable: sablierParams.cancelable,\\n transferable: sablierParams.transferable,\\n timestamps: sablierParams.timestamps,\\n broker: sablierParams.broker\\n });\\n\\n // Proxy the Sablier call through IAvatar\\n IAvatar(msg.sender).execTransactionFromModule(\\n address(sablierParams.sablier),\\n 0,\\n abi.encodeWithSignature(\\n \\\"createWithTimestamps((address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256)))\\\",\\n params\\n ),\\n Enum.Operation.Call\\n );\\n\\n unchecked {\\n ++i;\\n }\\n }\\n }\\n\\n /**\\n * Creates a new role hat and any streams on it.\\n *\\n * This contract should be enabled a module on the Safe for which the role is to be created, and disable after.\\n * In order for the module to be able to create hats on behalf of the Safe, the Safe must first\\n * transfer its top hat to this contract. This function transfers the top hat back to the Safe after\\n * creating the role hat.\\n *\\n * The function simply calls `createHatAndAccountAndMintAndStreams` and then transfers the top hat back to the Safe.\\n *\\n * @dev Role hat creation, minting, smart account creation and stream creation are handled here in order\\n * to avoid a race condition where not more than one active proposal to create a new role can exist at a time.\\n * See: https://github.com/decentdao/decent-interface/issues/2402\\n */\\n function createRoleHat(\\n IHats hatsProtocol,\\n uint256 adminHatId,\\n Hat calldata hat,\\n uint256 topHatId,\\n address topHatAccount,\\n IERC6551Registry registry,\\n address hatsAccountImplementation,\\n bytes32 salt\\n ) public returns (uint256 hatId, address accountAddress) {\\n (hatId, accountAddress) = createHatAndAccountAndMintAndStreams(\\n hatsProtocol,\\n adminHatId,\\n hat,\\n topHatAccount,\\n registry,\\n hatsAccountImplementation,\\n salt\\n );\\n\\n hatsProtocol.transferHat(topHatId, address(this), msg.sender);\\n }\\n\\n /**\\n * For a safe without any roles previously created on it, this function should be called. It sets up the\\n * top hat and admin hat, as well as any other hats and their streams that are provided.\\n *\\n * This contract should be enabled a module on the Safe for which the role(s) are to be created, and disabled after.\\n *\\n * @dev In order for a Safe to seamlessly create roles even if it has never previously created a role and thus has\\n * no hat tree, we defer the creation of the hat tree and its setup to this contract. This way, in a single tx block,\\n * the resulting topHatId of the newly created hat can be used to create an admin hat and any other hats needed.\\n * We also make use of `KeyValuePairs` to associate the topHatId with the Safe.\\n */\\n function createAndDeclareTree(CreateTreeParams calldata params) public {\\n bytes32 salt = getSalt();\\n\\n (uint256 topHatId, address topHatAccount) = createTopHatAndAccount(\\n params.hatsProtocol,\\n params.topHatDetails,\\n params.topHatImageURI,\\n params.registry,\\n params.hatsAccountImplementation,\\n salt\\n );\\n\\n declareSafeHatTree(params.keyValuePairs, topHatId);\\n\\n (uint256 adminHatId, ) = createHatAndAccountAndMintAndStreams(\\n params.hatsProtocol,\\n topHatId,\\n params.adminHat,\\n topHatAccount,\\n params.registry,\\n params.hatsAccountImplementation,\\n salt\\n );\\n\\n for (uint256 i = 0; i < params.hats.length; ) {\\n createHatAndAccountAndMintAndStreams(\\n params.hatsProtocol,\\n adminHatId,\\n params.hats[i],\\n topHatAccount,\\n params.registry,\\n params.hatsAccountImplementation,\\n salt\\n );\\n\\n unchecked {\\n ++i;\\n }\\n }\\n\\n params.hatsProtocol.transferHat(topHatId, address(this), msg.sender);\\n }\\n}\\n\",\"keccak256\":\"0x1886fc2edf8c34e58f6a95d33139d7513aa4b581a2c323af6394485752137e20\",\"license\":\"MIT\"},\"contracts/interfaces/IERC6551Registry.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.4;\\n\\ninterface IERC6551Registry {\\n /**\\n * @dev Creates a token bound account for a non-fungible token.\\n *\\n * If account has already been created, returns the account address without calling create2.\\n *\\n * Emits ERC6551AccountCreated event.\\n *\\n * @return account The address of the token bound account\\n */\\n function createAccount(\\n address implementation,\\n bytes32 salt,\\n uint256 chainId,\\n address tokenContract,\\n uint256 tokenId\\n ) external returns (address account);\\n}\\n\",\"keccak256\":\"0x64c52de8a8e68398e61dd8b42dda8e9af8cf6abf93bb85629c322440991ea568\",\"license\":\"MIT\"},\"contracts/interfaces/hats/IHats.sol\":{\"content\":\"// SPDX-License-Identifier: AGPL-3.0\\n// Copyright (C) 2023 Haberdasher Labs\\n//\\n// This program is free software: you can redistribute it and/or modify\\n// it under the terms of the GNU Affero General Public License as published by\\n// the Free Software Foundation, either version 3 of the License, or\\n// (at your option) any later version.\\n//\\n// This program is distributed in the hope that it will be useful,\\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\\n// GNU Affero General Public License for more details.\\n//\\n// You should have received a copy of the GNU Affero General Public License\\n// along with this program. If not, see .\\n\\npragma solidity >=0.8.13;\\n\\ninterface IHats {\\n function mintTopHat(\\n address _target,\\n string memory _details,\\n string memory _imageURI\\n ) external returns (uint256 topHatId);\\n\\n function createHat(\\n uint256 _admin,\\n string calldata _details,\\n uint32 _maxSupply,\\n address _eligibility,\\n address _toggle,\\n bool _mutable,\\n string calldata _imageURI\\n ) external returns (uint256 newHatId);\\n\\n function mintHat(\\n uint256 _hatId,\\n address _wearer\\n ) external returns (bool success);\\n\\n function transferHat(uint256 _hatId, address _from, address _to) external;\\n}\\n\",\"keccak256\":\"0x8e35022f5c0fcf0059033abec78ec890f0cf3bbac09d6d24051cff9679239511\",\"license\":\"AGPL-3.0\"},\"contracts/interfaces/sablier/ISablierV2LockupLinear.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport {LockupLinear} from \\\"./LockupLinear.sol\\\";\\nimport {IERC20} from \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\n\\ninterface ISablierV2LockupLinear {\\n function createWithTimestamps(\\n LockupLinear.CreateWithTimestamps calldata params\\n ) external returns (uint256 streamId);\\n}\\n\",\"keccak256\":\"0xf4899637eb2e6c76c35e2d201e56e162a50e6bc7b5b9156e00866f0703ad07ca\",\"license\":\"MIT\"},\"contracts/interfaces/sablier/LockupLinear.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport {IERC20} from \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\n\\nlibrary LockupLinear {\\n struct CreateWithTimestamps {\\n address sender;\\n address recipient;\\n uint128 totalAmount;\\n IERC20 asset;\\n bool cancelable;\\n bool transferable;\\n Timestamps timestamps;\\n Broker broker;\\n }\\n\\n struct Timestamps {\\n uint40 start;\\n uint40 cliff;\\n uint40 end;\\n }\\n\\n struct Broker {\\n address account;\\n uint256 fee;\\n }\\n}\\n\",\"keccak256\":\"0x497fdb52b5e1a5a7e0711a9f7d5fb036eb668ccb92ea908ee088f56ee08a4ce8\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x608060405234801561001057600080fd5b5061158a806100206000396000f3fe608060405234801561001057600080fd5b506004361061004c5760003560e01c806313a9589c146100515780636592b2ac146100845780638c5f591a146100b4578063a3f4df7e146100c9575b600080fd5b6040517f5d0e6ce4fd951366cc55da93f6e79d8b81483109d79676a04bcc2bed6a4b507281526020015b60405180910390f35b610097610092366004610b95565b610105565b604080519283526001600160a01b0390911660208301520161007b565b6100c76100c2366004610c40565b61018f565b005b6100f86040518060400160405280601081526020016f0446563656e74486174735f305f315f360841b81525081565b60405161007b9190610cc8565b6000806101178a8a8a898989896103dc565b6040516329287c1b60e21b8152600481018a905230602482015233604482015291935091506001600160a01b038b169063a4a1f06c90606401600060405180830381600087803b15801561016a57600080fd5b505af115801561017e573d6000803e3d6000fd5b505050509850989650505050505050565b7f5d0e6ce4fd951366cc55da93f6e79d8b81483109d79676a04bcc2bed6a4b507260008061026d6101c36020860186610cdb565b6101d06080870187610cf8565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506102129250505060a0880188610cf8565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610257925050506060890160408a01610cdb565b61026760408a0160208b01610cdb565b8861072b565b909250905061028b6102856080860160608701610cdb565b836107bd565b60006102d261029d6020870187610cdb565b846102ab60c0890189610d45565b856102bc60608b0160408c01610cdb565b6102cc60408c0160208d01610cdb565b8a6103dc565b50905060005b6102e560e0870187610d65565b905081101561035f576103556102fe6020880188610cdb565b8361030c60e08a018a610d65565b8581811061031c5761031c610dae565b905060200281019061032e9190610d45565b8661033f60608c0160408d01610cdb565b61034f60408d0160208e01610cdb565b8b6103dc565b50506001016102d8565b5061036d6020860186610cdb565b6040516329287c1b60e21b8152600481018590523060248201523360448201526001600160a01b03919091169063a4a1f06c90606401600060405180830381600087803b1580156103bd57600080fd5b505af11580156103d1573d6000803e3d6000fd5b505050505050505050565b6000806103f389896103ed8a611112565b8961093d565b91506104028585858c866109cf565b9050600061041660a0890160808a01610cdb565b6001600160a01b0316146104b6576001600160a01b03891663641f776e8361044460a08b0160808c01610cdb565b6040516001600160e01b031960e085901b16815260048101929092526001600160a01b031660248201526044016020604051808303816000875af1158015610490573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104b491906111d6565b505b60005b6104c660a08901896111f3565b905081101561071e5760006104de60a08a018a6111f3565b838181106104ee576104ee610dae565b90506101600201803603810190610505919061123c565b6060810151815160408084015190516001600160a01b0390921660248301526001600160801b03166044820152919250339163468721a7919060009060640160408051601f198184030181529181526020820180516001600160e01b031663095ea7b360e01b1790525160e085901b6001600160e01b031916815261059293929190600090600401611259565b6020604051808303816000875af11580156105b1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105d591906111d6565b50600060405180610100016040528083602001516001600160a01b03168152602001856001600160a01b0316815260200183604001516001600160801b0316815260200183606001516001600160a01b031681526020018360800151151581526020018360a00151151581526020018360c0015181526020018360e001518152509050336001600160a01b031663468721a7836000015160008460405160240161067f91906112af565b60408051601f198184030181529181526020820180516001600160e01b03166353b1572760e01b1790525160e085901b6001600160e01b03191681526106cd93929190600090600401611259565b6020604051808303816000875af11580156106ec573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061071091906111d6565b5082600101925050506104b9565b5097509795505050505050565b600080876001600160a01b0316631a64dfad3089896040518463ffffffff1660e01b815260040161075e93929190611371565b6020604051808303816000875af115801561077d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107a191906113a7565b91506107b08585858b866109cf565b9050965096945050505050565b604080516001808252818301909252600091816020015b60608152602001906001900390816107d457505060408051600180825281830190925291925060009190602082015b6060815260200190600190039081610803579050509050604051806040016040528060088152602001671d1bdc12185d125960c21b8152508260008151811061084e5761084e610dae565b602002602001018190525061086283610a65565b8160008151811061087557610875610dae565b6020026020010181905250336001600160a01b031663468721a785600085856040516024016108a5929190611415565b60408051601f198184030181529181526020820180516001600160e01b031663579374b960e11b1790525160e085901b6001600160e01b03191681526108f393929190600090600401611259565b6020604051808303816000875af1158015610912573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061093691906111d6565b5050505050565b6020820151825160608401516040808601519051635829492f60e11b81526000946001600160a01b038a169463b052925e94610983948b948a928392909160040161143a565b6020604051808303816000875af11580156109a2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109c691906113a7565b95945050505050565b604051638a54c52f60e01b81526001600160a01b0385811660048301526024820185905246604483015283811660648301526084820183905260009190871690638a54c52f9060a4016020604051808303816000875af1158015610a37573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a5b919061149e565b9695505050505050565b606081600003610a8c5750506040805180820190915260018152600360fc1b602082015290565b8160005b8115610ab65780610aa0816114d1565b9150610aaf9050600a83611500565b9150610a90565b6000816001600160401b03811115610ad057610ad0610dc4565b6040519080825280601f01601f191660200182016040528015610afa576020820181803683370190505b5090505b8415610b6557610b0f600183611514565b9150610b1c600a8661152d565b610b27906030611541565b60f81b818381518110610b3c57610b3c610dae565b60200101906001600160f81b031916908160001a905350610b5e600a86611500565b9450610afe565b949350505050565b6001600160a01b0381168114610b8257600080fd5b50565b8035610b9081610b6d565b919050565b600080600080600080600080610100898b031215610bb257600080fd5b8835610bbd81610b6d565b97506020890135965060408901356001600160401b03811115610bdf57600080fd5b890160c0818c031215610bf157600080fd5b9550606089013594506080890135610c0881610b6d565b935060a0890135610c1881610b6d565b925060c0890135610c2881610b6d565b8092505060e089013590509295985092959890939650565b600060208284031215610c5257600080fd5b81356001600160401b03811115610c6857600080fd5b82016101008185031215610c7b57600080fd5b9392505050565b6000815180845260005b81811015610ca857602081850181015186830182015201610c8c565b506000602082860101526020601f19601f83011685010191505092915050565b602081526000610c7b6020830184610c82565b600060208284031215610ced57600080fd5b8135610c7b81610b6d565b6000808335601e19843603018112610d0f57600080fd5b8301803591506001600160401b03821115610d2957600080fd5b602001915036819003821315610d3e57600080fd5b9250929050565b6000823560be19833603018112610d5b57600080fd5b9190910192915050565b6000808335601e19843603018112610d7c57600080fd5b8301803591506001600160401b03821115610d9657600080fd5b6020019150600581901b3603821315610d3e57600080fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b60405160c081016001600160401b0381118282101715610dfc57610dfc610dc4565b60405290565b604051601f8201601f191681016001600160401b0381118282101715610e2a57610e2a610dc4565b604052919050565b803563ffffffff81168114610b9057600080fd5b600082601f830112610e5757600080fd5b81356001600160401b03811115610e7057610e70610dc4565b610e83601f8201601f1916602001610e02565b818152846020838601011115610e9857600080fd5b816020850160208301376000918101602001919091529392505050565b8015158114610b8257600080fd5b8035610b9081610eb5565b80356001600160801b0381168114610b9057600080fd5b803564ffffffffff81168114610b9057600080fd5b600060608284031215610f0c57600080fd5b604051606081018181106001600160401b0382111715610f2e57610f2e610dc4565b604052905080610f3d83610ee5565b8152610f4b60208401610ee5565b6020820152610f5c60408401610ee5565b60408201525092915050565b600060408284031215610f7a57600080fd5b604051604081018181106001600160401b0382111715610f9c57610f9c610dc4565b6040529050808235610fad81610b6d565b8152602092830135920191909152919050565b60006101608284031215610fd357600080fd5b60405161010081018181106001600160401b0382111715610ff657610ff6610dc4565b60405290508061100583610b85565b815261101360208401610b85565b602082015261102460408401610ece565b604082015261103560608401610b85565b606082015261104660808401610ec3565b608082015261105760a08401610ec3565b60a08201526110698460c08501610efa565b60c082015261107c846101208501610f68565b60e08201525092915050565b600082601f83011261109957600080fd5b813560206001600160401b038211156110b4576110b4610dc4565b6110c2818360051b01610e02565b82815261016092830285018201928282019190878511156110e257600080fd5b8387015b85811015611105576110f88982610fc0565b84529284019281016110e6565b5090979650505050505050565b600060c0823603121561112457600080fd5b61112c610dda565b61113583610e32565b815260208301356001600160401b038082111561115157600080fd5b61115d36838701610e46565b6020840152604085013591508082111561117657600080fd5b61118236838701610e46565b604084015261119360608601610ec3565b60608401526111a460808601610b85565b608084015260a08501359150808211156111bd57600080fd5b506111ca36828601611088565b60a08301525092915050565b6000602082840312156111e857600080fd5b8151610c7b81610eb5565b6000808335601e1984360301811261120a57600080fd5b8301803591506001600160401b0382111561122457600080fd5b602001915061016081023603821315610d3e57600080fd5b6000610160828403121561124f57600080fd5b610c7b8383610fc0565b60018060a01b03851681528360208201526080604082015260006112806080830185610c82565b9050600283106112a057634e487b7160e01b600052602160045260246000fd5b82606083015295945050505050565b81516001600160a01b0390811682526020808401518216908301526040808401516001600160801b031690830152606080840151909116908201526080808301516101608301916113039084018215159052565b5060a083015161131760a084018215159052565b5060c083015161134a60c0840182805164ffffffffff908116835260208083015182169084015260409182015116910152565b5060e0929092015180516001600160a01b0316610120830152602001516101409091015290565b6001600160a01b038416815260606020820181905260009061139590830185610c82565b8281036040840152610a5b8185610c82565b6000602082840312156113b957600080fd5b5051919050565b600081518084526020808501808196508360051b8101915082860160005b858110156114085782840389526113f6848351610c82565b988501989350908401906001016113de565b5091979650505050505050565b60408152600061142860408301856113c0565b82810360208401526109c681856113c0565b87815260e06020820152600061145360e0830189610c82565b63ffffffff881660408401526001600160a01b0387811660608501528616608084015284151560a084015282810360c08401526114908185610c82565b9a9950505050505050505050565b6000602082840312156114b057600080fd5b8151610c7b81610b6d565b634e487b7160e01b600052601160045260246000fd5b6000600182016114e3576114e36114bb565b5060010190565b634e487b7160e01b600052601260045260246000fd5b60008261150f5761150f6114ea565b500490565b81810381811115611527576115276114bb565b92915050565b60008261153c5761153c6114ea565b500690565b80820180821115611527576115276114bb56fea26469706673582212208431b5cb9e9defda60834dc065f918f11d92dcbf19aba7475b779059a216011d64736f6c63430008130033", + "deployedBytecode": "0x608060405234801561001057600080fd5b506004361061004c5760003560e01c806313a9589c146100515780636592b2ac146100845780638c5f591a146100b4578063a3f4df7e146100c9575b600080fd5b6040517f5d0e6ce4fd951366cc55da93f6e79d8b81483109d79676a04bcc2bed6a4b507281526020015b60405180910390f35b610097610092366004610b95565b610105565b604080519283526001600160a01b0390911660208301520161007b565b6100c76100c2366004610c40565b61018f565b005b6100f86040518060400160405280601081526020016f0446563656e74486174735f305f315f360841b81525081565b60405161007b9190610cc8565b6000806101178a8a8a898989896103dc565b6040516329287c1b60e21b8152600481018a905230602482015233604482015291935091506001600160a01b038b169063a4a1f06c90606401600060405180830381600087803b15801561016a57600080fd5b505af115801561017e573d6000803e3d6000fd5b505050509850989650505050505050565b7f5d0e6ce4fd951366cc55da93f6e79d8b81483109d79676a04bcc2bed6a4b507260008061026d6101c36020860186610cdb565b6101d06080870187610cf8565b8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506102129250505060a0880188610cf8565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610257925050506060890160408a01610cdb565b61026760408a0160208b01610cdb565b8861072b565b909250905061028b6102856080860160608701610cdb565b836107bd565b60006102d261029d6020870187610cdb565b846102ab60c0890189610d45565b856102bc60608b0160408c01610cdb565b6102cc60408c0160208d01610cdb565b8a6103dc565b50905060005b6102e560e0870187610d65565b905081101561035f576103556102fe6020880188610cdb565b8361030c60e08a018a610d65565b8581811061031c5761031c610dae565b905060200281019061032e9190610d45565b8661033f60608c0160408d01610cdb565b61034f60408d0160208e01610cdb565b8b6103dc565b50506001016102d8565b5061036d6020860186610cdb565b6040516329287c1b60e21b8152600481018590523060248201523360448201526001600160a01b03919091169063a4a1f06c90606401600060405180830381600087803b1580156103bd57600080fd5b505af11580156103d1573d6000803e3d6000fd5b505050505050505050565b6000806103f389896103ed8a611112565b8961093d565b91506104028585858c866109cf565b9050600061041660a0890160808a01610cdb565b6001600160a01b0316146104b6576001600160a01b03891663641f776e8361044460a08b0160808c01610cdb565b6040516001600160e01b031960e085901b16815260048101929092526001600160a01b031660248201526044016020604051808303816000875af1158015610490573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104b491906111d6565b505b60005b6104c660a08901896111f3565b905081101561071e5760006104de60a08a018a6111f3565b838181106104ee576104ee610dae565b90506101600201803603810190610505919061123c565b6060810151815160408084015190516001600160a01b0390921660248301526001600160801b03166044820152919250339163468721a7919060009060640160408051601f198184030181529181526020820180516001600160e01b031663095ea7b360e01b1790525160e085901b6001600160e01b031916815261059293929190600090600401611259565b6020604051808303816000875af11580156105b1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105d591906111d6565b50600060405180610100016040528083602001516001600160a01b03168152602001856001600160a01b0316815260200183604001516001600160801b0316815260200183606001516001600160a01b031681526020018360800151151581526020018360a00151151581526020018360c0015181526020018360e001518152509050336001600160a01b031663468721a7836000015160008460405160240161067f91906112af565b60408051601f198184030181529181526020820180516001600160e01b03166353b1572760e01b1790525160e085901b6001600160e01b03191681526106cd93929190600090600401611259565b6020604051808303816000875af11580156106ec573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061071091906111d6565b5082600101925050506104b9565b5097509795505050505050565b600080876001600160a01b0316631a64dfad3089896040518463ffffffff1660e01b815260040161075e93929190611371565b6020604051808303816000875af115801561077d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107a191906113a7565b91506107b08585858b866109cf565b9050965096945050505050565b604080516001808252818301909252600091816020015b60608152602001906001900390816107d457505060408051600180825281830190925291925060009190602082015b6060815260200190600190039081610803579050509050604051806040016040528060088152602001671d1bdc12185d125960c21b8152508260008151811061084e5761084e610dae565b602002602001018190525061086283610a65565b8160008151811061087557610875610dae565b6020026020010181905250336001600160a01b031663468721a785600085856040516024016108a5929190611415565b60408051601f198184030181529181526020820180516001600160e01b031663579374b960e11b1790525160e085901b6001600160e01b03191681526108f393929190600090600401611259565b6020604051808303816000875af1158015610912573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061093691906111d6565b5050505050565b6020820151825160608401516040808601519051635829492f60e11b81526000946001600160a01b038a169463b052925e94610983948b948a928392909160040161143a565b6020604051808303816000875af11580156109a2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109c691906113a7565b95945050505050565b604051638a54c52f60e01b81526001600160a01b0385811660048301526024820185905246604483015283811660648301526084820183905260009190871690638a54c52f9060a4016020604051808303816000875af1158015610a37573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a5b919061149e565b9695505050505050565b606081600003610a8c5750506040805180820190915260018152600360fc1b602082015290565b8160005b8115610ab65780610aa0816114d1565b9150610aaf9050600a83611500565b9150610a90565b6000816001600160401b03811115610ad057610ad0610dc4565b6040519080825280601f01601f191660200182016040528015610afa576020820181803683370190505b5090505b8415610b6557610b0f600183611514565b9150610b1c600a8661152d565b610b27906030611541565b60f81b818381518110610b3c57610b3c610dae565b60200101906001600160f81b031916908160001a905350610b5e600a86611500565b9450610afe565b949350505050565b6001600160a01b0381168114610b8257600080fd5b50565b8035610b9081610b6d565b919050565b600080600080600080600080610100898b031215610bb257600080fd5b8835610bbd81610b6d565b97506020890135965060408901356001600160401b03811115610bdf57600080fd5b890160c0818c031215610bf157600080fd5b9550606089013594506080890135610c0881610b6d565b935060a0890135610c1881610b6d565b925060c0890135610c2881610b6d565b8092505060e089013590509295985092959890939650565b600060208284031215610c5257600080fd5b81356001600160401b03811115610c6857600080fd5b82016101008185031215610c7b57600080fd5b9392505050565b6000815180845260005b81811015610ca857602081850181015186830182015201610c8c565b506000602082860101526020601f19601f83011685010191505092915050565b602081526000610c7b6020830184610c82565b600060208284031215610ced57600080fd5b8135610c7b81610b6d565b6000808335601e19843603018112610d0f57600080fd5b8301803591506001600160401b03821115610d2957600080fd5b602001915036819003821315610d3e57600080fd5b9250929050565b6000823560be19833603018112610d5b57600080fd5b9190910192915050565b6000808335601e19843603018112610d7c57600080fd5b8301803591506001600160401b03821115610d9657600080fd5b6020019150600581901b3603821315610d3e57600080fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b60405160c081016001600160401b0381118282101715610dfc57610dfc610dc4565b60405290565b604051601f8201601f191681016001600160401b0381118282101715610e2a57610e2a610dc4565b604052919050565b803563ffffffff81168114610b9057600080fd5b600082601f830112610e5757600080fd5b81356001600160401b03811115610e7057610e70610dc4565b610e83601f8201601f1916602001610e02565b818152846020838601011115610e9857600080fd5b816020850160208301376000918101602001919091529392505050565b8015158114610b8257600080fd5b8035610b9081610eb5565b80356001600160801b0381168114610b9057600080fd5b803564ffffffffff81168114610b9057600080fd5b600060608284031215610f0c57600080fd5b604051606081018181106001600160401b0382111715610f2e57610f2e610dc4565b604052905080610f3d83610ee5565b8152610f4b60208401610ee5565b6020820152610f5c60408401610ee5565b60408201525092915050565b600060408284031215610f7a57600080fd5b604051604081018181106001600160401b0382111715610f9c57610f9c610dc4565b6040529050808235610fad81610b6d565b8152602092830135920191909152919050565b60006101608284031215610fd357600080fd5b60405161010081018181106001600160401b0382111715610ff657610ff6610dc4565b60405290508061100583610b85565b815261101360208401610b85565b602082015261102460408401610ece565b604082015261103560608401610b85565b606082015261104660808401610ec3565b608082015261105760a08401610ec3565b60a08201526110698460c08501610efa565b60c082015261107c846101208501610f68565b60e08201525092915050565b600082601f83011261109957600080fd5b813560206001600160401b038211156110b4576110b4610dc4565b6110c2818360051b01610e02565b82815261016092830285018201928282019190878511156110e257600080fd5b8387015b85811015611105576110f88982610fc0565b84529284019281016110e6565b5090979650505050505050565b600060c0823603121561112457600080fd5b61112c610dda565b61113583610e32565b815260208301356001600160401b038082111561115157600080fd5b61115d36838701610e46565b6020840152604085013591508082111561117657600080fd5b61118236838701610e46565b604084015261119360608601610ec3565b60608401526111a460808601610b85565b608084015260a08501359150808211156111bd57600080fd5b506111ca36828601611088565b60a08301525092915050565b6000602082840312156111e857600080fd5b8151610c7b81610eb5565b6000808335601e1984360301811261120a57600080fd5b8301803591506001600160401b0382111561122457600080fd5b602001915061016081023603821315610d3e57600080fd5b6000610160828403121561124f57600080fd5b610c7b8383610fc0565b60018060a01b03851681528360208201526080604082015260006112806080830185610c82565b9050600283106112a057634e487b7160e01b600052602160045260246000fd5b82606083015295945050505050565b81516001600160a01b0390811682526020808401518216908301526040808401516001600160801b031690830152606080840151909116908201526080808301516101608301916113039084018215159052565b5060a083015161131760a084018215159052565b5060c083015161134a60c0840182805164ffffffffff908116835260208083015182169084015260409182015116910152565b5060e0929092015180516001600160a01b0316610120830152602001516101409091015290565b6001600160a01b038416815260606020820181905260009061139590830185610c82565b8281036040840152610a5b8185610c82565b6000602082840312156113b957600080fd5b5051919050565b600081518084526020808501808196508360051b8101915082860160005b858110156114085782840389526113f6848351610c82565b988501989350908401906001016113de565b5091979650505050505050565b60408152600061142860408301856113c0565b82810360208401526109c681856113c0565b87815260e06020820152600061145360e0830189610c82565b63ffffffff881660408401526001600160a01b0387811660608501528616608084015284151560a084015282810360c08401526114908185610c82565b9a9950505050505050505050565b6000602082840312156114b057600080fd5b8151610c7b81610b6d565b634e487b7160e01b600052601160045260246000fd5b6000600182016114e3576114e36114bb565b5060010190565b634e487b7160e01b600052601260045260246000fd5b60008261150f5761150f6114ea565b500490565b81810381811115611527576115276114bb565b92915050565b60008261153c5761153c6114ea565b500690565b80820180821115611527576115276114bb56fea26469706673582212208431b5cb9e9defda60834dc065f918f11d92dcbf19aba7475b779059a216011d64736f6c63430008130033", "devdoc": { "kind": "dev", - "methods": {}, + "methods": { + "createAndDeclareTree((address,address,address,address,string,string,(uint32,string,string,bool,address,(address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256))[]),(uint32,string,string,bool,address,(address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256))[])[]))": { + "details": "In order for a Safe to seamlessly create roles even if it has never previously created a role and thus has no hat tree, we defer the creation of the hat tree and its setup to this contract. This way, in a single tx block, the resulting topHatId of the newly created hat can be used to create an admin hat and any other hats needed. We also make use of `KeyValuePairs` to associate the topHatId with the Safe." + }, + "createRoleHat(address,uint256,(uint32,string,string,bool,address,(address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256))[]),uint256,address,address,address,bytes32)": { + "details": "Role hat creation, minting, smart account creation and stream creation are handled here in order to avoid a race condition where not more than one active proposal to create a new role can exist at a time. See: https://github.com/decentdao/decent-interface/issues/2402" + } + }, "version": 1 }, "userdoc": { "kind": "user", - "methods": {}, + "methods": { + "createAndDeclareTree((address,address,address,address,string,string,(uint32,string,string,bool,address,(address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256))[]),(uint32,string,string,bool,address,(address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256))[])[]))": { + "notice": "For a safe without any roles previously created on it, this function should be called. It sets up the top hat and admin hat, as well as any other hats and their streams that are provided. This contract should be enabled a module on the Safe for which the role(s) are to be created, and disabled after." + }, + "createRoleHat(address,uint256,(uint32,string,string,bool,address,(address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256))[]),uint256,address,address,address,bytes32)": { + "notice": "Creates a new role hat and any streams on it. This contract should be enabled a module on the Safe for which the role is to be created, and disable after. In order for the module to be able to create hats on behalf of the Safe, the Safe must first transfer its top hat to this contract. This function transfers the top hat back to the Safe after creating the role hat. The function simply calls `createHatAndAccountAndMintAndStreams` and then transfers the top hat back to the Safe." + } + }, "version": 1 }, "storageLayout": { diff --git a/deployments/sepolia/solcInputs/4754a2f0c9d6a191a066af246491b62a.json b/deployments/sepolia/solcInputs/4754a2f0c9d6a191a066af246491b62a.json new file mode 100644 index 00000000..87cba363 --- /dev/null +++ b/deployments/sepolia/solcInputs/4754a2f0c9d6a191a066af246491b62a.json @@ -0,0 +1,59 @@ +{ + "language": "Solidity", + "sources": { + "@gnosis.pm/safe-contracts/contracts/common/Enum.sol": { + "content": "// SPDX-License-Identifier: LGPL-3.0-only\npragma solidity >=0.7.0 <0.9.0;\n\n/// @title Enum - Collection of enums\n/// @author Richard Meissner - \ncontract Enum {\n enum Operation {Call, DelegateCall}\n}\n" + }, + "@gnosis.pm/zodiac/contracts/interfaces/IAvatar.sol": { + "content": "// SPDX-License-Identifier: LGPL-3.0-only\n\n/// @title Zodiac Avatar - A contract that manages modules that can execute transactions via this contract.\npragma solidity >=0.7.0 <0.9.0;\n\nimport \"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\";\n\ninterface IAvatar {\n event EnabledModule(address module);\n event DisabledModule(address module);\n event ExecutionFromModuleSuccess(address indexed module);\n event ExecutionFromModuleFailure(address indexed module);\n\n /// @dev Enables a module on the avatar.\n /// @notice Can only be called by the avatar.\n /// @notice Modules should be stored as a linked list.\n /// @notice Must emit EnabledModule(address module) if successful.\n /// @param module Module to be enabled.\n function enableModule(address module) external;\n\n /// @dev Disables a module on the avatar.\n /// @notice Can only be called by the avatar.\n /// @notice Must emit DisabledModule(address module) if successful.\n /// @param prevModule Address that pointed to the module to be removed in the linked list\n /// @param module Module to be removed.\n function disableModule(address prevModule, address module) external;\n\n /// @dev Allows a Module to execute a transaction.\n /// @notice Can only be called by an enabled module.\n /// @notice Must emit ExecutionFromModuleSuccess(address module) if successful.\n /// @notice Must emit ExecutionFromModuleFailure(address module) if unsuccessful.\n /// @param to Destination address of module transaction.\n /// @param value Ether value of module transaction.\n /// @param data Data payload of module transaction.\n /// @param operation Operation type of module transaction: 0 == call, 1 == delegate call.\n function execTransactionFromModule(\n address to,\n uint256 value,\n bytes memory data,\n Enum.Operation operation\n ) external returns (bool success);\n\n /// @dev Allows a Module to execute a transaction and return data\n /// @notice Can only be called by an enabled module.\n /// @notice Must emit ExecutionFromModuleSuccess(address module) if successful.\n /// @notice Must emit ExecutionFromModuleFailure(address module) if unsuccessful.\n /// @param to Destination address of module transaction.\n /// @param value Ether value of module transaction.\n /// @param data Data payload of module transaction.\n /// @param operation Operation type of module transaction: 0 == call, 1 == delegate call.\n function execTransactionFromModuleReturnData(\n address to,\n uint256 value,\n bytes memory data,\n Enum.Operation operation\n ) external returns (bool success, bytes memory returnData);\n\n /// @dev Returns if an module is enabled\n /// @return True if the module is enabled\n function isModuleEnabled(address module) external view returns (bool);\n\n /// @dev Returns array of modules.\n /// @param start Start of the page.\n /// @param pageSize Maximum number of modules that should be returned.\n /// @return array Array of modules.\n /// @return next Start of the next page.\n function getModulesPaginated(address start, uint256 pageSize)\n external\n view\n returns (address[] memory array, address next);\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/IERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20 {\n /**\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\n * another (`to`).\n *\n * Note that `value` may be zero.\n */\n event Transfer(address indexed from, address indexed to, uint256 value);\n\n /**\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\n * a call to {approve}. `value` is the new allowance.\n */\n event Approval(address indexed owner, address indexed spender, uint256 value);\n\n /**\n * @dev Returns the amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by `account`.\n */\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * @dev Moves `amount` tokens from the caller's account to `to`.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transfer(address to, uint256 amount) external returns (bool);\n\n /**\n * @dev Returns the remaining number of tokens that `spender` will be\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\n * zero by default.\n *\n * This value changes when {approve} or {transferFrom} are called.\n */\n function allowance(address owner, address spender) external view returns (uint256);\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\n * that someone may use both the old and the new allowance by unfortunate\n * transaction ordering. One possible solution to mitigate this race\n * condition is to first reduce the spender's allowance to 0 and set the\n * desired value afterwards:\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n *\n * Emits an {Approval} event.\n */\n function approve(address spender, uint256 amount) external returns (bool);\n\n /**\n * @dev Moves `amount` tokens from `from` to `to` using the\n * allowance mechanism. `amount` is then deducted from the caller's\n * allowance.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(\n address from,\n address to,\n uint256 amount\n ) external returns (bool);\n}\n" + }, + "@openzeppelin/contracts/utils/Strings.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _HEX_SYMBOLS = \"0123456789abcdef\";\n uint8 private constant _ADDRESS_LENGTH = 20;\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n // Inspired by OraclizeAPI's implementation - MIT licence\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\n\n if (value == 0) {\n return \"0\";\n }\n uint256 temp = value;\n uint256 digits;\n while (temp != 0) {\n digits++;\n temp /= 10;\n }\n bytes memory buffer = new bytes(digits);\n while (value != 0) {\n digits -= 1;\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\n value /= 10;\n }\n return string(buffer);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n if (value == 0) {\n return \"0x00\";\n }\n uint256 temp = value;\n uint256 length = 0;\n while (temp != 0) {\n length++;\n temp >>= 8;\n }\n return toHexString(value, length);\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i > 1; --i) {\n buffer[i] = _HEX_SYMBOLS[value & 0xf];\n value >>= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n\n /**\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\n */\n function toHexString(address addr) internal pure returns (string memory) {\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\n }\n}\n" + }, + "contracts/DecentHats_0_1_0.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity =0.8.19;\n\nimport {Enum} from \"@gnosis.pm/safe-contracts/contracts/common/Enum.sol\";\nimport {IAvatar} from \"@gnosis.pm/zodiac/contracts/interfaces/IAvatar.sol\";\nimport {Strings} from \"@openzeppelin/contracts/utils/Strings.sol\";\nimport {IERC20} from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport {IERC6551Registry} from \"./interfaces/IERC6551Registry.sol\";\nimport {IHats} from \"./interfaces/hats/IHats.sol\";\nimport {ISablierV2LockupLinear} from \"./interfaces/sablier/ISablierV2LockupLinear.sol\";\nimport {LockupLinear} from \"./interfaces/sablier/LockupLinear.sol\";\n\ncontract DecentHats_0_1_0 {\n string public constant NAME = \"DecentHats_0_1_0\";\n\n struct SablierStreamParams {\n ISablierV2LockupLinear sablier;\n address sender;\n uint128 totalAmount;\n address asset;\n bool cancelable;\n bool transferable;\n LockupLinear.Timestamps timestamps;\n LockupLinear.Broker broker;\n }\n\n struct Hat {\n uint32 maxSupply;\n string details;\n string imageURI;\n bool isMutable;\n address wearer;\n SablierStreamParams[] sablierParams; // Optional Sablier stream parameters\n }\n\n struct CreateTreeParams {\n IHats hatsProtocol;\n address hatsAccountImplementation;\n IERC6551Registry registry;\n address keyValuePairs;\n string topHatDetails;\n string topHatImageURI;\n Hat adminHat;\n Hat[] hats;\n }\n\n function getSalt() public pure returns (bytes32 salt) {\n return\n 0x5d0e6ce4fd951366cc55da93f6e79d8b81483109d79676a04bcc2bed6a4b5072;\n }\n\n function declareSafeHatTree(\n address _keyValuePairs,\n uint256 topHatId\n ) internal {\n string[] memory keys = new string[](1);\n string[] memory values = new string[](1);\n keys[0] = \"topHatId\";\n values[0] = Strings.toString(topHatId);\n\n IAvatar(msg.sender).execTransactionFromModule(\n _keyValuePairs,\n 0,\n abi.encodeWithSignature(\n \"updateValues(string[],string[])\",\n keys,\n values\n ),\n Enum.Operation.Call\n );\n }\n\n function createHat(\n IHats _hatsProtocol,\n uint256 adminHatId,\n Hat memory _hat,\n address topHatAccount\n ) internal returns (uint256) {\n return\n _hatsProtocol.createHat(\n adminHatId,\n _hat.details,\n _hat.maxSupply,\n topHatAccount,\n topHatAccount,\n _hat.isMutable,\n _hat.imageURI\n );\n }\n\n function createAccount(\n IERC6551Registry _registry,\n address _hatsAccountImplementation,\n bytes32 salt,\n address protocolAddress,\n uint256 hatId\n ) internal returns (address) {\n return\n _registry.createAccount(\n _hatsAccountImplementation,\n salt,\n block.chainid,\n protocolAddress,\n hatId\n );\n }\n\n function createTopHatAndAccount(\n IHats _hatsProtocol,\n string memory _topHatDetails,\n string memory _topHatImageURI,\n IERC6551Registry _registry,\n address _hatsAccountImplementation,\n bytes32 salt\n ) internal returns (uint256 topHatId, address topHatAccount) {\n topHatId = _hatsProtocol.mintTopHat(\n address(this),\n _topHatDetails,\n _topHatImageURI\n );\n\n topHatAccount = createAccount(\n _registry,\n _hatsAccountImplementation,\n salt,\n address(_hatsProtocol),\n topHatId\n );\n }\n\n function createHatAndAccountAndMintAndStreams(\n IHats hatsProtocol,\n uint256 adminHatId,\n Hat calldata hat,\n address topHatAccount,\n IERC6551Registry registry,\n address hatsAccountImplementation,\n bytes32 salt\n ) internal returns (uint256 hatId, address accountAddress) {\n hatId = createHat(hatsProtocol, adminHatId, hat, topHatAccount);\n\n accountAddress = createAccount(\n registry,\n hatsAccountImplementation,\n salt,\n address(hatsProtocol),\n hatId\n );\n\n if (hat.wearer != address(0)) {\n hatsProtocol.mintHat(hatId, hat.wearer);\n }\n\n for (uint256 i = 0; i < hat.sablierParams.length; ) {\n SablierStreamParams memory sablierParams = hat.sablierParams[i];\n\n // Approve tokens for Sablier\n IAvatar(msg.sender).execTransactionFromModule(\n sablierParams.asset,\n 0,\n abi.encodeWithSignature(\n \"approve(address,uint256)\",\n address(sablierParams.sablier),\n sablierParams.totalAmount\n ),\n Enum.Operation.Call\n );\n\n LockupLinear.CreateWithTimestamps memory params = LockupLinear\n .CreateWithTimestamps({\n sender: sablierParams.sender,\n recipient: accountAddress,\n totalAmount: sablierParams.totalAmount,\n asset: IERC20(sablierParams.asset),\n cancelable: sablierParams.cancelable,\n transferable: sablierParams.transferable,\n timestamps: sablierParams.timestamps,\n broker: sablierParams.broker\n });\n\n // Proxy the Sablier call through IAvatar\n IAvatar(msg.sender).execTransactionFromModule(\n address(sablierParams.sablier),\n 0,\n abi.encodeWithSignature(\n \"createWithTimestamps((address,address,uint128,address,bool,bool,(uint40,uint40,uint40),(address,uint256)))\",\n params\n ),\n Enum.Operation.Call\n );\n\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * Creates a new role hat and any streams on it.\n *\n * This contract should be enabled a module on the Safe for which the role is to be created, and disable after.\n * In order for the module to be able to create hats on behalf of the Safe, the Safe must first\n * transfer its top hat to this contract. This function transfers the top hat back to the Safe after\n * creating the role hat.\n *\n * The function simply calls `createHatAndAccountAndMintAndStreams` and then transfers the top hat back to the Safe.\n *\n * @dev Role hat creation, minting, smart account creation and stream creation are handled here in order\n * to avoid a race condition where not more than one active proposal to create a new role can exist at a time.\n * See: https://github.com/decentdao/decent-interface/issues/2402\n */\n function createRoleHat(\n IHats hatsProtocol,\n uint256 adminHatId,\n Hat calldata hat,\n uint256 topHatId,\n address topHatAccount,\n IERC6551Registry registry,\n address hatsAccountImplementation,\n bytes32 salt\n ) public returns (uint256 hatId, address accountAddress) {\n (hatId, accountAddress) = createHatAndAccountAndMintAndStreams(\n hatsProtocol,\n adminHatId,\n hat,\n topHatAccount,\n registry,\n hatsAccountImplementation,\n salt\n );\n\n hatsProtocol.transferHat(topHatId, address(this), msg.sender);\n }\n\n /**\n * For a safe without any roles previously created on it, this function should be called. It sets up the\n * top hat and admin hat, as well as any other hats and their streams that are provided.\n *\n * This contract should be enabled a module on the Safe for which the role(s) are to be created, and disabled after.\n *\n * @dev In order for a Safe to seamlessly create roles even if it has never previously created a role and thus has\n * no hat tree, we defer the creation of the hat tree and its setup to this contract. This way, in a single tx block,\n * the resulting topHatId of the newly created hat can be used to create an admin hat and any other hats needed.\n * We also make use of `KeyValuePairs` to associate the topHatId with the Safe.\n */\n function createAndDeclareTree(CreateTreeParams calldata params) public {\n bytes32 salt = getSalt();\n\n (uint256 topHatId, address topHatAccount) = createTopHatAndAccount(\n params.hatsProtocol,\n params.topHatDetails,\n params.topHatImageURI,\n params.registry,\n params.hatsAccountImplementation,\n salt\n );\n\n declareSafeHatTree(params.keyValuePairs, topHatId);\n\n (uint256 adminHatId, ) = createHatAndAccountAndMintAndStreams(\n params.hatsProtocol,\n topHatId,\n params.adminHat,\n topHatAccount,\n params.registry,\n params.hatsAccountImplementation,\n salt\n );\n\n for (uint256 i = 0; i < params.hats.length; ) {\n createHatAndAccountAndMintAndStreams(\n params.hatsProtocol,\n adminHatId,\n params.hats[i],\n topHatAccount,\n params.registry,\n params.hatsAccountImplementation,\n salt\n );\n\n unchecked {\n ++i;\n }\n }\n\n params.hatsProtocol.transferHat(topHatId, address(this), msg.sender);\n }\n}\n" + }, + "contracts/interfaces/hats/IHats.sol": { + "content": "// SPDX-License-Identifier: AGPL-3.0\n// Copyright (C) 2023 Haberdasher Labs\n//\n// This program is free software: you can redistribute it and/or modify\n// it under the terms of the GNU Affero General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU Affero General Public License for more details.\n//\n// You should have received a copy of the GNU Affero General Public License\n// along with this program. If not, see .\n\npragma solidity >=0.8.13;\n\ninterface IHats {\n function mintTopHat(\n address _target,\n string memory _details,\n string memory _imageURI\n ) external returns (uint256 topHatId);\n\n function createHat(\n uint256 _admin,\n string calldata _details,\n uint32 _maxSupply,\n address _eligibility,\n address _toggle,\n bool _mutable,\n string calldata _imageURI\n ) external returns (uint256 newHatId);\n\n function mintHat(\n uint256 _hatId,\n address _wearer\n ) external returns (bool success);\n\n function transferHat(uint256 _hatId, address _from, address _to) external;\n}\n" + }, + "contracts/interfaces/IERC6551Registry.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.4;\n\ninterface IERC6551Registry {\n /**\n * @dev Creates a token bound account for a non-fungible token.\n *\n * If account has already been created, returns the account address without calling create2.\n *\n * Emits ERC6551AccountCreated event.\n *\n * @return account The address of the token bound account\n */\n function createAccount(\n address implementation,\n bytes32 salt,\n uint256 chainId,\n address tokenContract,\n uint256 tokenId\n ) external returns (address account);\n}\n" + }, + "contracts/interfaces/sablier/ISablierV2LockupLinear.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport {LockupLinear} from \"./LockupLinear.sol\";\nimport {IERC20} from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\n\ninterface ISablierV2LockupLinear {\n function createWithTimestamps(\n LockupLinear.CreateWithTimestamps calldata params\n ) external returns (uint256 streamId);\n}\n" + }, + "contracts/interfaces/sablier/LockupLinear.sol": { + "content": "// SPDX-License-Identifier: MIT\npragma solidity ^0.8.0;\n\nimport {IERC20} from \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\n\nlibrary LockupLinear {\n struct CreateWithTimestamps {\n address sender;\n address recipient;\n uint128 totalAmount;\n IERC20 asset;\n bool cancelable;\n bool transferable;\n Timestamps timestamps;\n Broker broker;\n }\n\n struct Timestamps {\n uint40 start;\n uint40 cliff;\n uint40 end;\n }\n\n struct Broker {\n address account;\n uint256 fee;\n }\n}\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200 + }, + "outputSelection": { + "*": { + "*": [ + "abi", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers", + "metadata", + "devdoc", + "userdoc", + "storageLayout", + "evm.gasEstimates" + ], + "": [ + "ast" + ] + } + }, + "metadata": { + "useLiteralContent": true + } + } +} \ No newline at end of file From 71561027934dc272d16aa2601959d28378de2fad Mon Sep 17 00:00:00 2001 From: Kellar Date: Fri, 25 Oct 2024 17:48:56 +0100 Subject: [PATCH 2/3] build bump --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 55e0d734..4c69e695 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@fractal-framework/fractal-contracts", - "version": "1.2.16", + "version": "1.2.17", "files": [ "publish", "contracts", From 3728ff6ae7db89a8afdc629953795957a5736984 Mon Sep 17 00:00:00 2001 From: Adam Gall Date: Fri, 25 Oct 2024 14:37:06 -0400 Subject: [PATCH 3/3] Bump version in package-lock --- package-lock.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package-lock.json b/package-lock.json index 5d05df06..09c4854d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@fractal-framework/fractal-contracts", - "version": "1.2.16", + "version": "1.2.17", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@fractal-framework/fractal-contracts", - "version": "1.2.16", + "version": "1.2.17", "license": "MIT", "dependencies": { "@gnosis.pm/zodiac": "^1.1.4",