Transaction Hash:
Block:
17712026 at Jul-17-2023 09:16:35 AM +UTC
Transaction Fee:
0.01060390969596816 ETH
$25.93
Gas Used:
388,960 Gas / 27.262211271 Gwei
Emitted Events:
326 |
0x8d53afbeb62c18917b5f71385d52e8ba87669794.0xc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f62( 0xc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f62, 0x0000000000000000000000004a27a0513a309fd928b10983dd0bf0226806843c, 0x0000000000000000000000004a27a0513a309fd928b10983dd0bf0226806843c, 0x000000000000000000000000779ea756adabeb89a48292aa85bac8e8c9c40753, 0000000000000000000000006100dd79fcaa88420750dcee3f735d168abcb771, 0000000000000000000000000000000000000000000000a4c8f62456b71624c1 )
|
327 |
ItemInteroperableInterface.Transfer( from=[Sender] 0x4a27a0513a309fd928b10983dd0bf0226806843c, to=0x779EA756aDABEB89A48292AA85bAc8E8C9C40753, value=3039746829695080342721 )
|
328 |
0x8d53afbeb62c18917b5f71385d52e8ba87669794.0xc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f62( 0xc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f62, 0x000000000000000000000000779ea756adabeb89a48292aa85bac8e8c9c40753, 0x000000000000000000000000779ea756adabeb89a48292aa85bac8e8c9c40753, 0x0000000000000000000000005553b418f975e1b93239d589d9933365e711dfc2, 0000000000000000000000006100dd79fcaa88420750dcee3f735d168abcb771, 0000000000000000000000000000000000000000000000a4c8f62456b71624c1 )
|
329 |
ItemInteroperableInterface.Transfer( from=0x779EA756aDABEB89A48292AA85bAc8E8C9C40753, to=TreasuryManager, value=3039746829695080342721 )
|
330 |
ItemInteroperableInterface.Transfer( from=0x0000000000000000000000000000000000000000, to=[Sender] 0x4a27a0513a309fd928b10983dd0bf0226806843c, value=3039746829695080342721 )
|
331 |
0x8d53afbeb62c18917b5f71385d52e8ba87669794.0x4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb( 0x4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb, 0x0000000000000000000000000000000000000000000000000000000000000000, 0x0000000000000000000000000000000000000000000000000000000000000000, 0x0000000000000000000000004a27a0513a309fd928b10983dd0bf0226806843c, 0000000000000000000000000000000000000000000000000000000000000040, 0000000000000000000000000000000000000000000000000000000000000080, 0000000000000000000000000000000000000000000000000000000000000001, 000000000000000000000000fe6f669da4e66d820eee6793b013f1e713355be7, 0000000000000000000000000000000000000000000000000000000000000001, 0000000000000000000000000000000000000000000000a4c8f62456b71624c1 )
|
Account State Difference:
Address | Before | After | State Difference | ||
---|---|---|---|---|---|
0x4a27A051...26806843c |
0.271784948862077473 Eth
Nonce: 89
|
0.261181039166109313 Eth
Nonce: 90
| 0.01060390969596816 | ||
0x8d53aFBE...a87669794 | |||||
0xDAFEA492...692c98Bc5
Miner
| (Flashbots: Builder) | 0.047330402533934283 Eth | 0.047369298533934283 Eth | 0.000038896 |
Execution Trace
Fake_Phishing308087.f242432a( )

-
ItemInteroperableInterface.emitEvent( forApprove=False, isMulti=False, data=0x0000000000000000000000004A27A0513A309FD928B10983DD0BF0226806843C000000000000000000000000779EA756ADABEB89A48292AA85BAC8E8C9C407530000000000000000000000000000000000000000000000A4C8F62456B71624C1 )
0x779ea756adabeb89a48292aa85bac8e8c9c40753.f23a6e61( )
-
DelegationsManager.exists( delegationAddress=0x4b81f8163e6ff824085cd2E5F8B057B125aE7639 ) => ( result=True, index=6, treasuryAddress=0x440d3A685babf013201F84d587D0F845AD2Fe9c4 )
-
DelegationsManager.STATICCALL( )
-
SubDAO.get( CFE1633DF53A0649D88D788961F26058C5E7A0B5644675F19F67BB2975827BA2 ) => ( 0x5553B418f975e1b93239d589D9933365E711DFC2 )
Fake_Phishing308087.f242432a( )
-
ItemInteroperableInterface.emitEvent( forApprove=False, isMulti=False, data=0x000000000000000000000000779EA756ADABEB89A48292AA85BAC8E8C9C407530000000000000000000000005553B418F975E1B93239D589D9933365E711DFC20000000000000000000000000000000000000000000000A4C8F62456B71624C1 )
-
TreasuryManager.onERC1155Received( 0x779EA756aDABEB89A48292AA85bAc8E8C9C40753, 0x779EA756aDABEB89A48292AA85bAc8E8C9C40753, 553791398095120659341456634783597180523460212593, 3039746829695080342721, 0x )
-
DelegationFactory.mintItems( items= ) => ( itemIds=[1452567977602978625129543871084414098928464911335] )
MultiOperatorHost.mintItems( items= ) => ( itemIds=[1452567977602978625129543871084414098928464911335] )
Fake_Phishing308087.41607140( )
-
ItemInteroperableInterface.emitEvent( forApprove=False, isMulti=True, data=0x000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000A000000000000000000000000000000000000000000000000000000000000000E00000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000004A27A0513A309FD928B10983DD0BF0226806843C00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000A4C8F62456B71624C1 )
-
-
File 1 of 7: ItemInteroperableInterface
File 2 of 7: TreasuryManager
File 3 of 7: ItemInteroperableInterface
File 4 of 7: DelegationsManager
File 5 of 7: SubDAO
File 6 of 7: DelegationFactory
File 7 of 7: MultiOperatorHost
// File: node_modules\@openzeppelin\contracts\utils\introspection\IERC165.sol // SPDX-License-Identifier: MIT pragma solidity ^0.8.0; /** * @dev Interface of the ERC165 standard, as defined in the * https://eips.ethereum.org/EIPS/eip-165[EIP]. * * Implementers can declare support of contract interfaces, which can then be * queried by others ({ERC165Checker}). * * For an implementation, see {ERC165}. */ interface IERC165 { /** * @dev Returns true if this contract implements the interface defined by * `interfaceId`. See the corresponding * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] * to learn more about how these ids are created. * * This function call must use less than 30 000 gas. */ function supportsInterface(bytes4 interfaceId) external view returns (bool); } // File: @openzeppelin\contracts\token\ERC1155\IERC1155.sol // SPDX_License_Identifier: MIT pragma solidity ^0.8.0; /** * @dev Required interface of an ERC1155 compliant contract, as defined in the * https://eips.ethereum.org/EIPS/eip-1155[EIP]. * * _Available since v3.1._ */ interface IERC1155 is IERC165 { /** * @dev Emitted when `value` tokens of token type `id` are transferred from `from` to `to` by `operator`. */ event TransferSingle(address indexed operator, address indexed from, address indexed to, uint256 id, uint256 value); /** * @dev Equivalent to multiple {TransferSingle} events, where `operator`, `from` and `to` are the same for all * transfers. */ event TransferBatch( address indexed operator, address indexed from, address indexed to, uint256[] ids, uint256[] values ); /** * @dev Emitted when `account` grants or revokes permission to `operator` to transfer their tokens, according to * `approved`. */ event ApprovalForAll(address indexed account, address indexed operator, bool approved); /** * @dev Emitted when the URI for token type `id` changes to `value`, if it is a non-programmatic URI. * * If an {URI} event was emitted for `id`, the standard * https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[guarantees] that `value` will equal the value * returned by {IERC1155MetadataURI-uri}. */ event URI(string value, uint256 indexed id); /** * @dev Returns the amount of tokens of token type `id` owned by `account`. * * Requirements: * * - `account` cannot be the zero address. */ function balanceOf(address account, uint256 id) external view returns (uint256); /** * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {balanceOf}. * * Requirements: * * - `accounts` and `ids` must have the same length. */ function balanceOfBatch(address[] calldata accounts, uint256[] calldata ids) external view returns (uint256[] memory); /** * @dev Grants or revokes permission to `operator` to transfer the caller's tokens, according to `approved`, * * Emits an {ApprovalForAll} event. * * Requirements: * * - `operator` cannot be the caller. */ function setApprovalForAll(address operator, bool approved) external; /** * @dev Returns true if `operator` is approved to transfer ``account``'s tokens. * * See {setApprovalForAll}. */ function isApprovedForAll(address account, address operator) external view returns (bool); /** * @dev Transfers `amount` tokens of token type `id` from `from` to `to`. * * Emits a {TransferSingle} event. * * Requirements: * * - `to` cannot be the zero address. * - If the caller is not `from`, it must be have been approved to spend ``from``'s tokens via {setApprovalForAll}. * - `from` must have a balance of tokens of type `id` of at least `amount`. * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the * acceptance magic value. */ function safeTransferFrom( address from, address to, uint256 id, uint256 amount, bytes calldata data ) external; /** * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {safeTransferFrom}. * * Emits a {TransferBatch} event. * * Requirements: * * - `ids` and `amounts` must have the same length. * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the * acceptance magic value. */ function safeBatchTransferFrom( address from, address to, uint256[] calldata ids, uint256[] calldata amounts, bytes calldata data ) external; } // File: contracts\model\IERC1155Views.sol // SPDX_License_Identifier: MIT pragma solidity >=0.7.0; /** * @title IERC1155Views - An optional utility interface to improve the ERC-1155 Standard. * @dev This interface introduces some additional capabilities for ERC-1155 Tokens. */ interface IERC1155Views { /** * @dev Returns the total supply of the given token id * @param itemId the id of the token whose availability you want to know */ function totalSupply(uint256 itemId) external view returns (uint256); /** * @dev Returns the name of the given token id * @param itemId the id of the token whose name you want to know */ function name(uint256 itemId) external view returns (string memory); /** * @dev Returns the symbol of the given token id * @param itemId the id of the token whose symbol you want to know */ function symbol(uint256 itemId) external view returns (string memory); /** * @dev Returns the decimals of the given token id * @param itemId the id of the token whose decimals you want to know */ function decimals(uint256 itemId) external view returns (uint256); /** * @dev Returns the uri of the given token id * @param itemId the id of the token whose uri you want to know */ function uri(uint256 itemId) external view returns (string memory); } // File: contracts\model\Item.sol //SPDX_License_Identifier: MIT pragma solidity >=0.7.0; pragma abicoder v2; struct Header { address host; string name; string symbol; string uri; } struct CreateItem { Header header; bytes32 collectionId; uint256 id; address[] accounts; uint256[] amounts; } interface Item is IERC1155, IERC1155Views { event CollectionItem(bytes32 indexed fromCollectionId, bytes32 indexed toCollectionId, uint256 indexed itemId); function name() external view returns(string memory); function symbol() external view returns(string memory); function decimals() external view returns(uint256); function burn(address account, uint256 itemId, uint256 amount) external; function burnBatch(address account, uint256[] calldata itemIds, uint256[] calldata amounts) external; function burn(address account, uint256 itemId, uint256 amount, bytes calldata data) external; function burnBatch(address account, uint256[] calldata itemIds, uint256[] calldata amounts, bytes calldata data) external; function mintItems(CreateItem[] calldata items) external returns(uint256[] memory itemIds); function setItemsCollection(uint256[] calldata itemIds, bytes32[] calldata collectionIds) external returns(bytes32[] memory oldCollectionIds); function setItemsMetadata(uint256[] calldata itemIds, Header[] calldata newValues) external returns(Header[] memory oldValues); function interoperableOf(uint256 itemId) external view returns(address); } // File: contracts\model\IItemMainInterface.sol //SPDX_License_Identifier: MIT pragma solidity >=0.7.0; struct ItemData { bytes32 collectionId; Header header; bytes32 domainSeparator; uint256 totalSupply; mapping(address => uint256) balanceOf; mapping(address => mapping(address => uint256)) allowance; mapping(address => uint256) nonces; } interface IItemMainInterface is Item { event Collection(address indexed from, address indexed to, bytes32 indexed collectionId); function interoperableInterfaceModel() external view returns(address); function uri() external view returns(string memory); function plainUri() external view returns(string memory); function dynamicUriResolver() external view returns(address); function hostInitializer() external view returns(address); function collection(bytes32 collectionId) external view returns(address host, string memory name, string memory symbol, string memory uri); function collectionUri(bytes32 collectionId) external view returns(string memory); function createCollection(Header calldata _collection, CreateItem[] calldata items) external returns(bytes32 collectionId, uint256[] memory itemIds); function setCollectionsMetadata(bytes32[] calldata collectionIds, Header[] calldata values) external returns(Header[] memory oldValues); function setApprovalForAllByCollectionHost(bytes32 collectionId, address account, address operator, bool approved) external; function item(uint256 itemId) external view returns(bytes32 collectionId, Header memory header, bytes32 domainSeparator, uint256 totalSupply); function mintTransferOrBurn(bool isMulti, bytes calldata data) external; function allowance(address account, address spender, uint256 itemId) external view returns(uint256); function approve(address account, address spender, uint256 amount, uint256 itemId) external; function TYPEHASH_PERMIT() external view returns (bytes32); function EIP712_PERMIT_DOMAINSEPARATOR_NAME_AND_VERSION() external view returns(string memory domainSeparatorName, string memory domainSeparatorVersion); function permit(uint256 itemId, address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s) external; function nonces(address owner, uint256 itemId) external view returns(uint256); } // File: @openzeppelin\contracts\token\ERC20\IERC20.sol // SPDX_License_Identifier: MIT pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20 { /** * @dev Returns the amount of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the amount of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves `amount` tokens from the caller's account to `recipient`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address recipient, uint256 amount) external returns (bool); /** * @dev Returns the remaining number of tokens that `spender` will be * allowed to spend on behalf of `owner` through {transferFrom}. This is * zero by default. * * This value changes when {approve} or {transferFrom} are called. */ function allowance(address owner, address spender) external view returns (uint256); /** * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. * * Returns a boolean value indicating whether the operation succeeded. * * IMPORTANT: Beware that changing an allowance with this method brings the risk * that someone may use both the old and the new allowance by unfortunate * transaction ordering. One possible solution to mitigate this race * condition is to first reduce the spender's allowance to 0 and set the * desired value afterwards: * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 * * Emits an {Approval} event. */ function approve(address spender, uint256 amount) external returns (bool); /** * @dev Moves `amount` tokens from `sender` to `recipient` using the * allowance mechanism. `amount` is then deducted from the caller's * allowance. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transferFrom( address sender, address recipient, uint256 amount ) external returns (bool); /** * @dev Emitted when `value` tokens are moved from one account (`from`) to * another (`to`). * * Note that `value` may be zero. */ event Transfer(address indexed from, address indexed to, uint256 value); /** * @dev Emitted when the allowance of a `spender` for an `owner` is set by * a call to {approve}. `value` is the new allowance. */ event Approval(address indexed owner, address indexed spender, uint256 value); } // File: @openzeppelin\contracts\token\ERC20\extensions\IERC20Metadata.sol // SPDX_License_Identifier: MIT pragma solidity ^0.8.0; /** * @dev Interface for the optional metadata functions from the ERC20 standard. * * _Available since v4.1._ */ interface IERC20Metadata is IERC20 { /** * @dev Returns the name of the token. */ function name() external view returns (string memory); /** * @dev Returns the symbol of the token. */ function symbol() external view returns (string memory); /** * @dev Returns the decimals places of the token. */ function decimals() external view returns (uint8); } // File: @openzeppelin\contracts\token\ERC20\extensions\draft-IERC20Permit.sol // SPDX_License_Identifier: MIT pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612]. * * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't * need to send a transaction, and thus is not required to hold Ether at all. */ interface IERC20Permit { /** * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens, * given ``owner``'s signed approval. * * IMPORTANT: The same issues {IERC20-approve} has related to transaction * ordering also apply here. * * Emits an {Approval} event. * * Requirements: * * - `spender` cannot be the zero address. * - `deadline` must be a timestamp in the future. * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner` * over the EIP712-formatted function arguments. * - the signature must use ``owner``'s current nonce (see {nonces}). * * For more information on the signature format, see the * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP * section]. */ function permit( address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) external; /** * @dev Returns the current nonce for `owner`. This value must be * included whenever a signature is generated for {permit}. * * Every successful call to {permit} increases ``owner``'s nonce by one. This * prevents a signature from being used multiple times. */ function nonces(address owner) external view returns (uint256); /** * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}. */ // solhint-disable-next-line func-name-mixedcase function DOMAIN_SEPARATOR() external view returns (bytes32); } // File: contracts\model\IItemInteroperableInterface.sol //SPDX_License_Identifier: MIT pragma solidity >=0.7.0; interface IItemInteroperableInterface is IERC20, IERC20Metadata, IERC20Permit { function init() external; function mainInterface() external view returns(address); function itemId() external view returns(uint256); function emitEvent(bool forApprove, bool isMulti, bytes calldata data) external; function burn(uint256 amount) external; function burnFrom(address account, uint256 amount) external; function EIP712_PERMIT_DOMAINSEPARATOR_NAME_AND_VERSION() external view returns(string memory name, string memory version); } // File: contracts\impl\ItemInteroperableInterface.sol //SPDX_License_Identifier: MIT pragma solidity >=0.7.0; contract ItemInteroperableInterface is IItemInteroperableInterface { address public override mainInterface; function init() override external { require(mainInterface == address(0)); mainInterface = msg.sender; } function DOMAIN_SEPARATOR() external override view returns (bytes32 domainSeparatorValue) { (,,domainSeparatorValue,) = IItemMainInterface(mainInterface).item(itemId()); } function EIP712_PERMIT_DOMAINSEPARATOR_NAME_AND_VERSION() external override view returns(string memory, string memory) { return IItemMainInterface(mainInterface).EIP712_PERMIT_DOMAINSEPARATOR_NAME_AND_VERSION(); } function itemId() override public view returns(uint256) { return uint160(address(this)); } function emitEvent(bool forApprove, bool isMulti, bytes calldata data) override external { require(msg.sender == mainInterface, "Unauthorized"); if(isMulti) { (address[] memory froms, address[] memory tos, uint256[] memory amounts) = abi.decode(data, (address[], address[], uint256[])); for(uint256 i = 0; i < froms.length; i++) { if(forApprove) { emit Approval(froms[i], tos[i], amounts[i]); } else { emit Transfer(froms[i], tos[i], amounts[i]); } } return; } (address from, address to, uint256 amount) = abi.decode(data, (address, address, uint256)); if(forApprove) { emit Approval(from, to, amount); } else { emit Transfer(from, to, amount); } } function permit(address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s) override external { IItemMainInterface(mainInterface).permit(itemId(), owner, spender, value, deadline, v, r, s); emit Approval(owner, spender, value); } function burn(uint256 amount) override external { IItemMainInterface(mainInterface).mintTransferOrBurn(false, abi.encode(msg.sender, msg.sender, address(0), itemId(), amount)); emit Transfer(msg.sender, address(0), amount); } function burnFrom(address account, uint256 amount) external override { require(account != address(0), "burn zero address"); IItemMainInterface(mainInterface).mintTransferOrBurn(false, abi.encode(msg.sender, account, address(0), itemId(), amount)); emit Transfer(msg.sender, address(0), amount); } function name() override external view returns (string memory) { (, Header memory header,,) = IItemMainInterface(mainInterface).item(itemId()); return header.name; } function symbol() override external view returns (string memory) { (, Header memory header,,) = IItemMainInterface(mainInterface).item(itemId()); return header.symbol; } function decimals() override external pure returns (uint8) { return 18; } function nonces(address owner) external override view returns(uint256) { return IItemMainInterface(mainInterface).nonces(owner, itemId()); } function totalSupply() override external view returns (uint256 totalSupplyValue) { (,,, totalSupplyValue) = IItemMainInterface(mainInterface).item(itemId()); } function balanceOf(address account) override external view returns (uint256) { return IItemMainInterface(mainInterface).balanceOf(account, itemId()); } function allowance(address owner, address spender) override external view returns (uint256) { return IItemMainInterface(mainInterface).allowance(owner, spender, itemId()); } function approve(address spender, uint256 amount) override external returns(bool) { IItemMainInterface(mainInterface).approve(msg.sender, spender, amount, itemId()); emit Approval(msg.sender, spender, amount); return true; } function transfer(address recipient, uint256 amount) override external returns(bool) { return _transferFrom(msg.sender, recipient, amount); } function transferFrom(address sender, address recipient, uint256 amount) override external returns(bool) { return _transferFrom(sender, recipient, amount); } function _transferFrom(address sender, address recipient, uint256 amount) private returns(bool) { require(sender != address(0), "transfer from the zero address"); require(recipient != address(0), "transfer to the zero address"); IItemMainInterface(mainInterface).mintTransferOrBurn(false, abi.encode(msg.sender, sender, recipient, itemId(), amount)); emit Transfer(sender, recipient, amount); return true; } }
File 2 of 7: TreasuryManager
// SPDX-License-Identifier: MIT pragma solidity >=0.7.0; import "../model/ITreasuryManager.sol"; import "@ethereansos/swissknife/contracts/generic/impl/LazyInitCapableElement.sol"; import { ReflectionUtilities, Uint256Utilities, BehaviorUtilities } from "@ethereansos/swissknife/contracts/lib/GeneralUtilities.sol"; import { Grimoire } from "../lib/KnowledgeBase.sol"; import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import "@openzeppelin/contracts/token/ERC721/IERC721.sol"; import "@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol"; import "@openzeppelin/contracts/token/ERC1155/IERC1155.sol"; import "@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol"; contract TreasuryManager is ITreasuryManager, IERC721Receiver, IERC1155Receiver, LazyInitCapableElement { using ReflectionUtilities for address; using Uint256Utilities for uint256; bytes32 private constant INTERNAL_SELECTOR_MANAGER_SALT = 0x93e9e71b539687571ead6f20e97c4672f2b76a6b58dd6502ea8a456e2f0cd2c7; constructor(bytes memory lazyInitData) LazyInitCapableElement(lazyInitData) { } function _lazyInit(bytes memory lazyInitData) internal override returns(bytes memory) { if(lazyInitData.length > 0) { (bytes4[] memory selectors, address[] memory locations) = abi.decode(lazyInitData, (bytes4[], address[])); require(selectors.length == locations.length, "length"); for(uint256 i = 0; i < selectors.length; i++) { _setAdditionalFunction(selectors[i], locations[i], true); } } return ""; } function _supportsInterface(bytes4 interfaceId) internal override view returns(bool) { return interfaceId == type(ITreasuryManager).interfaceId || interfaceId == type(IERC1155Receiver).interfaceId || interfaceId == this.onERC1155Received.selector || interfaceId == this.onERC1155BatchReceived.selector || interfaceId == type(IERC721Receiver).interfaceId || interfaceId == this.onERC721Received.selector || interfaceId == 0x00000000 || interfaceId == this.transfer.selector || interfaceId == this.batchTransfer.selector || interfaceId == this.setAdditionalFunction.selector || (additionalFunctionsServerManager().isContract() && AdditionalFunctionsServerManager(additionalFunctionsServerManager()).get(interfaceId) != address(0)); } receive() external payable { (bool result, bytes memory returnData) = _trySandboxedCall(false); if(result) { assembly { return(add(returnData, 0x20), mload(returnData)) } } } fallback() authorizedOnly external payable { (bool result, bytes memory returnData) = _trySandboxedCall(true); if(result) { assembly { return(add(returnData, 0x20), mload(returnData)) } } } function transfer(address token, uint256 value, address receiver, uint256 tokenType, uint256 objectId, bool safe, bool withData, bytes calldata data) external override authorizedOnly returns(bool result, bytes memory returnData) { (result, returnData) = _trySandboxedCall(false); if(result) { assembly { return(add(returnData, 0x20), mload(returnData)) } } (result, returnData) = _transfer(TransferEntry(token, tokenType == 0 ? new uint256[](0) : objectId.asSingletonArray(), tokenType == 1 ? new uint256[](0) : value.asSingletonArray(), receiver, safe, false, withData, data)); } function batchTransfer(TransferEntry[] calldata transferEntries) external override authorizedOnly returns(bool[] memory results, bytes[] memory returnDatas) { (bool result, bytes memory returnData) = _trySandboxedCall(false); if(result) { assembly { return(add(returnData, 0x20), mload(returnData)) } } results = new bool[](transferEntries.length); returnDatas = new bytes[](transferEntries.length); for(uint256 i = 0; i < transferEntries.length; i++) { (results[i], returnDatas[i]) = _transfer(transferEntries[i]); } } function onERC721Received(address, address, uint256, bytes calldata) external override returns (bytes4) { (bool result, bytes memory returnData) = _trySandboxedCall(false); if(result) { assembly { return(add(returnData, 0x20), mload(returnData)) } } return this.onERC721Received.selector; } function onERC1155Received(address, address, uint256, uint256, bytes calldata) external override returns(bytes4) { (bool result, bytes memory returnData) = _trySandboxedCall(false); if(result) { assembly { return(add(returnData, 0x20), mload(returnData)) } } return this.onERC1155Received.selector; } function onERC1155BatchReceived(address , address, uint256[] calldata, uint256[] calldata, bytes calldata) external override returns (bytes4) { (bool result, bytes memory returnData) = _trySandboxedCall(false); if(result) { assembly { return(add(returnData, 0x20), mload(returnData)) } } return this.onERC1155BatchReceived.selector; } function setAdditionalFunction(bytes4 selector, address newServer, bool log) external override authorizedOnly returns (address oldServer) { (bool result, bytes memory returnData) = _trySandboxedCall(false); if(result) { assembly { return(add(returnData, 0x20), mload(returnData)) } } oldServer = _setAdditionalFunction(selector, newServer, log); } function submit(address location, bytes calldata payload, address restReceiver) override authorizedOnly external payable returns(bytes memory response) { (bool result, bytes memory returnData) = _trySandboxedCall(false); if(result) { assembly { return(add(returnData, 0x20), mload(returnData)) } } uint256 oldBalance = address(this).balance - msg.value; response = location.submit(msg.value, payload); uint256 actualBalance = address(this).balance; if(actualBalance > oldBalance) { (restReceiver != address(0) ? restReceiver : msg.sender).submit(address(this).balance - oldBalance, ""); } } function additionalFunctionsServerManager() public view returns (address) { return address(uint160(uint256(keccak256(abi.encodePacked( hex'ff', address(this), INTERNAL_SELECTOR_MANAGER_SALT, keccak256(type(AdditionalFunctionsServerManager).creationCode) ))))); } function _setAdditionalFunction(bytes4 selector, address newServer, bool log) private returns (address oldServer) { oldServer = _getOrCreateAdditionalFunctionsServerManager().set(selector, newServer); if(log) { emit AdditionalFunction(msg.sender, selector, oldServer, newServer); } } function _transfer(TransferEntry memory transferEntry) private returns(bool result, bytes memory returnData) { if(transferEntry.values.length == 0 && transferEntry.objectIds.length == 0) { return (result, returnData); } if(transferEntry.token == address(0)) { if(transferEntry.values.length != 0 && transferEntry.values[0] != 0) { returnData = transferEntry.receiver.submit(transferEntry.values[0], ""); result = true; } return (result, returnData); } if(transferEntry.objectIds.length == 0) { if(transferEntry.values.length != 0 && transferEntry.values[0] != 0) { returnData = transferEntry.token.submit(0, abi.encodeWithSelector(IERC20(address(0)).transfer.selector, transferEntry.receiver, transferEntry.values[0])); result = true; } return (result, returnData); } if(transferEntry.values.length == 0) { if(!transferEntry.safe) { returnData = transferEntry.token.submit(0, abi.encodeWithSelector(IERC721(address(0)).transferFrom.selector, address(this), transferEntry.receiver, transferEntry.objectIds[0])); result = true; return (result, returnData); } if(transferEntry.withData) { returnData = transferEntry.token.submit(0, abi.encodeWithSignature("safeTransferFrom(address,address,uint256,bytes)", address(this), transferEntry.receiver, transferEntry.objectIds[0], transferEntry.data)); result = true; return (result, returnData); } returnData = transferEntry.token.submit(0, abi.encodeWithSignature("safeTransferFrom(address,address,uint256)", address(this), transferEntry.receiver, transferEntry.objectIds[0])); result = true; return (result, returnData); } if(transferEntry.batch) { returnData = transferEntry.token.submit(0, abi.encodeWithSelector(IERC1155(address(0)).safeBatchTransferFrom.selector, address(this), transferEntry.receiver, transferEntry.objectIds, transferEntry.values, transferEntry.data)); result = true; return (result, returnData); } if(transferEntry.values[0] != 0) { returnData = transferEntry.token.submit(0, abi.encodeWithSelector(IERC1155(address(0)).safeTransferFrom.selector, address(this), transferEntry.receiver, transferEntry.objectIds[0], transferEntry.values[0], transferEntry.data)); result = true; } } function _trySandboxedCall(bool launchErrorIfNone) internal returns(bool result, bytes memory returnData) { AdditionalFunctionsServerManager _additionalFunctionsServerManager = AdditionalFunctionsServerManager(additionalFunctionsServerManager()); address subject = address(_additionalFunctionsServerManager).isContract() ? _additionalFunctionsServerManager.get(msg.sig) : address(0); if(subject == address(0)) { require(!launchErrorIfNone, "none"); return (false, ""); } address _initializer = initializer; address _maintainer = host; bytes32 reentrancyLockKey = _additionalFunctionsServerManager.setReentrancyLock(); (result, returnData) = subject.delegatecall(msg.data); if(!result) { assembly { revert(add(returnData, 0x20), mload(returnData)) } } initializer = _initializer; host = _maintainer; require(_additionalFunctionsServerManager.releaseReentrancyLock(reentrancyLockKey) == reentrancyLockKey); } function _getOrCreateAdditionalFunctionsServerManager() private returns (AdditionalFunctionsServerManager _additionalFunctionsServerManager) { _additionalFunctionsServerManager = AdditionalFunctionsServerManager(additionalFunctionsServerManager()); if(!address(_additionalFunctionsServerManager).isContract()) { bytes memory bytecode = type(AdditionalFunctionsServerManager).creationCode; bytes32 salt = INTERNAL_SELECTOR_MANAGER_SALT; address addr; assembly { addr := create2(0, add(bytecode, 0x20), mload(bytecode), salt) } } } } contract AdditionalFunctionsServerManager { address immutable private _creator = msg.sender; bytes32 private _reentrancyLockKey; uint256 private _keyIndex; mapping (bytes4 => address) public get; modifier creatorOnly() { require(msg.sender == _creator); _; } function set(bytes4 selector, address newServer) external creatorOnly returns (address oldServer) { oldServer = get[selector]; get[selector] = newServer; } function setReentrancyLock() external creatorOnly returns (bytes32) { require(_reentrancyLockKey == bytes32(0)); return _reentrancyLockKey = BehaviorUtilities.randomKey(_keyIndex++); } function releaseReentrancyLock(bytes32 reentrancyLockKey) external creatorOnly returns(bytes32 lastReentrancyLockKey) { require((lastReentrancyLockKey = _reentrancyLockKey) != bytes32(0) && _reentrancyLockKey == reentrancyLockKey); _reentrancyLockKey = bytes32(0); } }// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "../../utils/introspection/IERC165.sol"; /** * @dev _Available since v3.1._ */ interface IERC1155Receiver is IERC165 { /** @dev Handles the receipt of a single ERC1155 token type. This function is called at the end of a `safeTransferFrom` after the balance has been updated. To accept the transfer, this must return `bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)"))` (i.e. 0xf23a6e61, or its own function selector). @param operator The address which initiated the transfer (i.e. msg.sender) @param from The address which previously owned the token @param id The ID of the token being transferred @param value The amount of tokens being transferred @param data Additional data with no specified format @return `bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)"))` if transfer is allowed */ function onERC1155Received( address operator, address from, uint256 id, uint256 value, bytes calldata data ) external returns (bytes4); /** @dev Handles the receipt of a multiple ERC1155 token types. This function is called at the end of a `safeBatchTransferFrom` after the balances have been updated. To accept the transfer(s), this must return `bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)"))` (i.e. 0xbc197c81, or its own function selector). @param operator The address which initiated the batch transfer (i.e. msg.sender) @param from The address which previously owned the token @param ids An array containing ids of each token being transferred (order and length must match values array) @param values An array containing amounts of each token being transferred (order and length must match ids array) @param data Additional data with no specified format @return `bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)"))` if transfer is allowed */ function onERC1155BatchReceived( address operator, address from, uint256[] calldata ids, uint256[] calldata values, bytes calldata data ) external returns (bytes4); } // SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "../../utils/introspection/IERC165.sol"; /** * @dev Required interface of an ERC1155 compliant contract, as defined in the * https://eips.ethereum.org/EIPS/eip-1155[EIP]. * * _Available since v3.1._ */ interface IERC1155 is IERC165 { /** * @dev Emitted when `value` tokens of token type `id` are transferred from `from` to `to` by `operator`. */ event TransferSingle(address indexed operator, address indexed from, address indexed to, uint256 id, uint256 value); /** * @dev Equivalent to multiple {TransferSingle} events, where `operator`, `from` and `to` are the same for all * transfers. */ event TransferBatch( address indexed operator, address indexed from, address indexed to, uint256[] ids, uint256[] values ); /** * @dev Emitted when `account` grants or revokes permission to `operator` to transfer their tokens, according to * `approved`. */ event ApprovalForAll(address indexed account, address indexed operator, bool approved); /** * @dev Emitted when the URI for token type `id` changes to `value`, if it is a non-programmatic URI. * * If an {URI} event was emitted for `id`, the standard * https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[guarantees] that `value` will equal the value * returned by {IERC1155MetadataURI-uri}. */ event URI(string value, uint256 indexed id); /** * @dev Returns the amount of tokens of token type `id` owned by `account`. * * Requirements: * * - `account` cannot be the zero address. */ function balanceOf(address account, uint256 id) external view returns (uint256); /** * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {balanceOf}. * * Requirements: * * - `accounts` and `ids` must have the same length. */ function balanceOfBatch(address[] calldata accounts, uint256[] calldata ids) external view returns (uint256[] memory); /** * @dev Grants or revokes permission to `operator` to transfer the caller's tokens, according to `approved`, * * Emits an {ApprovalForAll} event. * * Requirements: * * - `operator` cannot be the caller. */ function setApprovalForAll(address operator, bool approved) external; /** * @dev Returns true if `operator` is approved to transfer ``account``'s tokens. * * See {setApprovalForAll}. */ function isApprovedForAll(address account, address operator) external view returns (bool); /** * @dev Transfers `amount` tokens of token type `id` from `from` to `to`. * * Emits a {TransferSingle} event. * * Requirements: * * - `to` cannot be the zero address. * - If the caller is not `from`, it must be have been approved to spend ``from``'s tokens via {setApprovalForAll}. * - `from` must have a balance of tokens of type `id` of at least `amount`. * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the * acceptance magic value. */ function safeTransferFrom( address from, address to, uint256 id, uint256 amount, bytes calldata data ) external; /** * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {safeTransferFrom}. * * Emits a {TransferBatch} event. * * Requirements: * * - `ids` and `amounts` must have the same length. * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the * acceptance magic value. */ function safeBatchTransferFrom( address from, address to, uint256[] calldata ids, uint256[] calldata amounts, bytes calldata data ) external; } // SPDX-License-Identifier: MIT pragma solidity ^0.8.0; /** * @title ERC721 token receiver interface * @dev Interface for any contract that wants to support safeTransfers * from ERC721 asset contracts. */ interface IERC721Receiver { /** * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom} * by `operator` from `from`, this function is called. * * It must return its Solidity selector to confirm the token transfer. * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted. * * The selector can be obtained in Solidity with `IERC721.onERC721Received.selector`. */ function onERC721Received( address operator, address from, uint256 tokenId, bytes calldata data ) external returns (bytes4); } // SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "../../utils/introspection/IERC165.sol"; /** * @dev Required interface of an ERC721 compliant contract. */ interface IERC721 is IERC165 { /** * @dev Emitted when `tokenId` token is transferred from `from` to `to`. */ event Transfer(address indexed from, address indexed to, uint256 indexed tokenId); /** * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token. */ event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId); /** * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets. */ event ApprovalForAll(address indexed owner, address indexed operator, bool approved); /** * @dev Returns the number of tokens in ``owner``'s account. */ function balanceOf(address owner) external view returns (uint256 balance); /** * @dev Returns the owner of the `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function ownerOf(uint256 tokenId) external view returns (address owner); /** * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients * are aware of the ERC721 protocol to prevent tokens from being forever locked. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If the caller is not `from`, it must be have been allowed to move this token by either {approve} or {setApprovalForAll}. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function safeTransferFrom( address from, address to, uint256 tokenId ) external; /** * @dev Transfers `tokenId` token from `from` to `to`. * * WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must be owned by `from`. * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. * * Emits a {Transfer} event. */ function transferFrom( address from, address to, uint256 tokenId ) external; /** * @dev Gives permission to `to` to transfer `tokenId` token to another account. * The approval is cleared when the token is transferred. * * Only a single account can be approved at a time, so approving the zero address clears previous approvals. * * Requirements: * * - The caller must own the token or be an approved operator. * - `tokenId` must exist. * * Emits an {Approval} event. */ function approve(address to, uint256 tokenId) external; /** * @dev Returns the account approved for `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function getApproved(uint256 tokenId) external view returns (address operator); /** * @dev Approve or remove `operator` as an operator for the caller. * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller. * * Requirements: * * - The `operator` cannot be the caller. * * Emits an {ApprovalForAll} event. */ function setApprovalForAll(address operator, bool _approved) external; /** * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`. * * See {setApprovalForAll} */ function isApprovedForAll(address owner, address operator) external view returns (bool); /** * @dev Safely transfers `tokenId` token from `from` to `to`. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function safeTransferFrom( address from, address to, uint256 tokenId, bytes calldata data ) external; } // SPDX-License-Identifier: MIT pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20 { /** * @dev Returns the amount of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the amount of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves `amount` tokens from the caller's account to `recipient`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address recipient, uint256 amount) external returns (bool); /** * @dev Returns the remaining number of tokens that `spender` will be * allowed to spend on behalf of `owner` through {transferFrom}. This is * zero by default. * * This value changes when {approve} or {transferFrom} are called. */ function allowance(address owner, address spender) external view returns (uint256); /** * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. * * Returns a boolean value indicating whether the operation succeeded. * * IMPORTANT: Beware that changing an allowance with this method brings the risk * that someone may use both the old and the new allowance by unfortunate * transaction ordering. One possible solution to mitigate this race * condition is to first reduce the spender's allowance to 0 and set the * desired value afterwards: * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 * * Emits an {Approval} event. */ function approve(address spender, uint256 amount) external returns (bool); /** * @dev Moves `amount` tokens from `sender` to `recipient` using the * allowance mechanism. `amount` is then deducted from the caller's * allowance. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transferFrom( address sender, address recipient, uint256 amount ) external returns (bool); /** * @dev Emitted when `value` tokens are moved from one account (`from`) to * another (`to`). * * Note that `value` may be zero. */ event Transfer(address indexed from, address indexed to, uint256 value); /** * @dev Emitted when the allowance of a `spender` for an `owner` is set by * a call to {approve}. `value` is the new allowance. */ event Approval(address indexed owner, address indexed spender, uint256 value); } // SPDX-License-Identifier: MIT pragma solidity >=0.7.0; import "../../core/model/IOrganization.sol"; import "../model/IMicroservicesManager.sol"; import "../model/IStateManager.sol"; import "../model/IProposalsManager.sol"; import "../model/ITreasuryManager.sol"; import { ReflectionUtilities, BytesUtilities } from "@ethereansos/swissknife/contracts/lib/GeneralUtilities.sol"; library Grimoire { bytes32 constant public COMPONENT_KEY_TREASURY_MANAGER = 0xcfe1633df53a0649d88d788961f26058c5e7a0b5644675f19f67bb2975827ba2; bytes32 constant public COMPONENT_KEY_STATE_MANAGER = 0xd1d09e8f5708558865b8acd5f13c69781ae600e42dbc7f52b8ef1b9e33dbcd36; bytes32 constant public COMPONENT_KEY_MICROSERVICES_MANAGER = 0x0aef4c8f864010d3e1817691f51ade95a646fffafd7f3df9cb8200def342cfd7; bytes32 constant public COMPONENT_KEY_PROPOSALS_MANAGER = 0xa504406933af7ca120d20b97dfc79ea9788beb3c4d3ac1ff9a2c292b2c28e0cc; } library Getters { function treasuryManager(IOrganization organization) internal view returns(ITreasuryManager) { return ITreasuryManager(organization.get(Grimoire.COMPONENT_KEY_TREASURY_MANAGER)); } function stateManager(IOrganization organization) internal view returns(IStateManager) { return IStateManager(organization.get(Grimoire.COMPONENT_KEY_STATE_MANAGER)); } function microservicesManager(IOrganization organization) internal view returns(IMicroservicesManager) { return IMicroservicesManager(organization.get(Grimoire.COMPONENT_KEY_MICROSERVICES_MANAGER)); } function proposalsManager(IOrganization organization) internal view returns(IProposalsManager) { return IProposalsManager(organization.get(Grimoire.COMPONENT_KEY_PROPOSALS_MANAGER)); } } library Setters { function replaceTreasuryManager(IOrganization organization, address newComponentAddress) internal returns(ITreasuryManager oldComponent) { require(newComponentAddress != address(0), "void"); oldComponent = ITreasuryManager(organization.set(IOrganization.Component(Grimoire.COMPONENT_KEY_TREASURY_MANAGER, newComponentAddress, false, true))); } function replaceStateManager(IOrganization organization, address newComponentAddress) internal returns(IStateManager oldComponent) { require(newComponentAddress != address(0), "void"); oldComponent = IStateManager(organization.set(IOrganization.Component(Grimoire.COMPONENT_KEY_STATE_MANAGER, newComponentAddress, false ,true))); } function replaceMicroservicesManager(IOrganization organization, address newComponentAddress) internal returns(IMicroservicesManager oldComponent) { require(newComponentAddress != address(0), "void"); oldComponent = IMicroservicesManager(organization.set(IOrganization.Component(Grimoire.COMPONENT_KEY_MICROSERVICES_MANAGER, newComponentAddress, true, true))); } function replaceProposalsManager(IOrganization organization, address newComponentAddress) internal returns(IProposalsManager oldComponent) { require(newComponentAddress != address(0), "void"); oldComponent = IProposalsManager(organization.set(IOrganization.Component(Grimoire.COMPONENT_KEY_PROPOSALS_MANAGER, newComponentAddress, true, true))); } } library Treasury { using ReflectionUtilities for address; function storeETH(IOrganization organization, uint256 value) internal { if(value != 0) { organization.get(Grimoire.COMPONENT_KEY_TREASURY_MANAGER).submit(value, ""); } } function callTemporaryFunction(ITreasuryManager treasuryManager, bytes4 selector, address subject, uint256 value, bytes memory data) internal returns(bytes memory response) { address oldServer = treasuryManager.setAdditionalFunction(selector, subject, false); response = address(treasuryManager).submit(value, abi.encodePacked(selector, data)); treasuryManager.setAdditionalFunction(selector, oldServer, false); } } library State { using BytesUtilities for bytes; bytes32 constant public ENTRY_TYPE_ADDRESS = 0x421683f821a0574472445355be6d2b769119e8515f8376a1d7878523dfdecf7b; bytes32 constant public ENTRY_TYPE_ADDRESS_ARRAY = 0x23d8ff3dc5aed4a634bcf123581c95e70c60ac0e5246916790aef6d4451ff4c1; bytes32 constant public ENTRY_TYPE_BOOL = 0xc1053bdab4a5cf55238b667c39826bbb11a58be126010e7db397c1b67c24271b; bytes32 constant public ENTRY_TYPE_BOOL_ARRAY = 0x8761250c4d2c463ce51f91f5d2c2508fa9142f8a42aa9f30b965213bf3e6c2ac; bytes32 constant public ENTRY_TYPE_BYTES = 0xb963e9b45d014edd60cff22ec9ad383335bbc3f827be2aee8e291972b0fadcf2; bytes32 constant public ENTRY_TYPE_BYTES_ARRAY = 0x084b42f8a8730b98eb0305d92103d9107363192bb66162064a34dc5716ebe1a0; bytes32 constant public ENTRY_TYPE_STRING = 0x97fc46276c172633607a331542609db1e3da793fca183d594ed5a61803a10792; bytes32 constant public ENTRY_TYPE_STRING_ARRAY = 0xa227fd7a847724343a7dda3598ee0fb2d551b151b73e4a741067596daa6f5658; bytes32 constant public ENTRY_TYPE_UINT256 = 0xec13d6d12b88433319b64e1065a96ea19cd330ef6603f5f6fb685dde3959a320; bytes32 constant public ENTRY_TYPE_UINT256_ARRAY = 0xc1b76e99a35aa41ed28bbbd9e6c7228760c87b410ebac94fa6431da9b592411f; function getAddress(IStateManager stateManager, string memory name) internal view returns(address) { return stateManager.get(name).value.asAddress(); } function setAddress(IStateManager stateManager, string memory name, address val) internal returns(address oldValue) { return stateManager.set(IStateManager.StateEntry(name, ENTRY_TYPE_ADDRESS, abi.encodePacked(val))).asAddress(); } function getAddressArray(IStateManager stateManager, string memory name) internal view returns(address[] memory) { return stateManager.get(name).value.asAddressArray(); } function setAddressArray(IStateManager stateManager, string memory name, address[] memory val) internal returns(address[] memory oldValue) { return stateManager.set(IStateManager.StateEntry(name, ENTRY_TYPE_ADDRESS_ARRAY, abi.encode(val))).asAddressArray(); } function getBool(IStateManager stateManager, string memory name) internal view returns(bool) { return stateManager.get(name).value.asBool(); } function setBool(IStateManager stateManager, string memory name, bool val) internal returns(bool oldValue) { return stateManager.set(IStateManager.StateEntry(name, ENTRY_TYPE_BOOL, abi.encode(val ? 1 : 0))).asBool(); } function getBoolArray(IStateManager stateManager, string memory name) internal view returns(bool[] memory) { return stateManager.get(name).value.asBoolArray(); } function setBoolArray(IStateManager stateManager, string memory name, bool[] memory val) internal returns(bool[] memory oldValue) { return stateManager.set(IStateManager.StateEntry(name, ENTRY_TYPE_BOOL_ARRAY, abi.encode(val))).asBoolArray(); } function getBytes(IStateManager stateManager, string memory name) internal view returns(bytes memory) { return stateManager.get(name).value; } function setBytes(IStateManager stateManager, string memory name, bytes memory val) internal returns(bytes memory oldValue) { return stateManager.set(IStateManager.StateEntry(name, ENTRY_TYPE_BYTES, val)); } function getBytesArray(IStateManager stateManager, string memory name) internal view returns(bytes[] memory) { return stateManager.get(name).value.asBytesArray(); } function setBytesArray(IStateManager stateManager, string memory name, bytes[] memory val) internal returns(bytes[] memory oldValue) { return stateManager.set(IStateManager.StateEntry(name, ENTRY_TYPE_BYTES_ARRAY, abi.encode(val))).asBytesArray(); } function getString(IStateManager stateManager, string memory name) internal view returns(string memory) { return string(stateManager.get(name).value); } function setString(IStateManager stateManager, string memory name, string memory val) internal returns(string memory oldValue) { return string(stateManager.set(IStateManager.StateEntry(name, ENTRY_TYPE_STRING, bytes(val)))); } function getStringArray(IStateManager stateManager, string memory name) internal view returns(string[] memory) { return stateManager.get(name).value.asStringArray(); } function setStringArray(IStateManager stateManager, string memory name, string[] memory val) internal returns(string[] memory oldValue) { return stateManager.set(IStateManager.StateEntry(name, ENTRY_TYPE_STRING_ARRAY, abi.encode(val))).asStringArray(); } function getUint256(IStateManager stateManager, string memory name) internal view returns(uint256) { return stateManager.get(name).value.asUint256(); } function setUint256(IStateManager stateManager, string memory name, uint256 val) internal returns(uint256 oldValue) { return stateManager.set(IStateManager.StateEntry(name, ENTRY_TYPE_UINT256, abi.encode(val))).asUint256(); } function getUint256Array(IStateManager stateManager, string memory name) internal view returns(uint256[] memory) { return stateManager.get(name).value.asUint256Array(); } function setUint256Array(IStateManager stateManager, string memory name, uint256[] memory val) internal returns(uint256[] memory oldValue) { return stateManager.set(IStateManager.StateEntry(name, ENTRY_TYPE_UINT256_ARRAY, abi.encode(val))).asUint256Array(); } }// SPDX-License-Identifier: MIT pragma solidity >=0.7.0; import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; library BehaviorUtilities { function randomKey(uint256 i) internal view returns (bytes32) { return keccak256(abi.encode(i, block.timestamp, block.number, tx.origin, tx.gasprice, block.coinbase, block.difficulty, msg.sender, blockhash(block.number - 5))); } function calculateProjectedArraySizeAndLoopUpperBound(uint256 arraySize, uint256 start, uint256 offset) internal pure returns(uint256 projectedArraySize, uint256 projectedArrayLoopUpperBound) { if(arraySize != 0 && start < arraySize && offset != 0) { uint256 length = start + offset; if(start < (length = length > arraySize ? arraySize : length)) { projectedArraySize = (projectedArrayLoopUpperBound = length) - start; } } } } library ReflectionUtilities { function read(address subject, bytes memory inputData) internal view returns(bytes memory returnData) { bool result; (result, returnData) = subject.staticcall(inputData); if(!result) { assembly { revert(add(returnData, 0x20), mload(returnData)) } } } function submit(address subject, uint256 value, bytes memory inputData) internal returns(bytes memory returnData) { bool result; (result, returnData) = subject.call{value : value}(inputData); if(!result) { assembly { revert(add(returnData, 0x20), mload(returnData)) } } } function isContract(address subject) internal view returns (bool) { if(subject == address(0)) { return false; } uint256 codeLength; assembly { codeLength := extcodesize(subject) } return codeLength > 0; } function clone(address originalContract) internal returns(address copyContract) { assembly { mstore( 0, or( 0x5880730000000000000000000000000000000000000000803b80938091923cF3, mul(originalContract, 0x1000000000000000000) ) ) copyContract := create(0, 0, 32) switch extcodesize(copyContract) case 0 { invalid() } } } } library BytesUtilities { bytes private constant ALPHABET = "0123456789abcdef"; string internal constant BASE64_ENCODER_DATA = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'; function asAddress(bytes memory b) internal pure returns(address) { if(b.length == 0) { return address(0); } if(b.length == 20) { address addr; assembly { addr := mload(add(b, 20)) } return addr; } return abi.decode(b, (address)); } function asAddressArray(bytes memory b) internal pure returns(address[] memory callResult) { if(b.length > 0) { return abi.decode(b, (address[])); } } function asBool(bytes memory bs) internal pure returns(bool) { return asUint256(bs) != 0; } function asBoolArray(bytes memory b) internal pure returns(bool[] memory callResult) { if(b.length > 0) { return abi.decode(b, (bool[])); } } function asBytesArray(bytes memory b) internal pure returns(bytes[] memory callResult) { if(b.length > 0) { return abi.decode(b, (bytes[])); } } function asString(bytes memory b) internal pure returns(string memory callResult) { if(b.length > 0) { return abi.decode(b, (string)); } } function asStringArray(bytes memory b) internal pure returns(string[] memory callResult) { if(b.length > 0) { return abi.decode(b, (string[])); } } function asUint256(bytes memory bs) internal pure returns(uint256 x) { if (bs.length >= 32) { assembly { x := mload(add(bs, add(0x20, 0))) } } } function asUint256Array(bytes memory b) internal pure returns(uint256[] memory callResult) { if(b.length > 0) { return abi.decode(b, (uint256[])); } } function toString(bytes memory data) internal pure returns(string memory) { bytes memory str = new bytes(2 + data.length * 2); str[0] = "0"; str[1] = "x"; for (uint256 i = 0; i < data.length; i++) { str[2+i*2] = ALPHABET[uint256(uint8(data[i] >> 4))]; str[3+i*2] = ALPHABET[uint256(uint8(data[i] & 0x0f))]; } return string(str); } function asSingletonArray(bytes memory a) internal pure returns(bytes[] memory array) { array = new bytes[](1); array[0] = a; } function toBase64(bytes memory data) internal pure returns (string memory) { if (data.length == 0) return ''; string memory table = BASE64_ENCODER_DATA; uint256 encodedLen = 4 * ((data.length + 2) / 3); string memory result = new string(encodedLen + 32); assembly { mstore(result, encodedLen) let tablePtr := add(table, 1) let dataPtr := data let endPtr := add(dataPtr, mload(data)) let resultPtr := add(result, 32) for {} lt(dataPtr, endPtr) {} { dataPtr := add(dataPtr, 3) let input := mload(dataPtr) mstore8(resultPtr, mload(add(tablePtr, and(shr(18, input), 0x3F)))) resultPtr := add(resultPtr, 1) mstore8(resultPtr, mload(add(tablePtr, and(shr(12, input), 0x3F)))) resultPtr := add(resultPtr, 1) mstore8(resultPtr, mload(add(tablePtr, and(shr( 6, input), 0x3F)))) resultPtr := add(resultPtr, 1) mstore8(resultPtr, mload(add(tablePtr, and( input, 0x3F)))) resultPtr := add(resultPtr, 1) } switch mod(mload(data), 3) case 1 { mstore(sub(resultPtr, 2), shl(240, 0x3d3d)) } case 2 { mstore(sub(resultPtr, 1), shl(248, 0x3d)) } } return result; } } library StringUtilities { bytes1 private constant CHAR_0 = bytes1('0'); bytes1 private constant CHAR_A = bytes1('A'); bytes1 private constant CHAR_a = bytes1('a'); bytes1 private constant CHAR_f = bytes1('f'); bytes internal constant BASE64_DECODER_DATA = hex"0000000000000000000000000000000000000000000000000000000000000000" hex"00000000000000000000003e0000003f3435363738393a3b3c3d000000000000" hex"00000102030405060708090a0b0c0d0e0f101112131415161718190000000000" hex"001a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132330000000000"; function isEmpty(string memory test) internal pure returns (bool) { return equals(test, ""); } function equals(string memory a, string memory b) internal pure returns(bool) { return keccak256(abi.encodePacked(a)) == keccak256(abi.encodePacked(b)); } function toLowerCase(string memory str) internal pure returns(string memory) { bytes memory bStr = bytes(str); for (uint256 i = 0; i < bStr.length; i++) { bStr[i] = bStr[i] >= 0x41 && bStr[i] <= 0x5A ? bytes1(uint8(bStr[i]) + 0x20) : bStr[i]; } return string(bStr); } function asBytes(string memory str) internal pure returns(bytes memory toDecode) { bytes memory data = abi.encodePacked(str); if(data.length == 0 || data[0] != "0" || (data[1] != "x" && data[1] != "X")) { return ""; } uint256 start = 2; toDecode = new bytes((data.length - 2) / 2); for(uint256 i = 0; i < toDecode.length; i++) { toDecode[i] = bytes1(_fromHexChar(uint8(data[start++])) + _fromHexChar(uint8(data[start++])) * 16); } } function toBase64(string memory input) internal pure returns(string memory) { return BytesUtilities.toBase64(abi.encodePacked(input)); } function fromBase64(string memory _data) internal pure returns (bytes memory) { bytes memory data = bytes(_data); if (data.length == 0) return new bytes(0); require(data.length % 4 == 0, "invalid base64 decoder input"); bytes memory table = BASE64_DECODER_DATA; uint256 decodedLen = (data.length / 4) * 3; bytes memory result = new bytes(decodedLen + 32); assembly { let lastBytes := mload(add(data, mload(data))) if eq(and(lastBytes, 0xFF), 0x3d) { decodedLen := sub(decodedLen, 1) if eq(and(lastBytes, 0xFFFF), 0x3d3d) { decodedLen := sub(decodedLen, 1) } } mstore(result, decodedLen) let tablePtr := add(table, 1) let dataPtr := data let endPtr := add(dataPtr, mload(data)) let resultPtr := add(result, 32) for {} lt(dataPtr, endPtr) {} { dataPtr := add(dataPtr, 4) let input := mload(dataPtr) let output := add( add( shl(18, and(mload(add(tablePtr, and(shr(24, input), 0xFF))), 0xFF)), shl(12, and(mload(add(tablePtr, and(shr(16, input), 0xFF))), 0xFF))), add( shl( 6, and(mload(add(tablePtr, and(shr( 8, input), 0xFF))), 0xFF)), and(mload(add(tablePtr, and( input , 0xFF))), 0xFF) ) ) mstore(resultPtr, shl(232, output)) resultPtr := add(resultPtr, 3) } } return result; } function _fromHexChar(uint8 c) private pure returns (uint8) { bytes1 charc = bytes1(c); return charc < CHAR_0 || charc > CHAR_f ? 0 : (charc < CHAR_A ? 0 : 10) + c - uint8(charc < CHAR_A ? CHAR_0 : charc < CHAR_a ? CHAR_A : CHAR_a); } } library Uint256Utilities { function asSingletonArray(uint256 n) internal pure returns(uint256[] memory array) { array = new uint256[](1); array[0] = n; } function toHex(uint256 _i) internal pure returns (string memory) { return BytesUtilities.toString(abi.encodePacked(_i)); } function toString(uint256 _i) internal pure returns (string memory _uintAsString) { if (_i == 0) { return "0"; } uint256 j = _i; uint256 len; while (j != 0) { len++; j /= 10; } bytes memory bstr = new bytes(len); uint256 k = len; while (_i != 0) { k = k-1; uint8 temp = (48 + uint8(_i - _i / 10 * 10)); bytes1 b1 = bytes1(temp); bstr[k] = b1; _i /= 10; } return string(bstr); } function sum(uint256[] memory arr) internal pure returns (uint256 result) { for(uint256 i = 0; i < arr.length; i++) { result += arr[i]; } } } library AddressUtilities { function asSingletonArray(address a) internal pure returns(address[] memory array) { array = new address[](1); array[0] = a; } function toString(address _addr) internal pure returns (string memory) { return _addr == address(0) ? "0x0000000000000000000000000000000000000000" : BytesUtilities.toString(abi.encodePacked(_addr)); } } library Bytes32Utilities { function asSingletonArray(bytes32 a) internal pure returns(bytes32[] memory array) { array = new bytes32[](1); array[0] = a; } function toString(bytes32 bt) internal pure returns (string memory) { return bt == bytes32(0) ? "0x0000000000000000000000000000000000000000000000000000000000000000" : BytesUtilities.toString(abi.encodePacked(bt)); } } library TransferUtilities { using ReflectionUtilities for address; function balanceOf(address erc20TokenAddress, address account) internal view returns(uint256) { if(erc20TokenAddress == address(0)) { return account.balance; } return abi.decode(erc20TokenAddress.read(abi.encodeWithSelector(IERC20(erc20TokenAddress).balanceOf.selector, account)), (uint256)); } function allowance(address erc20TokenAddress, address account, address spender) internal view returns(uint256) { if(erc20TokenAddress == address(0)) { return 0; } return abi.decode(erc20TokenAddress.read(abi.encodeWithSelector(IERC20(erc20TokenAddress).allowance.selector, account, spender)), (uint256)); } function safeApprove(address erc20TokenAddress, address spender, uint256 value) internal { bytes memory returnData = erc20TokenAddress.submit(0, abi.encodeWithSelector(IERC20(erc20TokenAddress).approve.selector, spender, value)); require(returnData.length == 0 || abi.decode(returnData, (bool)), 'APPROVE_FAILED'); } function safeTransfer(address erc20TokenAddress, address to, uint256 value) internal { if(value == 0) { return; } if(erc20TokenAddress == address(0)) { to.submit(value, ""); return; } bytes memory returnData = erc20TokenAddress.submit(0, abi.encodeWithSelector(IERC20(erc20TokenAddress).transfer.selector, to, value)); require(returnData.length == 0 || abi.decode(returnData, (bool)), 'TRANSFER_FAILED'); } function safeTransferFrom(address erc20TokenAddress, address from, address to, uint256 value) internal { if(value == 0) { return; } if(erc20TokenAddress == address(0)) { to.submit(value, ""); return; } bytes memory returnData = erc20TokenAddress.submit(0, abi.encodeWithSelector(IERC20(erc20TokenAddress).transferFrom.selector, from, to, value)); require(returnData.length == 0 || abi.decode(returnData, (bool)), 'TRANSFERFROM_FAILED'); } }// SPDX-License-Identifier: MIT pragma solidity >=0.7.0; import "../model/ILazyInitCapableElement.sol"; import { ReflectionUtilities } from "../../lib/GeneralUtilities.sol"; abstract contract LazyInitCapableElement is ILazyInitCapableElement { using ReflectionUtilities for address; address public override initializer; address public override host; constructor(bytes memory lazyInitData) { if(lazyInitData.length > 0) { _privateLazyInit(lazyInitData); } } function lazyInit(bytes calldata lazyInitData) override external returns (bytes memory lazyInitResponse) { return _privateLazyInit(lazyInitData); } function supportsInterface(bytes4 interfaceId) override external view returns(bool) { return interfaceId == type(IERC165).interfaceId || interfaceId == this.supportsInterface.selector || interfaceId == type(ILazyInitCapableElement).interfaceId || interfaceId == this.lazyInit.selector || interfaceId == this.initializer.selector || interfaceId == this.subjectIsAuthorizedFor.selector || interfaceId == this.host.selector || interfaceId == this.setHost.selector || _supportsInterface(interfaceId); } function setHost(address newValue) external override authorizedOnly returns(address oldValue) { oldValue = host; host = newValue; emit Host(oldValue, newValue); } function subjectIsAuthorizedFor(address subject, address location, bytes4 selector, bytes calldata payload, uint256 value) public override virtual view returns(bool) { (bool chidlElementValidationIsConsistent, bool chidlElementValidationResult) = _subjectIsAuthorizedFor(subject, location, selector, payload, value); if(chidlElementValidationIsConsistent) { return chidlElementValidationResult; } if(subject == host) { return true; } if(!host.isContract()) { return false; } (bool result, bytes memory resultData) = host.staticcall(abi.encodeWithSelector(ILazyInitCapableElement(host).subjectIsAuthorizedFor.selector, subject, location, selector, payload, value)); return result && abi.decode(resultData, (bool)); } function _privateLazyInit(bytes memory lazyInitData) private returns (bytes memory lazyInitResponse) { require(initializer == address(0), "init"); initializer = msg.sender; (host, lazyInitResponse) = abi.decode(lazyInitData, (address, bytes)); emit Host(address(0), host); lazyInitResponse = _lazyInit(lazyInitResponse); } function _lazyInit(bytes memory) internal virtual returns (bytes memory) { return ""; } function _supportsInterface(bytes4 selector) internal virtual view returns (bool); function _subjectIsAuthorizedFor(address, address, bytes4, bytes calldata, uint256) internal virtual view returns(bool, bool) { } modifier authorizedOnly { require(_authorizedOnly(), "unauthorized"); _; } function _authorizedOnly() internal returns(bool) { return subjectIsAuthorizedFor(msg.sender, address(this), msg.sig, msg.data, msg.value); } }// SPDX-License-Identifier: MIT pragma solidity >=0.7.0; import "@ethereansos/swissknife/contracts/generic/model/ILazyInitCapableElement.sol"; interface ITreasuryManager is ILazyInitCapableElement { struct TransferEntry { address token; uint256[] objectIds; uint256[] values; address receiver; bool safe; bool batch; bool withData; bytes data; } function transfer(address token, uint256 value, address receiver, uint256 tokenType, uint256 objectId, bool safe, bool withData, bytes calldata data) external returns(bool result, bytes memory returnData); function batchTransfer(TransferEntry[] calldata transferEntries) external returns(bool[] memory results, bytes[] memory returnDatas); function submit(address location, bytes calldata payload, address restReceiver) external payable returns(bytes memory response); function setAdditionalFunction(bytes4 selector, address newServer, bool log) external returns (address oldServer); event AdditionalFunction(address caller, bytes4 indexed selector, address indexed oldServer, address indexed newServer); }// SPDX-License-Identifier: MIT pragma solidity >=0.7.0; import "@openzeppelin/contracts/utils/introspection/IERC165.sol"; interface ILazyInitCapableElement is IERC165 { function lazyInit(bytes calldata lazyInitData) external returns(bytes memory initResponse); function initializer() external view returns(address); event Host(address indexed from, address indexed to); function host() external view returns(address); function setHost(address newValue) external returns(address oldValue); function subjectIsAuthorizedFor(address subject, address location, bytes4 selector, bytes calldata payload, uint256 value) external view returns(bool); }// SPDX-License-Identifier: MIT pragma solidity >=0.7.0; import "@ethereansos/swissknife/contracts/generic/model/ILazyInitCapableElement.sol"; import "@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol"; interface IProposalsManager is IERC1155Receiver, ILazyInitCapableElement { struct ProposalCode { address location; bytes bytecode; } struct ProposalCodes { ProposalCode[] codes; bool alsoTerminate; } struct Proposal { address proposer; address[] codeSequence; uint256 creationBlock; uint256 accept; uint256 refuse; address triggeringRules; address[] canTerminateAddresses; address[] validatorsAddresses; bool validationPassed; uint256 terminationBlock; bytes votingTokens; } struct ProposalConfiguration { address[] collections; uint256[] objectIds; uint256[] weights; address creationRules; address triggeringRules; address[] canTerminateAddresses; address[] validatorsAddresses; } function batchCreate(ProposalCodes[] calldata codeSequences) external returns(bytes32[] memory createdProposalIds); function list(bytes32[] calldata proposalIds) external view returns(Proposal[] memory); function votes(bytes32[] calldata proposalIds, address[] calldata voters, bytes32[][] calldata items) external view returns(uint256[][] memory accepts, uint256[][] memory refuses, uint256[][] memory toWithdraw); function weight(bytes32 code) external view returns(uint256); function vote(address erc20TokenAddress, bytes memory permitSignature, bytes32 proposalId, uint256 accept, uint256 refuse, address voter, bool alsoTerminate) external payable; function batchVote(bytes[] calldata data) external payable; function withdrawAll(bytes32[] memory proposalIds, address voterOrReceiver, bool afterTermination) external; function terminate(bytes32[] calldata proposalIds) external; function configuration() external view returns(ProposalConfiguration memory); function setConfiguration(ProposalConfiguration calldata newValue) external returns(ProposalConfiguration memory oldValue); function lastProposalId() external view returns(bytes32); function lastVoteBlock(address voter) external view returns (uint256); event ProposalCreated(address indexed proposer, address indexed code, bytes32 indexed proposalId); event ProposalWeight(bytes32 indexed proposalId, address indexed collection, uint256 indexed id, bytes32 key, uint256 weight); event ProposalTerminated(bytes32 indexed proposalId, bool result, bytes errorData); event Accept(bytes32 indexed proposalId, address indexed voter, bytes32 indexed item, uint256 amount); event MoveToAccept(bytes32 indexed proposalId, address indexed voter, bytes32 indexed item, uint256 amount); event RetireAccept(bytes32 indexed proposalId, address indexed voter, bytes32 indexed item, uint256 amount); event Refuse(bytes32 indexed proposalId, address indexed voter, bytes32 indexed item, uint256 amount); event MoveToRefuse(bytes32 indexed proposalId, address indexed voter, bytes32 indexed item, uint256 amount); event RetireRefuse(bytes32 indexed proposalId, address indexed voter, bytes32 indexed item, uint256 amount); } interface IProposalChecker { function check(address proposalsManagerAddress, bytes32 id, bytes calldata data, address from, address voter) external view returns(bool); } interface IExternalProposalsManagerCommands { function createProposalCodeSequence(bytes32 proposalId, IProposalsManager.ProposalCode[] memory codeSequenceInput, address sender) external returns (address[] memory codeSequence, IProposalsManager.ProposalConfiguration memory localConfiguration); function proposalCanBeFinalized(bytes32 proposalId, IProposalsManager.Proposal memory proposal, bool validationPassed, bool result) external view returns (bool); function isVotable(bytes32 proposalId, IProposalsManager.Proposal memory proposal, address from, address voter, bool voteOrWithtraw) external view returns (bytes memory response); }// SPDX-License-Identifier: MIT pragma solidity >=0.7.0; import "@ethereansos/swissknife/contracts/generic/model/ILazyInitCapableElement.sol"; interface IStateManager is ILazyInitCapableElement { struct StateEntry { string key; bytes32 entryType; bytes value; } function size() external view returns (uint256); function all() external view returns (StateEntry[] memory); function partialList(uint256 start, uint256 offset) external view returns (StateEntry[] memory); function list(string[] calldata keys) external view returns (StateEntry[] memory); function listByIndices(uint256[] calldata indices) external view returns (StateEntry[] memory); function exists(string calldata key) external view returns(bool result, uint256 index); function get(string calldata key) external view returns(StateEntry memory); function getByIndex(uint256 index) external view returns(StateEntry memory); function set(StateEntry calldata newValue) external returns(bytes memory replacedValue); function batchSet(StateEntry[] calldata newValues) external returns(bytes[] memory replacedValues); function remove(string calldata key) external returns(bytes32 removedType, bytes memory removedValue); function batchRemove(string[] calldata keys) external returns(bytes32[] memory removedTypes, bytes[] memory removedValues); function removeByIndices(uint256[] calldata indices) external returns(bytes32[] memory removedTypes, bytes[] memory removedValues); }// SPDX-License-Identifier: MIT pragma solidity >=0.7.0; import "@ethereansos/swissknife/contracts/generic/model/ILazyInitCapableElement.sol"; interface IMicroservicesManager is ILazyInitCapableElement { struct Microservice { string key; address location; string methodSignature; bool submittable; string returnAbiParametersArray; bool isInternal; bool needsSender; } function size() external view returns (uint256); function all() external view returns (Microservice[] memory); function partialList(uint256 start, uint256 offset) external view returns (Microservice[] memory); function list(string[] calldata keys) external view returns (Microservice[] memory); function listByIndices(uint256[] calldata indices) external view returns (Microservice[] memory); function exists(string calldata key) external view returns(bool result, uint256 index); function get(string calldata key) external view returns(Microservice memory); function getByIndex(uint256 index) external view returns(Microservice memory); function set(Microservice calldata newValue) external returns(Microservice memory replacedValue); function batchSet(Microservice[] calldata newValues) external returns(Microservice[] memory replacedValues); event MicroserviceAdded(address indexed sender, bytes32 indexed keyHash, string key, address indexed location, string methodSignature, bool submittable, string returnAbiParametersArray, bool isInternal, bool needsSender); function remove(string calldata key) external returns(Microservice memory removedValue); function batchRemove(string[] calldata keys) external returns(Microservice[] memory removedValues); function removeByIndices(uint256[] calldata indices) external returns(Microservice[] memory removedValues); event MicroserviceRemoved(address indexed sender, bytes32 indexed keyHash, string key, address indexed location, string methodSignature, bool submittable, string returnAbiParametersArray, bool isInternal, bool needsSender); function read(string calldata key, bytes calldata data) external view returns(bytes memory returnData); function submit(string calldata key, bytes calldata data) external payable returns(bytes memory returnData); }// SPDX-License-Identifier: MIT pragma solidity >=0.7.0; import "@ethereansos/swissknife/contracts/dynamicMetadata/model/IDynamicMetadataCapableElement.sol"; interface IOrganization is IDynamicMetadataCapableElement { struct Component { bytes32 key; address location; bool active; bool log; } function keyOf(address componentAddress) external view returns(bytes32); function history(bytes32 key) external view returns(address[] memory componentsAddresses); function batchHistory(bytes32[] calldata keys) external view returns(address[][] memory componentsAddresses); function get(bytes32 key) external view returns(address componentAddress); function list(bytes32[] calldata keys) external view returns(address[] memory componentsAddresses); function isActive(address subject) external view returns(bool); function keyIsActive(bytes32 key) external view returns(bool); function set(Component calldata) external returns(address replacedComponentAddress); function batchSet(Component[] calldata) external returns (address[] memory replacedComponentAddresses); event ComponentSet(bytes32 indexed key, address indexed from, address indexed to, bool active); function submit(address location, bytes calldata payload, address restReceiver) external payable returns(bytes memory response); }// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; /** * @dev Interface of the ERC165 standard, as defined in the * https://eips.ethereum.org/EIPS/eip-165[EIP]. * * Implementers can declare support of contract interfaces, which can then be * queried by others ({ERC165Checker}). * * For an implementation, see {ERC165}. */ interface IERC165 { /** * @dev Returns true if this contract implements the interface defined by * `interfaceId`. See the corresponding * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] * to learn more about how these ids are created. * * This function call must use less than 30 000 gas. */ function supportsInterface(bytes4 interfaceId) external view returns (bool); } //SPDX-License-Identifier: MIT pragma solidity >=0.7.0; import "../../generic/model/ILazyInitCapableElement.sol"; interface IDynamicMetadataCapableElement is ILazyInitCapableElement { function uri() external view returns(string memory); function plainUri() external view returns(string memory); function setUri(string calldata newValue) external returns (string memory oldValue); function dynamicUriResolver() external view returns(address); function setDynamicUriResolver(address newValue) external returns(address oldValue); }
File 3 of 7: ItemInteroperableInterface
// File: node_modules\@openzeppelin\contracts\utils\introspection\IERC165.sol // SPDX-License-Identifier: MIT pragma solidity ^0.8.0; /** * @dev Interface of the ERC165 standard, as defined in the * https://eips.ethereum.org/EIPS/eip-165[EIP]. * * Implementers can declare support of contract interfaces, which can then be * queried by others ({ERC165Checker}). * * For an implementation, see {ERC165}. */ interface IERC165 { /** * @dev Returns true if this contract implements the interface defined by * `interfaceId`. See the corresponding * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] * to learn more about how these ids are created. * * This function call must use less than 30 000 gas. */ function supportsInterface(bytes4 interfaceId) external view returns (bool); } // File: @openzeppelin\contracts\token\ERC1155\IERC1155.sol // SPDX_License_Identifier: MIT pragma solidity ^0.8.0; /** * @dev Required interface of an ERC1155 compliant contract, as defined in the * https://eips.ethereum.org/EIPS/eip-1155[EIP]. * * _Available since v3.1._ */ interface IERC1155 is IERC165 { /** * @dev Emitted when `value` tokens of token type `id` are transferred from `from` to `to` by `operator`. */ event TransferSingle(address indexed operator, address indexed from, address indexed to, uint256 id, uint256 value); /** * @dev Equivalent to multiple {TransferSingle} events, where `operator`, `from` and `to` are the same for all * transfers. */ event TransferBatch( address indexed operator, address indexed from, address indexed to, uint256[] ids, uint256[] values ); /** * @dev Emitted when `account` grants or revokes permission to `operator` to transfer their tokens, according to * `approved`. */ event ApprovalForAll(address indexed account, address indexed operator, bool approved); /** * @dev Emitted when the URI for token type `id` changes to `value`, if it is a non-programmatic URI. * * If an {URI} event was emitted for `id`, the standard * https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[guarantees] that `value` will equal the value * returned by {IERC1155MetadataURI-uri}. */ event URI(string value, uint256 indexed id); /** * @dev Returns the amount of tokens of token type `id` owned by `account`. * * Requirements: * * - `account` cannot be the zero address. */ function balanceOf(address account, uint256 id) external view returns (uint256); /** * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {balanceOf}. * * Requirements: * * - `accounts` and `ids` must have the same length. */ function balanceOfBatch(address[] calldata accounts, uint256[] calldata ids) external view returns (uint256[] memory); /** * @dev Grants or revokes permission to `operator` to transfer the caller's tokens, according to `approved`, * * Emits an {ApprovalForAll} event. * * Requirements: * * - `operator` cannot be the caller. */ function setApprovalForAll(address operator, bool approved) external; /** * @dev Returns true if `operator` is approved to transfer ``account``'s tokens. * * See {setApprovalForAll}. */ function isApprovedForAll(address account, address operator) external view returns (bool); /** * @dev Transfers `amount` tokens of token type `id` from `from` to `to`. * * Emits a {TransferSingle} event. * * Requirements: * * - `to` cannot be the zero address. * - If the caller is not `from`, it must be have been approved to spend ``from``'s tokens via {setApprovalForAll}. * - `from` must have a balance of tokens of type `id` of at least `amount`. * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the * acceptance magic value. */ function safeTransferFrom( address from, address to, uint256 id, uint256 amount, bytes calldata data ) external; /** * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {safeTransferFrom}. * * Emits a {TransferBatch} event. * * Requirements: * * - `ids` and `amounts` must have the same length. * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the * acceptance magic value. */ function safeBatchTransferFrom( address from, address to, uint256[] calldata ids, uint256[] calldata amounts, bytes calldata data ) external; } // File: contracts\model\IERC1155Views.sol // SPDX_License_Identifier: MIT pragma solidity >=0.7.0; /** * @title IERC1155Views - An optional utility interface to improve the ERC-1155 Standard. * @dev This interface introduces some additional capabilities for ERC-1155 Tokens. */ interface IERC1155Views { /** * @dev Returns the total supply of the given token id * @param itemId the id of the token whose availability you want to know */ function totalSupply(uint256 itemId) external view returns (uint256); /** * @dev Returns the name of the given token id * @param itemId the id of the token whose name you want to know */ function name(uint256 itemId) external view returns (string memory); /** * @dev Returns the symbol of the given token id * @param itemId the id of the token whose symbol you want to know */ function symbol(uint256 itemId) external view returns (string memory); /** * @dev Returns the decimals of the given token id * @param itemId the id of the token whose decimals you want to know */ function decimals(uint256 itemId) external view returns (uint256); /** * @dev Returns the uri of the given token id * @param itemId the id of the token whose uri you want to know */ function uri(uint256 itemId) external view returns (string memory); } // File: contracts\model\Item.sol //SPDX_License_Identifier: MIT pragma solidity >=0.7.0; pragma abicoder v2; struct Header { address host; string name; string symbol; string uri; } struct CreateItem { Header header; bytes32 collectionId; uint256 id; address[] accounts; uint256[] amounts; } interface Item is IERC1155, IERC1155Views { event CollectionItem(bytes32 indexed fromCollectionId, bytes32 indexed toCollectionId, uint256 indexed itemId); function name() external view returns(string memory); function symbol() external view returns(string memory); function decimals() external view returns(uint256); function burn(address account, uint256 itemId, uint256 amount) external; function burnBatch(address account, uint256[] calldata itemIds, uint256[] calldata amounts) external; function burn(address account, uint256 itemId, uint256 amount, bytes calldata data) external; function burnBatch(address account, uint256[] calldata itemIds, uint256[] calldata amounts, bytes calldata data) external; function mintItems(CreateItem[] calldata items) external returns(uint256[] memory itemIds); function setItemsCollection(uint256[] calldata itemIds, bytes32[] calldata collectionIds) external returns(bytes32[] memory oldCollectionIds); function setItemsMetadata(uint256[] calldata itemIds, Header[] calldata newValues) external returns(Header[] memory oldValues); function interoperableOf(uint256 itemId) external view returns(address); } // File: contracts\model\IItemMainInterface.sol //SPDX_License_Identifier: MIT pragma solidity >=0.7.0; struct ItemData { bytes32 collectionId; Header header; bytes32 domainSeparator; uint256 totalSupply; mapping(address => uint256) balanceOf; mapping(address => mapping(address => uint256)) allowance; mapping(address => uint256) nonces; } interface IItemMainInterface is Item { event Collection(address indexed from, address indexed to, bytes32 indexed collectionId); function interoperableInterfaceModel() external view returns(address); function uri() external view returns(string memory); function plainUri() external view returns(string memory); function dynamicUriResolver() external view returns(address); function hostInitializer() external view returns(address); function collection(bytes32 collectionId) external view returns(address host, string memory name, string memory symbol, string memory uri); function collectionUri(bytes32 collectionId) external view returns(string memory); function createCollection(Header calldata _collection, CreateItem[] calldata items) external returns(bytes32 collectionId, uint256[] memory itemIds); function setCollectionsMetadata(bytes32[] calldata collectionIds, Header[] calldata values) external returns(Header[] memory oldValues); function setApprovalForAllByCollectionHost(bytes32 collectionId, address account, address operator, bool approved) external; function item(uint256 itemId) external view returns(bytes32 collectionId, Header memory header, bytes32 domainSeparator, uint256 totalSupply); function mintTransferOrBurn(bool isMulti, bytes calldata data) external; function allowance(address account, address spender, uint256 itemId) external view returns(uint256); function approve(address account, address spender, uint256 amount, uint256 itemId) external; function TYPEHASH_PERMIT() external view returns (bytes32); function EIP712_PERMIT_DOMAINSEPARATOR_NAME_AND_VERSION() external view returns(string memory domainSeparatorName, string memory domainSeparatorVersion); function permit(uint256 itemId, address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s) external; function nonces(address owner, uint256 itemId) external view returns(uint256); } // File: @openzeppelin\contracts\token\ERC20\IERC20.sol // SPDX_License_Identifier: MIT pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20 { /** * @dev Returns the amount of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the amount of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves `amount` tokens from the caller's account to `recipient`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address recipient, uint256 amount) external returns (bool); /** * @dev Returns the remaining number of tokens that `spender` will be * allowed to spend on behalf of `owner` through {transferFrom}. This is * zero by default. * * This value changes when {approve} or {transferFrom} are called. */ function allowance(address owner, address spender) external view returns (uint256); /** * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. * * Returns a boolean value indicating whether the operation succeeded. * * IMPORTANT: Beware that changing an allowance with this method brings the risk * that someone may use both the old and the new allowance by unfortunate * transaction ordering. One possible solution to mitigate this race * condition is to first reduce the spender's allowance to 0 and set the * desired value afterwards: * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 * * Emits an {Approval} event. */ function approve(address spender, uint256 amount) external returns (bool); /** * @dev Moves `amount` tokens from `sender` to `recipient` using the * allowance mechanism. `amount` is then deducted from the caller's * allowance. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transferFrom( address sender, address recipient, uint256 amount ) external returns (bool); /** * @dev Emitted when `value` tokens are moved from one account (`from`) to * another (`to`). * * Note that `value` may be zero. */ event Transfer(address indexed from, address indexed to, uint256 value); /** * @dev Emitted when the allowance of a `spender` for an `owner` is set by * a call to {approve}. `value` is the new allowance. */ event Approval(address indexed owner, address indexed spender, uint256 value); } // File: @openzeppelin\contracts\token\ERC20\extensions\IERC20Metadata.sol // SPDX_License_Identifier: MIT pragma solidity ^0.8.0; /** * @dev Interface for the optional metadata functions from the ERC20 standard. * * _Available since v4.1._ */ interface IERC20Metadata is IERC20 { /** * @dev Returns the name of the token. */ function name() external view returns (string memory); /** * @dev Returns the symbol of the token. */ function symbol() external view returns (string memory); /** * @dev Returns the decimals places of the token. */ function decimals() external view returns (uint8); } // File: @openzeppelin\contracts\token\ERC20\extensions\draft-IERC20Permit.sol // SPDX_License_Identifier: MIT pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612]. * * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't * need to send a transaction, and thus is not required to hold Ether at all. */ interface IERC20Permit { /** * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens, * given ``owner``'s signed approval. * * IMPORTANT: The same issues {IERC20-approve} has related to transaction * ordering also apply here. * * Emits an {Approval} event. * * Requirements: * * - `spender` cannot be the zero address. * - `deadline` must be a timestamp in the future. * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner` * over the EIP712-formatted function arguments. * - the signature must use ``owner``'s current nonce (see {nonces}). * * For more information on the signature format, see the * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP * section]. */ function permit( address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) external; /** * @dev Returns the current nonce for `owner`. This value must be * included whenever a signature is generated for {permit}. * * Every successful call to {permit} increases ``owner``'s nonce by one. This * prevents a signature from being used multiple times. */ function nonces(address owner) external view returns (uint256); /** * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}. */ // solhint-disable-next-line func-name-mixedcase function DOMAIN_SEPARATOR() external view returns (bytes32); } // File: contracts\model\IItemInteroperableInterface.sol //SPDX_License_Identifier: MIT pragma solidity >=0.7.0; interface IItemInteroperableInterface is IERC20, IERC20Metadata, IERC20Permit { function init() external; function mainInterface() external view returns(address); function itemId() external view returns(uint256); function emitEvent(bool forApprove, bool isMulti, bytes calldata data) external; function burn(uint256 amount) external; function burnFrom(address account, uint256 amount) external; function EIP712_PERMIT_DOMAINSEPARATOR_NAME_AND_VERSION() external view returns(string memory name, string memory version); } // File: contracts\impl\ItemInteroperableInterface.sol //SPDX_License_Identifier: MIT pragma solidity >=0.7.0; contract ItemInteroperableInterface is IItemInteroperableInterface { address public override mainInterface; function init() override external { require(mainInterface == address(0)); mainInterface = msg.sender; } function DOMAIN_SEPARATOR() external override view returns (bytes32 domainSeparatorValue) { (,,domainSeparatorValue,) = IItemMainInterface(mainInterface).item(itemId()); } function EIP712_PERMIT_DOMAINSEPARATOR_NAME_AND_VERSION() external override view returns(string memory, string memory) { return IItemMainInterface(mainInterface).EIP712_PERMIT_DOMAINSEPARATOR_NAME_AND_VERSION(); } function itemId() override public view returns(uint256) { return uint160(address(this)); } function emitEvent(bool forApprove, bool isMulti, bytes calldata data) override external { require(msg.sender == mainInterface, "Unauthorized"); if(isMulti) { (address[] memory froms, address[] memory tos, uint256[] memory amounts) = abi.decode(data, (address[], address[], uint256[])); for(uint256 i = 0; i < froms.length; i++) { if(forApprove) { emit Approval(froms[i], tos[i], amounts[i]); } else { emit Transfer(froms[i], tos[i], amounts[i]); } } return; } (address from, address to, uint256 amount) = abi.decode(data, (address, address, uint256)); if(forApprove) { emit Approval(from, to, amount); } else { emit Transfer(from, to, amount); } } function permit(address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s) override external { IItemMainInterface(mainInterface).permit(itemId(), owner, spender, value, deadline, v, r, s); emit Approval(owner, spender, value); } function burn(uint256 amount) override external { IItemMainInterface(mainInterface).mintTransferOrBurn(false, abi.encode(msg.sender, msg.sender, address(0), itemId(), amount)); emit Transfer(msg.sender, address(0), amount); } function burnFrom(address account, uint256 amount) external override { require(account != address(0), "burn zero address"); IItemMainInterface(mainInterface).mintTransferOrBurn(false, abi.encode(msg.sender, account, address(0), itemId(), amount)); emit Transfer(msg.sender, address(0), amount); } function name() override external view returns (string memory) { (, Header memory header,,) = IItemMainInterface(mainInterface).item(itemId()); return header.name; } function symbol() override external view returns (string memory) { (, Header memory header,,) = IItemMainInterface(mainInterface).item(itemId()); return header.symbol; } function decimals() override external pure returns (uint8) { return 18; } function nonces(address owner) external override view returns(uint256) { return IItemMainInterface(mainInterface).nonces(owner, itemId()); } function totalSupply() override external view returns (uint256 totalSupplyValue) { (,,, totalSupplyValue) = IItemMainInterface(mainInterface).item(itemId()); } function balanceOf(address account) override external view returns (uint256) { return IItemMainInterface(mainInterface).balanceOf(account, itemId()); } function allowance(address owner, address spender) override external view returns (uint256) { return IItemMainInterface(mainInterface).allowance(owner, spender, itemId()); } function approve(address spender, uint256 amount) override external returns(bool) { IItemMainInterface(mainInterface).approve(msg.sender, spender, amount, itemId()); emit Approval(msg.sender, spender, amount); return true; } function transfer(address recipient, uint256 amount) override external returns(bool) { return _transferFrom(msg.sender, recipient, amount); } function transferFrom(address sender, address recipient, uint256 amount) override external returns(bool) { return _transferFrom(sender, recipient, amount); } function _transferFrom(address sender, address recipient, uint256 amount) private returns(bool) { require(sender != address(0), "transfer from the zero address"); require(recipient != address(0), "transfer to the zero address"); IItemMainInterface(mainInterface).mintTransferOrBurn(false, abi.encode(msg.sender, sender, recipient, itemId(), amount)); emit Transfer(sender, recipient, amount); return true; } }
File 4 of 7: DelegationsManager
// SPDX-License-Identifier: MIT pragma solidity >=0.7.0; import "../../delegationsManager/model/IDelegationsManager.sol"; import "@ethereansos/swissknife/contracts/generic/impl/LazyInitCapableElement.sol"; import "@ethereansos/swissknife/contracts/factory/model/IFactory.sol"; import "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol"; import { BehaviorUtilities, ReflectionUtilities, TransferUtilities } from "@ethereansos/swissknife/contracts/lib/GeneralUtilities.sol"; import "@ethereansos/items-v2/contracts/model/Item.sol"; import "../../../core/model/IOrganization.sol"; import "../../delegation/model/IDelegationTokensManager.sol"; import { Getters, State } from "../../../base/lib/KnowledgeBase.sol"; import { DelegationGetters } from "../../lib/KnowledgeBase.sol"; import "@openzeppelin/contracts/token/ERC1155/IERC1155.sol"; import "@openzeppelin/contracts/token/ERC20/extensions/draft-IERC20Permit.sol"; import "@openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol"; contract DelegationsManager is IDelegationsManager, LazyInitCapableElement { using ReflectionUtilities for address; using Getters for IOrganization; using DelegationGetters for IOrganization; using TransferUtilities for address; uint256 private constant ONE_HUNDRED = 1e18; address private _collection; uint256 private _objectId; address private _treasuryManagerModelAddress; mapping(address => address) public override treasuryOf; mapping(uint256 => DelegationData) private _storage; mapping(address => uint256) private _index; uint256 public override size; uint256 public override maxSize; uint256 public override executorRewardPercentage; mapping(address => bool) public override factoryIsAllowed; mapping(address => bool) public override isBanned; bytes32 public flusherKey; mapping(address => uint256) private _paidFor; mapping(address => mapping(address => uint256)) private _retriever; uint256 private _attachInsurance; address private _attachInsuranceRetriever; constructor(bytes memory lazyInitData) LazyInitCapableElement(lazyInitData) { } function _lazyInit(bytes memory lazyInitData) internal override returns (bytes memory lazyInitResponse) { (maxSize, _treasuryManagerModelAddress, lazyInitResponse) = abi.decode(lazyInitData, (uint256, address, bytes)); (executorRewardPercentage, _collection, _objectId, lazyInitResponse) = abi.decode(lazyInitResponse, (uint256, address, uint256, bytes)); (_attachInsurance, _attachInsuranceRetriever, flusherKey, lazyInitResponse) = abi.decode(lazyInitResponse, (uint256, address, bytes32, bytes)); if(lazyInitResponse.length > 0) { (address[] memory allowedFactories, address[] memory bannedDelegations) = abi.decode(lazyInitResponse, (address[], address[])); for(uint256 i = 0; i < allowedFactories.length; i++) { factoryIsAllowed[allowedFactories[i]] = true; } for(uint256 i = 0; i < bannedDelegations.length; i++) { isBanned[bannedDelegations[i]] = true; } } lazyInitResponse = ""; } function _supportsInterface(bytes4 interfaceId) internal override pure returns(bool) { return interfaceId == type(IDelegationsManager).interfaceId || interfaceId == this.split.selector || interfaceId == this.supportedToken.selector || interfaceId == this.setSupportedToken.selector || interfaceId == this.maxSize.selector || interfaceId == this.setMaxSize.selector || interfaceId == this.size.selector || interfaceId == this.list.selector || interfaceId == this.partialList.selector || interfaceId == this.listByAddresses.selector || interfaceId == this.listByIndices.selector || interfaceId == this.exists.selector || interfaceId == this.treasuryOf.selector || interfaceId == this.get.selector || interfaceId == this.getByIndex.selector || interfaceId == this.set.selector || interfaceId == this.remove.selector || interfaceId == this.executorRewardPercentage.selector || interfaceId == this.getSplit.selector || interfaceId == this.factoryIsAllowed.selector || interfaceId == this.setFactoriesAllowed.selector || interfaceId == this.isBanned.selector || interfaceId == this.ban.selector || interfaceId == this.isValid.selector || interfaceId == this.payFor.selector || interfaceId == this.retirePayment.selector || interfaceId == this.attachInsurance.selector || interfaceId == this.setAttachInsurance.selector; } receive() external payable { } function supportedToken() external override view returns(address, uint256) { return (_collection, _objectId); } function setSupportedToken(address collection, uint256 objectId) external override authorizedOnly { _collection = collection; _objectId = objectId; } function setMaxSize(uint256 newValue) external override authorizedOnly returns(uint256 oldValue) { oldValue = maxSize; maxSize = newValue; } function list() override public view returns (DelegationData[] memory) { return partialList(0, size); } function partialList(uint256 start, uint256 offset) override public view returns (DelegationData[] memory delegations) { (uint256 projectedArraySize, uint256 projectedArrayLoopUpperBound) = BehaviorUtilities.calculateProjectedArraySizeAndLoopUpperBound(size, start, offset); if(projectedArraySize > 0) { delegations = new DelegationData[](projectedArraySize); uint256 cursor = 0; for(uint256 i = start; i < projectedArrayLoopUpperBound; i++) { delegations[cursor++] = _storage[i]; } } } function listByAddresses(address[] calldata delegationAddresses) override external view returns (DelegationData[] memory delegations) { delegations = new DelegationData[](delegationAddresses.length); for(uint256 i = 0; i < delegations.length; i++) { delegations[i] = _storage[_index[delegationAddresses[i]]]; } } function listByIndices(uint256[] memory indices) override public view returns (DelegationData[] memory delegations) { delegations = new DelegationData[](indices.length); for(uint256 i = 0; i < delegations.length; i++) { delegations[i] = _storage[indices[i]]; } } function exists(address delegationAddress) public override view returns(bool result, uint256 index, address treasuryAddress) { treasuryAddress = treasuryOf[delegationAddress]; result = delegationAddress != address(0) && _storage[index = _index[delegationAddress]].location == delegationAddress; } function get(address delegationAddress) external override view returns(DelegationData memory) { return _storage[_index[delegationAddress]]; } function getByIndex(uint256 index) override external view returns(DelegationData memory) { return _storage[index]; } function split(address executorRewardReceiver) external override { require(address(this).balance > 0, "No ETH"); (address[] memory receivers, uint256[] memory values) = getSplit(executorRewardReceiver); if(receivers.length == 0) { return; } for(uint256 i = 0; i < receivers.length; i++) { if(values[i] == 0) { continue; } receivers[i].submit(values[i], ""); } } function set() external override { _set(msg.sender); } function remove(address[] calldata delegationAddresses) external override authorizedOnly returns(DelegationData[] memory removedDelegations) { removedDelegations = new DelegationData[](delegationAddresses.length); for(uint256 i = 0; i < delegationAddresses.length; i++) { removedDelegations[i] = _remove(delegationAddresses[i]); } } function removeAll() external override authorizedOnly { while(size > 0) { _remove(size - 1); } } function setFactoriesAllowed(address[] memory factoryAddresses, bool[] memory allowed) external override authorizedOnly { for(uint256 i = 0; i < factoryAddresses.length; i++) { emit Factory(factoryAddresses[i], factoryIsAllowed[factoryAddresses[i]] = allowed[i]); } } function ban(address[] memory productAddresses) external override authorizedOnly { for(uint256 i = 0; i < productAddresses.length; i++) { isBanned[productAddresses[i]] = true; _remove(productAddresses[i]); _burn(productAddresses[i]); } } function isValid(address delegationAddress) public override view returns(bool) { if(isBanned[delegationAddress]) { return false; } IFactory factory = IFactory(ILazyInitCapableElement(delegationAddress).initializer()); if(!factoryIsAllowed[address(factory)]) { return false; } if(factory.deployer(delegationAddress) == address(0)) { return false; } return _paidFor[delegationAddress] >= attachInsurance(); } function getSplit(address executorRewardReceiver) public override view returns (address[] memory receivers, uint256[] memory values) { (address[] memory treasuries, uint256[] memory treasuryPercentages) = getSituation(); receivers = new address[](treasuries.length + (executorRewardPercentage == 0 ? 1 : 2)); values = new uint256[](receivers.length); uint256 availableAmount = address(this).balance; uint256 index = 0; if(executorRewardPercentage > 0) { receivers[index] = executorRewardReceiver != address(0) ? executorRewardReceiver : msg.sender; values[index] = _calculatePercentage(availableAmount, executorRewardPercentage); availableAmount -= values[index++]; } uint256 remainingAmount = availableAmount; for(uint256 i = 0; i < treasuries.length; i++) { receivers[index] = treasuries[i]; values[index] = _calculatePercentage(availableAmount, treasuryPercentages[i]); remainingAmount -= values[index++]; } receivers[index] = _flusher(); values[index] = remainingAmount; } function getSituation() public override view returns(address[] memory treasuries, uint256[] memory treasuryPercentages) { IDelegationsManager.DelegationData[] memory delegations = list(); uint256 totalSupply; uint256[] memory totalSupplyArray = new uint256[](delegations.length); treasuries = new address[](delegations.length); for(uint256 i = 0; i < delegations.length; i++) { totalSupplyArray[i] = _getDelegationTotalSupply(delegations[i].location); totalSupply += totalSupplyArray[i]; treasuries[i] = delegations[i].treasury; } treasuryPercentages = new uint256[](delegations.length); for(uint256 i = 0; i < treasuryPercentages.length; i++) { treasuryPercentages[i] = _retrievePercentage(totalSupplyArray[i], totalSupply); } } function attachInsurance() public override view returns (uint256) { if(_attachInsuranceRetriever != address(0)) { (bool result, bytes memory response) = _attachInsuranceRetriever.staticcall(abi.encodeWithSignature("get()")); if(!result || response.length == 0) { return 0; } return abi.decode(response, (uint256)); } return _attachInsurance; } function setAttachInsurance(uint256 value) external override authorizedOnly returns (uint256 oldValue) { oldValue = _attachInsurance; _attachInsurance = value; } function paidFor(address delegationAddress, address retriever) external override view returns(uint256 totalPaid, uint256 retrieverPaid) { totalPaid = _paidFor[delegationAddress]; retrieverPaid = _retriever[delegationAddress][retriever]; } function onERC1155Received(address, address from, uint256 objectId, uint256 amount, bytes calldata data) external returns(bytes4) { require(msg.sender == _collection && objectId == _objectId, "unauthorized"); (address delegationAddress, address retriever) = abi.decode(data, (address, address)); _payFor(delegationAddress, from, retriever, amount); return this.onERC1155Received.selector; } function onERC1155BatchReceived(address, address from, uint256[] calldata objectIds, uint256[] calldata amounts, bytes calldata data) external returns (bytes4) { require(_collection == msg.sender, "Unauthorized"); bytes[] memory payloads = abi.decode(data, (bytes[])); for(uint256 i = 0; i < objectIds.length; i++) { require(objectIds[i] == _objectId, "Unauthorized"); (address delegationAddress, address retriever) = abi.decode(payloads[i], (address, address)); _payFor(delegationAddress, from, retriever, amounts[i]); } return this.onERC1155BatchReceived.selector; } function payFor(address delegationAddress, uint256 amount, bytes memory permitSignature, address retriever) external payable override { require(_collection == address(0), "Use safeTransferFrom"); address erc20TokenAddress = address(uint160(_objectId)); require(erc20TokenAddress != address(0) ? msg.value == 0 : msg.value == amount, "ETH"); if(erc20TokenAddress != address(0) && permitSignature.length > 0) { (uint8 v, bytes32 r, bytes32 s, uint256 deadline) = abi.decode(permitSignature, (uint8, bytes32, bytes32, uint256)); IERC20Permit(erc20TokenAddress).permit(msg.sender, address(this), amount, deadline, v, r, s); } _payFor(delegationAddress, msg.sender, retriever, _safeTransferFrom(erc20TokenAddress, amount)); } function retirePayment(address delegationAddress, address receiver, bytes memory data) external override { require(delegationAddress != address(0), "Delegation"); require(!isBanned[delegationAddress], "banned"); (bool result,,) = exists(delegationAddress); require(!result, "still attached"); address realReceiver = receiver != address(0) ? receiver : msg.sender; uint256 amount = _retriever[delegationAddress][msg.sender]; require(amount > 0, "Amount"); _retriever[delegationAddress][msg.sender] = 0; _paidFor[delegationAddress] = _paidFor[delegationAddress] - amount; _giveBack(realReceiver, amount, data); } function _giveBack(address receiver, uint256 amount, bytes memory data) private { if(_collection == address(0)) { address(uint160(_objectId)).safeTransfer(receiver, amount); } else { IERC1155(_collection).safeTransferFrom(address(this), receiver, _objectId, amount, data); } } function _safeTransferFrom(address erc20TokenAddress, uint256 value) private returns(uint256) { if(erc20TokenAddress == address(0)) { return value; } uint256 previousBalance = erc20TokenAddress.balanceOf(address(this)); erc20TokenAddress.safeTransferFrom(msg.sender, address(this), value); uint256 actualBalance = erc20TokenAddress.balanceOf(address(this)); require(actualBalance > previousBalance); return actualBalance - previousBalance; } function _payFor(address delegationAddress, address from, address retriever, uint256 amount) private { require(amount > 0, "value"); require(delegationAddress != address(0), "Delegation"); require(!isBanned[delegationAddress], "banned"); _paidFor[delegationAddress] = _paidFor[delegationAddress] + amount; address realRetriever = retriever != address(0) ? retriever : from; _retriever[delegationAddress][realRetriever] = _retriever[delegationAddress][realRetriever] + amount; emit PaidFor(delegationAddress, from, realRetriever, amount); } function _set(address delegationAddress) private { require(maxSize == 0 || size < maxSize, "full"); (bool result,,) = exists(delegationAddress); require(!result, "exists"); require(isValid(delegationAddress), "not valid"); _index[delegationAddress] = size++; address treasuryAddress = treasuryOf[delegationAddress]; if(treasuryAddress == address(0)) { ILazyInitCapableElement(treasuryOf[delegationAddress] = treasuryAddress = _treasuryManagerModelAddress.clone()).lazyInit(abi.encode(delegationAddress, bytes(""))); } _storage[_index[delegationAddress]] = DelegationData({ location : delegationAddress, treasury : treasuryAddress }); emit DelegationSet(delegationAddress, treasuryAddress); } function _remove(address delegationAddress) private returns(DelegationData memory removedDelegation) { (bool result, uint256 index,) = exists(delegationAddress); removedDelegation = result ? _remove(index) : removedDelegation; } function _remove(uint256 index) private returns(DelegationData memory removedDelegation) { if(index >= size) { return removedDelegation; } delete _index[(removedDelegation = _storage[index]).location]; if(index != --size) { DelegationData memory lastEntry = _storage[size]; _storage[_index[lastEntry.location] = index] = lastEntry; } delete _storage[size]; } function _getDelegationTotalSupply(address delegationAddress) private view returns(uint256) { (address wrappedCollection, uint256 wrappedObjectId) = IOrganization(delegationAddress).tokensManager().wrapped(_collection, _objectId, address(this)); try Item(wrappedCollection).totalSupply(wrappedObjectId) returns (uint256 ts) { return ts; } catch { return 0; } } function _calculatePercentage(uint256 totalSupply, uint256 percentage) private pure returns(uint256) { return (totalSupply * ((percentage * 1e18) / ONE_HUNDRED)) / 1e18; } function _retrievePercentage(uint256 numerator, uint256 denominator) private pure returns(uint256) { if(denominator == 0) { return 0; } return (numerator * ONE_HUNDRED) / denominator; } function _flusher() private view returns (address flusher) { IOrganization org = IOrganization(host); if(flusherKey != bytes32(0)) { flusher = org.get(flusherKey); } flusher = flusher != address(0) ? flusher : address(org.treasuryManager()); } function _burn(address delegationsManagerAddress) private { uint256 value = _paidFor[delegationsManagerAddress]; if(value == 0) { return; } _paidFor[delegationsManagerAddress] = 0; if(_collection == address(0)) { address tokenAddress = address(uint160(_objectId)); if(tokenAddress == address(0)) { tokenAddress.safeTransfer(address(0), value); return; } try ERC20Burnable(tokenAddress).burn(value) { } catch { (bool result,) = tokenAddress.call(abi.encodeWithSelector(IERC20(tokenAddress).transfer.selector, address(0), value)); if(!result) { (result,) = tokenAddress.call(abi.encodeWithSelector(IERC20(tokenAddress).transfer.selector, 0x000000000000000000000000000000000000dEaD, value)); } } return; } try Item(_collection).burn(address(this), _objectId, value) { } catch { try Item(_collection).safeTransferFrom(address(this), address(0), _objectId, value, "") { } catch { _collection.call(abi.encodeWithSelector(Item(_collection).safeTransferFrom.selector, address(this), 0x000000000000000000000000000000000000dEaD, _objectId, value, bytes(""))); } } } }// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "../ERC20.sol"; import "../../../utils/Context.sol"; /** * @dev Extension of {ERC20} that allows token holders to destroy both their own * tokens and those that they have an allowance for, in a way that can be * recognized off-chain (via event analysis). */ abstract contract ERC20Burnable is Context, ERC20 { /** * @dev Destroys `amount` tokens from the caller. * * See {ERC20-_burn}. */ function burn(uint256 amount) public virtual { _burn(_msgSender(), amount); } /** * @dev Destroys `amount` tokens from `account`, deducting from the caller's * allowance. * * See {ERC20-_burn} and {ERC20-allowance}. * * Requirements: * * - the caller must have allowance for ``accounts``'s tokens of at least * `amount`. */ function burnFrom(address account, uint256 amount) public virtual { uint256 currentAllowance = allowance(account, _msgSender()); require(currentAllowance >= amount, "ERC20: burn amount exceeds allowance"); unchecked { _approve(account, _msgSender(), currentAllowance - amount); } _burn(account, amount); } } // SPDX-License-Identifier: MIT pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612]. * * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't * need to send a transaction, and thus is not required to hold Ether at all. */ interface IERC20Permit { /** * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens, * given ``owner``'s signed approval. * * IMPORTANT: The same issues {IERC20-approve} has related to transaction * ordering also apply here. * * Emits an {Approval} event. * * Requirements: * * - `spender` cannot be the zero address. * - `deadline` must be a timestamp in the future. * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner` * over the EIP712-formatted function arguments. * - the signature must use ``owner``'s current nonce (see {nonces}). * * For more information on the signature format, see the * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP * section]. */ function permit( address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) external; /** * @dev Returns the current nonce for `owner`. This value must be * included whenever a signature is generated for {permit}. * * Every successful call to {permit} increases ``owner``'s nonce by one. This * prevents a signature from being used multiple times. */ function nonces(address owner) external view returns (uint256); /** * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}. */ // solhint-disable-next-line func-name-mixedcase function DOMAIN_SEPARATOR() external view returns (bytes32); } // SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "../../utils/introspection/IERC165.sol"; /** * @dev Required interface of an ERC1155 compliant contract, as defined in the * https://eips.ethereum.org/EIPS/eip-1155[EIP]. * * _Available since v3.1._ */ interface IERC1155 is IERC165 { /** * @dev Emitted when `value` tokens of token type `id` are transferred from `from` to `to` by `operator`. */ event TransferSingle(address indexed operator, address indexed from, address indexed to, uint256 id, uint256 value); /** * @dev Equivalent to multiple {TransferSingle} events, where `operator`, `from` and `to` are the same for all * transfers. */ event TransferBatch( address indexed operator, address indexed from, address indexed to, uint256[] ids, uint256[] values ); /** * @dev Emitted when `account` grants or revokes permission to `operator` to transfer their tokens, according to * `approved`. */ event ApprovalForAll(address indexed account, address indexed operator, bool approved); /** * @dev Emitted when the URI for token type `id` changes to `value`, if it is a non-programmatic URI. * * If an {URI} event was emitted for `id`, the standard * https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[guarantees] that `value` will equal the value * returned by {IERC1155MetadataURI-uri}. */ event URI(string value, uint256 indexed id); /** * @dev Returns the amount of tokens of token type `id` owned by `account`. * * Requirements: * * - `account` cannot be the zero address. */ function balanceOf(address account, uint256 id) external view returns (uint256); /** * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {balanceOf}. * * Requirements: * * - `accounts` and `ids` must have the same length. */ function balanceOfBatch(address[] calldata accounts, uint256[] calldata ids) external view returns (uint256[] memory); /** * @dev Grants or revokes permission to `operator` to transfer the caller's tokens, according to `approved`, * * Emits an {ApprovalForAll} event. * * Requirements: * * - `operator` cannot be the caller. */ function setApprovalForAll(address operator, bool approved) external; /** * @dev Returns true if `operator` is approved to transfer ``account``'s tokens. * * See {setApprovalForAll}. */ function isApprovedForAll(address account, address operator) external view returns (bool); /** * @dev Transfers `amount` tokens of token type `id` from `from` to `to`. * * Emits a {TransferSingle} event. * * Requirements: * * - `to` cannot be the zero address. * - If the caller is not `from`, it must be have been approved to spend ``from``'s tokens via {setApprovalForAll}. * - `from` must have a balance of tokens of type `id` of at least `amount`. * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the * acceptance magic value. */ function safeTransferFrom( address from, address to, uint256 id, uint256 amount, bytes calldata data ) external; /** * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {safeTransferFrom}. * * Emits a {TransferBatch} event. * * Requirements: * * - `ids` and `amounts` must have the same length. * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the * acceptance magic value. */ function safeBatchTransferFrom( address from, address to, uint256[] calldata ids, uint256[] calldata amounts, bytes calldata data ) external; } // SPDX-License-Identifier: MIT pragma solidity >=0.7.0; import "../../core/model/IOrganization.sol"; import "../subDAOsManager/model/ISubDAOsManager.sol"; import "../delegationsManager/model/IDelegationsManager.sol"; import "../treasurySplitterManager/model/ITreasurySplitterManager.sol"; import "../investmentsManager/model/IInvestmentsManager.sol"; import "../delegation/model/IDelegationTokensManager.sol"; library Grimoire { bytes32 constant public COMPONENT_KEY_TREASURY_SPLITTER_MANAGER = 0x87a92f6bd20613c184485be8eadb46851dd4294a8359f902606085b8be6e7ae6; bytes32 constant public COMPONENT_KEY_SUBDAOS_MANAGER = 0x5b87d6e94145c2e242653a71b7d439a3638a93c3f0d32e1ea876f9fb1feb53e2; bytes32 constant public COMPONENT_KEY_DELEGATIONS_MANAGER = 0x49b87f4ee20613c184485be8eadb46851dd4294a8359f902606085b8be6e7ae6; bytes32 constant public COMPONENT_KEY_INVESTMENTS_MANAGER = 0x4f3ad97a91794a00945c0ead3983f793d34044c6300048d8b4ef95636edd234b; } library DelegationGrimoire { bytes32 constant public COMPONENT_KEY_TOKENS_MANAGER = 0x62b56c3ab20613c184485be8eadb46851dd4294a8359f902606085b8be9f7dc5; } library Getters { function treasurySplitterManager(IOrganization organization) internal view returns(ITreasurySplitterManager) { return ITreasurySplitterManager(organization.get(Grimoire.COMPONENT_KEY_TREASURY_SPLITTER_MANAGER)); } function subDAOsManager(IOrganization organization) internal view returns(ISubDAOsManager) { return ISubDAOsManager(organization.get(Grimoire.COMPONENT_KEY_SUBDAOS_MANAGER)); } function delegationsManager(IOrganization organization) internal view returns(IDelegationsManager) { return IDelegationsManager(organization.get(Grimoire.COMPONENT_KEY_DELEGATIONS_MANAGER)); } function investmentsManager(IOrganization organization) internal view returns(IInvestmentsManager) { return IInvestmentsManager(organization.get(Grimoire.COMPONENT_KEY_INVESTMENTS_MANAGER)); } } library Setters { function replaceTreasurySplitterManager(IOrganization organization, address newComponentAddress) internal returns(ITreasurySplitterManager oldComponent) { require(newComponentAddress != address(0), "void"); oldComponent = ITreasurySplitterManager(organization.set(IOrganization.Component(Grimoire.COMPONENT_KEY_TREASURY_SPLITTER_MANAGER, newComponentAddress, false, true))); } function replaceSubDAOsManager(IOrganization organization, address newComponentAddress) internal returns(ISubDAOsManager oldComponent) { require(newComponentAddress != address(0), "void"); oldComponent = ISubDAOsManager(organization.set(IOrganization.Component(Grimoire.COMPONENT_KEY_SUBDAOS_MANAGER, newComponentAddress, true, true))); } function replaceDelegationsManager(IOrganization organization, address newComponentAddress) internal returns(IDelegationsManager oldComponent) { require(newComponentAddress != address(0), "void"); oldComponent = IDelegationsManager(organization.set(IOrganization.Component(Grimoire.COMPONENT_KEY_DELEGATIONS_MANAGER, newComponentAddress, false, true))); } function replaceInvestmentsManager(IOrganization organization, address newComponentAddress) internal returns(IInvestmentsManager oldComponent) { require(newComponentAddress != address(0), "void"); oldComponent = IInvestmentsManager(organization.set(IOrganization.Component(Grimoire.COMPONENT_KEY_INVESTMENTS_MANAGER, newComponentAddress, false, true))); } } library DelegationGetters { function tokensManager(IOrganization organization) internal view returns(IDelegationTokensManager) { return IDelegationTokensManager(organization.get(DelegationGrimoire.COMPONENT_KEY_TOKENS_MANAGER)); } } library DelegationUtilities { using DelegationGetters for IOrganization; function extractVotingTokens(address delegationsManagerAddress, address delegationAddress) internal view returns (bytes memory) { IDelegationsManager delegationsManager = IDelegationsManager(delegationsManagerAddress); (bool exists,,) = delegationsManager.exists(delegationAddress); require(exists, "wrong address"); (address collection, uint256 tokenId) = delegationsManager.supportedToken(); (collection, tokenId) = IOrganization(delegationAddress).tokensManager().wrapped(collection, tokenId, delegationsManagerAddress); require(tokenId != 0, "Wrap tokens first"); address[] memory collections = new address[](1); uint256[] memory tokenIds = new uint256[](1); uint256[] memory weights = new uint256[](1); collections[0] = collection; tokenIds[0] = tokenId; weights[0] = 1; return abi.encode(collections, tokenIds, weights); } }// SPDX-License-Identifier: MIT pragma solidity >=0.7.0; import "../../core/model/IOrganization.sol"; import "../model/IMicroservicesManager.sol"; import "../model/IStateManager.sol"; import "../model/IProposalsManager.sol"; import "../model/ITreasuryManager.sol"; import { ReflectionUtilities, BytesUtilities } from "@ethereansos/swissknife/contracts/lib/GeneralUtilities.sol"; library Grimoire { bytes32 constant public COMPONENT_KEY_TREASURY_MANAGER = 0xcfe1633df53a0649d88d788961f26058c5e7a0b5644675f19f67bb2975827ba2; bytes32 constant public COMPONENT_KEY_STATE_MANAGER = 0xd1d09e8f5708558865b8acd5f13c69781ae600e42dbc7f52b8ef1b9e33dbcd36; bytes32 constant public COMPONENT_KEY_MICROSERVICES_MANAGER = 0x0aef4c8f864010d3e1817691f51ade95a646fffafd7f3df9cb8200def342cfd7; bytes32 constant public COMPONENT_KEY_PROPOSALS_MANAGER = 0xa504406933af7ca120d20b97dfc79ea9788beb3c4d3ac1ff9a2c292b2c28e0cc; } library Getters { function treasuryManager(IOrganization organization) internal view returns(ITreasuryManager) { return ITreasuryManager(organization.get(Grimoire.COMPONENT_KEY_TREASURY_MANAGER)); } function stateManager(IOrganization organization) internal view returns(IStateManager) { return IStateManager(organization.get(Grimoire.COMPONENT_KEY_STATE_MANAGER)); } function microservicesManager(IOrganization organization) internal view returns(IMicroservicesManager) { return IMicroservicesManager(organization.get(Grimoire.COMPONENT_KEY_MICROSERVICES_MANAGER)); } function proposalsManager(IOrganization organization) internal view returns(IProposalsManager) { return IProposalsManager(organization.get(Grimoire.COMPONENT_KEY_PROPOSALS_MANAGER)); } } library Setters { function replaceTreasuryManager(IOrganization organization, address newComponentAddress) internal returns(ITreasuryManager oldComponent) { require(newComponentAddress != address(0), "void"); oldComponent = ITreasuryManager(organization.set(IOrganization.Component(Grimoire.COMPONENT_KEY_TREASURY_MANAGER, newComponentAddress, false, true))); } function replaceStateManager(IOrganization organization, address newComponentAddress) internal returns(IStateManager oldComponent) { require(newComponentAddress != address(0), "void"); oldComponent = IStateManager(organization.set(IOrganization.Component(Grimoire.COMPONENT_KEY_STATE_MANAGER, newComponentAddress, false ,true))); } function replaceMicroservicesManager(IOrganization organization, address newComponentAddress) internal returns(IMicroservicesManager oldComponent) { require(newComponentAddress != address(0), "void"); oldComponent = IMicroservicesManager(organization.set(IOrganization.Component(Grimoire.COMPONENT_KEY_MICROSERVICES_MANAGER, newComponentAddress, true, true))); } function replaceProposalsManager(IOrganization organization, address newComponentAddress) internal returns(IProposalsManager oldComponent) { require(newComponentAddress != address(0), "void"); oldComponent = IProposalsManager(organization.set(IOrganization.Component(Grimoire.COMPONENT_KEY_PROPOSALS_MANAGER, newComponentAddress, true, true))); } } library Treasury { using ReflectionUtilities for address; function storeETH(IOrganization organization, uint256 value) internal { if(value != 0) { organization.get(Grimoire.COMPONENT_KEY_TREASURY_MANAGER).submit(value, ""); } } function callTemporaryFunction(ITreasuryManager treasuryManager, bytes4 selector, address subject, uint256 value, bytes memory data) internal returns(bytes memory response) { address oldServer = treasuryManager.setAdditionalFunction(selector, subject, false); response = address(treasuryManager).submit(value, abi.encodePacked(selector, data)); treasuryManager.setAdditionalFunction(selector, oldServer, false); } } library State { using BytesUtilities for bytes; bytes32 constant public ENTRY_TYPE_ADDRESS = 0x421683f821a0574472445355be6d2b769119e8515f8376a1d7878523dfdecf7b; bytes32 constant public ENTRY_TYPE_ADDRESS_ARRAY = 0x23d8ff3dc5aed4a634bcf123581c95e70c60ac0e5246916790aef6d4451ff4c1; bytes32 constant public ENTRY_TYPE_BOOL = 0xc1053bdab4a5cf55238b667c39826bbb11a58be126010e7db397c1b67c24271b; bytes32 constant public ENTRY_TYPE_BOOL_ARRAY = 0x8761250c4d2c463ce51f91f5d2c2508fa9142f8a42aa9f30b965213bf3e6c2ac; bytes32 constant public ENTRY_TYPE_BYTES = 0xb963e9b45d014edd60cff22ec9ad383335bbc3f827be2aee8e291972b0fadcf2; bytes32 constant public ENTRY_TYPE_BYTES_ARRAY = 0x084b42f8a8730b98eb0305d92103d9107363192bb66162064a34dc5716ebe1a0; bytes32 constant public ENTRY_TYPE_STRING = 0x97fc46276c172633607a331542609db1e3da793fca183d594ed5a61803a10792; bytes32 constant public ENTRY_TYPE_STRING_ARRAY = 0xa227fd7a847724343a7dda3598ee0fb2d551b151b73e4a741067596daa6f5658; bytes32 constant public ENTRY_TYPE_UINT256 = 0xec13d6d12b88433319b64e1065a96ea19cd330ef6603f5f6fb685dde3959a320; bytes32 constant public ENTRY_TYPE_UINT256_ARRAY = 0xc1b76e99a35aa41ed28bbbd9e6c7228760c87b410ebac94fa6431da9b592411f; function getAddress(IStateManager stateManager, string memory name) internal view returns(address) { return stateManager.get(name).value.asAddress(); } function setAddress(IStateManager stateManager, string memory name, address val) internal returns(address oldValue) { return stateManager.set(IStateManager.StateEntry(name, ENTRY_TYPE_ADDRESS, abi.encodePacked(val))).asAddress(); } function getAddressArray(IStateManager stateManager, string memory name) internal view returns(address[] memory) { return stateManager.get(name).value.asAddressArray(); } function setAddressArray(IStateManager stateManager, string memory name, address[] memory val) internal returns(address[] memory oldValue) { return stateManager.set(IStateManager.StateEntry(name, ENTRY_TYPE_ADDRESS_ARRAY, abi.encode(val))).asAddressArray(); } function getBool(IStateManager stateManager, string memory name) internal view returns(bool) { return stateManager.get(name).value.asBool(); } function setBool(IStateManager stateManager, string memory name, bool val) internal returns(bool oldValue) { return stateManager.set(IStateManager.StateEntry(name, ENTRY_TYPE_BOOL, abi.encode(val ? 1 : 0))).asBool(); } function getBoolArray(IStateManager stateManager, string memory name) internal view returns(bool[] memory) { return stateManager.get(name).value.asBoolArray(); } function setBoolArray(IStateManager stateManager, string memory name, bool[] memory val) internal returns(bool[] memory oldValue) { return stateManager.set(IStateManager.StateEntry(name, ENTRY_TYPE_BOOL_ARRAY, abi.encode(val))).asBoolArray(); } function getBytes(IStateManager stateManager, string memory name) internal view returns(bytes memory) { return stateManager.get(name).value; } function setBytes(IStateManager stateManager, string memory name, bytes memory val) internal returns(bytes memory oldValue) { return stateManager.set(IStateManager.StateEntry(name, ENTRY_TYPE_BYTES, val)); } function getBytesArray(IStateManager stateManager, string memory name) internal view returns(bytes[] memory) { return stateManager.get(name).value.asBytesArray(); } function setBytesArray(IStateManager stateManager, string memory name, bytes[] memory val) internal returns(bytes[] memory oldValue) { return stateManager.set(IStateManager.StateEntry(name, ENTRY_TYPE_BYTES_ARRAY, abi.encode(val))).asBytesArray(); } function getString(IStateManager stateManager, string memory name) internal view returns(string memory) { return string(stateManager.get(name).value); } function setString(IStateManager stateManager, string memory name, string memory val) internal returns(string memory oldValue) { return string(stateManager.set(IStateManager.StateEntry(name, ENTRY_TYPE_STRING, bytes(val)))); } function getStringArray(IStateManager stateManager, string memory name) internal view returns(string[] memory) { return stateManager.get(name).value.asStringArray(); } function setStringArray(IStateManager stateManager, string memory name, string[] memory val) internal returns(string[] memory oldValue) { return stateManager.set(IStateManager.StateEntry(name, ENTRY_TYPE_STRING_ARRAY, abi.encode(val))).asStringArray(); } function getUint256(IStateManager stateManager, string memory name) internal view returns(uint256) { return stateManager.get(name).value.asUint256(); } function setUint256(IStateManager stateManager, string memory name, uint256 val) internal returns(uint256 oldValue) { return stateManager.set(IStateManager.StateEntry(name, ENTRY_TYPE_UINT256, abi.encode(val))).asUint256(); } function getUint256Array(IStateManager stateManager, string memory name) internal view returns(uint256[] memory) { return stateManager.get(name).value.asUint256Array(); } function setUint256Array(IStateManager stateManager, string memory name, uint256[] memory val) internal returns(uint256[] memory oldValue) { return stateManager.set(IStateManager.StateEntry(name, ENTRY_TYPE_UINT256_ARRAY, abi.encode(val))).asUint256Array(); } }// SPDX-License-Identifier: MIT pragma solidity >=0.7.0; import "@ethereansos/swissknife/contracts/generic/model/ILazyInitCapableElement.sol"; import "@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol"; interface IDelegationTokensManager is ILazyInitCapableElement, IERC1155Receiver { event Wrapped(address sourceAddress, uint256 sourceObjectId, address indexed sourceDelegationsManagerAddress, uint256 indexed wrappedObjectId); function itemMainInterfaceAddress() external view returns(address); function projectionAddress() external view returns(address); function collectionId() external view returns(bytes32); function ticker() external view returns(string memory); function wrap(address sourceDelegationsManagerAddress, bytes memory permitSignature, uint256 amount, address receiver) payable external returns(uint256 wrappedObjectId); function wrapped(address sourceCollection, uint256 sourceObjectId, address sourceDelegationsManagerAddress) external view returns(address wrappedCollection, uint256 wrappedObjectId); function source(uint256 wrappedObjectId) external view returns(address sourceCollectionAddress, uint256 sourceObjectId, address sourceDelegationsManagerAddress); }// SPDX-License-Identifier: MIT pragma solidity >=0.7.0; import "@ethereansos/swissknife/contracts/dynamicMetadata/model/IDynamicMetadataCapableElement.sol"; interface IOrganization is IDynamicMetadataCapableElement { struct Component { bytes32 key; address location; bool active; bool log; } function keyOf(address componentAddress) external view returns(bytes32); function history(bytes32 key) external view returns(address[] memory componentsAddresses); function batchHistory(bytes32[] calldata keys) external view returns(address[][] memory componentsAddresses); function get(bytes32 key) external view returns(address componentAddress); function list(bytes32[] calldata keys) external view returns(address[] memory componentsAddresses); function isActive(address subject) external view returns(bool); function keyIsActive(bytes32 key) external view returns(bool); function set(Component calldata) external returns(address replacedComponentAddress); function batchSet(Component[] calldata) external returns (address[] memory replacedComponentAddresses); event ComponentSet(bytes32 indexed key, address indexed from, address indexed to, bool active); function submit(address location, bytes calldata payload, address restReceiver) external payable returns(bytes memory response); }//SPDX-License-Identifier: MIT pragma solidity >=0.7.0; pragma abicoder v2; import "@openzeppelin/contracts/token/ERC1155/IERC1155.sol"; import "./IERC1155Views.sol"; struct Header { address host; string name; string symbol; string uri; } struct CreateItem { Header header; bytes32 collectionId; uint256 id; address[] accounts; uint256[] amounts; } interface Item is IERC1155, IERC1155Views { event CollectionItem(bytes32 indexed fromCollectionId, bytes32 indexed toCollectionId, uint256 indexed itemId); function name() external view returns(string memory); function symbol() external view returns(string memory); function decimals() external view returns(uint256); function burn(address account, uint256 itemId, uint256 amount) external; function burnBatch(address account, uint256[] calldata itemIds, uint256[] calldata amounts) external; function burn(address account, uint256 itemId, uint256 amount, bytes calldata data) external; function burnBatch(address account, uint256[] calldata itemIds, uint256[] calldata amounts, bytes calldata data) external; function mintItems(CreateItem[] calldata items) external returns(uint256[] memory itemIds); function setItemsCollection(uint256[] calldata itemIds, bytes32[] calldata collectionIds) external returns(bytes32[] memory oldCollectionIds); function setItemsMetadata(uint256[] calldata itemIds, Header[] calldata newValues) external returns(Header[] memory oldValues); function interoperableOf(uint256 itemId) external view returns(address); }// SPDX-License-Identifier: MIT pragma solidity >=0.7.0; import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; library BehaviorUtilities { function randomKey(uint256 i) internal view returns (bytes32) { return keccak256(abi.encode(i, block.timestamp, block.number, tx.origin, tx.gasprice, block.coinbase, block.difficulty, msg.sender, blockhash(block.number - 5))); } function calculateProjectedArraySizeAndLoopUpperBound(uint256 arraySize, uint256 start, uint256 offset) internal pure returns(uint256 projectedArraySize, uint256 projectedArrayLoopUpperBound) { if(arraySize != 0 && start < arraySize && offset != 0) { uint256 length = start + offset; if(start < (length = length > arraySize ? arraySize : length)) { projectedArraySize = (projectedArrayLoopUpperBound = length) - start; } } } } library ReflectionUtilities { function read(address subject, bytes memory inputData) internal view returns(bytes memory returnData) { bool result; (result, returnData) = subject.staticcall(inputData); if(!result) { assembly { revert(add(returnData, 0x20), mload(returnData)) } } } function submit(address subject, uint256 value, bytes memory inputData) internal returns(bytes memory returnData) { bool result; (result, returnData) = subject.call{value : value}(inputData); if(!result) { assembly { revert(add(returnData, 0x20), mload(returnData)) } } } function isContract(address subject) internal view returns (bool) { if(subject == address(0)) { return false; } uint256 codeLength; assembly { codeLength := extcodesize(subject) } return codeLength > 0; } function clone(address originalContract) internal returns(address copyContract) { assembly { mstore( 0, or( 0x5880730000000000000000000000000000000000000000803b80938091923cF3, mul(originalContract, 0x1000000000000000000) ) ) copyContract := create(0, 0, 32) switch extcodesize(copyContract) case 0 { invalid() } } } } library BytesUtilities { bytes private constant ALPHABET = "0123456789abcdef"; string internal constant BASE64_ENCODER_DATA = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'; function asAddress(bytes memory b) internal pure returns(address) { if(b.length == 0) { return address(0); } if(b.length == 20) { address addr; assembly { addr := mload(add(b, 20)) } return addr; } return abi.decode(b, (address)); } function asAddressArray(bytes memory b) internal pure returns(address[] memory callResult) { if(b.length > 0) { return abi.decode(b, (address[])); } } function asBool(bytes memory bs) internal pure returns(bool) { return asUint256(bs) != 0; } function asBoolArray(bytes memory b) internal pure returns(bool[] memory callResult) { if(b.length > 0) { return abi.decode(b, (bool[])); } } function asBytesArray(bytes memory b) internal pure returns(bytes[] memory callResult) { if(b.length > 0) { return abi.decode(b, (bytes[])); } } function asString(bytes memory b) internal pure returns(string memory callResult) { if(b.length > 0) { return abi.decode(b, (string)); } } function asStringArray(bytes memory b) internal pure returns(string[] memory callResult) { if(b.length > 0) { return abi.decode(b, (string[])); } } function asUint256(bytes memory bs) internal pure returns(uint256 x) { if (bs.length >= 32) { assembly { x := mload(add(bs, add(0x20, 0))) } } } function asUint256Array(bytes memory b) internal pure returns(uint256[] memory callResult) { if(b.length > 0) { return abi.decode(b, (uint256[])); } } function toString(bytes memory data) internal pure returns(string memory) { bytes memory str = new bytes(2 + data.length * 2); str[0] = "0"; str[1] = "x"; for (uint256 i = 0; i < data.length; i++) { str[2+i*2] = ALPHABET[uint256(uint8(data[i] >> 4))]; str[3+i*2] = ALPHABET[uint256(uint8(data[i] & 0x0f))]; } return string(str); } function asSingletonArray(bytes memory a) internal pure returns(bytes[] memory array) { array = new bytes[](1); array[0] = a; } function toBase64(bytes memory data) internal pure returns (string memory) { if (data.length == 0) return ''; string memory table = BASE64_ENCODER_DATA; uint256 encodedLen = 4 * ((data.length + 2) / 3); string memory result = new string(encodedLen + 32); assembly { mstore(result, encodedLen) let tablePtr := add(table, 1) let dataPtr := data let endPtr := add(dataPtr, mload(data)) let resultPtr := add(result, 32) for {} lt(dataPtr, endPtr) {} { dataPtr := add(dataPtr, 3) let input := mload(dataPtr) mstore8(resultPtr, mload(add(tablePtr, and(shr(18, input), 0x3F)))) resultPtr := add(resultPtr, 1) mstore8(resultPtr, mload(add(tablePtr, and(shr(12, input), 0x3F)))) resultPtr := add(resultPtr, 1) mstore8(resultPtr, mload(add(tablePtr, and(shr( 6, input), 0x3F)))) resultPtr := add(resultPtr, 1) mstore8(resultPtr, mload(add(tablePtr, and( input, 0x3F)))) resultPtr := add(resultPtr, 1) } switch mod(mload(data), 3) case 1 { mstore(sub(resultPtr, 2), shl(240, 0x3d3d)) } case 2 { mstore(sub(resultPtr, 1), shl(248, 0x3d)) } } return result; } } library StringUtilities { bytes1 private constant CHAR_0 = bytes1('0'); bytes1 private constant CHAR_A = bytes1('A'); bytes1 private constant CHAR_a = bytes1('a'); bytes1 private constant CHAR_f = bytes1('f'); bytes internal constant BASE64_DECODER_DATA = hex"0000000000000000000000000000000000000000000000000000000000000000" hex"00000000000000000000003e0000003f3435363738393a3b3c3d000000000000" hex"00000102030405060708090a0b0c0d0e0f101112131415161718190000000000" hex"001a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132330000000000"; function isEmpty(string memory test) internal pure returns (bool) { return equals(test, ""); } function equals(string memory a, string memory b) internal pure returns(bool) { return keccak256(abi.encodePacked(a)) == keccak256(abi.encodePacked(b)); } function toLowerCase(string memory str) internal pure returns(string memory) { bytes memory bStr = bytes(str); for (uint256 i = 0; i < bStr.length; i++) { bStr[i] = bStr[i] >= 0x41 && bStr[i] <= 0x5A ? bytes1(uint8(bStr[i]) + 0x20) : bStr[i]; } return string(bStr); } function asBytes(string memory str) internal pure returns(bytes memory toDecode) { bytes memory data = abi.encodePacked(str); if(data.length == 0 || data[0] != "0" || (data[1] != "x" && data[1] != "X")) { return ""; } uint256 start = 2; toDecode = new bytes((data.length - 2) / 2); for(uint256 i = 0; i < toDecode.length; i++) { toDecode[i] = bytes1(_fromHexChar(uint8(data[start++])) + _fromHexChar(uint8(data[start++])) * 16); } } function toBase64(string memory input) internal pure returns(string memory) { return BytesUtilities.toBase64(abi.encodePacked(input)); } function fromBase64(string memory _data) internal pure returns (bytes memory) { bytes memory data = bytes(_data); if (data.length == 0) return new bytes(0); require(data.length % 4 == 0, "invalid base64 decoder input"); bytes memory table = BASE64_DECODER_DATA; uint256 decodedLen = (data.length / 4) * 3; bytes memory result = new bytes(decodedLen + 32); assembly { let lastBytes := mload(add(data, mload(data))) if eq(and(lastBytes, 0xFF), 0x3d) { decodedLen := sub(decodedLen, 1) if eq(and(lastBytes, 0xFFFF), 0x3d3d) { decodedLen := sub(decodedLen, 1) } } mstore(result, decodedLen) let tablePtr := add(table, 1) let dataPtr := data let endPtr := add(dataPtr, mload(data)) let resultPtr := add(result, 32) for {} lt(dataPtr, endPtr) {} { dataPtr := add(dataPtr, 4) let input := mload(dataPtr) let output := add( add( shl(18, and(mload(add(tablePtr, and(shr(24, input), 0xFF))), 0xFF)), shl(12, and(mload(add(tablePtr, and(shr(16, input), 0xFF))), 0xFF))), add( shl( 6, and(mload(add(tablePtr, and(shr( 8, input), 0xFF))), 0xFF)), and(mload(add(tablePtr, and( input , 0xFF))), 0xFF) ) ) mstore(resultPtr, shl(232, output)) resultPtr := add(resultPtr, 3) } } return result; } function _fromHexChar(uint8 c) private pure returns (uint8) { bytes1 charc = bytes1(c); return charc < CHAR_0 || charc > CHAR_f ? 0 : (charc < CHAR_A ? 0 : 10) + c - uint8(charc < CHAR_A ? CHAR_0 : charc < CHAR_a ? CHAR_A : CHAR_a); } } library Uint256Utilities { function asSingletonArray(uint256 n) internal pure returns(uint256[] memory array) { array = new uint256[](1); array[0] = n; } function toHex(uint256 _i) internal pure returns (string memory) { return BytesUtilities.toString(abi.encodePacked(_i)); } function toString(uint256 _i) internal pure returns (string memory _uintAsString) { if (_i == 0) { return "0"; } uint256 j = _i; uint256 len; while (j != 0) { len++; j /= 10; } bytes memory bstr = new bytes(len); uint256 k = len; while (_i != 0) { k = k-1; uint8 temp = (48 + uint8(_i - _i / 10 * 10)); bytes1 b1 = bytes1(temp); bstr[k] = b1; _i /= 10; } return string(bstr); } function sum(uint256[] memory arr) internal pure returns (uint256 result) { for(uint256 i = 0; i < arr.length; i++) { result += arr[i]; } } } library AddressUtilities { function asSingletonArray(address a) internal pure returns(address[] memory array) { array = new address[](1); array[0] = a; } function toString(address _addr) internal pure returns (string memory) { return _addr == address(0) ? "0x0000000000000000000000000000000000000000" : BytesUtilities.toString(abi.encodePacked(_addr)); } } library Bytes32Utilities { function asSingletonArray(bytes32 a) internal pure returns(bytes32[] memory array) { array = new bytes32[](1); array[0] = a; } function toString(bytes32 bt) internal pure returns (string memory) { return bt == bytes32(0) ? "0x0000000000000000000000000000000000000000000000000000000000000000" : BytesUtilities.toString(abi.encodePacked(bt)); } } library TransferUtilities { using ReflectionUtilities for address; function balanceOf(address erc20TokenAddress, address account) internal view returns(uint256) { if(erc20TokenAddress == address(0)) { return account.balance; } return abi.decode(erc20TokenAddress.read(abi.encodeWithSelector(IERC20(erc20TokenAddress).balanceOf.selector, account)), (uint256)); } function allowance(address erc20TokenAddress, address account, address spender) internal view returns(uint256) { if(erc20TokenAddress == address(0)) { return 0; } return abi.decode(erc20TokenAddress.read(abi.encodeWithSelector(IERC20(erc20TokenAddress).allowance.selector, account, spender)), (uint256)); } function safeApprove(address erc20TokenAddress, address spender, uint256 value) internal { bytes memory returnData = erc20TokenAddress.submit(0, abi.encodeWithSelector(IERC20(erc20TokenAddress).approve.selector, spender, value)); require(returnData.length == 0 || abi.decode(returnData, (bool)), 'APPROVE_FAILED'); } function safeTransfer(address erc20TokenAddress, address to, uint256 value) internal { if(value == 0) { return; } if(erc20TokenAddress == address(0)) { to.submit(value, ""); return; } bytes memory returnData = erc20TokenAddress.submit(0, abi.encodeWithSelector(IERC20(erc20TokenAddress).transfer.selector, to, value)); require(returnData.length == 0 || abi.decode(returnData, (bool)), 'TRANSFER_FAILED'); } function safeTransferFrom(address erc20TokenAddress, address from, address to, uint256 value) internal { if(value == 0) { return; } if(erc20TokenAddress == address(0)) { to.submit(value, ""); return; } bytes memory returnData = erc20TokenAddress.submit(0, abi.encodeWithSelector(IERC20(erc20TokenAddress).transferFrom.selector, from, to, value)); require(returnData.length == 0 || abi.decode(returnData, (bool)), 'TRANSFERFROM_FAILED'); } }// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "../IERC20.sol"; /** * @dev Interface for the optional metadata functions from the ERC20 standard. * * _Available since v4.1._ */ interface IERC20Metadata is IERC20 { /** * @dev Returns the name of the token. */ function name() external view returns (string memory); /** * @dev Returns the symbol of the token. */ function symbol() external view returns (string memory); /** * @dev Returns the decimals places of the token. */ function decimals() external view returns (uint8); } // SPDX-License-Identifier: MIT pragma solidity >=0.7.0; import "../../dynamicMetadata/model/IDynamicMetadataCapableElement.sol"; interface IFactory is IDynamicMetadataCapableElement { event Deployed(address indexed modelAddress, address indexed deployedAddress, address indexed deployer, bytes deployedLazyInitResponse); function modelAddress() external view returns(address); function setModelAddress(address newValue) external returns(address oldValue); function deployer(address deployedAddress) external view returns(address); function deploy(bytes calldata deployData) external payable returns(address deployedAddress, bytes memory deployedLazyInitResponse); }// SPDX-License-Identifier: MIT pragma solidity >=0.7.0; import "../model/ILazyInitCapableElement.sol"; import { ReflectionUtilities } from "../../lib/GeneralUtilities.sol"; abstract contract LazyInitCapableElement is ILazyInitCapableElement { using ReflectionUtilities for address; address public override initializer; address public override host; constructor(bytes memory lazyInitData) { if(lazyInitData.length > 0) { _privateLazyInit(lazyInitData); } } function lazyInit(bytes calldata lazyInitData) override external returns (bytes memory lazyInitResponse) { return _privateLazyInit(lazyInitData); } function supportsInterface(bytes4 interfaceId) override external view returns(bool) { return interfaceId == type(IERC165).interfaceId || interfaceId == this.supportsInterface.selector || interfaceId == type(ILazyInitCapableElement).interfaceId || interfaceId == this.lazyInit.selector || interfaceId == this.initializer.selector || interfaceId == this.subjectIsAuthorizedFor.selector || interfaceId == this.host.selector || interfaceId == this.setHost.selector || _supportsInterface(interfaceId); } function setHost(address newValue) external override authorizedOnly returns(address oldValue) { oldValue = host; host = newValue; emit Host(oldValue, newValue); } function subjectIsAuthorizedFor(address subject, address location, bytes4 selector, bytes calldata payload, uint256 value) public override virtual view returns(bool) { (bool chidlElementValidationIsConsistent, bool chidlElementValidationResult) = _subjectIsAuthorizedFor(subject, location, selector, payload, value); if(chidlElementValidationIsConsistent) { return chidlElementValidationResult; } if(subject == host) { return true; } if(!host.isContract()) { return false; } (bool result, bytes memory resultData) = host.staticcall(abi.encodeWithSelector(ILazyInitCapableElement(host).subjectIsAuthorizedFor.selector, subject, location, selector, payload, value)); return result && abi.decode(resultData, (bool)); } function _privateLazyInit(bytes memory lazyInitData) private returns (bytes memory lazyInitResponse) { require(initializer == address(0), "init"); initializer = msg.sender; (host, lazyInitResponse) = abi.decode(lazyInitData, (address, bytes)); emit Host(address(0), host); lazyInitResponse = _lazyInit(lazyInitResponse); } function _lazyInit(bytes memory) internal virtual returns (bytes memory) { return ""; } function _supportsInterface(bytes4 selector) internal virtual view returns (bool); function _subjectIsAuthorizedFor(address, address, bytes4, bytes calldata, uint256) internal virtual view returns(bool, bool) { } modifier authorizedOnly { require(_authorizedOnly(), "unauthorized"); _; } function _authorizedOnly() internal returns(bool) { return subjectIsAuthorizedFor(msg.sender, address(this), msg.sig, msg.data, msg.value); } }// SPDX-License-Identifier: MIT pragma solidity >=0.7.0; import "@ethereansos/swissknife/contracts/generic/model/ILazyInitCapableElement.sol"; interface IDelegationsManager is ILazyInitCapableElement { event DelegationSet(address indexed delegationAddress, address indexed treasuryAddress); event SupportedToken(address indexed collectionAddress, uint256 indexed objectId); event Factory(address indexed factory, bool indexed allowed); struct DelegationData { address location; address treasury; } function split(address executorRewardReceiver) external; function supportedToken() external view returns(address collection, uint256 objectId); function setSupportedToken(address collection, uint256 tokenId) external; function maxSize() external view returns(uint256); function setMaxSize(uint256 newValue) external returns (uint256 oldValue); function size() external view returns (uint256); function list() external view returns (DelegationData[] memory); function partialList(uint256 start, uint256 offset) external view returns (DelegationData[] memory); function listByAddresses(address[] calldata delegationAddresses) external view returns (DelegationData[] memory); function listByIndices(uint256[] calldata indices) external view returns (DelegationData[] memory); function exists(address delegationAddress) external view returns(bool result, uint256 index, address treasuryOf); function treasuryOf(address delegationAddress) external view returns(address treasuryAddress); function get(address delegationAddress) external view returns(DelegationData memory); function getByIndex(uint256 index) external view returns(DelegationData memory); function set() external; function remove(address[] calldata delegationAddresses) external returns(DelegationData[] memory removedDelegations); function removeAll() external; function executorRewardPercentage() external view returns(uint256); function getSplit(address executorRewardReceiver) external view returns (address[] memory receivers, uint256[] memory values); function getSituation() external view returns(address[] memory treasuries, uint256[] memory treasuryPercentages); function factoryIsAllowed(address factoryAddress) external view returns(bool); function setFactoriesAllowed(address[] memory factoryAddresses, bool[] memory allowed) external; function isBanned(address productAddress) external view returns(bool); function ban(address[] memory productAddresses) external; function isValid(address delegationAddress) external view returns(bool); event PaidFor(address indexed delegationAddress, address indexed from, address indexed retriever, uint256 amount); function paidFor(address delegationAddress, address retriever) external view returns(uint256 totalPaid, uint256 retrieverPaid); function payFor(address delegationAddress, uint256 amount, bytes memory permitSignature, address retriever) external payable; function retirePayment(address delegationAddress, address receiver, bytes memory data) external; function attachInsurance() external view returns (uint256); function setAttachInsurance(uint256 value) external returns (uint256 oldValue); }// SPDX-License-Identifier: MIT pragma solidity >=0.7.0; import "@ethereansos/swissknife/contracts/generic/model/ILazyInitCapableElement.sol"; import "@ethereansos/covenants/contracts/presto/IPrestoUniV3.sol"; interface IInvestmentsManager is ILazyInitCapableElement { function ONE_HUNDRED() external pure returns(uint256); function refundETHReceiver() external view returns(bytes32 key, address receiverAddress); function executorRewardPercentage() external view returns(uint256); function prestoAddress() external view returns(address prestoAddress); function tokenFromETHToBurn() external view returns(address addr); function tokensFromETH() external view returns(address[] memory addresses); function setTokensFromETH(address[] calldata addresses) external returns(address[] memory oldAddresses); function swapFromETH(PrestoOperation[] calldata tokensFromETHData, PrestoOperation calldata tokenFromETHToBurnData, address executorRewardReceiver) external returns (uint256[] memory tokenAmounts, uint256 tokenFromETHToBurnAmount, uint256 executorReward); function lastSwapToETHBlock() external view returns (uint256); function swapToETHInterval() external view returns (uint256); function nextSwapToETHBlock() external view returns (uint256); function tokensToETH() external view returns(address[] memory addresses, uint256[] memory percentages); function setTokensToETH(address[] calldata addresses, uint256[] calldata percentages) external returns(address[] memory oldAddresses, uint256[] memory oldPercentages); function swapToETH(PrestoOperation[] calldata tokensToETHData, address executorRewardReceiver) external returns (uint256[] memory executorRewards, uint256[] memory ethAmounts); }// SPDX-License-Identifier: MIT pragma solidity >=0.7.0; import "@ethereansos/swissknife/contracts/generic/model/ILazyInitCapableElement.sol"; interface ITreasurySplitterManager is ILazyInitCapableElement { event Splitted(bytes32 indexed subDAO, address indexed receiver, uint256 amount); function ONE_HUNDRED() external pure returns(uint256); function lastSplitBlock() external view returns (uint256); function splitInterval() external view returns (uint256); function nextSplitBlock() external view returns (uint256); function executorRewardPercentage() external view returns(uint256); function flushExecutorRewardPercentage() external view returns(uint256); function receiversAndPercentages() external view returns (bytes32[] memory keys, address[] memory addresses, uint256[] memory percentages); function flushReceiver() external view returns(bytes32 key, address addr); function flushERC20Tokens(address[] calldata tokenAddresses, address executorRewardReceiver) external; function splitTreasury(address executorRewardReceiver) external; }// SPDX-License-Identifier: MIT pragma solidity >=0.7.0; import "@ethereansos/swissknife/contracts/generic/model/ILazyInitCapableElement.sol"; interface ISubDAOsManager is ILazyInitCapableElement { struct SubDAOEntry { bytes32 key; address location; address newHost; } function keyOf(address subdaoAddress) external view returns(bytes32); function history(bytes32 key) external view returns(address[] memory subdaosAddresses); function batchHistory(bytes32[] calldata keys) external view returns(address[][] memory subdaosAddresses); function get(bytes32 key) external view returns(address subdaoAddress); function list(bytes32[] calldata keys) external view returns(address[] memory subdaosAddresses); function exists(address subject) external view returns(bool); function keyExists(bytes32 key) external view returns(bool); function set(bytes32 key, address location, address newHost) external returns(address replacedSubdaoAddress); function batchSet(SubDAOEntry[] calldata) external returns (address[] memory replacedSubdaoAddresses); function submit(bytes32 key, bytes calldata payload, address restReceiver) external payable returns(bytes memory response); event SubDAOSet(bytes32 indexed key, address indexed from, address indexed to); }// SPDX-License-Identifier: MIT pragma solidity >=0.7.0; import "@openzeppelin/contracts/utils/introspection/IERC165.sol"; interface ILazyInitCapableElement is IERC165 { function lazyInit(bytes calldata lazyInitData) external returns(bytes memory initResponse); function initializer() external view returns(address); event Host(address indexed from, address indexed to); function host() external view returns(address); function setHost(address newValue) external returns(address oldValue); function subjectIsAuthorizedFor(address subject, address location, bytes4 selector, bytes calldata payload, uint256 value) external view returns(bool); }// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "../../utils/introspection/IERC165.sol"; /** * @dev _Available since v3.1._ */ interface IERC1155Receiver is IERC165 { /** @dev Handles the receipt of a single ERC1155 token type. This function is called at the end of a `safeTransferFrom` after the balance has been updated. To accept the transfer, this must return `bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)"))` (i.e. 0xf23a6e61, or its own function selector). @param operator The address which initiated the transfer (i.e. msg.sender) @param from The address which previously owned the token @param id The ID of the token being transferred @param value The amount of tokens being transferred @param data Additional data with no specified format @return `bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)"))` if transfer is allowed */ function onERC1155Received( address operator, address from, uint256 id, uint256 value, bytes calldata data ) external returns (bytes4); /** @dev Handles the receipt of a multiple ERC1155 token types. This function is called at the end of a `safeBatchTransferFrom` after the balances have been updated. To accept the transfer(s), this must return `bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)"))` (i.e. 0xbc197c81, or its own function selector). @param operator The address which initiated the batch transfer (i.e. msg.sender) @param from The address which previously owned the token @param ids An array containing ids of each token being transferred (order and length must match values array) @param values An array containing amounts of each token being transferred (order and length must match ids array) @param data Additional data with no specified format @return `bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)"))` if transfer is allowed */ function onERC1155BatchReceived( address operator, address from, uint256[] calldata ids, uint256[] calldata values, bytes calldata data ) external returns (bytes4); } //SPDX-License-Identifier: MIT pragma solidity >=0.7.0; import "../../generic/model/ILazyInitCapableElement.sol"; interface IDynamicMetadataCapableElement is ILazyInitCapableElement { function uri() external view returns(string memory); function plainUri() external view returns(string memory); function setUri(string calldata newValue) external returns (string memory oldValue); function dynamicUriResolver() external view returns(address); function setDynamicUriResolver(address newValue) external returns(address oldValue); }// SPDX-License-Identifier: MIT pragma solidity >=0.7.0; import "@ethereansos/swissknife/contracts/generic/model/ILazyInitCapableElement.sol"; interface ITreasuryManager is ILazyInitCapableElement { struct TransferEntry { address token; uint256[] objectIds; uint256[] values; address receiver; bool safe; bool batch; bool withData; bytes data; } function transfer(address token, uint256 value, address receiver, uint256 tokenType, uint256 objectId, bool safe, bool withData, bytes calldata data) external returns(bool result, bytes memory returnData); function batchTransfer(TransferEntry[] calldata transferEntries) external returns(bool[] memory results, bytes[] memory returnDatas); function submit(address location, bytes calldata payload, address restReceiver) external payable returns(bytes memory response); function setAdditionalFunction(bytes4 selector, address newServer, bool log) external returns (address oldServer); event AdditionalFunction(address caller, bytes4 indexed selector, address indexed oldServer, address indexed newServer); }// SPDX-License-Identifier: MIT pragma solidity >=0.7.0; import "@ethereansos/swissknife/contracts/generic/model/ILazyInitCapableElement.sol"; import "@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol"; interface IProposalsManager is IERC1155Receiver, ILazyInitCapableElement { struct ProposalCode { address location; bytes bytecode; } struct ProposalCodes { ProposalCode[] codes; bool alsoTerminate; } struct Proposal { address proposer; address[] codeSequence; uint256 creationBlock; uint256 accept; uint256 refuse; address triggeringRules; address[] canTerminateAddresses; address[] validatorsAddresses; bool validationPassed; uint256 terminationBlock; bytes votingTokens; } struct ProposalConfiguration { address[] collections; uint256[] objectIds; uint256[] weights; address creationRules; address triggeringRules; address[] canTerminateAddresses; address[] validatorsAddresses; } function batchCreate(ProposalCodes[] calldata codeSequences) external returns(bytes32[] memory createdProposalIds); function list(bytes32[] calldata proposalIds) external view returns(Proposal[] memory); function votes(bytes32[] calldata proposalIds, address[] calldata voters, bytes32[][] calldata items) external view returns(uint256[][] memory accepts, uint256[][] memory refuses, uint256[][] memory toWithdraw); function weight(bytes32 code) external view returns(uint256); function vote(address erc20TokenAddress, bytes memory permitSignature, bytes32 proposalId, uint256 accept, uint256 refuse, address voter, bool alsoTerminate) external payable; function batchVote(bytes[] calldata data) external payable; function withdrawAll(bytes32[] memory proposalIds, address voterOrReceiver, bool afterTermination) external; function terminate(bytes32[] calldata proposalIds) external; function configuration() external view returns(ProposalConfiguration memory); function setConfiguration(ProposalConfiguration calldata newValue) external returns(ProposalConfiguration memory oldValue); function lastProposalId() external view returns(bytes32); function lastVoteBlock(address voter) external view returns (uint256); event ProposalCreated(address indexed proposer, address indexed code, bytes32 indexed proposalId); event ProposalWeight(bytes32 indexed proposalId, address indexed collection, uint256 indexed id, bytes32 key, uint256 weight); event ProposalTerminated(bytes32 indexed proposalId, bool result, bytes errorData); event Accept(bytes32 indexed proposalId, address indexed voter, bytes32 indexed item, uint256 amount); event MoveToAccept(bytes32 indexed proposalId, address indexed voter, bytes32 indexed item, uint256 amount); event RetireAccept(bytes32 indexed proposalId, address indexed voter, bytes32 indexed item, uint256 amount); event Refuse(bytes32 indexed proposalId, address indexed voter, bytes32 indexed item, uint256 amount); event MoveToRefuse(bytes32 indexed proposalId, address indexed voter, bytes32 indexed item, uint256 amount); event RetireRefuse(bytes32 indexed proposalId, address indexed voter, bytes32 indexed item, uint256 amount); } interface IProposalChecker { function check(address proposalsManagerAddress, bytes32 id, bytes calldata data, address from, address voter) external view returns(bool); } interface IExternalProposalsManagerCommands { function createProposalCodeSequence(bytes32 proposalId, IProposalsManager.ProposalCode[] memory codeSequenceInput, address sender) external returns (address[] memory codeSequence, IProposalsManager.ProposalConfiguration memory localConfiguration); function proposalCanBeFinalized(bytes32 proposalId, IProposalsManager.Proposal memory proposal, bool validationPassed, bool result) external view returns (bool); function isVotable(bytes32 proposalId, IProposalsManager.Proposal memory proposal, address from, address voter, bool voteOrWithtraw) external view returns (bytes memory response); }// SPDX-License-Identifier: MIT pragma solidity >=0.7.0; import "@ethereansos/swissknife/contracts/generic/model/ILazyInitCapableElement.sol"; interface IStateManager is ILazyInitCapableElement { struct StateEntry { string key; bytes32 entryType; bytes value; } function size() external view returns (uint256); function all() external view returns (StateEntry[] memory); function partialList(uint256 start, uint256 offset) external view returns (StateEntry[] memory); function list(string[] calldata keys) external view returns (StateEntry[] memory); function listByIndices(uint256[] calldata indices) external view returns (StateEntry[] memory); function exists(string calldata key) external view returns(bool result, uint256 index); function get(string calldata key) external view returns(StateEntry memory); function getByIndex(uint256 index) external view returns(StateEntry memory); function set(StateEntry calldata newValue) external returns(bytes memory replacedValue); function batchSet(StateEntry[] calldata newValues) external returns(bytes[] memory replacedValues); function remove(string calldata key) external returns(bytes32 removedType, bytes memory removedValue); function batchRemove(string[] calldata keys) external returns(bytes32[] memory removedTypes, bytes[] memory removedValues); function removeByIndices(uint256[] calldata indices) external returns(bytes32[] memory removedTypes, bytes[] memory removedValues); }// SPDX-License-Identifier: MIT pragma solidity >=0.7.0; import "@ethereansos/swissknife/contracts/generic/model/ILazyInitCapableElement.sol"; interface IMicroservicesManager is ILazyInitCapableElement { struct Microservice { string key; address location; string methodSignature; bool submittable; string returnAbiParametersArray; bool isInternal; bool needsSender; } function size() external view returns (uint256); function all() external view returns (Microservice[] memory); function partialList(uint256 start, uint256 offset) external view returns (Microservice[] memory); function list(string[] calldata keys) external view returns (Microservice[] memory); function listByIndices(uint256[] calldata indices) external view returns (Microservice[] memory); function exists(string calldata key) external view returns(bool result, uint256 index); function get(string calldata key) external view returns(Microservice memory); function getByIndex(uint256 index) external view returns(Microservice memory); function set(Microservice calldata newValue) external returns(Microservice memory replacedValue); function batchSet(Microservice[] calldata newValues) external returns(Microservice[] memory replacedValues); event MicroserviceAdded(address indexed sender, bytes32 indexed keyHash, string key, address indexed location, string methodSignature, bool submittable, string returnAbiParametersArray, bool isInternal, bool needsSender); function remove(string calldata key) external returns(Microservice memory removedValue); function batchRemove(string[] calldata keys) external returns(Microservice[] memory removedValues); function removeByIndices(uint256[] calldata indices) external returns(Microservice[] memory removedValues); event MicroserviceRemoved(address indexed sender, bytes32 indexed keyHash, string key, address indexed location, string methodSignature, bool submittable, string returnAbiParametersArray, bool isInternal, bool needsSender); function read(string calldata key, bytes calldata data) external view returns(bytes memory returnData); function submit(string calldata key, bytes calldata data) external payable returns(bytes memory returnData); }// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20 { /** * @dev Returns the amount of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the amount of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves `amount` tokens from the caller's account to `recipient`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address recipient, uint256 amount) external returns (bool); /** * @dev Returns the remaining number of tokens that `spender` will be * allowed to spend on behalf of `owner` through {transferFrom}. This is * zero by default. * * This value changes when {approve} or {transferFrom} are called. */ function allowance(address owner, address spender) external view returns (uint256); /** * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. * * Returns a boolean value indicating whether the operation succeeded. * * IMPORTANT: Beware that changing an allowance with this method brings the risk * that someone may use both the old and the new allowance by unfortunate * transaction ordering. One possible solution to mitigate this race * condition is to first reduce the spender's allowance to 0 and set the * desired value afterwards: * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 * * Emits an {Approval} event. */ function approve(address spender, uint256 amount) external returns (bool); /** * @dev Moves `amount` tokens from `sender` to `recipient` using the * allowance mechanism. `amount` is then deducted from the caller's * allowance. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transferFrom( address sender, address recipient, uint256 amount ) external returns (bool); /** * @dev Emitted when `value` tokens are moved from one account (`from`) to * another (`to`). * * Note that `value` may be zero. */ event Transfer(address indexed from, address indexed to, uint256 value); /** * @dev Emitted when the allowance of a `spender` for an `owner` is set by * a call to {approve}. `value` is the new allowance. */ event Approval(address indexed owner, address indexed spender, uint256 value); } // SPDX-License-Identifier: MIT pragma solidity ^0.8.0; /* * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ abstract contract Context { function _msgSender() internal view virtual returns (address) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { return msg.data; } } // SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "./IERC20.sol"; import "./extensions/IERC20Metadata.sol"; import "../../utils/Context.sol"; /** * @dev Implementation of the {IERC20} interface. * * This implementation is agnostic to the way tokens are created. This means * that a supply mechanism has to be added in a derived contract using {_mint}. * For a generic mechanism see {ERC20PresetMinterPauser}. * * TIP: For a detailed writeup see our guide * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How * to implement supply mechanisms]. * * We have followed general OpenZeppelin guidelines: functions revert instead * of returning `false` on failure. This behavior is nonetheless conventional * and does not conflict with the expectations of ERC20 applications. * * Additionally, an {Approval} event is emitted on calls to {transferFrom}. * This allows applications to reconstruct the allowance for all accounts just * by listening to said events. Other implementations of the EIP may not emit * these events, as it isn't required by the specification. * * Finally, the non-standard {decreaseAllowance} and {increaseAllowance} * functions have been added to mitigate the well-known issues around setting * allowances. See {IERC20-approve}. */ contract ERC20 is Context, IERC20, IERC20Metadata { mapping(address => uint256) private _balances; mapping(address => mapping(address => uint256)) private _allowances; uint256 private _totalSupply; string private _name; string private _symbol; /** * @dev Sets the values for {name} and {symbol}. * * The default value of {decimals} is 18. To select a different value for * {decimals} you should overload it. * * All two of these values are immutable: they can only be set once during * construction. */ constructor(string memory name_, string memory symbol_) { _name = name_; _symbol = symbol_; } /** * @dev Returns the name of the token. */ function name() public view virtual override returns (string memory) { return _name; } /** * @dev Returns the symbol of the token, usually a shorter version of the * name. */ function symbol() public view virtual override returns (string memory) { return _symbol; } /** * @dev Returns the number of decimals used to get its user representation. * For example, if `decimals` equals `2`, a balance of `505` tokens should * be displayed to a user as `5,05` (`505 / 10 ** 2`). * * Tokens usually opt for a value of 18, imitating the relationship between * Ether and Wei. This is the value {ERC20} uses, unless this function is * overridden; * * NOTE: This information is only used for _display_ purposes: it in * no way affects any of the arithmetic of the contract, including * {IERC20-balanceOf} and {IERC20-transfer}. */ function decimals() public view virtual override returns (uint8) { return 18; } /** * @dev See {IERC20-totalSupply}. */ function totalSupply() public view virtual override returns (uint256) { return _totalSupply; } /** * @dev See {IERC20-balanceOf}. */ function balanceOf(address account) public view virtual override returns (uint256) { return _balances[account]; } /** * @dev See {IERC20-transfer}. * * Requirements: * * - `recipient` cannot be the zero address. * - the caller must have a balance of at least `amount`. */ function transfer(address recipient, uint256 amount) public virtual override returns (bool) { _transfer(_msgSender(), recipient, amount); return true; } /** * @dev See {IERC20-allowance}. */ function allowance(address owner, address spender) public view virtual override returns (uint256) { return _allowances[owner][spender]; } /** * @dev See {IERC20-approve}. * * Requirements: * * - `spender` cannot be the zero address. */ function approve(address spender, uint256 amount) public virtual override returns (bool) { _approve(_msgSender(), spender, amount); return true; } /** * @dev See {IERC20-transferFrom}. * * Emits an {Approval} event indicating the updated allowance. This is not * required by the EIP. See the note at the beginning of {ERC20}. * * Requirements: * * - `sender` and `recipient` cannot be the zero address. * - `sender` must have a balance of at least `amount`. * - the caller must have allowance for ``sender``'s tokens of at least * `amount`. */ function transferFrom( address sender, address recipient, uint256 amount ) public virtual override returns (bool) { _transfer(sender, recipient, amount); uint256 currentAllowance = _allowances[sender][_msgSender()]; require(currentAllowance >= amount, "ERC20: transfer amount exceeds allowance"); unchecked { _approve(sender, _msgSender(), currentAllowance - amount); } return true; } /** * @dev Atomically increases the allowance granted to `spender` by the caller. * * This is an alternative to {approve} that can be used as a mitigation for * problems described in {IERC20-approve}. * * Emits an {Approval} event indicating the updated allowance. * * Requirements: * * - `spender` cannot be the zero address. */ function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) { _approve(_msgSender(), spender, _allowances[_msgSender()][spender] + addedValue); return true; } /** * @dev Atomically decreases the allowance granted to `spender` by the caller. * * This is an alternative to {approve} that can be used as a mitigation for * problems described in {IERC20-approve}. * * Emits an {Approval} event indicating the updated allowance. * * Requirements: * * - `spender` cannot be the zero address. * - `spender` must have allowance for the caller of at least * `subtractedValue`. */ function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) { uint256 currentAllowance = _allowances[_msgSender()][spender]; require(currentAllowance >= subtractedValue, "ERC20: decreased allowance below zero"); unchecked { _approve(_msgSender(), spender, currentAllowance - subtractedValue); } return true; } /** * @dev Moves `amount` of tokens from `sender` to `recipient`. * * This internal function is equivalent to {transfer}, and can be used to * e.g. implement automatic token fees, slashing mechanisms, etc. * * Emits a {Transfer} event. * * Requirements: * * - `sender` cannot be the zero address. * - `recipient` cannot be the zero address. * - `sender` must have a balance of at least `amount`. */ function _transfer( address sender, address recipient, uint256 amount ) internal virtual { require(sender != address(0), "ERC20: transfer from the zero address"); require(recipient != address(0), "ERC20: transfer to the zero address"); _beforeTokenTransfer(sender, recipient, amount); uint256 senderBalance = _balances[sender]; require(senderBalance >= amount, "ERC20: transfer amount exceeds balance"); unchecked { _balances[sender] = senderBalance - amount; } _balances[recipient] += amount; emit Transfer(sender, recipient, amount); _afterTokenTransfer(sender, recipient, amount); } /** @dev Creates `amount` tokens and assigns them to `account`, increasing * the total supply. * * Emits a {Transfer} event with `from` set to the zero address. * * Requirements: * * - `account` cannot be the zero address. */ function _mint(address account, uint256 amount) internal virtual { require(account != address(0), "ERC20: mint to the zero address"); _beforeTokenTransfer(address(0), account, amount); _totalSupply += amount; _balances[account] += amount; emit Transfer(address(0), account, amount); _afterTokenTransfer(address(0), account, amount); } /** * @dev Destroys `amount` tokens from `account`, reducing the * total supply. * * Emits a {Transfer} event with `to` set to the zero address. * * Requirements: * * - `account` cannot be the zero address. * - `account` must have at least `amount` tokens. */ function _burn(address account, uint256 amount) internal virtual { require(account != address(0), "ERC20: burn from the zero address"); _beforeTokenTransfer(account, address(0), amount); uint256 accountBalance = _balances[account]; require(accountBalance >= amount, "ERC20: burn amount exceeds balance"); unchecked { _balances[account] = accountBalance - amount; } _totalSupply -= amount; emit Transfer(account, address(0), amount); _afterTokenTransfer(account, address(0), amount); } /** * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens. * * This internal function is equivalent to `approve`, and can be used to * e.g. set automatic allowances for certain subsystems, etc. * * Emits an {Approval} event. * * Requirements: * * - `owner` cannot be the zero address. * - `spender` cannot be the zero address. */ function _approve( address owner, address spender, uint256 amount ) internal virtual { require(owner != address(0), "ERC20: approve from the zero address"); require(spender != address(0), "ERC20: approve to the zero address"); _allowances[owner][spender] = amount; emit Approval(owner, spender, amount); } /** * @dev Hook that is called before any transfer of tokens. This includes * minting and burning. * * Calling conditions: * * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens * will be transferred to `to`. * - when `from` is zero, `amount` tokens will be minted for `to`. * - when `to` is zero, `amount` of ``from``'s tokens will be burned. * - `from` and `to` are never both zero. * * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. */ function _beforeTokenTransfer( address from, address to, uint256 amount ) internal virtual {} /** * @dev Hook that is called after any transfer of tokens. This includes * minting and burning. * * Calling conditions: * * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens * has been transferred to `to`. * - when `from` is zero, `amount` tokens have been minted for `to`. * - when `to` is zero, `amount` of ``from``'s tokens have been burned. * - `from` and `to` are never both zero. * * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. */ function _afterTokenTransfer( address from, address to, uint256 amount ) internal virtual {} } // SPDX-License-Identifier: MIT pragma solidity ^0.8.0; /** * @dev Interface of the ERC165 standard, as defined in the * https://eips.ethereum.org/EIPS/eip-165[EIP]. * * Implementers can declare support of contract interfaces, which can then be * queried by others ({ERC165Checker}). * * For an implementation, see {ERC165}. */ interface IERC165 { /** * @dev Returns true if this contract implements the interface defined by * `interfaceId`. See the corresponding * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] * to learn more about how these ids are created. * * This function call must use less than 30 000 gas. */ function supportsInterface(bytes4 interfaceId) external view returns (bool); } // SPDX-License-Identifier: MIT pragma solidity >=0.7.0; /** * @title IERC1155Views - An optional utility interface to improve the ERC-1155 Standard. * @dev This interface introduces some additional capabilities for ERC-1155 Tokens. */ interface IERC1155Views { /** * @dev Returns the total supply of the given token id * @param itemId the id of the token whose availability you want to know */ function totalSupply(uint256 itemId) external view returns (uint256); /** * @dev Returns the name of the given token id * @param itemId the id of the token whose name you want to know */ function name(uint256 itemId) external view returns (string memory); /** * @dev Returns the symbol of the given token id * @param itemId the id of the token whose symbol you want to know */ function symbol(uint256 itemId) external view returns (string memory); /** * @dev Returns the decimals of the given token id * @param itemId the id of the token whose decimals you want to know */ function decimals(uint256 itemId) external view returns (uint256); /** * @dev Returns the uri of the given token id * @param itemId the id of the token whose uri you want to know */ function uri(uint256 itemId) external view returns (string memory); }//SPDX-License-Identifier: MIT pragma solidity >=0.7.0; pragma abicoder v2; import "./PrestoDataUniV3.sol"; interface IPrestoUniV3 { function ONE_HUNDRED() external view returns (uint256); function doubleProxy() external view returns (address); function feePercentage() external view returns (uint256); function feePercentageInfo() external view returns (uint256, address); function setDoubleProxy(address _doubleProxy) external; function setFeePercentage(uint256 _feePercentage) external; function execute(PrestoOperation[] memory operations) external payable returns(uint256[] memory outputAmounts); }//SPDX-License-Identifier: MIT pragma solidity >=0.7.0; struct PrestoOperation { address inputTokenAddress; uint256 inputTokenAmount; address ammPlugin; address[] liquidityPoolAddresses; address[] swapPath; bool enterInETH; bool exitInETH; uint256[] tokenMins; address[] receivers; uint256[] receiversPercentages; }
File 5 of 7: SubDAO
// SPDX-License-Identifier: MIT pragma solidity >=0.7.0; import "../model/ISubDAO.sol"; import "../../../core/impl/Organization.sol"; import "../../../base/model/IProposalsManager.sol"; import { AddressUtilities, ReflectionUtilities, Bytes32Utilities } from "@ethereansos/swissknife/contracts/lib/GeneralUtilities.sol"; import { Getters } from "../../../base/lib/KnowledgeBase.sol"; contract SubDAO is ISubDAO, Organization { using ReflectionUtilities for address; using Getters for IOrganization; using Bytes32Utilities for bytes32; using AddressUtilities for address; mapping(bytes32 => bytes) private _ballotData; mapping(bytes32 => bytes32) private _ballotOptions; SubDAOProposalModel[] private _proposalModels; uint256 public override presetArrayMaxSize; bool private _initToBeFinalized; bool internal _firstProposalSet; mapping(bytes32 => bool) private _persistent; mapping(bytes32 => bool) private _deprecated; constructor(bytes memory lazyInitData) Organization(lazyInitData) { } function _dynamicMetadataElementLazyInit(bytes memory lazyInitData) internal virtual override returns(bytes memory lazyInitResponse) { (_initToBeFinalized, presetArrayMaxSize, lazyInitResponse) = abi.decode(lazyInitData, (bool, uint256, bytes)); require(!_initToBeFinalized || host == address(0), "Init to be finalized"); SubDAOProposalModel[] memory models; (models, lazyInitResponse) = abi.decode(lazyInitResponse, (SubDAOProposalModel[], bytes)); if(models.length > 0) { _setProposalModels(models); } lazyInitResponse = abi.encode(_set(abi.decode(lazyInitResponse, (Component[])))); } function _dynamicMetadataElementSupportsInterface(bytes4 interfaceId) internal virtual pure override returns(bool) { return interfaceId == type(ISubDAO).interfaceId || interfaceId == this.proposalModels.selector || interfaceId == this.setProposalModels.selector || interfaceId == this.setVotingRules.selector || super._dynamicMetadataElementSupportsInterface(interfaceId); } function finalizeInit(address firstHost) external override authorizedOnly { _initToBeFinalized = false; host = firstHost; emit Host(address(0), host); } function proposalModels() external view override returns(SubDAOProposalModel[] memory) { return _proposalModels; } function setProposalModels(SubDAOProposalModel[] calldata newValue) external override authorizedOnly returns(SubDAOProposalModel[] memory oldValue) { return _setProposalModels(newValue); } function setInitialProposalModels(SubDAOProposalModel[] calldata newValue) external override { require(!_firstProposalSet, "already done"); require(msg.sender == initializer, "unauthorized"); _setProposalModels(newValue); } function setVotingRules(uint256 modelIndex, uint256 votingRulesIndex) external override authorizedOnly returns(address[] memory oldCanTerminateAddresses, address[] memory oldValidatorsAddresses) { require(modelIndex < _proposalModels.length, "index"); SubDAOProposalModel storage proposalModel = _proposalModels[modelIndex]; require(votingRulesIndex < proposalModel.canTerminateAddresses.length, "Invalid rule"); oldCanTerminateAddresses = proposalModel.canTerminateAddresses[votingRulesIndex]; oldValidatorsAddresses = proposalModel.validatorsAddresses[votingRulesIndex]; proposalModel.votingRulesIndex = votingRulesIndex; } function setCreationAndTriggeringRules(uint256 modelIndex, address newCreationRules, address newTriggeringRules) external override authorizedOnly returns(address oldCreationRules, address oldTriggeringRules) { SubDAOProposalModel storage proposalModel = _proposalModels[modelIndex]; oldCreationRules = proposalModel.creationRules; oldTriggeringRules = proposalModel.triggeringRules; proposalModel.creationRules = newCreationRules; proposalModel.triggeringRules = newTriggeringRules; } function setPresetValues(uint256 modelIndex, bytes[] memory newPresetValues) external override authorizedOnly returns(bytes[] memory oldPresetValues, bytes32[] memory deprecatedProposalIds) { SubDAOProposalModel storage proposalModel = _proposalModels[modelIndex]; require(proposalModel.isPreset, "Not preset"); oldPresetValues = proposalModel.presetValues; deprecatedProposalIds = proposalModel.presetProposals; for(uint256 i = 0; i < deprecatedProposalIds.length; i++) { bytes32 proposalId = deprecatedProposalIds[i]; if(proposalId != bytes32(0)) { _deprecated[proposalId] = true; } } proposalModel.presetValues = newPresetValues; proposalModel.presetProposals = new bytes32[](newPresetValues.length); } function isPersistent(bytes32 proposalId) public override view returns(bool result, bool isDeprecated) { result = _persistent[proposalId]; isDeprecated = _deprecated[proposalId]; } function createProposalCodeSequence(bytes32 proposalId, IProposalsManager.ProposalCode[] memory codeSequenceInput, address) external authorizedOnly override virtual returns (address[] memory codeSequence, IProposalsManager.ProposalConfiguration memory localConfiguration) { uint256 modelIndex = uint160(codeSequenceInput[0].location); bytes memory lazyInitData = codeSequenceInput[0].bytecode; require(modelIndex < _proposalModels.length, "Invalid model"); SubDAOProposalModel storage proposalModel = _proposalModels[modelIndex]; uint256 presetIndex = 0; if(proposalModel.isPreset) { require((presetIndex = abi.decode(lazyInitData, (uint256))) < proposalModel.presetValues.length, "Invalid preset"); require(proposalModel.presetProposals[presetIndex] == bytes32(0), "Preset created"); proposalModel.presetProposals[presetIndex] = proposalId; _persistent[proposalId] = true; lazyInitData = proposalModel.presetValues[presetIndex]; } emit Proposed(modelIndex, presetIndex, proposalId); codeSequence = proposalModel.source.clone().asSingletonArray(); lazyInitData = ILazyInitCapableElement(codeSequence[0]).lazyInit(abi.encode(proposalModel.uri, lazyInitData)); (address[] memory collections, uint256[] memory objectIds, uint256[] memory weights) = lazyInitData.length == 0 ? (new address[](0), new uint256[](0), new uint256[](0)) : abi.decode(lazyInitData, (address[], uint256[], uint256[])); localConfiguration = IProposalsManager.ProposalConfiguration( collections, objectIds, weights, proposalModel.creationRules, proposalModel.triggeringRules, proposalModel.canTerminateAddresses[proposalModel.votingRulesIndex], proposalModel.validatorsAddresses[proposalModel.votingRulesIndex] ); } function proposalCanBeFinalized(bytes32 proposalId, IProposalsManager.Proposal memory, bool validationPassed, bool result) external override view virtual returns (bool) { (bool persistent, bool deprecated) = isPersistent(proposalId); require(!persistent || !deprecated, "deprecated"); return !persistent && (!validationPassed || result); } function isVotable(bytes32 proposalId, IProposalsManager.Proposal memory, address, address, bool) external override view returns (bytes memory) { return _persistent[proposalId] ? abi.encode(true) : bytes(""); } function _setProposalModels(SubDAOProposalModel[] memory newValue) private returns(SubDAOProposalModel[] memory oldValue) { oldValue = _proposalModels; delete _proposalModels; for(uint256 i = 0; i < newValue.length; i++) { SubDAOProposalModel memory proposalModel = newValue[i]; proposalModel.presetProposals = new bytes32[](proposalModel.isPreset ? proposalModel.presetValues.length : 0); require(proposalModel.isPreset || proposalModel.presetValues.length == 0, "Not preset"); require(presetArrayMaxSize == 0 || proposalModel.presetValues.length <= presetArrayMaxSize, "Preset length"); require(proposalModel.canTerminateAddresses.length == 0 || proposalModel.votingRulesIndex < proposalModel.canTerminateAddresses.length, "Voting Rules"); require(proposalModel.canTerminateAddresses.length == proposalModel.validatorsAddresses.length, "Voting Rules"); _proposalModels.push(proposalModel); } _firstProposalSet = true; } function _subjectIsAuthorizedFor(address subject, address location, bytes4 selector, bytes calldata, uint256) internal virtual override view returns(bool, bool) { if(location == address(this) && subject == host ) { return (true, true); } if(location == address(this) && selector == this.finalizeInit.selector) { return (true, (host == address(0) && _initToBeFinalized)); } return (true, isActive(subject)); } }// SPDX-License-Identifier: MIT pragma solidity >=0.7.0; import "../../core/model/IOrganization.sol"; import "../model/IMicroservicesManager.sol"; import "../model/IStateManager.sol"; import "../model/IProposalsManager.sol"; import "../model/ITreasuryManager.sol"; import { ReflectionUtilities, BytesUtilities } from "@ethereansos/swissknife/contracts/lib/GeneralUtilities.sol"; library Grimoire { bytes32 constant public COMPONENT_KEY_TREASURY_MANAGER = 0xcfe1633df53a0649d88d788961f26058c5e7a0b5644675f19f67bb2975827ba2; bytes32 constant public COMPONENT_KEY_STATE_MANAGER = 0xd1d09e8f5708558865b8acd5f13c69781ae600e42dbc7f52b8ef1b9e33dbcd36; bytes32 constant public COMPONENT_KEY_MICROSERVICES_MANAGER = 0x0aef4c8f864010d3e1817691f51ade95a646fffafd7f3df9cb8200def342cfd7; bytes32 constant public COMPONENT_KEY_PROPOSALS_MANAGER = 0xa504406933af7ca120d20b97dfc79ea9788beb3c4d3ac1ff9a2c292b2c28e0cc; } library Getters { function treasuryManager(IOrganization organization) internal view returns(ITreasuryManager) { return ITreasuryManager(organization.get(Grimoire.COMPONENT_KEY_TREASURY_MANAGER)); } function stateManager(IOrganization organization) internal view returns(IStateManager) { return IStateManager(organization.get(Grimoire.COMPONENT_KEY_STATE_MANAGER)); } function microservicesManager(IOrganization organization) internal view returns(IMicroservicesManager) { return IMicroservicesManager(organization.get(Grimoire.COMPONENT_KEY_MICROSERVICES_MANAGER)); } function proposalsManager(IOrganization organization) internal view returns(IProposalsManager) { return IProposalsManager(organization.get(Grimoire.COMPONENT_KEY_PROPOSALS_MANAGER)); } } library Setters { function replaceTreasuryManager(IOrganization organization, address newComponentAddress) internal returns(ITreasuryManager oldComponent) { require(newComponentAddress != address(0), "void"); oldComponent = ITreasuryManager(organization.set(IOrganization.Component(Grimoire.COMPONENT_KEY_TREASURY_MANAGER, newComponentAddress, false, true))); } function replaceStateManager(IOrganization organization, address newComponentAddress) internal returns(IStateManager oldComponent) { require(newComponentAddress != address(0), "void"); oldComponent = IStateManager(organization.set(IOrganization.Component(Grimoire.COMPONENT_KEY_STATE_MANAGER, newComponentAddress, false ,true))); } function replaceMicroservicesManager(IOrganization organization, address newComponentAddress) internal returns(IMicroservicesManager oldComponent) { require(newComponentAddress != address(0), "void"); oldComponent = IMicroservicesManager(organization.set(IOrganization.Component(Grimoire.COMPONENT_KEY_MICROSERVICES_MANAGER, newComponentAddress, true, true))); } function replaceProposalsManager(IOrganization organization, address newComponentAddress) internal returns(IProposalsManager oldComponent) { require(newComponentAddress != address(0), "void"); oldComponent = IProposalsManager(organization.set(IOrganization.Component(Grimoire.COMPONENT_KEY_PROPOSALS_MANAGER, newComponentAddress, true, true))); } } library Treasury { using ReflectionUtilities for address; function storeETH(IOrganization organization, uint256 value) internal { if(value != 0) { organization.get(Grimoire.COMPONENT_KEY_TREASURY_MANAGER).submit(value, ""); } } function callTemporaryFunction(ITreasuryManager treasuryManager, bytes4 selector, address subject, uint256 value, bytes memory data) internal returns(bytes memory response) { address oldServer = treasuryManager.setAdditionalFunction(selector, subject, false); response = address(treasuryManager).submit(value, abi.encodePacked(selector, data)); treasuryManager.setAdditionalFunction(selector, oldServer, false); } } library State { using BytesUtilities for bytes; bytes32 constant public ENTRY_TYPE_ADDRESS = 0x421683f821a0574472445355be6d2b769119e8515f8376a1d7878523dfdecf7b; bytes32 constant public ENTRY_TYPE_ADDRESS_ARRAY = 0x23d8ff3dc5aed4a634bcf123581c95e70c60ac0e5246916790aef6d4451ff4c1; bytes32 constant public ENTRY_TYPE_BOOL = 0xc1053bdab4a5cf55238b667c39826bbb11a58be126010e7db397c1b67c24271b; bytes32 constant public ENTRY_TYPE_BOOL_ARRAY = 0x8761250c4d2c463ce51f91f5d2c2508fa9142f8a42aa9f30b965213bf3e6c2ac; bytes32 constant public ENTRY_TYPE_BYTES = 0xb963e9b45d014edd60cff22ec9ad383335bbc3f827be2aee8e291972b0fadcf2; bytes32 constant public ENTRY_TYPE_BYTES_ARRAY = 0x084b42f8a8730b98eb0305d92103d9107363192bb66162064a34dc5716ebe1a0; bytes32 constant public ENTRY_TYPE_STRING = 0x97fc46276c172633607a331542609db1e3da793fca183d594ed5a61803a10792; bytes32 constant public ENTRY_TYPE_STRING_ARRAY = 0xa227fd7a847724343a7dda3598ee0fb2d551b151b73e4a741067596daa6f5658; bytes32 constant public ENTRY_TYPE_UINT256 = 0xec13d6d12b88433319b64e1065a96ea19cd330ef6603f5f6fb685dde3959a320; bytes32 constant public ENTRY_TYPE_UINT256_ARRAY = 0xc1b76e99a35aa41ed28bbbd9e6c7228760c87b410ebac94fa6431da9b592411f; function getAddress(IStateManager stateManager, string memory name) internal view returns(address) { return stateManager.get(name).value.asAddress(); } function setAddress(IStateManager stateManager, string memory name, address val) internal returns(address oldValue) { return stateManager.set(IStateManager.StateEntry(name, ENTRY_TYPE_ADDRESS, abi.encodePacked(val))).asAddress(); } function getAddressArray(IStateManager stateManager, string memory name) internal view returns(address[] memory) { return stateManager.get(name).value.asAddressArray(); } function setAddressArray(IStateManager stateManager, string memory name, address[] memory val) internal returns(address[] memory oldValue) { return stateManager.set(IStateManager.StateEntry(name, ENTRY_TYPE_ADDRESS_ARRAY, abi.encode(val))).asAddressArray(); } function getBool(IStateManager stateManager, string memory name) internal view returns(bool) { return stateManager.get(name).value.asBool(); } function setBool(IStateManager stateManager, string memory name, bool val) internal returns(bool oldValue) { return stateManager.set(IStateManager.StateEntry(name, ENTRY_TYPE_BOOL, abi.encode(val ? 1 : 0))).asBool(); } function getBoolArray(IStateManager stateManager, string memory name) internal view returns(bool[] memory) { return stateManager.get(name).value.asBoolArray(); } function setBoolArray(IStateManager stateManager, string memory name, bool[] memory val) internal returns(bool[] memory oldValue) { return stateManager.set(IStateManager.StateEntry(name, ENTRY_TYPE_BOOL_ARRAY, abi.encode(val))).asBoolArray(); } function getBytes(IStateManager stateManager, string memory name) internal view returns(bytes memory) { return stateManager.get(name).value; } function setBytes(IStateManager stateManager, string memory name, bytes memory val) internal returns(bytes memory oldValue) { return stateManager.set(IStateManager.StateEntry(name, ENTRY_TYPE_BYTES, val)); } function getBytesArray(IStateManager stateManager, string memory name) internal view returns(bytes[] memory) { return stateManager.get(name).value.asBytesArray(); } function setBytesArray(IStateManager stateManager, string memory name, bytes[] memory val) internal returns(bytes[] memory oldValue) { return stateManager.set(IStateManager.StateEntry(name, ENTRY_TYPE_BYTES_ARRAY, abi.encode(val))).asBytesArray(); } function getString(IStateManager stateManager, string memory name) internal view returns(string memory) { return string(stateManager.get(name).value); } function setString(IStateManager stateManager, string memory name, string memory val) internal returns(string memory oldValue) { return string(stateManager.set(IStateManager.StateEntry(name, ENTRY_TYPE_STRING, bytes(val)))); } function getStringArray(IStateManager stateManager, string memory name) internal view returns(string[] memory) { return stateManager.get(name).value.asStringArray(); } function setStringArray(IStateManager stateManager, string memory name, string[] memory val) internal returns(string[] memory oldValue) { return stateManager.set(IStateManager.StateEntry(name, ENTRY_TYPE_STRING_ARRAY, abi.encode(val))).asStringArray(); } function getUint256(IStateManager stateManager, string memory name) internal view returns(uint256) { return stateManager.get(name).value.asUint256(); } function setUint256(IStateManager stateManager, string memory name, uint256 val) internal returns(uint256 oldValue) { return stateManager.set(IStateManager.StateEntry(name, ENTRY_TYPE_UINT256, abi.encode(val))).asUint256(); } function getUint256Array(IStateManager stateManager, string memory name) internal view returns(uint256[] memory) { return stateManager.get(name).value.asUint256Array(); } function setUint256Array(IStateManager stateManager, string memory name, uint256[] memory val) internal returns(uint256[] memory oldValue) { return stateManager.set(IStateManager.StateEntry(name, ENTRY_TYPE_UINT256_ARRAY, abi.encode(val))).asUint256Array(); } }// SPDX-License-Identifier: MIT pragma solidity >=0.7.0; import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; library BehaviorUtilities { function randomKey(uint256 i) internal view returns (bytes32) { return keccak256(abi.encode(i, block.timestamp, block.number, tx.origin, tx.gasprice, block.coinbase, block.difficulty, msg.sender, blockhash(block.number - 5))); } function calculateProjectedArraySizeAndLoopUpperBound(uint256 arraySize, uint256 start, uint256 offset) internal pure returns(uint256 projectedArraySize, uint256 projectedArrayLoopUpperBound) { if(arraySize != 0 && start < arraySize && offset != 0) { uint256 length = start + offset; if(start < (length = length > arraySize ? arraySize : length)) { projectedArraySize = (projectedArrayLoopUpperBound = length) - start; } } } } library ReflectionUtilities { function read(address subject, bytes memory inputData) internal view returns(bytes memory returnData) { bool result; (result, returnData) = subject.staticcall(inputData); if(!result) { assembly { revert(add(returnData, 0x20), mload(returnData)) } } } function submit(address subject, uint256 value, bytes memory inputData) internal returns(bytes memory returnData) { bool result; (result, returnData) = subject.call{value : value}(inputData); if(!result) { assembly { revert(add(returnData, 0x20), mload(returnData)) } } } function isContract(address subject) internal view returns (bool) { if(subject == address(0)) { return false; } uint256 codeLength; assembly { codeLength := extcodesize(subject) } return codeLength > 0; } function clone(address originalContract) internal returns(address copyContract) { assembly { mstore( 0, or( 0x5880730000000000000000000000000000000000000000803b80938091923cF3, mul(originalContract, 0x1000000000000000000) ) ) copyContract := create(0, 0, 32) switch extcodesize(copyContract) case 0 { invalid() } } } } library BytesUtilities { bytes private constant ALPHABET = "0123456789abcdef"; string internal constant BASE64_ENCODER_DATA = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'; function asAddress(bytes memory b) internal pure returns(address) { if(b.length == 0) { return address(0); } if(b.length == 20) { address addr; assembly { addr := mload(add(b, 20)) } return addr; } return abi.decode(b, (address)); } function asAddressArray(bytes memory b) internal pure returns(address[] memory callResult) { if(b.length > 0) { return abi.decode(b, (address[])); } } function asBool(bytes memory bs) internal pure returns(bool) { return asUint256(bs) != 0; } function asBoolArray(bytes memory b) internal pure returns(bool[] memory callResult) { if(b.length > 0) { return abi.decode(b, (bool[])); } } function asBytesArray(bytes memory b) internal pure returns(bytes[] memory callResult) { if(b.length > 0) { return abi.decode(b, (bytes[])); } } function asString(bytes memory b) internal pure returns(string memory callResult) { if(b.length > 0) { return abi.decode(b, (string)); } } function asStringArray(bytes memory b) internal pure returns(string[] memory callResult) { if(b.length > 0) { return abi.decode(b, (string[])); } } function asUint256(bytes memory bs) internal pure returns(uint256 x) { if (bs.length >= 32) { assembly { x := mload(add(bs, add(0x20, 0))) } } } function asUint256Array(bytes memory b) internal pure returns(uint256[] memory callResult) { if(b.length > 0) { return abi.decode(b, (uint256[])); } } function toString(bytes memory data) internal pure returns(string memory) { bytes memory str = new bytes(2 + data.length * 2); str[0] = "0"; str[1] = "x"; for (uint256 i = 0; i < data.length; i++) { str[2+i*2] = ALPHABET[uint256(uint8(data[i] >> 4))]; str[3+i*2] = ALPHABET[uint256(uint8(data[i] & 0x0f))]; } return string(str); } function asSingletonArray(bytes memory a) internal pure returns(bytes[] memory array) { array = new bytes[](1); array[0] = a; } function toBase64(bytes memory data) internal pure returns (string memory) { if (data.length == 0) return ''; string memory table = BASE64_ENCODER_DATA; uint256 encodedLen = 4 * ((data.length + 2) / 3); string memory result = new string(encodedLen + 32); assembly { mstore(result, encodedLen) let tablePtr := add(table, 1) let dataPtr := data let endPtr := add(dataPtr, mload(data)) let resultPtr := add(result, 32) for {} lt(dataPtr, endPtr) {} { dataPtr := add(dataPtr, 3) let input := mload(dataPtr) mstore8(resultPtr, mload(add(tablePtr, and(shr(18, input), 0x3F)))) resultPtr := add(resultPtr, 1) mstore8(resultPtr, mload(add(tablePtr, and(shr(12, input), 0x3F)))) resultPtr := add(resultPtr, 1) mstore8(resultPtr, mload(add(tablePtr, and(shr( 6, input), 0x3F)))) resultPtr := add(resultPtr, 1) mstore8(resultPtr, mload(add(tablePtr, and( input, 0x3F)))) resultPtr := add(resultPtr, 1) } switch mod(mload(data), 3) case 1 { mstore(sub(resultPtr, 2), shl(240, 0x3d3d)) } case 2 { mstore(sub(resultPtr, 1), shl(248, 0x3d)) } } return result; } } library StringUtilities { bytes1 private constant CHAR_0 = bytes1('0'); bytes1 private constant CHAR_A = bytes1('A'); bytes1 private constant CHAR_a = bytes1('a'); bytes1 private constant CHAR_f = bytes1('f'); bytes internal constant BASE64_DECODER_DATA = hex"0000000000000000000000000000000000000000000000000000000000000000" hex"00000000000000000000003e0000003f3435363738393a3b3c3d000000000000" hex"00000102030405060708090a0b0c0d0e0f101112131415161718190000000000" hex"001a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132330000000000"; function isEmpty(string memory test) internal pure returns (bool) { return equals(test, ""); } function equals(string memory a, string memory b) internal pure returns(bool) { return keccak256(abi.encodePacked(a)) == keccak256(abi.encodePacked(b)); } function toLowerCase(string memory str) internal pure returns(string memory) { bytes memory bStr = bytes(str); for (uint256 i = 0; i < bStr.length; i++) { bStr[i] = bStr[i] >= 0x41 && bStr[i] <= 0x5A ? bytes1(uint8(bStr[i]) + 0x20) : bStr[i]; } return string(bStr); } function asBytes(string memory str) internal pure returns(bytes memory toDecode) { bytes memory data = abi.encodePacked(str); if(data.length == 0 || data[0] != "0" || (data[1] != "x" && data[1] != "X")) { return ""; } uint256 start = 2; toDecode = new bytes((data.length - 2) / 2); for(uint256 i = 0; i < toDecode.length; i++) { toDecode[i] = bytes1(_fromHexChar(uint8(data[start++])) + _fromHexChar(uint8(data[start++])) * 16); } } function toBase64(string memory input) internal pure returns(string memory) { return BytesUtilities.toBase64(abi.encodePacked(input)); } function fromBase64(string memory _data) internal pure returns (bytes memory) { bytes memory data = bytes(_data); if (data.length == 0) return new bytes(0); require(data.length % 4 == 0, "invalid base64 decoder input"); bytes memory table = BASE64_DECODER_DATA; uint256 decodedLen = (data.length / 4) * 3; bytes memory result = new bytes(decodedLen + 32); assembly { let lastBytes := mload(add(data, mload(data))) if eq(and(lastBytes, 0xFF), 0x3d) { decodedLen := sub(decodedLen, 1) if eq(and(lastBytes, 0xFFFF), 0x3d3d) { decodedLen := sub(decodedLen, 1) } } mstore(result, decodedLen) let tablePtr := add(table, 1) let dataPtr := data let endPtr := add(dataPtr, mload(data)) let resultPtr := add(result, 32) for {} lt(dataPtr, endPtr) {} { dataPtr := add(dataPtr, 4) let input := mload(dataPtr) let output := add( add( shl(18, and(mload(add(tablePtr, and(shr(24, input), 0xFF))), 0xFF)), shl(12, and(mload(add(tablePtr, and(shr(16, input), 0xFF))), 0xFF))), add( shl( 6, and(mload(add(tablePtr, and(shr( 8, input), 0xFF))), 0xFF)), and(mload(add(tablePtr, and( input , 0xFF))), 0xFF) ) ) mstore(resultPtr, shl(232, output)) resultPtr := add(resultPtr, 3) } } return result; } function _fromHexChar(uint8 c) private pure returns (uint8) { bytes1 charc = bytes1(c); return charc < CHAR_0 || charc > CHAR_f ? 0 : (charc < CHAR_A ? 0 : 10) + c - uint8(charc < CHAR_A ? CHAR_0 : charc < CHAR_a ? CHAR_A : CHAR_a); } } library Uint256Utilities { function asSingletonArray(uint256 n) internal pure returns(uint256[] memory array) { array = new uint256[](1); array[0] = n; } function toHex(uint256 _i) internal pure returns (string memory) { return BytesUtilities.toString(abi.encodePacked(_i)); } function toString(uint256 _i) internal pure returns (string memory _uintAsString) { if (_i == 0) { return "0"; } uint256 j = _i; uint256 len; while (j != 0) { len++; j /= 10; } bytes memory bstr = new bytes(len); uint256 k = len; while (_i != 0) { k = k-1; uint8 temp = (48 + uint8(_i - _i / 10 * 10)); bytes1 b1 = bytes1(temp); bstr[k] = b1; _i /= 10; } return string(bstr); } function sum(uint256[] memory arr) internal pure returns (uint256 result) { for(uint256 i = 0; i < arr.length; i++) { result += arr[i]; } } } library AddressUtilities { function asSingletonArray(address a) internal pure returns(address[] memory array) { array = new address[](1); array[0] = a; } function toString(address _addr) internal pure returns (string memory) { return _addr == address(0) ? "0x0000000000000000000000000000000000000000" : BytesUtilities.toString(abi.encodePacked(_addr)); } } library Bytes32Utilities { function asSingletonArray(bytes32 a) internal pure returns(bytes32[] memory array) { array = new bytes32[](1); array[0] = a; } function toString(bytes32 bt) internal pure returns (string memory) { return bt == bytes32(0) ? "0x0000000000000000000000000000000000000000000000000000000000000000" : BytesUtilities.toString(abi.encodePacked(bt)); } } library TransferUtilities { using ReflectionUtilities for address; function balanceOf(address erc20TokenAddress, address account) internal view returns(uint256) { if(erc20TokenAddress == address(0)) { return account.balance; } return abi.decode(erc20TokenAddress.read(abi.encodeWithSelector(IERC20(erc20TokenAddress).balanceOf.selector, account)), (uint256)); } function allowance(address erc20TokenAddress, address account, address spender) internal view returns(uint256) { if(erc20TokenAddress == address(0)) { return 0; } return abi.decode(erc20TokenAddress.read(abi.encodeWithSelector(IERC20(erc20TokenAddress).allowance.selector, account, spender)), (uint256)); } function safeApprove(address erc20TokenAddress, address spender, uint256 value) internal { bytes memory returnData = erc20TokenAddress.submit(0, abi.encodeWithSelector(IERC20(erc20TokenAddress).approve.selector, spender, value)); require(returnData.length == 0 || abi.decode(returnData, (bool)), 'APPROVE_FAILED'); } function safeTransfer(address erc20TokenAddress, address to, uint256 value) internal { if(value == 0) { return; } if(erc20TokenAddress == address(0)) { to.submit(value, ""); return; } bytes memory returnData = erc20TokenAddress.submit(0, abi.encodeWithSelector(IERC20(erc20TokenAddress).transfer.selector, to, value)); require(returnData.length == 0 || abi.decode(returnData, (bool)), 'TRANSFER_FAILED'); } function safeTransferFrom(address erc20TokenAddress, address from, address to, uint256 value) internal { if(value == 0) { return; } if(erc20TokenAddress == address(0)) { to.submit(value, ""); return; } bytes memory returnData = erc20TokenAddress.submit(0, abi.encodeWithSelector(IERC20(erc20TokenAddress).transferFrom.selector, from, to, value)); require(returnData.length == 0 || abi.decode(returnData, (bool)), 'TRANSFERFROM_FAILED'); } }// SPDX-License-Identifier: MIT pragma solidity >=0.7.0; import "@ethereansos/swissknife/contracts/generic/model/ILazyInitCapableElement.sol"; import "@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol"; interface IProposalsManager is IERC1155Receiver, ILazyInitCapableElement { struct ProposalCode { address location; bytes bytecode; } struct ProposalCodes { ProposalCode[] codes; bool alsoTerminate; } struct Proposal { address proposer; address[] codeSequence; uint256 creationBlock; uint256 accept; uint256 refuse; address triggeringRules; address[] canTerminateAddresses; address[] validatorsAddresses; bool validationPassed; uint256 terminationBlock; bytes votingTokens; } struct ProposalConfiguration { address[] collections; uint256[] objectIds; uint256[] weights; address creationRules; address triggeringRules; address[] canTerminateAddresses; address[] validatorsAddresses; } function batchCreate(ProposalCodes[] calldata codeSequences) external returns(bytes32[] memory createdProposalIds); function list(bytes32[] calldata proposalIds) external view returns(Proposal[] memory); function votes(bytes32[] calldata proposalIds, address[] calldata voters, bytes32[][] calldata items) external view returns(uint256[][] memory accepts, uint256[][] memory refuses, uint256[][] memory toWithdraw); function weight(bytes32 code) external view returns(uint256); function vote(address erc20TokenAddress, bytes memory permitSignature, bytes32 proposalId, uint256 accept, uint256 refuse, address voter, bool alsoTerminate) external payable; function batchVote(bytes[] calldata data) external payable; function withdrawAll(bytes32[] memory proposalIds, address voterOrReceiver, bool afterTermination) external; function terminate(bytes32[] calldata proposalIds) external; function configuration() external view returns(ProposalConfiguration memory); function setConfiguration(ProposalConfiguration calldata newValue) external returns(ProposalConfiguration memory oldValue); function lastProposalId() external view returns(bytes32); function lastVoteBlock(address voter) external view returns (uint256); event ProposalCreated(address indexed proposer, address indexed code, bytes32 indexed proposalId); event ProposalWeight(bytes32 indexed proposalId, address indexed collection, uint256 indexed id, bytes32 key, uint256 weight); event ProposalTerminated(bytes32 indexed proposalId, bool result, bytes errorData); event Accept(bytes32 indexed proposalId, address indexed voter, bytes32 indexed item, uint256 amount); event MoveToAccept(bytes32 indexed proposalId, address indexed voter, bytes32 indexed item, uint256 amount); event RetireAccept(bytes32 indexed proposalId, address indexed voter, bytes32 indexed item, uint256 amount); event Refuse(bytes32 indexed proposalId, address indexed voter, bytes32 indexed item, uint256 amount); event MoveToRefuse(bytes32 indexed proposalId, address indexed voter, bytes32 indexed item, uint256 amount); event RetireRefuse(bytes32 indexed proposalId, address indexed voter, bytes32 indexed item, uint256 amount); } interface IProposalChecker { function check(address proposalsManagerAddress, bytes32 id, bytes calldata data, address from, address voter) external view returns(bool); } interface IExternalProposalsManagerCommands { function createProposalCodeSequence(bytes32 proposalId, IProposalsManager.ProposalCode[] memory codeSequenceInput, address sender) external returns (address[] memory codeSequence, IProposalsManager.ProposalConfiguration memory localConfiguration); function proposalCanBeFinalized(bytes32 proposalId, IProposalsManager.Proposal memory proposal, bool validationPassed, bool result) external view returns (bool); function isVotable(bytes32 proposalId, IProposalsManager.Proposal memory proposal, address from, address voter, bool voteOrWithtraw) external view returns (bytes memory response); }// SPDX-License-Identifier: MIT pragma solidity >=0.7.0; import "../model/IOrganization.sol"; import "@ethereansos/swissknife/contracts/dynamicMetadata/impl/DynamicMetadataCapableElement.sol"; import { ReflectionUtilities } from "@ethereansos/swissknife/contracts/lib/GeneralUtilities.sol"; contract Organization is IOrganization, DynamicMetadataCapableElement { using ReflectionUtilities for address; mapping(bytes32 => address[]) private _history; mapping(address => bytes32) public override keyOf; mapping(bytes32 => address) public override get; mapping(bytes32 => bool) public override keyIsActive; constructor(bytes memory lazyInitData) DynamicMetadataCapableElement(lazyInitData) { } function _dynamicMetadataElementLazyInit(bytes memory lazyInitData) internal virtual override returns(bytes memory) { require(host == address(0)); return abi.encode(_set(abi.decode(lazyInitData, (Component[])))); } function _dynamicMetadataElementSupportsInterface(bytes4 interfaceId) internal virtual override pure returns(bool) { return interfaceId == type(IOrganization).interfaceId || interfaceId == this.keyOf.selector || interfaceId == this.history.selector || interfaceId == this.batchHistory.selector || interfaceId == this.get.selector || interfaceId == this.list.selector || interfaceId == this.isActive.selector || interfaceId == this.keyIsActive.selector || interfaceId == this.set.selector || interfaceId == this.batchSet.selector || interfaceId == this.submit.selector; } function history(bytes32 key) override external view returns(address[] memory componentsAddresses) { return _history[key]; } function batchHistory(bytes32[] calldata keys) override external view returns(address[][] memory componentsAddresses) { componentsAddresses = new address[][](keys.length); for(uint256 i = 0; i < componentsAddresses.length; i++) { componentsAddresses[i] = _history[keys[i]]; } } function list(bytes32[] calldata keys) override external view returns(address[] memory componentsAddresses) { componentsAddresses = new address[](keys.length); for(uint256 i = 0; i < componentsAddresses.length; i++) { componentsAddresses[i] = get[keys[i]]; } } function isActive(address componentAddress) override public view returns(bool) { return get[keyOf[componentAddress]] == componentAddress && keyIsActive[keyOf[componentAddress]]; } function set(Component calldata component) override authorizedOnly external returns(address replacedComponentAddress) { replacedComponentAddress = _set(component); } function batchSet(Component[] calldata components) override authorizedOnly external returns (address[] memory replacedComponentAddresses) { replacedComponentAddresses = _set(components); } function submit(address location, bytes calldata payload, address restReceiver) override authorizedOnly external payable returns(bytes memory response) { uint256 oldBalance = address(this).balance - msg.value; response = location.submit(msg.value, payload); uint256 actualBalance = address(this).balance; if(actualBalance > oldBalance) { (restReceiver != address(0) ? restReceiver : msg.sender).submit(address(this).balance - oldBalance, ""); } } function _subjectIsAuthorizedFor(address subject, address location, bytes4 selector, bytes calldata, uint256) internal virtual override view returns(bool, bool) { if(location == address(this) && selector == this.setHost.selector) { return (true, false); } return (true, isActive(subject)); } function _set(Component[] memory components) internal returns(address[] memory replacedComponentAddresses) { replacedComponentAddresses = new address[](components.length); for(uint256 i = 0; i < components.length; i++) { replacedComponentAddresses[i] = _set(components[i]); } } function _set(Component memory component) internal returns(address replacedComponentAddress) { require(component.key != bytes32(0), "key"); if(!component.active || component.location == address(0)) { delete keyIsActive[component.key]; } replacedComponentAddress = get[component.key]; get[component.key] = component.location; if(component.location != address(0)) { address location = component.location; uint256 codeSize; assembly { codeSize := extcodesize(location) } require(codeSize != 0, "address"); keyIsActive[keyOf[component.location] = component.key] = component.active; if(component.log) { _history[component.key].push(component.location); } } if(component.log) { emit ComponentSet(component.key, replacedComponentAddress, component.location, component.active); } } }// SPDX-License-Identifier: MIT pragma solidity >=0.7.0; import "../../../core/model/IOrganization.sol"; import "../../../base/model/IProposalsManager.sol"; interface ISubDAO is IOrganization, IExternalProposalsManagerCommands { event Proposed(uint256 indexed modelIndex, uint256 indexed presetIndex, bytes32 indexed proposalId); struct SubDAOProposalModel { address source; string uri; bool isPreset; bytes[] presetValues; bytes32[] presetProposals; address creationRules; address triggeringRules; uint256 votingRulesIndex; address[][] canTerminateAddresses; address[][] validatorsAddresses; } function presetArrayMaxSize() external view returns(uint256); function proposalModels() external view returns(SubDAOProposalModel[] memory); function setProposalModels(SubDAOProposalModel[] calldata newValue) external returns(SubDAOProposalModel[] memory oldValue); function setInitialProposalModels(SubDAOProposalModel[] calldata newValue) external; function setVotingRules(uint256 modelIndex, uint256 votingRulesIndex) external returns(address[] memory oldCanTerminateAddresses, address[] memory oldValidatorsAddresses); function setCreationAndTriggeringRules(uint256 modelIndex, address newCreationRules, address newTriggeringRules) external returns(address oldCreationRules, address oldTriggeringRules); function setPresetValues(uint256 modelIndex, bytes[] calldata newPresetValues) external returns(bytes[] memory oldPresetValues, bytes32[] memory deprecatedProposalIds); function finalizeInit(address firstHost) external; function isPersistent(bytes32 proposalId) external view returns(bool result, bool isDeprecated); }// SPDX-License-Identifier: MIT pragma solidity >=0.7.0; import "@ethereansos/swissknife/contracts/dynamicMetadata/model/IDynamicMetadataCapableElement.sol"; interface IOrganization is IDynamicMetadataCapableElement { struct Component { bytes32 key; address location; bool active; bool log; } function keyOf(address componentAddress) external view returns(bytes32); function history(bytes32 key) external view returns(address[] memory componentsAddresses); function batchHistory(bytes32[] calldata keys) external view returns(address[][] memory componentsAddresses); function get(bytes32 key) external view returns(address componentAddress); function list(bytes32[] calldata keys) external view returns(address[] memory componentsAddresses); function isActive(address subject) external view returns(bool); function keyIsActive(bytes32 key) external view returns(bool); function set(Component calldata) external returns(address replacedComponentAddress); function batchSet(Component[] calldata) external returns (address[] memory replacedComponentAddresses); event ComponentSet(bytes32 indexed key, address indexed from, address indexed to, bool active); function submit(address location, bytes calldata payload, address restReceiver) external payable returns(bytes memory response); }//SPDX-License-Identifier: MIT pragma solidity >=0.7.0; import "../model/IDynamicMetadataCapableElement.sol"; import "../model/IDynamicUriResolver.sol"; import "../../generic/impl/LazyInitCapableElement.sol"; abstract contract DynamicMetadataCapableElement is IDynamicMetadataCapableElement, LazyInitCapableElement { string public override plainUri; address public override dynamicUriResolver; constructor(bytes memory lazyInitData) LazyInitCapableElement(lazyInitData) { } function _lazyInit(bytes memory lazyInitData) internal override returns (bytes memory lazyInitResponse) { (plainUri, dynamicUriResolver, lazyInitResponse) = abi.decode(lazyInitData, (string, address, bytes)); lazyInitResponse = _dynamicMetadataElementLazyInit(lazyInitResponse); } function _supportsInterface(bytes4 interfaceId) internal override view returns(bool) { return interfaceId == type(IDynamicMetadataCapableElement).interfaceId || interfaceId == this.plainUri.selector || interfaceId == this.uri.selector || interfaceId == this.dynamicUriResolver.selector || interfaceId == this.setUri.selector || interfaceId == this.setDynamicUriResolver.selector || _dynamicMetadataElementSupportsInterface(interfaceId); } function uri() external override view returns(string memory) { return _uri(plainUri, ""); } function setUri(string calldata newValue) external override authorizedOnly returns (string memory oldValue) { oldValue = plainUri; plainUri = newValue; } function setDynamicUriResolver(address newValue) external override authorizedOnly returns(address oldValue) { oldValue = dynamicUriResolver; dynamicUriResolver = newValue; } function _uri(string memory _plainUri, bytes memory additionalData) internal view returns(string memory) { if(dynamicUriResolver == address(0)) { return _plainUri; } return IDynamicUriResolver(dynamicUriResolver).resolve(address(this), _plainUri, additionalData, msg.sender); } function _dynamicMetadataElementLazyInit(bytes memory lazyInitData) internal virtual returns(bytes memory); function _dynamicMetadataElementSupportsInterface(bytes4 interfaceId) internal virtual view returns(bool); }// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "../../utils/introspection/IERC165.sol"; /** * @dev _Available since v3.1._ */ interface IERC1155Receiver is IERC165 { /** @dev Handles the receipt of a single ERC1155 token type. This function is called at the end of a `safeTransferFrom` after the balance has been updated. To accept the transfer, this must return `bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)"))` (i.e. 0xf23a6e61, or its own function selector). @param operator The address which initiated the transfer (i.e. msg.sender) @param from The address which previously owned the token @param id The ID of the token being transferred @param value The amount of tokens being transferred @param data Additional data with no specified format @return `bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)"))` if transfer is allowed */ function onERC1155Received( address operator, address from, uint256 id, uint256 value, bytes calldata data ) external returns (bytes4); /** @dev Handles the receipt of a multiple ERC1155 token types. This function is called at the end of a `safeBatchTransferFrom` after the balances have been updated. To accept the transfer(s), this must return `bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)"))` (i.e. 0xbc197c81, or its own function selector). @param operator The address which initiated the batch transfer (i.e. msg.sender) @param from The address which previously owned the token @param ids An array containing ids of each token being transferred (order and length must match values array) @param values An array containing amounts of each token being transferred (order and length must match ids array) @param data Additional data with no specified format @return `bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)"))` if transfer is allowed */ function onERC1155BatchReceived( address operator, address from, uint256[] calldata ids, uint256[] calldata values, bytes calldata data ) external returns (bytes4); } // SPDX-License-Identifier: MIT pragma solidity >=0.7.0; import "@openzeppelin/contracts/utils/introspection/IERC165.sol"; interface ILazyInitCapableElement is IERC165 { function lazyInit(bytes calldata lazyInitData) external returns(bytes memory initResponse); function initializer() external view returns(address); event Host(address indexed from, address indexed to); function host() external view returns(address); function setHost(address newValue) external returns(address oldValue); function subjectIsAuthorizedFor(address subject, address location, bytes4 selector, bytes calldata payload, uint256 value) external view returns(bool); }// SPDX-License-Identifier: MIT pragma solidity >=0.7.0; import "@ethereansos/swissknife/contracts/generic/model/ILazyInitCapableElement.sol"; interface ITreasuryManager is ILazyInitCapableElement { struct TransferEntry { address token; uint256[] objectIds; uint256[] values; address receiver; bool safe; bool batch; bool withData; bytes data; } function transfer(address token, uint256 value, address receiver, uint256 tokenType, uint256 objectId, bool safe, bool withData, bytes calldata data) external returns(bool result, bytes memory returnData); function batchTransfer(TransferEntry[] calldata transferEntries) external returns(bool[] memory results, bytes[] memory returnDatas); function submit(address location, bytes calldata payload, address restReceiver) external payable returns(bytes memory response); function setAdditionalFunction(bytes4 selector, address newServer, bool log) external returns (address oldServer); event AdditionalFunction(address caller, bytes4 indexed selector, address indexed oldServer, address indexed newServer); }// SPDX-License-Identifier: MIT pragma solidity >=0.7.0; import "@ethereansos/swissknife/contracts/generic/model/ILazyInitCapableElement.sol"; interface IStateManager is ILazyInitCapableElement { struct StateEntry { string key; bytes32 entryType; bytes value; } function size() external view returns (uint256); function all() external view returns (StateEntry[] memory); function partialList(uint256 start, uint256 offset) external view returns (StateEntry[] memory); function list(string[] calldata keys) external view returns (StateEntry[] memory); function listByIndices(uint256[] calldata indices) external view returns (StateEntry[] memory); function exists(string calldata key) external view returns(bool result, uint256 index); function get(string calldata key) external view returns(StateEntry memory); function getByIndex(uint256 index) external view returns(StateEntry memory); function set(StateEntry calldata newValue) external returns(bytes memory replacedValue); function batchSet(StateEntry[] calldata newValues) external returns(bytes[] memory replacedValues); function remove(string calldata key) external returns(bytes32 removedType, bytes memory removedValue); function batchRemove(string[] calldata keys) external returns(bytes32[] memory removedTypes, bytes[] memory removedValues); function removeByIndices(uint256[] calldata indices) external returns(bytes32[] memory removedTypes, bytes[] memory removedValues); }// SPDX-License-Identifier: MIT pragma solidity >=0.7.0; import "@ethereansos/swissknife/contracts/generic/model/ILazyInitCapableElement.sol"; interface IMicroservicesManager is ILazyInitCapableElement { struct Microservice { string key; address location; string methodSignature; bool submittable; string returnAbiParametersArray; bool isInternal; bool needsSender; } function size() external view returns (uint256); function all() external view returns (Microservice[] memory); function partialList(uint256 start, uint256 offset) external view returns (Microservice[] memory); function list(string[] calldata keys) external view returns (Microservice[] memory); function listByIndices(uint256[] calldata indices) external view returns (Microservice[] memory); function exists(string calldata key) external view returns(bool result, uint256 index); function get(string calldata key) external view returns(Microservice memory); function getByIndex(uint256 index) external view returns(Microservice memory); function set(Microservice calldata newValue) external returns(Microservice memory replacedValue); function batchSet(Microservice[] calldata newValues) external returns(Microservice[] memory replacedValues); event MicroserviceAdded(address indexed sender, bytes32 indexed keyHash, string key, address indexed location, string methodSignature, bool submittable, string returnAbiParametersArray, bool isInternal, bool needsSender); function remove(string calldata key) external returns(Microservice memory removedValue); function batchRemove(string[] calldata keys) external returns(Microservice[] memory removedValues); function removeByIndices(uint256[] calldata indices) external returns(Microservice[] memory removedValues); event MicroserviceRemoved(address indexed sender, bytes32 indexed keyHash, string key, address indexed location, string methodSignature, bool submittable, string returnAbiParametersArray, bool isInternal, bool needsSender); function read(string calldata key, bytes calldata data) external view returns(bytes memory returnData); function submit(string calldata key, bytes calldata data) external payable returns(bytes memory returnData); }// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20 { /** * @dev Returns the amount of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the amount of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves `amount` tokens from the caller's account to `recipient`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address recipient, uint256 amount) external returns (bool); /** * @dev Returns the remaining number of tokens that `spender` will be * allowed to spend on behalf of `owner` through {transferFrom}. This is * zero by default. * * This value changes when {approve} or {transferFrom} are called. */ function allowance(address owner, address spender) external view returns (uint256); /** * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. * * Returns a boolean value indicating whether the operation succeeded. * * IMPORTANT: Beware that changing an allowance with this method brings the risk * that someone may use both the old and the new allowance by unfortunate * transaction ordering. One possible solution to mitigate this race * condition is to first reduce the spender's allowance to 0 and set the * desired value afterwards: * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 * * Emits an {Approval} event. */ function approve(address spender, uint256 amount) external returns (bool); /** * @dev Moves `amount` tokens from `sender` to `recipient` using the * allowance mechanism. `amount` is then deducted from the caller's * allowance. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transferFrom( address sender, address recipient, uint256 amount ) external returns (bool); /** * @dev Emitted when `value` tokens are moved from one account (`from`) to * another (`to`). * * Note that `value` may be zero. */ event Transfer(address indexed from, address indexed to, uint256 value); /** * @dev Emitted when the allowance of a `spender` for an `owner` is set by * a call to {approve}. `value` is the new allowance. */ event Approval(address indexed owner, address indexed spender, uint256 value); } //SPDX-License-Identifier: MIT pragma solidity >=0.7.0; import "../../generic/model/ILazyInitCapableElement.sol"; interface IDynamicMetadataCapableElement is ILazyInitCapableElement { function uri() external view returns(string memory); function plainUri() external view returns(string memory); function setUri(string calldata newValue) external returns (string memory oldValue); function dynamicUriResolver() external view returns(address); function setDynamicUriResolver(address newValue) external returns(address oldValue); }// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; /** * @dev Interface of the ERC165 standard, as defined in the * https://eips.ethereum.org/EIPS/eip-165[EIP]. * * Implementers can declare support of contract interfaces, which can then be * queried by others ({ERC165Checker}). * * For an implementation, see {ERC165}. */ interface IERC165 { /** * @dev Returns true if this contract implements the interface defined by * `interfaceId`. See the corresponding * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] * to learn more about how these ids are created. * * This function call must use less than 30 000 gas. */ function supportsInterface(bytes4 interfaceId) external view returns (bool); } // SPDX-License-Identifier: MIT pragma solidity >=0.7.0; import "../model/ILazyInitCapableElement.sol"; import { ReflectionUtilities } from "../../lib/GeneralUtilities.sol"; abstract contract LazyInitCapableElement is ILazyInitCapableElement { using ReflectionUtilities for address; address public override initializer; address public override host; constructor(bytes memory lazyInitData) { if(lazyInitData.length > 0) { _privateLazyInit(lazyInitData); } } function lazyInit(bytes calldata lazyInitData) override external returns (bytes memory lazyInitResponse) { return _privateLazyInit(lazyInitData); } function supportsInterface(bytes4 interfaceId) override external view returns(bool) { return interfaceId == type(IERC165).interfaceId || interfaceId == this.supportsInterface.selector || interfaceId == type(ILazyInitCapableElement).interfaceId || interfaceId == this.lazyInit.selector || interfaceId == this.initializer.selector || interfaceId == this.subjectIsAuthorizedFor.selector || interfaceId == this.host.selector || interfaceId == this.setHost.selector || _supportsInterface(interfaceId); } function setHost(address newValue) external override authorizedOnly returns(address oldValue) { oldValue = host; host = newValue; emit Host(oldValue, newValue); } function subjectIsAuthorizedFor(address subject, address location, bytes4 selector, bytes calldata payload, uint256 value) public override virtual view returns(bool) { (bool chidlElementValidationIsConsistent, bool chidlElementValidationResult) = _subjectIsAuthorizedFor(subject, location, selector, payload, value); if(chidlElementValidationIsConsistent) { return chidlElementValidationResult; } if(subject == host) { return true; } if(!host.isContract()) { return false; } (bool result, bytes memory resultData) = host.staticcall(abi.encodeWithSelector(ILazyInitCapableElement(host).subjectIsAuthorizedFor.selector, subject, location, selector, payload, value)); return result && abi.decode(resultData, (bool)); } function _privateLazyInit(bytes memory lazyInitData) private returns (bytes memory lazyInitResponse) { require(initializer == address(0), "init"); initializer = msg.sender; (host, lazyInitResponse) = abi.decode(lazyInitData, (address, bytes)); emit Host(address(0), host); lazyInitResponse = _lazyInit(lazyInitResponse); } function _lazyInit(bytes memory) internal virtual returns (bytes memory) { return ""; } function _supportsInterface(bytes4 selector) internal virtual view returns (bool); function _subjectIsAuthorizedFor(address, address, bytes4, bytes calldata, uint256) internal virtual view returns(bool, bool) { } modifier authorizedOnly { require(_authorizedOnly(), "unauthorized"); _; } function _authorizedOnly() internal returns(bool) { return subjectIsAuthorizedFor(msg.sender, address(this), msg.sig, msg.data, msg.value); } }//SPDX-License-Identifier: MIT pragma solidity >=0.7.0; interface IDynamicUriResolver { function resolve(address subject, string calldata plainUri, bytes calldata inputData, address caller) external view returns(string memory); }
File 6 of 7: DelegationFactory
// SPDX-License-Identifier: MIT pragma solidity >=0.7.0; pragma abicoder v2; import "../model/IDelegationFactory.sol"; import "./EthereansFactory.sol"; import "../../../base/model/IProposalsManager.sol"; import { ReflectionUtilities, BehaviorUtilities, Uint256Utilities, AddressUtilities } from "@ethereansos/swissknife/contracts/lib/GeneralUtilities.sol"; import { Grimoire as BaseGrimoire, Getters } from "../../../base/lib/KnowledgeBase.sol"; import { Getters as ExternalGetters } from "../../../ext/lib/KnowledgeBase.sol"; import "../../../ext/subDAO/model/ISubDAO.sol"; import "../../../base/model/IProposalsManager.sol"; import "../../../core/model/IOrganization.sol"; import "../../../base/model/IStateManager.sol"; import { State } from "../../../base/lib/KnowledgeBase.sol"; import "@ethereansos/items-v2/contracts/projection/IItemProjection.sol"; import "@ethereansos/items-v2/contracts/projection/factory/model/IItemProjectionFactory.sol"; import "../model/IProposalModelsFactory.sol"; contract DelegationFactory is EthereansFactory, IDelegationFactory { using ReflectionUtilities for address; using Getters for IOrganization; using ExternalGetters for IOrganization; using State for IStateManager; using Uint256Utilities for uint256; using AddressUtilities for address; uint256 public constant MANDATORY_COMPONENTS = 3; //ProposalsManager true //TreasuryManager false //DelegationTokensManager true uint256 public constant PROPOSALS_MANAGER_POSITION = 0; address[] private _utilityModels; bytes32[] private _utilityModelKeys; bool[] private _utilityModelsActive; uint256 public presetArrayMaxSize; address public itemProjectionFactoryAddress; address public mainInterface; address public projectionAddress; bytes32 public collectionId; ISubDAO.SubDAOProposalModel[] private _proposalModels; address public proposalModelsFactory; uint256 private constant BY_SPECIFIC_ADDRESS_POSITION = 0; uint256 private constant BLOCK_LENGTH_POSITION = 2; uint256 private constant HARD_CAP_POSITION = 3; uint256 private constant VALIDATION_BOMB_POSITION = 4; uint256 private constant QUORUM_POSITION = 5; constructor(bytes memory lazyInitData) EthereansFactory(lazyInitData) { } function _ethosFactoryLazyInit(bytes memory lazyInitData) internal override returns(bytes memory lazyInitResponse) { (proposalModelsFactory, _utilityModels, _utilityModelKeys, _utilityModelsActive, lazyInitResponse) = abi.decode(lazyInitData, (address, address[], bytes32[], bool[], bytes)); ISubDAO.SubDAOProposalModel[] memory proposalModels; Header memory collectionHeader; (itemProjectionFactoryAddress, collectionHeader, presetArrayMaxSize, proposalModels) = abi.decode(lazyInitResponse, (address, Header, uint256, ISubDAO.SubDAOProposalModel[])); for(uint256 i = 0; i < proposalModels.length; i++) { _proposalModels.push(proposalModels[i]); } _deployCollection(collectionHeader); lazyInitResponse = ""; } function mintItems(CreateItem[] memory items) external returns(uint256[] memory itemIds) { require(deployer[msg.sender] != address(0), "unauthorized"); for(uint256 i = 0; i < items.length; i++) { items[i].collectionId = collectionId; } return IItemProjection(projectionAddress).mintItems(items); } function data() external override view returns(address[] memory utilityModels, bytes32[] memory utilitiyModelKeys, bool[] memory utilitiyModelActive, string memory proposalUri) { return (_utilityModels, _utilityModelKeys, _utilityModelsActive, ""); } function deploy(bytes calldata deployData) external payable override(Factory, IFactory) virtual returns(address productAddress, bytes memory productInitResponse) { (OrganizationDeployData memory organizationDeployData) = abi.decode(deployData, (OrganizationDeployData)); deployer[productAddress = modelAddress.clone()] = msg.sender; uint256 componentsLength = MANDATORY_COMPONENTS; IOrganization.Component[] memory components = new IOrganization.Component[](componentsLength); for(uint256 i = 0; i < MANDATORY_COMPONENTS; i++) { components[i] = _createOrganizationComponent(i, productAddress, i == PROPOSALS_MANAGER_POSITION ? abi.encode(true, organizationDeployData.mandatoryComponentsDeployData[i]) : organizationDeployData.mandatoryComponentsDeployData[i]); } productInitResponse = _emitDeploy(productAddress, organizationDeployData.uri, components); require(ILazyInitCapableElement(productAddress).initializer() == address(this)); } address[] private _validationAddresses; address[] private _canTerminateAddresses; function createNewRules( address delegationAddress, uint256 quorumPercentage, uint256 validationBomb, uint256 blockLength, uint256 hardCapPercentage ) public override returns (address[] memory validationAddresses, address[] memory canTerminateAddresses) { require(deployer[delegationAddress] != address(0), "unknown delegation"); _addTo(QUORUM_POSITION, quorumPercentage, true, true); if(validationBomb > 0) { _addTo(VALIDATION_BOMB_POSITION, validationBomb, false, true); } if(blockLength > 0) { _addTo(BLOCK_LENGTH_POSITION, blockLength, false, false); } if(hardCapPercentage > 0) { _addTo(HARD_CAP_POSITION, hardCapPercentage, true, false); } validationAddresses = _validationAddresses; canTerminateAddresses = _canTerminateAddresses; require(validationAddresses.length > 0, "No validators"); require(canTerminateAddresses.length > 0, "No canTerminates"); delete _validationAddresses; delete _canTerminateAddresses; } function initializeProposalModels( address delegationAddress, address host, uint256 quorumPercentage, uint256 validationBomb, uint256 blockLength, uint256 hardCapPercentage ) external override { require(deployer[delegationAddress] == msg.sender, "unauthorized"); (address creationRules,) = IProposalModelsFactory(proposalModelsFactory).deploy(abi.encode(BY_SPECIFIC_ADDRESS_POSITION, abi.encode(host, true))); (address[] memory validationAddresses, address[] memory canTerminateAddresses) = createNewRules( delegationAddress, quorumPercentage, validationBomb, blockLength, hardCapPercentage ); ISubDAO.SubDAOProposalModel[] memory proposalModels = _proposalModels; proposalModels[0].creationRules = creationRules;//Attach-Detach proposalModels[1].creationRules = creationRules;//Change URI proposalModels[2].creationRules = creationRules;//Change Rules proposalModels[3].creationRules = creationRules;//Transfer proposalModels[3].validatorsAddresses[0] = validationAddresses; proposalModels[3].canTerminateAddresses[0] = canTerminateAddresses; proposalModels[4].creationRules = creationRules;//Vote proposalModels[4].validatorsAddresses[0] = validationAddresses; proposalModels[4].canTerminateAddresses[0] = canTerminateAddresses; ISubDAO(delegationAddress).setInitialProposalModels(proposalModels); } function _addTo(uint256 position, uint256 value, bool valueIsPercentage, bool validators) private { bytes memory init = valueIsPercentage ? abi.encode(value, true) : abi.encode(value); (address model,) = IProposalModelsFactory(proposalModelsFactory).deploy(abi.encode(position, init)); if(validators) { _validationAddresses.push(model); } else { _canTerminateAddresses.push(model); } } function _emitDeploy(address productAddress, string memory uri, IOrganization.Component[] memory components) private returns(bytes memory productInitResponse) { emit Deployed(modelAddress, productAddress, msg.sender, productInitResponse = ILazyInitCapableElement(productAddress).lazyInit(abi.encode(address(0), abi.encode(uri, dynamicUriResolver, abi.encode(false, presetArrayMaxSize, abi.encode(new ISubDAO.SubDAOProposalModel[](0), abi.encode(components))))))); } function proposeToAttachOrDetach(address delegationAddress, address delegationsManagerAddress, bool attach) public returns(bytes32 proposalId) { require(deployer[delegationAddress] != address(0), "Unrecognized"); IProposalsManager.ProposalCode[] memory proposalCodes = new IProposalsManager.ProposalCode[](1); proposalCodes[0] = IProposalsManager.ProposalCode(address(0), abi.encode(delegationsManagerAddress, attach)); IProposalsManager.ProposalCodes[] memory proposalCodesArray = new IProposalsManager.ProposalCodes[](1); proposalCodesArray[0] = IProposalsManager.ProposalCodes(proposalCodes, true); return IOrganization(delegationAddress).proposalsManager().batchCreate(proposalCodesArray)[0]; } function _createOrganizationComponent(uint256 index, address productAddress, bytes memory lazyInitData) private returns(IOrganization.Component memory organizationComponent) { ILazyInitCapableElement((organizationComponent = IOrganization.Component(_utilityModelKeys[index], _utilityModels[index].clone(), _utilityModelsActive[index], true)).location).lazyInit(abi.encode(productAddress, lazyInitData)); deployer[organizationComponent.location] = msg.sender; } function _deployCollection(Header memory collectionHeader) private { mainInterface = IItemProjectionFactory(itemProjectionFactoryAddress).mainInterface(); collectionHeader.host = address(0); bytes memory deployData = abi.encode((uint256(1)).asSingletonArray(), address(this).asSingletonArray()); deployData = abi.encode(bytes32(0), collectionHeader, new CreateItem[](0), deployData); deployData = abi.encode(address(0), deployData); deployData = abi.encode(0, deployData); (projectionAddress,) = IItemProjectionFactory(itemProjectionFactoryAddress).deploy(deployData); collectionId = IItemProjection(projectionAddress).collectionId(); } }//SPDX-License-Identifier: MIT pragma solidity >=0.7.0; pragma abicoder v2; import "@ethereansos/swissknife/contracts/factory/impl/Factory.sol"; interface IProposalModelsFactory is IFactory { event Singleton(address indexed productAddress); function deploySingleton(bytes calldata code, bytes calldata deployData) external returns(address deployedAddress, bytes memory deployLazyInitResponse); function addModel(bytes calldata code, string calldata uri) external returns(address modelAddress, uint256 positionIndex); function models() external view returns(address[] memory addresses, string[] memory uris); function singletons() external view returns(address[] memory addresses); function setModelUris(uint256[] memory indices, string[] memory uris) external; function model(uint256 i) external view returns(address modelAddress, string memory modelUri); function singleton(uint256 i) external view returns(address singletonAddress); }//SPDX-License-Identifier: MIT pragma solidity >=0.7.0; pragma abicoder v2; import "@ethereansos/swissknife/contracts/factory/impl/Factory.sol"; interface IItemProjectionFactory is IFactory { function mainInterface() external view returns(address); function deploySingleton(bytes calldata code, bytes calldata deployData) external returns(address deployedAddress, bytes memory deployLazyInitResponse); function addModel(bytes calldata code) external returns(address modelAddress, uint256 positionIndex); function models() external view returns(address[] memory); }//SPDX-License-Identifier: MIT pragma solidity >=0.7.0; pragma abicoder v2; import "../model/Item.sol"; import "@ethereansos/swissknife/contracts/generic/model/ILazyInitCapableElement.sol"; interface IItemProjection is Item, ILazyInitCapableElement { function mainInterface() external view returns(address); function collectionId() external view returns(bytes32); function uri() external view returns(string memory); function plainUri() external view returns(string memory); function itemPlainUri(uint256 itemId) external view returns(string memory); function setHeader(Header calldata value) external returns(Header memory oldValue); function toInteroperableInterfaceAmount(uint256 amount, uint256 itemId, address account) external view returns(uint256); function toMainInterfaceAmount(uint256 amount, uint256 itemId) external view returns(uint256); }// SPDX-License-Identifier: MIT pragma solidity >=0.7.0; import "../../core/model/IOrganization.sol"; import "../model/IMicroservicesManager.sol"; import "../model/IStateManager.sol"; import "../model/IProposalsManager.sol"; import "../model/ITreasuryManager.sol"; import { ReflectionUtilities, BytesUtilities } from "@ethereansos/swissknife/contracts/lib/GeneralUtilities.sol"; library Grimoire { bytes32 constant public COMPONENT_KEY_TREASURY_MANAGER = 0xcfe1633df53a0649d88d788961f26058c5e7a0b5644675f19f67bb2975827ba2; bytes32 constant public COMPONENT_KEY_STATE_MANAGER = 0xd1d09e8f5708558865b8acd5f13c69781ae600e42dbc7f52b8ef1b9e33dbcd36; bytes32 constant public COMPONENT_KEY_MICROSERVICES_MANAGER = 0x0aef4c8f864010d3e1817691f51ade95a646fffafd7f3df9cb8200def342cfd7; bytes32 constant public COMPONENT_KEY_PROPOSALS_MANAGER = 0xa504406933af7ca120d20b97dfc79ea9788beb3c4d3ac1ff9a2c292b2c28e0cc; } library Getters { function treasuryManager(IOrganization organization) internal view returns(ITreasuryManager) { return ITreasuryManager(organization.get(Grimoire.COMPONENT_KEY_TREASURY_MANAGER)); } function stateManager(IOrganization organization) internal view returns(IStateManager) { return IStateManager(organization.get(Grimoire.COMPONENT_KEY_STATE_MANAGER)); } function microservicesManager(IOrganization organization) internal view returns(IMicroservicesManager) { return IMicroservicesManager(organization.get(Grimoire.COMPONENT_KEY_MICROSERVICES_MANAGER)); } function proposalsManager(IOrganization organization) internal view returns(IProposalsManager) { return IProposalsManager(organization.get(Grimoire.COMPONENT_KEY_PROPOSALS_MANAGER)); } } library Setters { function replaceTreasuryManager(IOrganization organization, address newComponentAddress) internal returns(ITreasuryManager oldComponent) { require(newComponentAddress != address(0), "void"); oldComponent = ITreasuryManager(organization.set(IOrganization.Component(Grimoire.COMPONENT_KEY_TREASURY_MANAGER, newComponentAddress, false, true))); } function replaceStateManager(IOrganization organization, address newComponentAddress) internal returns(IStateManager oldComponent) { require(newComponentAddress != address(0), "void"); oldComponent = IStateManager(organization.set(IOrganization.Component(Grimoire.COMPONENT_KEY_STATE_MANAGER, newComponentAddress, false ,true))); } function replaceMicroservicesManager(IOrganization organization, address newComponentAddress) internal returns(IMicroservicesManager oldComponent) { require(newComponentAddress != address(0), "void"); oldComponent = IMicroservicesManager(organization.set(IOrganization.Component(Grimoire.COMPONENT_KEY_MICROSERVICES_MANAGER, newComponentAddress, true, true))); } function replaceProposalsManager(IOrganization organization, address newComponentAddress) internal returns(IProposalsManager oldComponent) { require(newComponentAddress != address(0), "void"); oldComponent = IProposalsManager(organization.set(IOrganization.Component(Grimoire.COMPONENT_KEY_PROPOSALS_MANAGER, newComponentAddress, true, true))); } } library Treasury { using ReflectionUtilities for address; function storeETH(IOrganization organization, uint256 value) internal { if(value != 0) { organization.get(Grimoire.COMPONENT_KEY_TREASURY_MANAGER).submit(value, ""); } } function callTemporaryFunction(ITreasuryManager treasuryManager, bytes4 selector, address subject, uint256 value, bytes memory data) internal returns(bytes memory response) { address oldServer = treasuryManager.setAdditionalFunction(selector, subject, false); response = address(treasuryManager).submit(value, abi.encodePacked(selector, data)); treasuryManager.setAdditionalFunction(selector, oldServer, false); } } library State { using BytesUtilities for bytes; bytes32 constant public ENTRY_TYPE_ADDRESS = 0x421683f821a0574472445355be6d2b769119e8515f8376a1d7878523dfdecf7b; bytes32 constant public ENTRY_TYPE_ADDRESS_ARRAY = 0x23d8ff3dc5aed4a634bcf123581c95e70c60ac0e5246916790aef6d4451ff4c1; bytes32 constant public ENTRY_TYPE_BOOL = 0xc1053bdab4a5cf55238b667c39826bbb11a58be126010e7db397c1b67c24271b; bytes32 constant public ENTRY_TYPE_BOOL_ARRAY = 0x8761250c4d2c463ce51f91f5d2c2508fa9142f8a42aa9f30b965213bf3e6c2ac; bytes32 constant public ENTRY_TYPE_BYTES = 0xb963e9b45d014edd60cff22ec9ad383335bbc3f827be2aee8e291972b0fadcf2; bytes32 constant public ENTRY_TYPE_BYTES_ARRAY = 0x084b42f8a8730b98eb0305d92103d9107363192bb66162064a34dc5716ebe1a0; bytes32 constant public ENTRY_TYPE_STRING = 0x97fc46276c172633607a331542609db1e3da793fca183d594ed5a61803a10792; bytes32 constant public ENTRY_TYPE_STRING_ARRAY = 0xa227fd7a847724343a7dda3598ee0fb2d551b151b73e4a741067596daa6f5658; bytes32 constant public ENTRY_TYPE_UINT256 = 0xec13d6d12b88433319b64e1065a96ea19cd330ef6603f5f6fb685dde3959a320; bytes32 constant public ENTRY_TYPE_UINT256_ARRAY = 0xc1b76e99a35aa41ed28bbbd9e6c7228760c87b410ebac94fa6431da9b592411f; function getAddress(IStateManager stateManager, string memory name) internal view returns(address) { return stateManager.get(name).value.asAddress(); } function setAddress(IStateManager stateManager, string memory name, address val) internal returns(address oldValue) { return stateManager.set(IStateManager.StateEntry(name, ENTRY_TYPE_ADDRESS, abi.encodePacked(val))).asAddress(); } function getAddressArray(IStateManager stateManager, string memory name) internal view returns(address[] memory) { return stateManager.get(name).value.asAddressArray(); } function setAddressArray(IStateManager stateManager, string memory name, address[] memory val) internal returns(address[] memory oldValue) { return stateManager.set(IStateManager.StateEntry(name, ENTRY_TYPE_ADDRESS_ARRAY, abi.encode(val))).asAddressArray(); } function getBool(IStateManager stateManager, string memory name) internal view returns(bool) { return stateManager.get(name).value.asBool(); } function setBool(IStateManager stateManager, string memory name, bool val) internal returns(bool oldValue) { return stateManager.set(IStateManager.StateEntry(name, ENTRY_TYPE_BOOL, abi.encode(val ? 1 : 0))).asBool(); } function getBoolArray(IStateManager stateManager, string memory name) internal view returns(bool[] memory) { return stateManager.get(name).value.asBoolArray(); } function setBoolArray(IStateManager stateManager, string memory name, bool[] memory val) internal returns(bool[] memory oldValue) { return stateManager.set(IStateManager.StateEntry(name, ENTRY_TYPE_BOOL_ARRAY, abi.encode(val))).asBoolArray(); } function getBytes(IStateManager stateManager, string memory name) internal view returns(bytes memory) { return stateManager.get(name).value; } function setBytes(IStateManager stateManager, string memory name, bytes memory val) internal returns(bytes memory oldValue) { return stateManager.set(IStateManager.StateEntry(name, ENTRY_TYPE_BYTES, val)); } function getBytesArray(IStateManager stateManager, string memory name) internal view returns(bytes[] memory) { return stateManager.get(name).value.asBytesArray(); } function setBytesArray(IStateManager stateManager, string memory name, bytes[] memory val) internal returns(bytes[] memory oldValue) { return stateManager.set(IStateManager.StateEntry(name, ENTRY_TYPE_BYTES_ARRAY, abi.encode(val))).asBytesArray(); } function getString(IStateManager stateManager, string memory name) internal view returns(string memory) { return string(stateManager.get(name).value); } function setString(IStateManager stateManager, string memory name, string memory val) internal returns(string memory oldValue) { return string(stateManager.set(IStateManager.StateEntry(name, ENTRY_TYPE_STRING, bytes(val)))); } function getStringArray(IStateManager stateManager, string memory name) internal view returns(string[] memory) { return stateManager.get(name).value.asStringArray(); } function setStringArray(IStateManager stateManager, string memory name, string[] memory val) internal returns(string[] memory oldValue) { return stateManager.set(IStateManager.StateEntry(name, ENTRY_TYPE_STRING_ARRAY, abi.encode(val))).asStringArray(); } function getUint256(IStateManager stateManager, string memory name) internal view returns(uint256) { return stateManager.get(name).value.asUint256(); } function setUint256(IStateManager stateManager, string memory name, uint256 val) internal returns(uint256 oldValue) { return stateManager.set(IStateManager.StateEntry(name, ENTRY_TYPE_UINT256, abi.encode(val))).asUint256(); } function getUint256Array(IStateManager stateManager, string memory name) internal view returns(uint256[] memory) { return stateManager.get(name).value.asUint256Array(); } function setUint256Array(IStateManager stateManager, string memory name, uint256[] memory val) internal returns(uint256[] memory oldValue) { return stateManager.set(IStateManager.StateEntry(name, ENTRY_TYPE_UINT256_ARRAY, abi.encode(val))).asUint256Array(); } }// SPDX-License-Identifier: MIT pragma solidity >=0.7.0; import "@ethereansos/swissknife/contracts/generic/model/ILazyInitCapableElement.sol"; interface IStateManager is ILazyInitCapableElement { struct StateEntry { string key; bytes32 entryType; bytes value; } function size() external view returns (uint256); function all() external view returns (StateEntry[] memory); function partialList(uint256 start, uint256 offset) external view returns (StateEntry[] memory); function list(string[] calldata keys) external view returns (StateEntry[] memory); function listByIndices(uint256[] calldata indices) external view returns (StateEntry[] memory); function exists(string calldata key) external view returns(bool result, uint256 index); function get(string calldata key) external view returns(StateEntry memory); function getByIndex(uint256 index) external view returns(StateEntry memory); function set(StateEntry calldata newValue) external returns(bytes memory replacedValue); function batchSet(StateEntry[] calldata newValues) external returns(bytes[] memory replacedValues); function remove(string calldata key) external returns(bytes32 removedType, bytes memory removedValue); function batchRemove(string[] calldata keys) external returns(bytes32[] memory removedTypes, bytes[] memory removedValues); function removeByIndices(uint256[] calldata indices) external returns(bytes32[] memory removedTypes, bytes[] memory removedValues); }// SPDX-License-Identifier: MIT pragma solidity >=0.7.0; import "@ethereansos/swissknife/contracts/dynamicMetadata/model/IDynamicMetadataCapableElement.sol"; interface IOrganization is IDynamicMetadataCapableElement { struct Component { bytes32 key; address location; bool active; bool log; } function keyOf(address componentAddress) external view returns(bytes32); function history(bytes32 key) external view returns(address[] memory componentsAddresses); function batchHistory(bytes32[] calldata keys) external view returns(address[][] memory componentsAddresses); function get(bytes32 key) external view returns(address componentAddress); function list(bytes32[] calldata keys) external view returns(address[] memory componentsAddresses); function isActive(address subject) external view returns(bool); function keyIsActive(bytes32 key) external view returns(bool); function set(Component calldata) external returns(address replacedComponentAddress); function batchSet(Component[] calldata) external returns (address[] memory replacedComponentAddresses); event ComponentSet(bytes32 indexed key, address indexed from, address indexed to, bool active); function submit(address location, bytes calldata payload, address restReceiver) external payable returns(bytes memory response); }// SPDX-License-Identifier: MIT pragma solidity >=0.7.0; import "@ethereansos/swissknife/contracts/generic/model/ILazyInitCapableElement.sol"; import "@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol"; interface IProposalsManager is IERC1155Receiver, ILazyInitCapableElement { struct ProposalCode { address location; bytes bytecode; } struct ProposalCodes { ProposalCode[] codes; bool alsoTerminate; } struct Proposal { address proposer; address[] codeSequence; uint256 creationBlock; uint256 accept; uint256 refuse; address triggeringRules; address[] canTerminateAddresses; address[] validatorsAddresses; bool validationPassed; uint256 terminationBlock; bytes votingTokens; } struct ProposalConfiguration { address[] collections; uint256[] objectIds; uint256[] weights; address creationRules; address triggeringRules; address[] canTerminateAddresses; address[] validatorsAddresses; } function batchCreate(ProposalCodes[] calldata codeSequences) external returns(bytes32[] memory createdProposalIds); function list(bytes32[] calldata proposalIds) external view returns(Proposal[] memory); function votes(bytes32[] calldata proposalIds, address[] calldata voters, bytes32[][] calldata items) external view returns(uint256[][] memory accepts, uint256[][] memory refuses, uint256[][] memory toWithdraw); function weight(bytes32 code) external view returns(uint256); function vote(address erc20TokenAddress, bytes memory permitSignature, bytes32 proposalId, uint256 accept, uint256 refuse, address voter, bool alsoTerminate) external payable; function batchVote(bytes[] calldata data) external payable; function withdrawAll(bytes32[] memory proposalIds, address voterOrReceiver, bool afterTermination) external; function terminate(bytes32[] calldata proposalIds) external; function configuration() external view returns(ProposalConfiguration memory); function setConfiguration(ProposalConfiguration calldata newValue) external returns(ProposalConfiguration memory oldValue); function lastProposalId() external view returns(bytes32); function lastVoteBlock(address voter) external view returns (uint256); event ProposalCreated(address indexed proposer, address indexed code, bytes32 indexed proposalId); event ProposalWeight(bytes32 indexed proposalId, address indexed collection, uint256 indexed id, bytes32 key, uint256 weight); event ProposalTerminated(bytes32 indexed proposalId, bool result, bytes errorData); event Accept(bytes32 indexed proposalId, address indexed voter, bytes32 indexed item, uint256 amount); event MoveToAccept(bytes32 indexed proposalId, address indexed voter, bytes32 indexed item, uint256 amount); event RetireAccept(bytes32 indexed proposalId, address indexed voter, bytes32 indexed item, uint256 amount); event Refuse(bytes32 indexed proposalId, address indexed voter, bytes32 indexed item, uint256 amount); event MoveToRefuse(bytes32 indexed proposalId, address indexed voter, bytes32 indexed item, uint256 amount); event RetireRefuse(bytes32 indexed proposalId, address indexed voter, bytes32 indexed item, uint256 amount); } interface IProposalChecker { function check(address proposalsManagerAddress, bytes32 id, bytes calldata data, address from, address voter) external view returns(bool); } interface IExternalProposalsManagerCommands { function createProposalCodeSequence(bytes32 proposalId, IProposalsManager.ProposalCode[] memory codeSequenceInput, address sender) external returns (address[] memory codeSequence, IProposalsManager.ProposalConfiguration memory localConfiguration); function proposalCanBeFinalized(bytes32 proposalId, IProposalsManager.Proposal memory proposal, bool validationPassed, bool result) external view returns (bool); function isVotable(bytes32 proposalId, IProposalsManager.Proposal memory proposal, address from, address voter, bool voteOrWithtraw) external view returns (bytes memory response); }// SPDX-License-Identifier: MIT pragma solidity >=0.7.0; import "../../../core/model/IOrganization.sol"; import "../../../base/model/IProposalsManager.sol"; interface ISubDAO is IOrganization, IExternalProposalsManagerCommands { event Proposed(uint256 indexed modelIndex, uint256 indexed presetIndex, bytes32 indexed proposalId); struct SubDAOProposalModel { address source; string uri; bool isPreset; bytes[] presetValues; bytes32[] presetProposals; address creationRules; address triggeringRules; uint256 votingRulesIndex; address[][] canTerminateAddresses; address[][] validatorsAddresses; } function presetArrayMaxSize() external view returns(uint256); function proposalModels() external view returns(SubDAOProposalModel[] memory); function setProposalModels(SubDAOProposalModel[] calldata newValue) external returns(SubDAOProposalModel[] memory oldValue); function setInitialProposalModels(SubDAOProposalModel[] calldata newValue) external; function setVotingRules(uint256 modelIndex, uint256 votingRulesIndex) external returns(address[] memory oldCanTerminateAddresses, address[] memory oldValidatorsAddresses); function setCreationAndTriggeringRules(uint256 modelIndex, address newCreationRules, address newTriggeringRules) external returns(address oldCreationRules, address oldTriggeringRules); function setPresetValues(uint256 modelIndex, bytes[] calldata newPresetValues) external returns(bytes[] memory oldPresetValues, bytes32[] memory deprecatedProposalIds); function finalizeInit(address firstHost) external; function isPersistent(bytes32 proposalId) external view returns(bool result, bool isDeprecated); }// SPDX-License-Identifier: MIT pragma solidity >=0.7.0; import "../../core/model/IOrganization.sol"; import "../subDAOsManager/model/ISubDAOsManager.sol"; import "../delegationsManager/model/IDelegationsManager.sol"; import "../treasurySplitterManager/model/ITreasurySplitterManager.sol"; import "../investmentsManager/model/IInvestmentsManager.sol"; import "../delegation/model/IDelegationTokensManager.sol"; library Grimoire { bytes32 constant public COMPONENT_KEY_TREASURY_SPLITTER_MANAGER = 0x87a92f6bd20613c184485be8eadb46851dd4294a8359f902606085b8be6e7ae6; bytes32 constant public COMPONENT_KEY_SUBDAOS_MANAGER = 0x5b87d6e94145c2e242653a71b7d439a3638a93c3f0d32e1ea876f9fb1feb53e2; bytes32 constant public COMPONENT_KEY_DELEGATIONS_MANAGER = 0x49b87f4ee20613c184485be8eadb46851dd4294a8359f902606085b8be6e7ae6; bytes32 constant public COMPONENT_KEY_INVESTMENTS_MANAGER = 0x4f3ad97a91794a00945c0ead3983f793d34044c6300048d8b4ef95636edd234b; } library DelegationGrimoire { bytes32 constant public COMPONENT_KEY_TOKENS_MANAGER = 0x62b56c3ab20613c184485be8eadb46851dd4294a8359f902606085b8be9f7dc5; } library Getters { function treasurySplitterManager(IOrganization organization) internal view returns(ITreasurySplitterManager) { return ITreasurySplitterManager(organization.get(Grimoire.COMPONENT_KEY_TREASURY_SPLITTER_MANAGER)); } function subDAOsManager(IOrganization organization) internal view returns(ISubDAOsManager) { return ISubDAOsManager(organization.get(Grimoire.COMPONENT_KEY_SUBDAOS_MANAGER)); } function delegationsManager(IOrganization organization) internal view returns(IDelegationsManager) { return IDelegationsManager(organization.get(Grimoire.COMPONENT_KEY_DELEGATIONS_MANAGER)); } function investmentsManager(IOrganization organization) internal view returns(IInvestmentsManager) { return IInvestmentsManager(organization.get(Grimoire.COMPONENT_KEY_INVESTMENTS_MANAGER)); } } library Setters { function replaceTreasurySplitterManager(IOrganization organization, address newComponentAddress) internal returns(ITreasurySplitterManager oldComponent) { require(newComponentAddress != address(0), "void"); oldComponent = ITreasurySplitterManager(organization.set(IOrganization.Component(Grimoire.COMPONENT_KEY_TREASURY_SPLITTER_MANAGER, newComponentAddress, false, true))); } function replaceSubDAOsManager(IOrganization organization, address newComponentAddress) internal returns(ISubDAOsManager oldComponent) { require(newComponentAddress != address(0), "void"); oldComponent = ISubDAOsManager(organization.set(IOrganization.Component(Grimoire.COMPONENT_KEY_SUBDAOS_MANAGER, newComponentAddress, true, true))); } function replaceDelegationsManager(IOrganization organization, address newComponentAddress) internal returns(IDelegationsManager oldComponent) { require(newComponentAddress != address(0), "void"); oldComponent = IDelegationsManager(organization.set(IOrganization.Component(Grimoire.COMPONENT_KEY_DELEGATIONS_MANAGER, newComponentAddress, false, true))); } function replaceInvestmentsManager(IOrganization organization, address newComponentAddress) internal returns(IInvestmentsManager oldComponent) { require(newComponentAddress != address(0), "void"); oldComponent = IInvestmentsManager(organization.set(IOrganization.Component(Grimoire.COMPONENT_KEY_INVESTMENTS_MANAGER, newComponentAddress, false, true))); } } library DelegationGetters { function tokensManager(IOrganization organization) internal view returns(IDelegationTokensManager) { return IDelegationTokensManager(organization.get(DelegationGrimoire.COMPONENT_KEY_TOKENS_MANAGER)); } } library DelegationUtilities { using DelegationGetters for IOrganization; function extractVotingTokens(address delegationsManagerAddress, address delegationAddress) internal view returns (bytes memory) { IDelegationsManager delegationsManager = IDelegationsManager(delegationsManagerAddress); (bool exists,,) = delegationsManager.exists(delegationAddress); require(exists, "wrong address"); (address collection, uint256 tokenId) = delegationsManager.supportedToken(); (collection, tokenId) = IOrganization(delegationAddress).tokensManager().wrapped(collection, tokenId, delegationsManagerAddress); require(tokenId != 0, "Wrap tokens first"); address[] memory collections = new address[](1); uint256[] memory tokenIds = new uint256[](1); uint256[] memory weights = new uint256[](1); collections[0] = collection; tokenIds[0] = tokenId; weights[0] = 1; return abi.encode(collections, tokenIds, weights); } }// SPDX-License-Identifier: MIT pragma solidity >=0.7.0; import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; library BehaviorUtilities { function randomKey(uint256 i) internal view returns (bytes32) { return keccak256(abi.encode(i, block.timestamp, block.number, tx.origin, tx.gasprice, block.coinbase, block.difficulty, msg.sender, blockhash(block.number - 5))); } function calculateProjectedArraySizeAndLoopUpperBound(uint256 arraySize, uint256 start, uint256 offset) internal pure returns(uint256 projectedArraySize, uint256 projectedArrayLoopUpperBound) { if(arraySize != 0 && start < arraySize && offset != 0) { uint256 length = start + offset; if(start < (length = length > arraySize ? arraySize : length)) { projectedArraySize = (projectedArrayLoopUpperBound = length) - start; } } } } library ReflectionUtilities { function read(address subject, bytes memory inputData) internal view returns(bytes memory returnData) { bool result; (result, returnData) = subject.staticcall(inputData); if(!result) { assembly { revert(add(returnData, 0x20), mload(returnData)) } } } function submit(address subject, uint256 value, bytes memory inputData) internal returns(bytes memory returnData) { bool result; (result, returnData) = subject.call{value : value}(inputData); if(!result) { assembly { revert(add(returnData, 0x20), mload(returnData)) } } } function isContract(address subject) internal view returns (bool) { if(subject == address(0)) { return false; } uint256 codeLength; assembly { codeLength := extcodesize(subject) } return codeLength > 0; } function clone(address originalContract) internal returns(address copyContract) { assembly { mstore( 0, or( 0x5880730000000000000000000000000000000000000000803b80938091923cF3, mul(originalContract, 0x1000000000000000000) ) ) copyContract := create(0, 0, 32) switch extcodesize(copyContract) case 0 { invalid() } } } } library BytesUtilities { bytes private constant ALPHABET = "0123456789abcdef"; string internal constant BASE64_ENCODER_DATA = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'; function asAddress(bytes memory b) internal pure returns(address) { if(b.length == 0) { return address(0); } if(b.length == 20) { address addr; assembly { addr := mload(add(b, 20)) } return addr; } return abi.decode(b, (address)); } function asAddressArray(bytes memory b) internal pure returns(address[] memory callResult) { if(b.length > 0) { return abi.decode(b, (address[])); } } function asBool(bytes memory bs) internal pure returns(bool) { return asUint256(bs) != 0; } function asBoolArray(bytes memory b) internal pure returns(bool[] memory callResult) { if(b.length > 0) { return abi.decode(b, (bool[])); } } function asBytesArray(bytes memory b) internal pure returns(bytes[] memory callResult) { if(b.length > 0) { return abi.decode(b, (bytes[])); } } function asString(bytes memory b) internal pure returns(string memory callResult) { if(b.length > 0) { return abi.decode(b, (string)); } } function asStringArray(bytes memory b) internal pure returns(string[] memory callResult) { if(b.length > 0) { return abi.decode(b, (string[])); } } function asUint256(bytes memory bs) internal pure returns(uint256 x) { if (bs.length >= 32) { assembly { x := mload(add(bs, add(0x20, 0))) } } } function asUint256Array(bytes memory b) internal pure returns(uint256[] memory callResult) { if(b.length > 0) { return abi.decode(b, (uint256[])); } } function toString(bytes memory data) internal pure returns(string memory) { bytes memory str = new bytes(2 + data.length * 2); str[0] = "0"; str[1] = "x"; for (uint256 i = 0; i < data.length; i++) { str[2+i*2] = ALPHABET[uint256(uint8(data[i] >> 4))]; str[3+i*2] = ALPHABET[uint256(uint8(data[i] & 0x0f))]; } return string(str); } function asSingletonArray(bytes memory a) internal pure returns(bytes[] memory array) { array = new bytes[](1); array[0] = a; } function toBase64(bytes memory data) internal pure returns (string memory) { if (data.length == 0) return ''; string memory table = BASE64_ENCODER_DATA; uint256 encodedLen = 4 * ((data.length + 2) / 3); string memory result = new string(encodedLen + 32); assembly { mstore(result, encodedLen) let tablePtr := add(table, 1) let dataPtr := data let endPtr := add(dataPtr, mload(data)) let resultPtr := add(result, 32) for {} lt(dataPtr, endPtr) {} { dataPtr := add(dataPtr, 3) let input := mload(dataPtr) mstore8(resultPtr, mload(add(tablePtr, and(shr(18, input), 0x3F)))) resultPtr := add(resultPtr, 1) mstore8(resultPtr, mload(add(tablePtr, and(shr(12, input), 0x3F)))) resultPtr := add(resultPtr, 1) mstore8(resultPtr, mload(add(tablePtr, and(shr( 6, input), 0x3F)))) resultPtr := add(resultPtr, 1) mstore8(resultPtr, mload(add(tablePtr, and( input, 0x3F)))) resultPtr := add(resultPtr, 1) } switch mod(mload(data), 3) case 1 { mstore(sub(resultPtr, 2), shl(240, 0x3d3d)) } case 2 { mstore(sub(resultPtr, 1), shl(248, 0x3d)) } } return result; } } library StringUtilities { bytes1 private constant CHAR_0 = bytes1('0'); bytes1 private constant CHAR_A = bytes1('A'); bytes1 private constant CHAR_a = bytes1('a'); bytes1 private constant CHAR_f = bytes1('f'); bytes internal constant BASE64_DECODER_DATA = hex"0000000000000000000000000000000000000000000000000000000000000000" hex"00000000000000000000003e0000003f3435363738393a3b3c3d000000000000" hex"00000102030405060708090a0b0c0d0e0f101112131415161718190000000000" hex"001a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132330000000000"; function isEmpty(string memory test) internal pure returns (bool) { return equals(test, ""); } function equals(string memory a, string memory b) internal pure returns(bool) { return keccak256(abi.encodePacked(a)) == keccak256(abi.encodePacked(b)); } function toLowerCase(string memory str) internal pure returns(string memory) { bytes memory bStr = bytes(str); for (uint256 i = 0; i < bStr.length; i++) { bStr[i] = bStr[i] >= 0x41 && bStr[i] <= 0x5A ? bytes1(uint8(bStr[i]) + 0x20) : bStr[i]; } return string(bStr); } function asBytes(string memory str) internal pure returns(bytes memory toDecode) { bytes memory data = abi.encodePacked(str); if(data.length == 0 || data[0] != "0" || (data[1] != "x" && data[1] != "X")) { return ""; } uint256 start = 2; toDecode = new bytes((data.length - 2) / 2); for(uint256 i = 0; i < toDecode.length; i++) { toDecode[i] = bytes1(_fromHexChar(uint8(data[start++])) + _fromHexChar(uint8(data[start++])) * 16); } } function toBase64(string memory input) internal pure returns(string memory) { return BytesUtilities.toBase64(abi.encodePacked(input)); } function fromBase64(string memory _data) internal pure returns (bytes memory) { bytes memory data = bytes(_data); if (data.length == 0) return new bytes(0); require(data.length % 4 == 0, "invalid base64 decoder input"); bytes memory table = BASE64_DECODER_DATA; uint256 decodedLen = (data.length / 4) * 3; bytes memory result = new bytes(decodedLen + 32); assembly { let lastBytes := mload(add(data, mload(data))) if eq(and(lastBytes, 0xFF), 0x3d) { decodedLen := sub(decodedLen, 1) if eq(and(lastBytes, 0xFFFF), 0x3d3d) { decodedLen := sub(decodedLen, 1) } } mstore(result, decodedLen) let tablePtr := add(table, 1) let dataPtr := data let endPtr := add(dataPtr, mload(data)) let resultPtr := add(result, 32) for {} lt(dataPtr, endPtr) {} { dataPtr := add(dataPtr, 4) let input := mload(dataPtr) let output := add( add( shl(18, and(mload(add(tablePtr, and(shr(24, input), 0xFF))), 0xFF)), shl(12, and(mload(add(tablePtr, and(shr(16, input), 0xFF))), 0xFF))), add( shl( 6, and(mload(add(tablePtr, and(shr( 8, input), 0xFF))), 0xFF)), and(mload(add(tablePtr, and( input , 0xFF))), 0xFF) ) ) mstore(resultPtr, shl(232, output)) resultPtr := add(resultPtr, 3) } } return result; } function _fromHexChar(uint8 c) private pure returns (uint8) { bytes1 charc = bytes1(c); return charc < CHAR_0 || charc > CHAR_f ? 0 : (charc < CHAR_A ? 0 : 10) + c - uint8(charc < CHAR_A ? CHAR_0 : charc < CHAR_a ? CHAR_A : CHAR_a); } } library Uint256Utilities { function asSingletonArray(uint256 n) internal pure returns(uint256[] memory array) { array = new uint256[](1); array[0] = n; } function toHex(uint256 _i) internal pure returns (string memory) { return BytesUtilities.toString(abi.encodePacked(_i)); } function toString(uint256 _i) internal pure returns (string memory _uintAsString) { if (_i == 0) { return "0"; } uint256 j = _i; uint256 len; while (j != 0) { len++; j /= 10; } bytes memory bstr = new bytes(len); uint256 k = len; while (_i != 0) { k = k-1; uint8 temp = (48 + uint8(_i - _i / 10 * 10)); bytes1 b1 = bytes1(temp); bstr[k] = b1; _i /= 10; } return string(bstr); } function sum(uint256[] memory arr) internal pure returns (uint256 result) { for(uint256 i = 0; i < arr.length; i++) { result += arr[i]; } } } library AddressUtilities { function asSingletonArray(address a) internal pure returns(address[] memory array) { array = new address[](1); array[0] = a; } function toString(address _addr) internal pure returns (string memory) { return _addr == address(0) ? "0x0000000000000000000000000000000000000000" : BytesUtilities.toString(abi.encodePacked(_addr)); } } library Bytes32Utilities { function asSingletonArray(bytes32 a) internal pure returns(bytes32[] memory array) { array = new bytes32[](1); array[0] = a; } function toString(bytes32 bt) internal pure returns (string memory) { return bt == bytes32(0) ? "0x0000000000000000000000000000000000000000000000000000000000000000" : BytesUtilities.toString(abi.encodePacked(bt)); } } library TransferUtilities { using ReflectionUtilities for address; function balanceOf(address erc20TokenAddress, address account) internal view returns(uint256) { if(erc20TokenAddress == address(0)) { return account.balance; } return abi.decode(erc20TokenAddress.read(abi.encodeWithSelector(IERC20(erc20TokenAddress).balanceOf.selector, account)), (uint256)); } function allowance(address erc20TokenAddress, address account, address spender) internal view returns(uint256) { if(erc20TokenAddress == address(0)) { return 0; } return abi.decode(erc20TokenAddress.read(abi.encodeWithSelector(IERC20(erc20TokenAddress).allowance.selector, account, spender)), (uint256)); } function safeApprove(address erc20TokenAddress, address spender, uint256 value) internal { bytes memory returnData = erc20TokenAddress.submit(0, abi.encodeWithSelector(IERC20(erc20TokenAddress).approve.selector, spender, value)); require(returnData.length == 0 || abi.decode(returnData, (bool)), 'APPROVE_FAILED'); } function safeTransfer(address erc20TokenAddress, address to, uint256 value) internal { if(value == 0) { return; } if(erc20TokenAddress == address(0)) { to.submit(value, ""); return; } bytes memory returnData = erc20TokenAddress.submit(0, abi.encodeWithSelector(IERC20(erc20TokenAddress).transfer.selector, to, value)); require(returnData.length == 0 || abi.decode(returnData, (bool)), 'TRANSFER_FAILED'); } function safeTransferFrom(address erc20TokenAddress, address from, address to, uint256 value) internal { if(value == 0) { return; } if(erc20TokenAddress == address(0)) { to.submit(value, ""); return; } bytes memory returnData = erc20TokenAddress.submit(0, abi.encodeWithSelector(IERC20(erc20TokenAddress).transferFrom.selector, from, to, value)); require(returnData.length == 0 || abi.decode(returnData, (bool)), 'TRANSFERFROM_FAILED'); } }// SPDX-License-Identifier: MIT pragma solidity >=0.7.0; import "../model/IEthereansFactory.sol"; import "@ethereansos/swissknife/contracts/factory/impl/Factory.sol"; import "../../factoryOfFactories/model/IFactoryOfFactories.sol"; import "@openzeppelin/contracts/token/ERC1155/IERC1155.sol"; import { TransferUtilities } from "@ethereansos/swissknife/contracts/lib/GeneralUtilities.sol"; import "@openzeppelin/contracts/token/ERC20/extensions/draft-IERC20Permit.sol"; abstract contract EthereansFactory is Factory, IEthereansFactory { using TransferUtilities for address; uint256 internal _feePercentageForTransacted; address internal _feeReceiver; address internal _tokenToTransferOrBurnAddressInCreation; uint256 internal _transferOrBurnAmountInCreation; address internal _transferOrBurnReceiverInCreation; address internal _tokenToTransferOrBurnAddressInApplication; uint256 internal _transferOrBurnAmountInApplication; address internal _transferOrBurnReceiverInApplication; constructor(bytes memory lazyInitData) Factory(lazyInitData) { } receive() external payable { } function _factoryLazyInit(bytes memory initData) internal override virtual returns (bytes memory factoryLazyInitResponse) { EthereansFactoryInitializer memory ethereansFactoryInitializer; (ethereansFactoryInitializer) = abi.decode(initData, (EthereansFactoryInitializer)); _feePercentageForTransacted = ethereansFactoryInitializer.feePercentageForTransacted; _feeReceiver = ethereansFactoryInitializer.feeReceiver; _tokenToTransferOrBurnAddressInCreation = ethereansFactoryInitializer.tokenToTransferOrBurnAddressInCreation; _transferOrBurnAmountInCreation = ethereansFactoryInitializer.transferOrBurnAmountInCreation; _transferOrBurnReceiverInCreation = ethereansFactoryInitializer.transferOrBurnReceiverInCreation; _tokenToTransferOrBurnAddressInApplication = ethereansFactoryInitializer.tokenToTransferOrBurnAddressInApplication; _transferOrBurnAmountInApplication = ethereansFactoryInitializer.transferOrBurnAmountInApplication; _transferOrBurnReceiverInApplication = ethereansFactoryInitializer.transferOrBurnReceiverInApplication; factoryLazyInitResponse = _ethosFactoryLazyInit(ethereansFactoryInitializer.factoryLazyInitData); } function feeInfo() public override view returns(address operator, uint256 feePercentageForTransacted, address feeReceiver, address tokenToTransferOrBurnAddressInCreation, uint256 transferOrBurnAmountInCreation, address transferOrBurnReceiverInCreation, address tokenToTransferOrBurnAddressInApplication, uint256 transferOrBurnAmountInApplication, address transferOrBurnReceiverInApplication) { operator = initializer; (feePercentageForTransacted, feeReceiver, tokenToTransferOrBurnAddressInCreation, transferOrBurnAmountInCreation, transferOrBurnReceiverInCreation, tokenToTransferOrBurnAddressInApplication, transferOrBurnAmountInApplication, transferOrBurnReceiverInApplication) = _realFeeInfo(); } function payFee(address sender, address tokenAddress, uint256 value, bytes calldata permitSignature) external override payable returns (uint256 feePaid) { (uint256 feePercentageForTransacted, address feeReceiver, , , , , uint256 transferOrBurnAmountInApplication, ) = _realFeeInfo(); if(feePercentageForTransacted != 0) { (uint256 feeSentOrBurnt, uint256 fofFeePaid) = IFactoryOfFactories(initializer).payFee{value : tokenAddress == address(0) ? value : 0}(sender, tokenAddress, value, permitSignature, feePercentageForTransacted, feeReceiver); feePaid = feeSentOrBurnt + fofFeePaid; _feePaid(sender, tokenAddress, value, feeSentOrBurnt, fofFeePaid, feePercentageForTransacted, feeReceiver); } else { require(transferOrBurnAmountInApplication == 0, "zero fees"); } } function _feePaid(address sender, address tokenAddress, uint256 value, uint256 feeSentOrBurnt, uint256 feePaid, uint256 feePercentageForTransacted, address feeReceiver) internal virtual { } function burnOrTransferToken(address sender, bytes calldata permitSignature) external payable override returns(uint256 amountTransferedOrBurnt) { (uint256 feePercentageForTransacted, , , , , address tokenToTransferOrBurnAddressInApplication, uint256 transferOrBurnAmountInApplication, address transferOrBurnReceiverInApplication) = _realFeeInfo(); if(transferOrBurnAmountInApplication != 0) { (uint256 feeSentOrBurnt, uint256 fofAmountTransferedOrBurnt) = IFactoryOfFactories(initializer).burnOrTransferTokenAmount{value : tokenToTransferOrBurnAddressInApplication == address(0) ? transferOrBurnAmountInApplication : 0}(sender, tokenToTransferOrBurnAddressInApplication, transferOrBurnAmountInApplication, permitSignature, transferOrBurnReceiverInApplication); amountTransferedOrBurnt = feeSentOrBurnt + fofAmountTransferedOrBurnt; _amountTransferedOrBurnt(sender, feeSentOrBurnt, fofAmountTransferedOrBurnt, tokenToTransferOrBurnAddressInApplication, transferOrBurnAmountInApplication, transferOrBurnReceiverInApplication); } else { require(feePercentageForTransacted == 0, "zero amount"); } } function _amountTransferedOrBurnt(address sender, uint256 feeSentOrBurnt, uint256 amountTransferedOrBurnt, address tokenToTransferOrBurnAddressInApplication, uint256 transferOrBurnAmountInApplication, address transferOrBurnReceiverInApplication) internal virtual { } function _burnOrTransferTokenAtCreation(address sender, bytes memory permitSignature) internal returns(uint256 amountTransferedOrBurnt) { (, , address tokenToTransferOrBurnAddressInCreation, uint256 transferOrBurnAmountInCreation, address transferOrBurnReceiverInCreation, , , ) = _realFeeInfo(); if(transferOrBurnAmountInCreation != 0) { (uint256 feeSentOrBurnt, uint256 fofAmountTransferedOrBurnt) = IFactoryOfFactories(initializer).burnOrTransferTokenAmount{value : tokenToTransferOrBurnAddressInCreation == address(0) ? transferOrBurnAmountInCreation : 0}(sender, tokenToTransferOrBurnAddressInCreation, transferOrBurnAmountInCreation, permitSignature, transferOrBurnReceiverInCreation); amountTransferedOrBurnt = feeSentOrBurnt + fofAmountTransferedOrBurnt; _amountTransferedOrBurntAtCreation(sender, feeSentOrBurnt, fofAmountTransferedOrBurnt, tokenToTransferOrBurnAddressInCreation, transferOrBurnAmountInCreation, transferOrBurnReceiverInCreation); } } function _amountTransferedOrBurntAtCreation(address sender, uint256 feeSentOrBurnt, uint256 amountTransferedOrBurnt, address tokenToTransferOrBurnAddressInCreation, uint256 transferOrBurnAmountInCreation, address transferOrBurnReceiverInCreation) internal virtual { } function _subjectIsAuthorizedFor(address, address, bytes4 selector, bytes calldata, uint256) internal override pure returns (bool, bool) { if(selector == this.setModelAddress.selector || selector == this.setDynamicUriResolver.selector) { return (true, false); } return (false, false); } function _realFeeInfo() internal virtual view returns(uint256 feePercentageForTransacted, address feeReceiver, address tokenToTransferOrBurnAddressInCreation, uint256 transferOrBurnAmountInCreation, address transferOrBurnReceiverInCreation, address tokenToTransferOrBurnAddressInApplication, uint256 transferOrBurnAmountInApplication, address transferOrBurnReceiverInApplication) { return (_feePercentageForTransacted, _feeReceiver, _tokenToTransferOrBurnAddressInCreation, _transferOrBurnAmountInCreation, _transferOrBurnReceiverInCreation, _tokenToTransferOrBurnAddressInApplication, _transferOrBurnAmountInApplication, _transferOrBurnReceiverInApplication); } function _ethosFactoryLazyInit(bytes memory lazyInitData) internal virtual returns(bytes memory lazyInitResponse); }// SPDX-License-Identifier: MIT pragma solidity >=0.7.0; import "./IOrganizationFactory.sol"; import { IDelegationRulesChanger } from "../../../ext/delegation/impl/DelegationProposals.sol"; interface IDelegationFactory is IOrganizationFactory, IDelegationRulesChanger { function initializeProposalModels( address delegationAddress, address host, uint256 quorum, uint256 validationBomb, uint256 blockLength, uint256 hardCap) external; }// SPDX-License-Identifier: MIT pragma solidity >=0.7.0; import "@ethereansos/swissknife/contracts/generic/model/ILazyInitCapableElement.sol"; import "@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol"; interface IDelegationTokensManager is ILazyInitCapableElement, IERC1155Receiver { event Wrapped(address sourceAddress, uint256 sourceObjectId, address indexed sourceDelegationsManagerAddress, uint256 indexed wrappedObjectId); function itemMainInterfaceAddress() external view returns(address); function projectionAddress() external view returns(address); function collectionId() external view returns(bytes32); function ticker() external view returns(string memory); function wrap(address sourceDelegationsManagerAddress, bytes memory permitSignature, uint256 amount, address receiver) payable external returns(uint256 wrappedObjectId); function wrapped(address sourceCollection, uint256 sourceObjectId, address sourceDelegationsManagerAddress) external view returns(address wrappedCollection, uint256 wrappedObjectId); function source(uint256 wrappedObjectId) external view returns(address sourceCollectionAddress, uint256 sourceObjectId, address sourceDelegationsManagerAddress); }// SPDX-License-Identifier: MIT pragma solidity >=0.7.0; import "@ethereansos/swissknife/contracts/generic/model/ILazyInitCapableElement.sol"; import "@ethereansos/covenants/contracts/presto/IPrestoUniV3.sol"; interface IInvestmentsManager is ILazyInitCapableElement { function ONE_HUNDRED() external pure returns(uint256); function refundETHReceiver() external view returns(bytes32 key, address receiverAddress); function executorRewardPercentage() external view returns(uint256); function prestoAddress() external view returns(address prestoAddress); function tokenFromETHToBurn() external view returns(address addr); function tokensFromETH() external view returns(address[] memory addresses); function setTokensFromETH(address[] calldata addresses) external returns(address[] memory oldAddresses); function swapFromETH(PrestoOperation[] calldata tokensFromETHData, PrestoOperation calldata tokenFromETHToBurnData, address executorRewardReceiver) external returns (uint256[] memory tokenAmounts, uint256 tokenFromETHToBurnAmount, uint256 executorReward); function lastSwapToETHBlock() external view returns (uint256); function swapToETHInterval() external view returns (uint256); function nextSwapToETHBlock() external view returns (uint256); function tokensToETH() external view returns(address[] memory addresses, uint256[] memory percentages); function setTokensToETH(address[] calldata addresses, uint256[] calldata percentages) external returns(address[] memory oldAddresses, uint256[] memory oldPercentages); function swapToETH(PrestoOperation[] calldata tokensToETHData, address executorRewardReceiver) external returns (uint256[] memory executorRewards, uint256[] memory ethAmounts); }// SPDX-License-Identifier: MIT pragma solidity >=0.7.0; import "@ethereansos/swissknife/contracts/generic/model/ILazyInitCapableElement.sol"; interface ITreasurySplitterManager is ILazyInitCapableElement { event Splitted(bytes32 indexed subDAO, address indexed receiver, uint256 amount); function ONE_HUNDRED() external pure returns(uint256); function lastSplitBlock() external view returns (uint256); function splitInterval() external view returns (uint256); function nextSplitBlock() external view returns (uint256); function executorRewardPercentage() external view returns(uint256); function flushExecutorRewardPercentage() external view returns(uint256); function receiversAndPercentages() external view returns (bytes32[] memory keys, address[] memory addresses, uint256[] memory percentages); function flushReceiver() external view returns(bytes32 key, address addr); function flushERC20Tokens(address[] calldata tokenAddresses, address executorRewardReceiver) external; function splitTreasury(address executorRewardReceiver) external; }// SPDX-License-Identifier: MIT pragma solidity >=0.7.0; import "@ethereansos/swissknife/contracts/generic/model/ILazyInitCapableElement.sol"; interface IDelegationsManager is ILazyInitCapableElement { event DelegationSet(address indexed delegationAddress, address indexed treasuryAddress); event SupportedToken(address indexed collectionAddress, uint256 indexed objectId); event Factory(address indexed factory, bool indexed allowed); struct DelegationData { address location; address treasury; } function split(address executorRewardReceiver) external; function supportedToken() external view returns(address collection, uint256 objectId); function setSupportedToken(address collection, uint256 tokenId) external; function maxSize() external view returns(uint256); function setMaxSize(uint256 newValue) external returns (uint256 oldValue); function size() external view returns (uint256); function list() external view returns (DelegationData[] memory); function partialList(uint256 start, uint256 offset) external view returns (DelegationData[] memory); function listByAddresses(address[] calldata delegationAddresses) external view returns (DelegationData[] memory); function listByIndices(uint256[] calldata indices) external view returns (DelegationData[] memory); function exists(address delegationAddress) external view returns(bool result, uint256 index, address treasuryOf); function treasuryOf(address delegationAddress) external view returns(address treasuryAddress); function get(address delegationAddress) external view returns(DelegationData memory); function getByIndex(uint256 index) external view returns(DelegationData memory); function set() external; function remove(address[] calldata delegationAddresses) external returns(DelegationData[] memory removedDelegations); function removeAll() external; function executorRewardPercentage() external view returns(uint256); function getSplit(address executorRewardReceiver) external view returns (address[] memory receivers, uint256[] memory values); function getSituation() external view returns(address[] memory treasuries, uint256[] memory treasuryPercentages); function factoryIsAllowed(address factoryAddress) external view returns(bool); function setFactoriesAllowed(address[] memory factoryAddresses, bool[] memory allowed) external; function isBanned(address productAddress) external view returns(bool); function ban(address[] memory productAddresses) external; function isValid(address delegationAddress) external view returns(bool); event PaidFor(address indexed delegationAddress, address indexed from, address indexed retriever, uint256 amount); function paidFor(address delegationAddress, address retriever) external view returns(uint256 totalPaid, uint256 retrieverPaid); function payFor(address delegationAddress, uint256 amount, bytes memory permitSignature, address retriever) external payable; function retirePayment(address delegationAddress, address receiver, bytes memory data) external; function attachInsurance() external view returns (uint256); function setAttachInsurance(uint256 value) external returns (uint256 oldValue); }// SPDX-License-Identifier: MIT pragma solidity >=0.7.0; import "@ethereansos/swissknife/contracts/generic/model/ILazyInitCapableElement.sol"; interface ISubDAOsManager is ILazyInitCapableElement { struct SubDAOEntry { bytes32 key; address location; address newHost; } function keyOf(address subdaoAddress) external view returns(bytes32); function history(bytes32 key) external view returns(address[] memory subdaosAddresses); function batchHistory(bytes32[] calldata keys) external view returns(address[][] memory subdaosAddresses); function get(bytes32 key) external view returns(address subdaoAddress); function list(bytes32[] calldata keys) external view returns(address[] memory subdaosAddresses); function exists(address subject) external view returns(bool); function keyExists(bytes32 key) external view returns(bool); function set(bytes32 key, address location, address newHost) external returns(address replacedSubdaoAddress); function batchSet(SubDAOEntry[] calldata) external returns (address[] memory replacedSubdaoAddresses); function submit(bytes32 key, bytes calldata payload, address restReceiver) external payable returns(bytes memory response); event SubDAOSet(bytes32 indexed key, address indexed from, address indexed to); }// SPDX-License-Identifier: MIT pragma solidity >=0.7.0; import "../model/IFactory.sol"; import "../../dynamicMetadata/impl/DynamicMetadataCapableElement.sol"; import { ReflectionUtilities } from "../../lib/GeneralUtilities.sol"; contract Factory is IFactory, DynamicMetadataCapableElement { using ReflectionUtilities for address; address public override modelAddress; mapping(address => address) public override deployer; constructor(bytes memory lazyInitData) DynamicMetadataCapableElement(lazyInitData) { } function _dynamicMetadataElementLazyInit(bytes memory lazyInitData) internal override returns (bytes memory lazyInitResponse) { require(modelAddress == address(0), "init"); (modelAddress, lazyInitResponse) = abi.decode(lazyInitData, (address, bytes)); lazyInitResponse = _factoryLazyInit(lazyInitResponse); } function _dynamicMetadataElementSupportsInterface(bytes4 interfaceId) override internal view returns(bool) { return interfaceId == type(IFactory).interfaceId || interfaceId == this.modelAddress.selector || interfaceId == this.setModelAddress.selector || interfaceId == this.deployer.selector || interfaceId == this.deploy.selector || _factorySupportsInterface(interfaceId); } function setModelAddress(address newValue) external override authorizedOnly returns(address oldValue) { oldValue = modelAddress; modelAddress = newValue; } function deploy(bytes calldata deployData) external payable override virtual returns(address deployedAddress, bytes memory deployedLazyInitResponse) { deployer[deployedAddress = modelAddress.clone()] = msg.sender; emit Deployed(modelAddress, deployedAddress, msg.sender, deployedLazyInitResponse = ILazyInitCapableElement(deployedAddress).lazyInit(deployData)); require(ILazyInitCapableElement(deployedAddress).initializer() == address(this)); } function _factoryLazyInit(bytes memory) internal virtual returns (bytes memory) { return ""; } function _factorySupportsInterface(bytes4 interfaceId) internal virtual view returns(bool) { } }// SPDX-License-Identifier: MIT pragma solidity >=0.7.0; import "../../delegationsManager/model/IDelegationsManager.sol"; import "@ethereansos/swissknife/contracts/factory/model/IFactory.sol"; import "../../../base/model/IProposalsManager.sol"; import "../../../base/model/ITreasuryManager.sol"; import "../../../core/model/IOrganization.sol"; import { Getters } from "../../../base/lib/KnowledgeBase.sol"; import { Uint256Utilities, AddressUtilities, TransferUtilities, Bytes32Utilities } from "@ethereansos/swissknife/contracts/lib/GeneralUtilities.sol"; import "../../../ext/subDAO/model/ISubDAO.sol"; import { Getters as ExternalGetters, DelegationUtilities } from "../../../ext/lib/KnowledgeBase.sol"; import "../../../ethereans/factories/model/IDelegationFactory.sol"; contract DelegationsManagerAttacherProposal { using AddressUtilities for address; string public uri; address public delegationsManagerAddress; string public additionalUri; function lazyInit(bytes memory lazyInitData) external returns(bytes memory lazyInitResponseData) { require(keccak256(bytes(uri)) == keccak256("")); (uri, lazyInitResponseData) = abi.decode(lazyInitData, (string, bytes)); require(keccak256(bytes(uri)) != keccak256("")); (additionalUri, delegationsManagerAddress) = abi.decode(lazyInitResponseData, (string, address)); lazyInitResponseData = ""; } function execute(bytes32) external { IOrganization organization = IOrganization(ILazyInitCapableElement(msg.sender).host()); organization.submit(delegationsManagerAddress, abi.encodeWithSignature("set()"), address(0)); } } contract DelegationTransferManagerProposal { string public uri; address public treasuryManagerAddress; ITreasuryManager.TransferEntry[] public entries; string public additionalUri; function lazyInit(bytes memory lazyInitData) external returns(bytes memory lazyInitResponseData) { require(keccak256(bytes(uri)) == keccak256("")); (uri, lazyInitResponseData) = abi.decode(lazyInitData, (string, bytes)); require(keccak256(bytes(uri)) != keccak256("")); ITreasuryManager.TransferEntry[] memory _entries; (additionalUri, treasuryManagerAddress, _entries) = abi.decode(lazyInitResponseData, (string, address, ITreasuryManager.TransferEntry[])); for(uint256 i = 0; i < _entries.length; i++) { entries.push(_entries[i]); } require(ILazyInitCapableElement(treasuryManagerAddress).host() == msg.sender, "Wrong Treasury Manager"); lazyInitResponseData = DelegationUtilities.extractVotingTokens(ILazyInitCapableElement(treasuryManagerAddress).initializer(), msg.sender); } function execute(bytes32) external { ITreasuryManager(treasuryManagerAddress).batchTransfer(entries); } function allEntries() external view returns(ITreasuryManager.TransferEntry[] memory) { return entries; } } contract VoteProposal { using Getters for IOrganization; using ExternalGetters for IOrganization; using Uint256Utilities for uint256; using TransferUtilities for address; using Bytes32Utilities for bytes32; string public uri; address public proposalsManagerAddress; bytes32 public organizationProposalID; address public collectionAddress; uint256 public objectId; uint256 public accept; uint256 public refuse; bool public vote; bool public afterTermination; bool public _voting; string public additionalUri; function lazyInit(bytes memory lazyInitData) external returns(bytes memory lazyInitResponseData) { require(keccak256(bytes(uri)) == keccak256("")); (uri, lazyInitResponseData) = abi.decode(lazyInitData, (string, bytes)); require(keccak256(bytes(uri)) != keccak256("")); _lazyInit1(lazyInitResponseData); lazyInitResponseData = DelegationUtilities.extractVotingTokens(address(IOrganization(ILazyInitCapableElement(proposalsManagerAddress).host()).delegationsManager()), msg.sender); } function _lazyInit1(bytes memory lazyInitResponseData) private { (proposalsManagerAddress, organizationProposalID, collectionAddress, lazyInitResponseData) = abi.decode(lazyInitResponseData, (address, bytes32, address, bytes)); _lazyInit2(lazyInitResponseData); } function _lazyInit2(bytes memory lazyInitResponseData) private { (objectId, accept, refuse, vote, afterTermination, additionalUri) = abi.decode(lazyInitResponseData, (uint256, uint256, uint256, bool, bool, string)); } receive() external payable { require(_voting, "not voting"); } function execute(bytes32) external { ITreasuryManager treasuryManager = IOrganization(ILazyInitCapableElement(msg.sender).host()).treasuryManager(); return vote ? _vote(treasuryManager) : _withdraw(treasuryManager); } function _vote(ITreasuryManager treasuryManager) private { bool hasERC20 = collectionAddress == address(0); ITreasuryManager.TransferEntry[] memory transferEntries = new ITreasuryManager.TransferEntry[](1); transferEntries[0] = ITreasuryManager.TransferEntry({ token : hasERC20 ? address(uint160(objectId)) : collectionAddress, objectIds : hasERC20 ? new uint256[](0) : objectId.asSingletonArray(), values : (accept + refuse).asSingletonArray(), receiver : hasERC20 ? address(this) : proposalsManagerAddress, safe : false, batch : false, withData : false, data : hasERC20 ? bytes("") : abi.encode(organizationProposalID, accept, refuse, address(treasuryManager), false) }); _voting = hasERC20; treasuryManager.batchTransfer(transferEntries); _voting = false; IProposalsManager proposalsManager = IProposalsManager(proposalsManagerAddress); if(hasERC20) { address erc20TokenAddress = address(uint160(objectId)); if(erc20TokenAddress != address(0)) { erc20TokenAddress.safeApprove(proposalsManagerAddress, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff); } proposalsManager.vote{value : erc20TokenAddress != address(0) ? 0 : (accept + refuse)}(erc20TokenAddress, "", organizationProposalID, accept, refuse, address(treasuryManager), false); } } function _withdraw(ITreasuryManager treasuryManager) private { treasuryManager.submit(proposalsManagerAddress, abi.encodeWithSelector(IProposalsManager(proposalsManagerAddress).withdrawAll.selector, organizationProposalID.asSingletonArray(), address(treasuryManager), afterTermination), address(treasuryManager)); } } interface IDelegationRulesChanger { function createNewRules( address delegationAddress, uint256 quorum, uint256 validationBomb, uint256 blockLength, uint256 hardCap) external returns (address[] memory validationAddresses, address[] memory canTerminateAddresses); } contract DelegationChangeRulesProposal { string public uri; uint256 public quorum; uint256 public validationBomb; uint256 public blockLength; uint256 public hardCap; string public additionalUri; function lazyInit(bytes memory lazyInitData) external returns(bytes memory lazyInitResponseData) { require(keccak256(bytes(uri)) == keccak256("")); (uri, lazyInitResponseData) = abi.decode(lazyInitData, (string, bytes)); require(keccak256(bytes(uri)) != keccak256("")); (additionalUri, quorum, validationBomb, blockLength, hardCap) = abi.decode(lazyInitResponseData, (string, uint256, uint256, uint256, uint256)); require(blockLength > 0 || hardCap > 0, "No termination rules"); lazyInitResponseData = ""; } function execute(bytes32) external { ISubDAO subDAO = ISubDAO(ILazyInitCapableElement(msg.sender).host()); (address[] memory validators, address[] memory canTerminates) = IDelegationRulesChanger(subDAO.initializer()).createNewRules(address(subDAO), quorum, validationBomb, blockLength, hardCap); ISubDAO.SubDAOProposalModel[] memory proposalModels = subDAO.proposalModels(); ISubDAO.SubDAOProposalModel memory prop = proposalModels[proposalModels.length - 2]; prop.validatorsAddresses[0] = validators; prop.canTerminateAddresses[0] = canTerminates; proposalModels[proposalModels.length - 2] = prop; prop = proposalModels[proposalModels.length - 1]; prop.validatorsAddresses[0] = validators; prop.canTerminateAddresses[0] = canTerminates; proposalModels[proposalModels.length - 1] = prop; subDAO.setProposalModels(proposalModels); } }// SPDX-License-Identifier: MIT pragma solidity >=0.7.0; import "./IEthereansFactory.sol"; interface IOrganizationFactory is IEthereansFactory { struct OrganizationDeployData { string uri; bytes[] mandatoryComponentsDeployData; uint256[] additionalComponents; bytes[] additionalComponentsDeployData; bytes[] specialComponentsData; bytes specificOrganizationData; } function data() external view returns(address[] memory utilityModels, bytes32[] memory utilitiyModelKeys, bool[] memory utilitiyModelActive, string memory proposalUri); }// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612]. * * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't * need to send a transaction, and thus is not required to hold Ether at all. */ interface IERC20Permit { /** * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens, * given ``owner``'s signed approval. * * IMPORTANT: The same issues {IERC20-approve} has related to transaction * ordering also apply here. * * Emits an {Approval} event. * * Requirements: * * - `spender` cannot be the zero address. * - `deadline` must be a timestamp in the future. * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner` * over the EIP712-formatted function arguments. * - the signature must use ``owner``'s current nonce (see {nonces}). * * For more information on the signature format, see the * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP * section]. */ function permit( address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) external; /** * @dev Returns the current nonce for `owner`. This value must be * included whenever a signature is generated for {permit}. * * Every successful call to {permit} increases ``owner``'s nonce by one. This * prevents a signature from being used multiple times. */ function nonces(address owner) external view returns (uint256); /** * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}. */ // solhint-disable-next-line func-name-mixedcase function DOMAIN_SEPARATOR() external view returns (bytes32); } // SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "../../utils/introspection/IERC165.sol"; /** * @dev Required interface of an ERC1155 compliant contract, as defined in the * https://eips.ethereum.org/EIPS/eip-1155[EIP]. * * _Available since v3.1._ */ interface IERC1155 is IERC165 { /** * @dev Emitted when `value` tokens of token type `id` are transferred from `from` to `to` by `operator`. */ event TransferSingle(address indexed operator, address indexed from, address indexed to, uint256 id, uint256 value); /** * @dev Equivalent to multiple {TransferSingle} events, where `operator`, `from` and `to` are the same for all * transfers. */ event TransferBatch( address indexed operator, address indexed from, address indexed to, uint256[] ids, uint256[] values ); /** * @dev Emitted when `account` grants or revokes permission to `operator` to transfer their tokens, according to * `approved`. */ event ApprovalForAll(address indexed account, address indexed operator, bool approved); /** * @dev Emitted when the URI for token type `id` changes to `value`, if it is a non-programmatic URI. * * If an {URI} event was emitted for `id`, the standard * https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[guarantees] that `value` will equal the value * returned by {IERC1155MetadataURI-uri}. */ event URI(string value, uint256 indexed id); /** * @dev Returns the amount of tokens of token type `id` owned by `account`. * * Requirements: * * - `account` cannot be the zero address. */ function balanceOf(address account, uint256 id) external view returns (uint256); /** * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {balanceOf}. * * Requirements: * * - `accounts` and `ids` must have the same length. */ function balanceOfBatch(address[] calldata accounts, uint256[] calldata ids) external view returns (uint256[] memory); /** * @dev Grants or revokes permission to `operator` to transfer the caller's tokens, according to `approved`, * * Emits an {ApprovalForAll} event. * * Requirements: * * - `operator` cannot be the caller. */ function setApprovalForAll(address operator, bool approved) external; /** * @dev Returns true if `operator` is approved to transfer ``account``'s tokens. * * See {setApprovalForAll}. */ function isApprovedForAll(address account, address operator) external view returns (bool); /** * @dev Transfers `amount` tokens of token type `id` from `from` to `to`. * * Emits a {TransferSingle} event. * * Requirements: * * - `to` cannot be the zero address. * - If the caller is not `from`, it must be have been approved to spend ``from``'s tokens via {setApprovalForAll}. * - `from` must have a balance of tokens of type `id` of at least `amount`. * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the * acceptance magic value. */ function safeTransferFrom( address from, address to, uint256 id, uint256 amount, bytes calldata data ) external; /** * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {safeTransferFrom}. * * Emits a {TransferBatch} event. * * Requirements: * * - `ids` and `amounts` must have the same length. * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the * acceptance magic value. */ function safeBatchTransferFrom( address from, address to, uint256[] calldata ids, uint256[] calldata amounts, bytes calldata data ) external; } // SPDX-License-Identifier: MIT pragma solidity >=0.7.0; interface IFactoryOfFactories { function size() external view returns (uint256); function all() external view returns (address[] memory hosts, address[][] memory factoryLists); function partialList(uint256 start, uint256 offset) external view returns (address[] memory hosts, address[][] memory factoryLists); function get(uint256 index) external view returns(address host, address[] memory factoryList); function create(address[] calldata hosts, bytes[][] calldata factoryBytecodes) external returns (address[][] memory factoryLists, uint256[] memory listPositions); function setFactoryListsMetadata(uint256[] calldata listPositions, address[] calldata newHosts) external returns (address[] memory replacedHosts); event FactoryList(uint256 indexed listPosition, address indexed fromHost, address indexed toHost); function add(uint256[] calldata listPositions, bytes[][] calldata factoryBytecodes) external returns(address[][] memory factoryLists, uint256[][] memory factoryPositions); event FactoryAdded(uint256 indexed listPosition, address indexed host, address indexed factoryAddress, uint256 factoryPosition); function payFee(address sender, address tokenAddress, uint256 value, bytes calldata permitSignature, uint256 feePercentage, address feeReceiver) external payable returns (uint256 feeSentOrBurnt, uint256 feePaid); function burnOrTransferTokenAmount(address sender, address tokenAddress, uint256 value, bytes calldata permitSignature, address receiver) external payable returns(uint256 feeSentOrBurnt, uint256 amountTransferedOrBurnt); }// SPDX-License-Identifier: MIT pragma solidity >=0.7.0; import "@ethereansos/swissknife/contracts/factory/model/IFactory.sol"; import "@openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol"; interface IEthereansFactory is IFactory { struct EthereansFactoryInitializer { uint256 feePercentageForTransacted; address feeReceiver; address tokenToTransferOrBurnAddressInCreation; uint256 transferOrBurnAmountInCreation; address transferOrBurnReceiverInCreation; address tokenToTransferOrBurnAddressInApplication; uint256 transferOrBurnAmountInApplication; address transferOrBurnReceiverInApplication; bytes factoryLazyInitData; } function feeInfo() external view returns(address operator, uint256 feePercentageForTransacted, address feeReceiver, address tokenToTransferOrBurnAddressInCreation, uint256 transferOrBurnAmountInCreation, address transferOrBurnReceiverInCreation, address tokenToTransferOrBurnAddressInApplication, uint256 transferOrBurnAmountInApplication, address transferOrBurnReceiverInApplication); function payFee(address sender, address tokenAddress, uint256 value, bytes calldata permitSignature) external payable returns (uint256 feePaid); function burnOrTransferToken(address sender, bytes calldata permitSignature) external payable returns(uint256 amountTransferedOrBurnt); }//SPDX-License-Identifier: MIT pragma solidity >=0.7.0; import "../../generic/model/ILazyInitCapableElement.sol"; interface IDynamicMetadataCapableElement is ILazyInitCapableElement { function uri() external view returns(string memory); function plainUri() external view returns(string memory); function setUri(string calldata newValue) external returns (string memory oldValue); function dynamicUriResolver() external view returns(address); function setDynamicUriResolver(address newValue) external returns(address oldValue); }// SPDX-License-Identifier: MIT pragma solidity >=0.7.0; import "@openzeppelin/contracts/utils/introspection/IERC165.sol"; interface ILazyInitCapableElement is IERC165 { function lazyInit(bytes calldata lazyInitData) external returns(bytes memory initResponse); function initializer() external view returns(address); event Host(address indexed from, address indexed to); function host() external view returns(address); function setHost(address newValue) external returns(address oldValue); function subjectIsAuthorizedFor(address subject, address location, bytes4 selector, bytes calldata payload, uint256 value) external view returns(bool); }// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "../../utils/introspection/IERC165.sol"; /** * @dev _Available since v3.1._ */ interface IERC1155Receiver is IERC165 { /** @dev Handles the receipt of a single ERC1155 token type. This function is called at the end of a `safeTransferFrom` after the balance has been updated. To accept the transfer, this must return `bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)"))` (i.e. 0xf23a6e61, or its own function selector). @param operator The address which initiated the transfer (i.e. msg.sender) @param from The address which previously owned the token @param id The ID of the token being transferred @param value The amount of tokens being transferred @param data Additional data with no specified format @return `bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)"))` if transfer is allowed */ function onERC1155Received( address operator, address from, uint256 id, uint256 value, bytes calldata data ) external returns (bytes4); /** @dev Handles the receipt of a multiple ERC1155 token types. This function is called at the end of a `safeBatchTransferFrom` after the balances have been updated. To accept the transfer(s), this must return `bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)"))` (i.e. 0xbc197c81, or its own function selector). @param operator The address which initiated the batch transfer (i.e. msg.sender) @param from The address which previously owned the token @param ids An array containing ids of each token being transferred (order and length must match values array) @param values An array containing amounts of each token being transferred (order and length must match ids array) @param data Additional data with no specified format @return `bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)"))` if transfer is allowed */ function onERC1155BatchReceived( address operator, address from, uint256[] calldata ids, uint256[] calldata values, bytes calldata data ) external returns (bytes4); } // SPDX-License-Identifier: MIT pragma solidity >=0.7.0; import "@ethereansos/swissknife/contracts/generic/model/ILazyInitCapableElement.sol"; interface ITreasuryManager is ILazyInitCapableElement { struct TransferEntry { address token; uint256[] objectIds; uint256[] values; address receiver; bool safe; bool batch; bool withData; bytes data; } function transfer(address token, uint256 value, address receiver, uint256 tokenType, uint256 objectId, bool safe, bool withData, bytes calldata data) external returns(bool result, bytes memory returnData); function batchTransfer(TransferEntry[] calldata transferEntries) external returns(bool[] memory results, bytes[] memory returnDatas); function submit(address location, bytes calldata payload, address restReceiver) external payable returns(bytes memory response); function setAdditionalFunction(bytes4 selector, address newServer, bool log) external returns (address oldServer); event AdditionalFunction(address caller, bytes4 indexed selector, address indexed oldServer, address indexed newServer); }// SPDX-License-Identifier: MIT pragma solidity >=0.7.0; import "@ethereansos/swissknife/contracts/generic/model/ILazyInitCapableElement.sol"; interface IMicroservicesManager is ILazyInitCapableElement { struct Microservice { string key; address location; string methodSignature; bool submittable; string returnAbiParametersArray; bool isInternal; bool needsSender; } function size() external view returns (uint256); function all() external view returns (Microservice[] memory); function partialList(uint256 start, uint256 offset) external view returns (Microservice[] memory); function list(string[] calldata keys) external view returns (Microservice[] memory); function listByIndices(uint256[] calldata indices) external view returns (Microservice[] memory); function exists(string calldata key) external view returns(bool result, uint256 index); function get(string calldata key) external view returns(Microservice memory); function getByIndex(uint256 index) external view returns(Microservice memory); function set(Microservice calldata newValue) external returns(Microservice memory replacedValue); function batchSet(Microservice[] calldata newValues) external returns(Microservice[] memory replacedValues); event MicroserviceAdded(address indexed sender, bytes32 indexed keyHash, string key, address indexed location, string methodSignature, bool submittable, string returnAbiParametersArray, bool isInternal, bool needsSender); function remove(string calldata key) external returns(Microservice memory removedValue); function batchRemove(string[] calldata keys) external returns(Microservice[] memory removedValues); function removeByIndices(uint256[] calldata indices) external returns(Microservice[] memory removedValues); event MicroserviceRemoved(address indexed sender, bytes32 indexed keyHash, string key, address indexed location, string methodSignature, bool submittable, string returnAbiParametersArray, bool isInternal, bool needsSender); function read(string calldata key, bytes calldata data) external view returns(bytes memory returnData); function submit(string calldata key, bytes calldata data) external payable returns(bytes memory returnData); }// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20 { /** * @dev Returns the amount of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the amount of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves `amount` tokens from the caller's account to `recipient`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address recipient, uint256 amount) external returns (bool); /** * @dev Returns the remaining number of tokens that `spender` will be * allowed to spend on behalf of `owner` through {transferFrom}. This is * zero by default. * * This value changes when {approve} or {transferFrom} are called. */ function allowance(address owner, address spender) external view returns (uint256); /** * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. * * Returns a boolean value indicating whether the operation succeeded. * * IMPORTANT: Beware that changing an allowance with this method brings the risk * that someone may use both the old and the new allowance by unfortunate * transaction ordering. One possible solution to mitigate this race * condition is to first reduce the spender's allowance to 0 and set the * desired value afterwards: * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 * * Emits an {Approval} event. */ function approve(address spender, uint256 amount) external returns (bool); /** * @dev Moves `amount` tokens from `sender` to `recipient` using the * allowance mechanism. `amount` is then deducted from the caller's * allowance. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transferFrom( address sender, address recipient, uint256 amount ) external returns (bool); /** * @dev Emitted when `value` tokens are moved from one account (`from`) to * another (`to`). * * Note that `value` may be zero. */ event Transfer(address indexed from, address indexed to, uint256 value); /** * @dev Emitted when the allowance of a `spender` for an `owner` is set by * a call to {approve}. `value` is the new allowance. */ event Approval(address indexed owner, address indexed spender, uint256 value); } //SPDX-License-Identifier: MIT pragma solidity >=0.7.0; pragma abicoder v2; import "@openzeppelin/contracts/token/ERC1155/IERC1155.sol"; import "./IERC1155Views.sol"; struct Header { address host; string name; string symbol; string uri; } struct CreateItem { Header header; bytes32 collectionId; uint256 id; address[] accounts; uint256[] amounts; } interface Item is IERC1155, IERC1155Views { event CollectionItem(bytes32 indexed fromCollectionId, bytes32 indexed toCollectionId, uint256 indexed itemId); function name() external view returns(string memory); function symbol() external view returns(string memory); function decimals() external view returns(uint256); function burn(address account, uint256 itemId, uint256 amount) external; function burnBatch(address account, uint256[] calldata itemIds, uint256[] calldata amounts) external; function burn(address account, uint256 itemId, uint256 amount, bytes calldata data) external; function burnBatch(address account, uint256[] calldata itemIds, uint256[] calldata amounts, bytes calldata data) external; function mintItems(CreateItem[] calldata items) external returns(uint256[] memory itemIds); function setItemsCollection(uint256[] calldata itemIds, bytes32[] calldata collectionIds) external returns(bytes32[] memory oldCollectionIds); function setItemsMetadata(uint256[] calldata itemIds, Header[] calldata newValues) external returns(Header[] memory oldValues); function interoperableOf(uint256 itemId) external view returns(address); }//SPDX-License-Identifier: MIT pragma solidity >=0.7.0; pragma abicoder v2; import "./PrestoDataUniV3.sol"; interface IPrestoUniV3 { function ONE_HUNDRED() external view returns (uint256); function doubleProxy() external view returns (address); function feePercentage() external view returns (uint256); function feePercentageInfo() external view returns (uint256, address); function setDoubleProxy(address _doubleProxy) external; function setFeePercentage(uint256 _feePercentage) external; function execute(PrestoOperation[] memory operations) external payable returns(uint256[] memory outputAmounts); }// SPDX-License-Identifier: MIT pragma solidity >=0.7.0; import "../../dynamicMetadata/model/IDynamicMetadataCapableElement.sol"; interface IFactory is IDynamicMetadataCapableElement { event Deployed(address indexed modelAddress, address indexed deployedAddress, address indexed deployer, bytes deployedLazyInitResponse); function modelAddress() external view returns(address); function setModelAddress(address newValue) external returns(address oldValue); function deployer(address deployedAddress) external view returns(address); function deploy(bytes calldata deployData) external payable returns(address deployedAddress, bytes memory deployedLazyInitResponse); }// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; /** * @dev Interface of the ERC165 standard, as defined in the * https://eips.ethereum.org/EIPS/eip-165[EIP]. * * Implementers can declare support of contract interfaces, which can then be * queried by others ({ERC165Checker}). * * For an implementation, see {ERC165}. */ interface IERC165 { /** * @dev Returns true if this contract implements the interface defined by * `interfaceId`. See the corresponding * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] * to learn more about how these ids are created. * * This function call must use less than 30 000 gas. */ function supportsInterface(bytes4 interfaceId) external view returns (bool); } //SPDX-License-Identifier: MIT pragma solidity >=0.7.0; import "../model/IDynamicMetadataCapableElement.sol"; import "../model/IDynamicUriResolver.sol"; import "../../generic/impl/LazyInitCapableElement.sol"; abstract contract DynamicMetadataCapableElement is IDynamicMetadataCapableElement, LazyInitCapableElement { string public override plainUri; address public override dynamicUriResolver; constructor(bytes memory lazyInitData) LazyInitCapableElement(lazyInitData) { } function _lazyInit(bytes memory lazyInitData) internal override returns (bytes memory lazyInitResponse) { (plainUri, dynamicUriResolver, lazyInitResponse) = abi.decode(lazyInitData, (string, address, bytes)); lazyInitResponse = _dynamicMetadataElementLazyInit(lazyInitResponse); } function _supportsInterface(bytes4 interfaceId) internal override view returns(bool) { return interfaceId == type(IDynamicMetadataCapableElement).interfaceId || interfaceId == this.plainUri.selector || interfaceId == this.uri.selector || interfaceId == this.dynamicUriResolver.selector || interfaceId == this.setUri.selector || interfaceId == this.setDynamicUriResolver.selector || _dynamicMetadataElementSupportsInterface(interfaceId); } function uri() external override view returns(string memory) { return _uri(plainUri, ""); } function setUri(string calldata newValue) external override authorizedOnly returns (string memory oldValue) { oldValue = plainUri; plainUri = newValue; } function setDynamicUriResolver(address newValue) external override authorizedOnly returns(address oldValue) { oldValue = dynamicUriResolver; dynamicUriResolver = newValue; } function _uri(string memory _plainUri, bytes memory additionalData) internal view returns(string memory) { if(dynamicUriResolver == address(0)) { return _plainUri; } return IDynamicUriResolver(dynamicUriResolver).resolve(address(this), _plainUri, additionalData, msg.sender); } function _dynamicMetadataElementLazyInit(bytes memory lazyInitData) internal virtual returns(bytes memory); function _dynamicMetadataElementSupportsInterface(bytes4 interfaceId) internal virtual view returns(bool); }// SPDX-License-Identifier: MIT pragma solidity >=0.7.0; /** * @title IERC1155Views - An optional utility interface to improve the ERC-1155 Standard. * @dev This interface introduces some additional capabilities for ERC-1155 Tokens. */ interface IERC1155Views { /** * @dev Returns the total supply of the given token id * @param itemId the id of the token whose availability you want to know */ function totalSupply(uint256 itemId) external view returns (uint256); /** * @dev Returns the name of the given token id * @param itemId the id of the token whose name you want to know */ function name(uint256 itemId) external view returns (string memory); /** * @dev Returns the symbol of the given token id * @param itemId the id of the token whose symbol you want to know */ function symbol(uint256 itemId) external view returns (string memory); /** * @dev Returns the decimals of the given token id * @param itemId the id of the token whose decimals you want to know */ function decimals(uint256 itemId) external view returns (uint256); /** * @dev Returns the uri of the given token id * @param itemId the id of the token whose uri you want to know */ function uri(uint256 itemId) external view returns (string memory); }// SPDX-License-Identifier: MIT pragma solidity >=0.7.0; import "../model/ILazyInitCapableElement.sol"; import { ReflectionUtilities } from "../../lib/GeneralUtilities.sol"; abstract contract LazyInitCapableElement is ILazyInitCapableElement { using ReflectionUtilities for address; address public override initializer; address public override host; constructor(bytes memory lazyInitData) { if(lazyInitData.length > 0) { _privateLazyInit(lazyInitData); } } function lazyInit(bytes calldata lazyInitData) override external returns (bytes memory lazyInitResponse) { return _privateLazyInit(lazyInitData); } function supportsInterface(bytes4 interfaceId) override external view returns(bool) { return interfaceId == type(IERC165).interfaceId || interfaceId == this.supportsInterface.selector || interfaceId == type(ILazyInitCapableElement).interfaceId || interfaceId == this.lazyInit.selector || interfaceId == this.initializer.selector || interfaceId == this.subjectIsAuthorizedFor.selector || interfaceId == this.host.selector || interfaceId == this.setHost.selector || _supportsInterface(interfaceId); } function setHost(address newValue) external override authorizedOnly returns(address oldValue) { oldValue = host; host = newValue; emit Host(oldValue, newValue); } function subjectIsAuthorizedFor(address subject, address location, bytes4 selector, bytes calldata payload, uint256 value) public override virtual view returns(bool) { (bool chidlElementValidationIsConsistent, bool chidlElementValidationResult) = _subjectIsAuthorizedFor(subject, location, selector, payload, value); if(chidlElementValidationIsConsistent) { return chidlElementValidationResult; } if(subject == host) { return true; } if(!host.isContract()) { return false; } (bool result, bytes memory resultData) = host.staticcall(abi.encodeWithSelector(ILazyInitCapableElement(host).subjectIsAuthorizedFor.selector, subject, location, selector, payload, value)); return result && abi.decode(resultData, (bool)); } function _privateLazyInit(bytes memory lazyInitData) private returns (bytes memory lazyInitResponse) { require(initializer == address(0), "init"); initializer = msg.sender; (host, lazyInitResponse) = abi.decode(lazyInitData, (address, bytes)); emit Host(address(0), host); lazyInitResponse = _lazyInit(lazyInitResponse); } function _lazyInit(bytes memory) internal virtual returns (bytes memory) { return ""; } function _supportsInterface(bytes4 selector) internal virtual view returns (bool); function _subjectIsAuthorizedFor(address, address, bytes4, bytes calldata, uint256) internal virtual view returns(bool, bool) { } modifier authorizedOnly { require(_authorizedOnly(), "unauthorized"); _; } function _authorizedOnly() internal returns(bool) { return subjectIsAuthorizedFor(msg.sender, address(this), msg.sig, msg.data, msg.value); } }//SPDX-License-Identifier: MIT pragma solidity >=0.7.0; interface IDynamicUriResolver { function resolve(address subject, string calldata plainUri, bytes calldata inputData, address caller) external view returns(string memory); }//SPDX-License-Identifier: MIT pragma solidity >=0.7.0; struct PrestoOperation { address inputTokenAddress; uint256 inputTokenAmount; address ammPlugin; address[] liquidityPoolAddresses; address[] swapPath; bool enterInETH; bool exitInETH; uint256[] tokenMins; address[] receivers; uint256[] receiversPercentages; }
File 7 of 7: MultiOperatorHost
// File: @openzeppelin\contracts\utils\introspection\IERC165.sol // SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC165 standard, as defined in the * https://eips.ethereum.org/EIPS/eip-165[EIP]. * * Implementers can declare support of contract interfaces, which can then be * queried by others ({ERC165Checker}). * * For an implementation, see {ERC165}. */ interface IERC165 { /** * @dev Returns true if this contract implements the interface defined by * `interfaceId`. See the corresponding * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] * to learn more about how these ids are created. * * This function call must use less than 30 000 gas. */ function supportsInterface(bytes4 interfaceId) external view returns (bool); } // File: @openzeppelin\contracts\token\ERC1155\IERC1155.sol // SPDX_License_Identifier: MIT // OpenZeppelin Contracts v4.4.1 (token/ERC1155/IERC1155.sol) pragma solidity ^0.8.0; /** * @dev Required interface of an ERC1155 compliant contract, as defined in the * https://eips.ethereum.org/EIPS/eip-1155[EIP]. * * _Available since v3.1._ */ interface IERC1155 is IERC165 { /** * @dev Emitted when `value` tokens of token type `id` are transferred from `from` to `to` by `operator`. */ event TransferSingle(address indexed operator, address indexed from, address indexed to, uint256 id, uint256 value); /** * @dev Equivalent to multiple {TransferSingle} events, where `operator`, `from` and `to` are the same for all * transfers. */ event TransferBatch( address indexed operator, address indexed from, address indexed to, uint256[] ids, uint256[] values ); /** * @dev Emitted when `account` grants or revokes permission to `operator` to transfer their tokens, according to * `approved`. */ event ApprovalForAll(address indexed account, address indexed operator, bool approved); /** * @dev Emitted when the URI for token type `id` changes to `value`, if it is a non-programmatic URI. * * If an {URI} event was emitted for `id`, the standard * https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[guarantees] that `value` will equal the value * returned by {IERC1155MetadataURI-uri}. */ event URI(string value, uint256 indexed id); /** * @dev Returns the amount of tokens of token type `id` owned by `account`. * * Requirements: * * - `account` cannot be the zero address. */ function balanceOf(address account, uint256 id) external view returns (uint256); /** * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {balanceOf}. * * Requirements: * * - `accounts` and `ids` must have the same length. */ function balanceOfBatch(address[] calldata accounts, uint256[] calldata ids) external view returns (uint256[] memory); /** * @dev Grants or revokes permission to `operator` to transfer the caller's tokens, according to `approved`, * * Emits an {ApprovalForAll} event. * * Requirements: * * - `operator` cannot be the caller. */ function setApprovalForAll(address operator, bool approved) external; /** * @dev Returns true if `operator` is approved to transfer ``account``'s tokens. * * See {setApprovalForAll}. */ function isApprovedForAll(address account, address operator) external view returns (bool); /** * @dev Transfers `amount` tokens of token type `id` from `from` to `to`. * * Emits a {TransferSingle} event. * * Requirements: * * - `to` cannot be the zero address. * - If the caller is not `from`, it must be have been approved to spend ``from``'s tokens via {setApprovalForAll}. * - `from` must have a balance of tokens of type `id` of at least `amount`. * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the * acceptance magic value. */ function safeTransferFrom( address from, address to, uint256 id, uint256 amount, bytes calldata data ) external; /** * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {safeTransferFrom}. * * Emits a {TransferBatch} event. * * Requirements: * * - `ids` and `amounts` must have the same length. * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the * acceptance magic value. */ function safeBatchTransferFrom( address from, address to, uint256[] calldata ids, uint256[] calldata amounts, bytes calldata data ) external; } // File: contracts\model\IERC1155Views.sol // SPDX_License_Identifier: MIT pragma solidity >=0.7.0; /** * @title IERC1155Views - An optional utility interface to improve the ERC-1155 Standard. * @dev This interface introduces some additional capabilities for ERC-1155 Tokens. */ interface IERC1155Views { /** * @dev Returns the total supply of the given token id * @param itemId the id of the token whose availability you want to know */ function totalSupply(uint256 itemId) external view returns (uint256); /** * @dev Returns the name of the given token id * @param itemId the id of the token whose name you want to know */ function name(uint256 itemId) external view returns (string memory); /** * @dev Returns the symbol of the given token id * @param itemId the id of the token whose symbol you want to know */ function symbol(uint256 itemId) external view returns (string memory); /** * @dev Returns the decimals of the given token id * @param itemId the id of the token whose decimals you want to know */ function decimals(uint256 itemId) external view returns (uint256); /** * @dev Returns the uri of the given token id * @param itemId the id of the token whose uri you want to know */ function uri(uint256 itemId) external view returns (string memory); } // File: contracts\model\Item.sol //SPDX_License_Identifier: MIT pragma solidity >=0.7.0; pragma abicoder v2; struct Header { address host; string name; string symbol; string uri; } struct CreateItem { Header header; bytes32 collectionId; uint256 id; address[] accounts; uint256[] amounts; } interface Item is IERC1155, IERC1155Views { event CollectionItem(bytes32 indexed fromCollectionId, bytes32 indexed toCollectionId, uint256 indexed itemId); function name() external view returns(string memory); function symbol() external view returns(string memory); function decimals() external view returns(uint256); function burn(address account, uint256 itemId, uint256 amount) external; function burnBatch(address account, uint256[] calldata itemIds, uint256[] calldata amounts) external; function burn(address account, uint256 itemId, uint256 amount, bytes calldata data) external; function burnBatch(address account, uint256[] calldata itemIds, uint256[] calldata amounts, bytes calldata data) external; function mintItems(CreateItem[] calldata items) external returns(uint256[] memory itemIds); function setItemsCollection(uint256[] calldata itemIds, bytes32[] calldata collectionIds) external returns(bytes32[] memory oldCollectionIds); function setItemsMetadata(uint256[] calldata itemIds, Header[] calldata newValues) external returns(Header[] memory oldValues); function interoperableOf(uint256 itemId) external view returns(address); } // File: @ethereansos\swissknife\contracts\generic\model\ILazyInitCapableElement.sol // SPDX_License_Identifier: MIT pragma solidity >=0.7.0; interface ILazyInitCapableElement is IERC165 { function lazyInit(bytes calldata lazyInitData) external returns(bytes memory initResponse); function initializer() external view returns(address); event Host(address indexed from, address indexed to); function host() external view returns(address); function setHost(address newValue) external returns(address oldValue); function subjectIsAuthorizedFor(address subject, address location, bytes4 selector, bytes calldata payload, uint256 value) external view returns(bool); } // File: contracts\projection\IItemProjection.sol //SPDX_License_Identifier: MIT pragma solidity >=0.7.0; //pragma abicoder v2; interface IItemProjection is Item, ILazyInitCapableElement { function mainInterface() external view returns(address); function collectionId() external view returns(bytes32); function uri() external view returns(string memory); function plainUri() external view returns(string memory); function itemPlainUri(uint256 itemId) external view returns(string memory); function setHeader(Header calldata value) external returns(Header memory oldValue); function toInteroperableInterfaceAmount(uint256 amount, uint256 itemId, address account) external view returns(uint256); function toMainInterfaceAmount(uint256 amount, uint256 itemId) external view returns(uint256); } // File: contracts\projection\multiOperatorHost\model\IMultiOperatorHost.sol //SPDX_License_Identifier: MIT pragma solidity >=0.7.0; //pragma abicoder v2; interface IMultiOperatorHost is IItemProjection { event Operator(uint256 indexed op, address indexed from, address indexed to); function operator(uint256 op) external view returns (address); function setOperator(uint256 op, address newValue) external returns(address oldValue); } // File: contracts\model\IItemMainInterface.sol //SPDX_License_Identifier: MIT pragma solidity >=0.7.0; struct ItemData { bytes32 collectionId; Header header; bytes32 domainSeparator; uint256 totalSupply; mapping(address => uint256) balanceOf; mapping(address => mapping(address => uint256)) allowance; mapping(address => uint256) nonces; } interface IItemMainInterface is Item { event Collection(address indexed from, address indexed to, bytes32 indexed collectionId); function interoperableInterfaceModel() external view returns(address); function uri() external view returns(string memory); function plainUri() external view returns(string memory); function dynamicUriResolver() external view returns(address); function hostInitializer() external view returns(address); function collection(bytes32 collectionId) external view returns(address host, string memory name, string memory symbol, string memory uri); function collectionUri(bytes32 collectionId) external view returns(string memory); function createCollection(Header calldata _collection, CreateItem[] calldata items) external returns(bytes32 collectionId, uint256[] memory itemIds); function setCollectionsMetadata(bytes32[] calldata collectionIds, Header[] calldata values) external returns(Header[] memory oldValues); function setApprovalForAllByCollectionHost(bytes32 collectionId, address account, address operator, bool approved) external; function item(uint256 itemId) external view returns(bytes32 collectionId, Header memory header, bytes32 domainSeparator, uint256 totalSupply); function mintTransferOrBurn(bool isMulti, bytes calldata data) external; function allowance(address account, address spender, uint256 itemId) external view returns(uint256); function approve(address account, address spender, uint256 amount, uint256 itemId) external; function TYPEHASH_PERMIT() external view returns (bytes32); function EIP712_PERMIT_DOMAINSEPARATOR_NAME_AND_VERSION() external view returns(string memory domainSeparatorName, string memory domainSeparatorVersion); function permit(uint256 itemId, address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s) external; function nonces(address owner, uint256 itemId) external view returns(uint256); } // File: @openzeppelin\contracts\token\ERC1155\IERC1155Receiver.sol // SPDX_License_Identifier: MIT // OpenZeppelin Contracts (last updated v4.5.0) (token/ERC1155/IERC1155Receiver.sol) pragma solidity ^0.8.0; /** * @dev _Available since v3.1._ */ interface IERC1155Receiver is IERC165 { /** * @dev Handles the receipt of a single ERC1155 token type. This function is * called at the end of a `safeTransferFrom` after the balance has been updated. * * NOTE: To accept the transfer, this must return * `bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)"))` * (i.e. 0xf23a6e61, or its own function selector). * * @param operator The address which initiated the transfer (i.e. msg.sender) * @param from The address which previously owned the token * @param id The ID of the token being transferred * @param value The amount of tokens being transferred * @param data Additional data with no specified format * @return `bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)"))` if transfer is allowed */ function onERC1155Received( address operator, address from, uint256 id, uint256 value, bytes calldata data ) external returns (bytes4); /** * @dev Handles the receipt of a multiple ERC1155 token types. This function * is called at the end of a `safeBatchTransferFrom` after the balances have * been updated. * * NOTE: To accept the transfer(s), this must return * `bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)"))` * (i.e. 0xbc197c81, or its own function selector). * * @param operator The address which initiated the batch transfer (i.e. msg.sender) * @param from The address which previously owned the token * @param ids An array containing ids of each token being transferred (order and length must match values array) * @param values An array containing amounts of each token being transferred (order and length must match ids array) * @param data Additional data with no specified format * @return `bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)"))` if transfer is allowed */ function onERC1155BatchReceived( address operator, address from, uint256[] calldata ids, uint256[] calldata values, bytes calldata data ) external returns (bytes4); } // File: @openzeppelin\contracts\token\ERC20\IERC20.sol // SPDX_License_Identifier: MIT // OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/IERC20.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20 { /** * @dev Returns the amount of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the amount of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves `amount` tokens from the caller's account to `to`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address to, uint256 amount) external returns (bool); /** * @dev Returns the remaining number of tokens that `spender` will be * allowed to spend on behalf of `owner` through {transferFrom}. This is * zero by default. * * This value changes when {approve} or {transferFrom} are called. */ function allowance(address owner, address spender) external view returns (uint256); /** * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. * * Returns a boolean value indicating whether the operation succeeded. * * IMPORTANT: Beware that changing an allowance with this method brings the risk * that someone may use both the old and the new allowance by unfortunate * transaction ordering. One possible solution to mitigate this race * condition is to first reduce the spender's allowance to 0 and set the * desired value afterwards: * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 * * Emits an {Approval} event. */ function approve(address spender, uint256 amount) external returns (bool); /** * @dev Moves `amount` tokens from `from` to `to` using the * allowance mechanism. `amount` is then deducted from the caller's * allowance. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transferFrom( address from, address to, uint256 amount ) external returns (bool); /** * @dev Emitted when `value` tokens are moved from one account (`from`) to * another (`to`). * * Note that `value` may be zero. */ event Transfer(address indexed from, address indexed to, uint256 value); /** * @dev Emitted when the allowance of a `spender` for an `owner` is set by * a call to {approve}. `value` is the new allowance. */ event Approval(address indexed owner, address indexed spender, uint256 value); } // File: @ethereansos\swissknife\contracts\lib\GeneralUtilities.sol // SPDX_License_Identifier: MIT pragma solidity >=0.7.0; library BehaviorUtilities { function randomKey(uint256 i) internal view returns (bytes32) { return keccak256(abi.encode(i, block.timestamp, block.number, tx.origin, tx.gasprice, block.coinbase, block.difficulty, msg.sender, blockhash(block.number - 5))); } function calculateProjectedArraySizeAndLoopUpperBound(uint256 arraySize, uint256 start, uint256 offset) internal pure returns(uint256 projectedArraySize, uint256 projectedArrayLoopUpperBound) { if(arraySize != 0 && start < arraySize && offset != 0) { uint256 length = start + offset; if(start < (length = length > arraySize ? arraySize : length)) { projectedArraySize = (projectedArrayLoopUpperBound = length) - start; } } } } library ReflectionUtilities { function read(address subject, bytes memory inputData) internal view returns(bytes memory returnData) { bool result; (result, returnData) = subject.staticcall(inputData); if(!result) { assembly { revert(add(returnData, 0x20), mload(returnData)) } } } function submit(address subject, uint256 value, bytes memory inputData) internal returns(bytes memory returnData) { bool result; (result, returnData) = subject.call{value : value}(inputData); if(!result) { assembly { revert(add(returnData, 0x20), mload(returnData)) } } } function isContract(address subject) internal view returns (bool) { if(subject == address(0)) { return false; } uint256 codeLength; assembly { codeLength := extcodesize(subject) } return codeLength > 0; } function clone(address originalContract) internal returns(address copyContract) { assembly { mstore( 0, or( 0x5880730000000000000000000000000000000000000000803b80938091923cF3, mul(originalContract, 0x1000000000000000000) ) ) copyContract := create(0, 0, 32) switch extcodesize(copyContract) case 0 { invalid() } } } } library BytesUtilities { bytes private constant ALPHABET = "0123456789abcdef"; string internal constant BASE64_ENCODER_DATA = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'; function asAddress(bytes memory b) internal pure returns(address) { if(b.length == 0) { return address(0); } if(b.length == 20) { address addr; assembly { addr := mload(add(b, 20)) } return addr; } return abi.decode(b, (address)); } function asAddressArray(bytes memory b) internal pure returns(address[] memory callResult) { if(b.length > 0) { return abi.decode(b, (address[])); } } function asBool(bytes memory bs) internal pure returns(bool) { return asUint256(bs) != 0; } function asBoolArray(bytes memory b) internal pure returns(bool[] memory callResult) { if(b.length > 0) { return abi.decode(b, (bool[])); } } function asBytesArray(bytes memory b) internal pure returns(bytes[] memory callResult) { if(b.length > 0) { return abi.decode(b, (bytes[])); } } function asString(bytes memory b) internal pure returns(string memory callResult) { if(b.length > 0) { return abi.decode(b, (string)); } } function asStringArray(bytes memory b) internal pure returns(string[] memory callResult) { if(b.length > 0) { return abi.decode(b, (string[])); } } function asUint256(bytes memory bs) internal pure returns(uint256 x) { if (bs.length >= 32) { assembly { x := mload(add(bs, add(0x20, 0))) } } } function asUint256Array(bytes memory b) internal pure returns(uint256[] memory callResult) { if(b.length > 0) { return abi.decode(b, (uint256[])); } } function toString(bytes memory data) internal pure returns(string memory) { bytes memory str = new bytes(2 + data.length * 2); str[0] = "0"; str[1] = "x"; for (uint256 i = 0; i < data.length; i++) { str[2+i*2] = ALPHABET[uint256(uint8(data[i] >> 4))]; str[3+i*2] = ALPHABET[uint256(uint8(data[i] & 0x0f))]; } return string(str); } function asSingletonArray(bytes memory a) internal pure returns(bytes[] memory array) { array = new bytes[](1); array[0] = a; } function toBase64(bytes memory data) internal pure returns (string memory) { if (data.length == 0) return ''; string memory table = BASE64_ENCODER_DATA; uint256 encodedLen = 4 * ((data.length + 2) / 3); string memory result = new string(encodedLen + 32); assembly { mstore(result, encodedLen) let tablePtr := add(table, 1) let dataPtr := data let endPtr := add(dataPtr, mload(data)) let resultPtr := add(result, 32) for {} lt(dataPtr, endPtr) {} { dataPtr := add(dataPtr, 3) let input := mload(dataPtr) mstore8(resultPtr, mload(add(tablePtr, and(shr(18, input), 0x3F)))) resultPtr := add(resultPtr, 1) mstore8(resultPtr, mload(add(tablePtr, and(shr(12, input), 0x3F)))) resultPtr := add(resultPtr, 1) mstore8(resultPtr, mload(add(tablePtr, and(shr( 6, input), 0x3F)))) resultPtr := add(resultPtr, 1) mstore8(resultPtr, mload(add(tablePtr, and( input, 0x3F)))) resultPtr := add(resultPtr, 1) } switch mod(mload(data), 3) case 1 { mstore(sub(resultPtr, 2), shl(240, 0x3d3d)) } case 2 { mstore(sub(resultPtr, 1), shl(248, 0x3d)) } } return result; } } library StringUtilities { bytes1 private constant CHAR_0 = bytes1('0'); bytes1 private constant CHAR_A = bytes1('A'); bytes1 private constant CHAR_a = bytes1('a'); bytes1 private constant CHAR_f = bytes1('f'); bytes internal constant BASE64_DECODER_DATA = hex"0000000000000000000000000000000000000000000000000000000000000000" hex"00000000000000000000003e0000003f3435363738393a3b3c3d000000000000" hex"00000102030405060708090a0b0c0d0e0f101112131415161718190000000000" hex"001a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132330000000000"; function isEmpty(string memory test) internal pure returns (bool) { return equals(test, ""); } function equals(string memory a, string memory b) internal pure returns(bool) { return keccak256(abi.encodePacked(a)) == keccak256(abi.encodePacked(b)); } function toLowerCase(string memory str) internal pure returns(string memory) { bytes memory bStr = bytes(str); for (uint256 i = 0; i < bStr.length; i++) { bStr[i] = bStr[i] >= 0x41 && bStr[i] <= 0x5A ? bytes1(uint8(bStr[i]) + 0x20) : bStr[i]; } return string(bStr); } function asBytes(string memory str) internal pure returns(bytes memory toDecode) { bytes memory data = abi.encodePacked(str); if(data.length == 0 || data[0] != "0" || (data[1] != "x" && data[1] != "X")) { return ""; } uint256 start = 2; toDecode = new bytes((data.length - 2) / 2); for(uint256 i = 0; i < toDecode.length; i++) { toDecode[i] = bytes1(_fromHexChar(uint8(data[start++])) + _fromHexChar(uint8(data[start++])) * 16); } } function toBase64(string memory input) internal pure returns(string memory) { return BytesUtilities.toBase64(abi.encodePacked(input)); } function fromBase64(string memory _data) internal pure returns (bytes memory) { bytes memory data = bytes(_data); if (data.length == 0) return new bytes(0); require(data.length % 4 == 0, "invalid base64 decoder input"); bytes memory table = BASE64_DECODER_DATA; uint256 decodedLen = (data.length / 4) * 3; bytes memory result = new bytes(decodedLen + 32); assembly { let lastBytes := mload(add(data, mload(data))) if eq(and(lastBytes, 0xFF), 0x3d) { decodedLen := sub(decodedLen, 1) if eq(and(lastBytes, 0xFFFF), 0x3d3d) { decodedLen := sub(decodedLen, 1) } } mstore(result, decodedLen) let tablePtr := add(table, 1) let dataPtr := data let endPtr := add(dataPtr, mload(data)) let resultPtr := add(result, 32) for {} lt(dataPtr, endPtr) {} { dataPtr := add(dataPtr, 4) let input := mload(dataPtr) let output := add( add( shl(18, and(mload(add(tablePtr, and(shr(24, input), 0xFF))), 0xFF)), shl(12, and(mload(add(tablePtr, and(shr(16, input), 0xFF))), 0xFF))), add( shl( 6, and(mload(add(tablePtr, and(shr( 8, input), 0xFF))), 0xFF)), and(mload(add(tablePtr, and( input , 0xFF))), 0xFF) ) ) mstore(resultPtr, shl(232, output)) resultPtr := add(resultPtr, 3) } } return result; } function _fromHexChar(uint8 c) private pure returns (uint8) { bytes1 charc = bytes1(c); return charc < CHAR_0 || charc > CHAR_f ? 0 : (charc < CHAR_A ? 0 : 10) + c - uint8(charc < CHAR_A ? CHAR_0 : charc < CHAR_a ? CHAR_A : CHAR_a); } } library Uint256Utilities { function asSingletonArray(uint256 n) internal pure returns(uint256[] memory array) { array = new uint256[](1); array[0] = n; } function toHex(uint256 _i) internal pure returns (string memory) { return BytesUtilities.toString(abi.encodePacked(_i)); } function toString(uint256 _i) internal pure returns (string memory _uintAsString) { if (_i == 0) { return "0"; } uint256 j = _i; uint256 len; while (j != 0) { len++; j /= 10; } bytes memory bstr = new bytes(len); uint256 k = len; while (_i != 0) { k = k-1; uint8 temp = (48 + uint8(_i - _i / 10 * 10)); bytes1 b1 = bytes1(temp); bstr[k] = b1; _i /= 10; } return string(bstr); } function sum(uint256[] memory arr) internal pure returns (uint256 result) { for(uint256 i = 0; i < arr.length; i++) { result += arr[i]; } } } library AddressUtilities { function asSingletonArray(address a) internal pure returns(address[] memory array) { array = new address[](1); array[0] = a; } function toString(address _addr) internal pure returns (string memory) { return _addr == address(0) ? "0x0000000000000000000000000000000000000000" : BytesUtilities.toString(abi.encodePacked(_addr)); } } library Bytes32Utilities { function asSingletonArray(bytes32 a) internal pure returns(bytes32[] memory array) { array = new bytes32[](1); array[0] = a; } function toString(bytes32 bt) internal pure returns (string memory) { return bt == bytes32(0) ? "0x0000000000000000000000000000000000000000000000000000000000000000" : BytesUtilities.toString(abi.encodePacked(bt)); } } library TransferUtilities { using ReflectionUtilities for address; function balanceOf(address erc20TokenAddress, address account) internal view returns(uint256) { if(erc20TokenAddress == address(0)) { return account.balance; } return abi.decode(erc20TokenAddress.read(abi.encodeWithSelector(IERC20(erc20TokenAddress).balanceOf.selector, account)), (uint256)); } function allowance(address erc20TokenAddress, address account, address spender) internal view returns(uint256) { if(erc20TokenAddress == address(0)) { return 0; } return abi.decode(erc20TokenAddress.read(abi.encodeWithSelector(IERC20(erc20TokenAddress).allowance.selector, account, spender)), (uint256)); } function safeApprove(address erc20TokenAddress, address spender, uint256 value) internal { bytes memory returnData = erc20TokenAddress.submit(0, abi.encodeWithSelector(IERC20(erc20TokenAddress).approve.selector, spender, value)); require(returnData.length == 0 || abi.decode(returnData, (bool)), 'APPROVE_FAILED'); } function safeTransfer(address erc20TokenAddress, address to, uint256 value) internal { if(value == 0) { return; } if(erc20TokenAddress == address(0)) { to.submit(value, ""); return; } bytes memory returnData = erc20TokenAddress.submit(0, abi.encodeWithSelector(IERC20(erc20TokenAddress).transfer.selector, to, value)); require(returnData.length == 0 || abi.decode(returnData, (bool)), 'TRANSFER_FAILED'); } function safeTransferFrom(address erc20TokenAddress, address from, address to, uint256 value) internal { if(value == 0) { return; } if(erc20TokenAddress == address(0)) { to.submit(value, ""); return; } bytes memory returnData = erc20TokenAddress.submit(0, abi.encodeWithSelector(IERC20(erc20TokenAddress).transferFrom.selector, from, to, value)); require(returnData.length == 0 || abi.decode(returnData, (bool)), 'TRANSFERFROM_FAILED'); } } // File: @ethereansos\swissknife\contracts\generic\impl\LazyInitCapableElement.sol // SPDX_License_Identifier: MIT pragma solidity >=0.7.0; abstract contract LazyInitCapableElement is ILazyInitCapableElement { using ReflectionUtilities for address; address public override initializer; address public override host; constructor(bytes memory lazyInitData) { if(lazyInitData.length > 0) { _privateLazyInit(lazyInitData); } } function lazyInit(bytes calldata lazyInitData) override external returns (bytes memory lazyInitResponse) { return _privateLazyInit(lazyInitData); } function supportsInterface(bytes4 interfaceId) override external view returns(bool) { return interfaceId == type(IERC165).interfaceId || interfaceId == this.supportsInterface.selector || interfaceId == type(ILazyInitCapableElement).interfaceId || interfaceId == this.lazyInit.selector || interfaceId == this.initializer.selector || interfaceId == this.subjectIsAuthorizedFor.selector || interfaceId == this.host.selector || interfaceId == this.setHost.selector || _supportsInterface(interfaceId); } function setHost(address newValue) external override authorizedOnly returns(address oldValue) { oldValue = host; host = newValue; emit Host(oldValue, newValue); } function subjectIsAuthorizedFor(address subject, address location, bytes4 selector, bytes calldata payload, uint256 value) public override virtual view returns(bool) { (bool chidlElementValidationIsConsistent, bool chidlElementValidationResult) = _subjectIsAuthorizedFor(subject, location, selector, payload, value); if(chidlElementValidationIsConsistent) { return chidlElementValidationResult; } if(subject == host) { return true; } if(!host.isContract()) { return false; } (bool result, bytes memory resultData) = host.staticcall(abi.encodeWithSelector(ILazyInitCapableElement(host).subjectIsAuthorizedFor.selector, subject, location, selector, payload, value)); return result && abi.decode(resultData, (bool)); } function _privateLazyInit(bytes memory lazyInitData) private returns (bytes memory lazyInitResponse) { require(initializer == address(0), "init"); initializer = msg.sender; (host, lazyInitResponse) = abi.decode(lazyInitData, (address, bytes)); emit Host(address(0), host); lazyInitResponse = _lazyInit(lazyInitResponse); } function _lazyInit(bytes memory) internal virtual returns (bytes memory) { return ""; } function _supportsInterface(bytes4 selector) internal virtual view returns (bool); function _subjectIsAuthorizedFor(address, address, bytes4, bytes calldata, uint256) internal virtual view returns(bool, bool) { } modifier authorizedOnly { require(_authorizedOnly(), "unauthorized"); _; } function _authorizedOnly() internal returns(bool) { return subjectIsAuthorizedFor(msg.sender, address(this), msg.sig, msg.data, msg.value); } } // File: contracts\util\ERC1155CommonLibrary.sol //SPDX_License_Identifier: MIT pragma solidity >=0.7.0; library ERC1155CommonLibrary { using ReflectionUtilities for address; function doSafeTransferAcceptanceCheck( address operator, address from, address to, uint256 id, uint256 amount, bytes calldata data ) internal { if (to.isContract()) { try IERC1155Receiver(to).onERC1155Received( operator, from, id, amount, data ) returns (bytes4 response) { if ( response != IERC1155Receiver(to).onERC1155Received.selector ) { revert("ERC1155: ERC1155Receiver rejected tokens"); } } catch Error(string memory reason) { revert(reason); } catch { revert("ERC1155: transfer to non ERC1155Receiver implementer"); } } } function doSafeBatchTransferAcceptanceCheck( address operator, address from, address to, uint256[] calldata ids, uint256[] calldata amounts, bytes calldata data ) internal { if (to.isContract()) { try IERC1155Receiver(to).onERC1155BatchReceived( operator, from, ids, amounts, data ) returns (bytes4 response) { if ( response != IERC1155Receiver(to).onERC1155BatchReceived.selector ) { revert("ERC1155: ERC1155Receiver rejected tokens"); } } catch Error(string memory reason) { revert(reason); } catch { revert("ERC1155: transfer to non ERC1155Receiver implementer"); } } } } // File: contracts\projection\ItemProjection.sol //SPDX_License_Identifier: MIT pragma solidity >=0.7.0; //pragma abicoder v2; abstract contract ItemProjection is IItemProjection, LazyInitCapableElement { using AddressUtilities for address; using BytesUtilities for bytes; address public override mainInterface; bytes32 public override collectionId; constructor(bytes memory lazyInitData) LazyInitCapableElement(lazyInitData) { } function _lazyInit(bytes memory lazyInitParams) override virtual internal returns(bytes memory lazyInitResponse) { (mainInterface, lazyInitResponse) = abi.decode(lazyInitParams, (address, bytes)); Header memory header; CreateItem[] memory items; (collectionId, header, items, lazyInitResponse) = abi.decode(lazyInitResponse, (bytes32, Header, CreateItem[], bytes)); if(collectionId == bytes32(0)) { header.host = address(this); (collectionId,) = IItemMainInterface(mainInterface).createCollection(header, items); } else if(items.length > 0) { IItemMainInterface(mainInterface).mintItems(items); } lazyInitResponse = _projectionLazyInit(lazyInitResponse); } function _supportsInterface(bytes4 interfaceId) override internal pure returns (bool) { return interfaceId == type(IItemProjection).interfaceId || interfaceId == 0xeac989f8 ||//uri() interfaceId == this.mainInterface.selector || interfaceId == this.collectionId.selector || interfaceId == this.plainUri.selector || interfaceId == this.itemPlainUri.selector || interfaceId == this.setHeader.selector || interfaceId == this.toInteroperableInterfaceAmount.selector || interfaceId == this.toMainInterfaceAmount.selector || interfaceId == this.balanceOf.selector || interfaceId == this.balanceOfBatch.selector || interfaceId == this.setApprovalForAll.selector || interfaceId == this.isApprovedForAll.selector || interfaceId == this.safeTransferFrom.selector || interfaceId == this.safeBatchTransferFrom.selector || interfaceId == 0xd9b67a26 ||//OpenSea Standard interfaceId == type(IERC1155Views).interfaceId || interfaceId == this.totalSupply.selector || interfaceId == 0x00ad800c ||//name(uint256) interfaceId == 0x4e41a1fb ||//symbol(uint256) interfaceId == 0x3f47e662 ||//decimals(uint256) interfaceId == 0x313ce567 ||//decimals() interfaceId == 0x0e89341c ||//uri(uint256) interfaceId == type(Item).interfaceId || interfaceId == 0x06fdde03 ||//name() interfaceId == 0x95d89b41 ||//symbol() interfaceId == 0xf5298aca ||//burn(address,uint256,uint256) interfaceId == 0x6b20c454 ||//burnBatch(address,uint256[],uint256[]) interfaceId == 0x8a94b05f ||//burn(address,uint256,uint256,bytes) interfaceId == 0x5473422e ||//burnBatch(address,uint256[],uint256[],bytes) interfaceId == this.mintItems.selector || interfaceId == this.setItemsCollection.selector || interfaceId == this.setItemsMetadata.selector || interfaceId == this.interoperableOf.selector; } function _projectionLazyInit(bytes memory) internal virtual returns (bytes memory) { return ""; } function setHeader(Header calldata value) authorizedOnly override external virtual returns(Header memory oldValue) { Header[] memory values = new Header[](1); values[0] = value; bytes32[] memory collectionIds = new bytes32[](1); collectionIds[0] = collectionId; return IItemMainInterface(mainInterface).setCollectionsMetadata(collectionIds, values)[0]; } function setItemsMetadata(uint256[] calldata itemIds, Header[] calldata values) authorizedOnly override external virtual returns(Header[] memory oldValues) { return IItemMainInterface(mainInterface).setItemsMetadata(itemIds, values); } function mintItems(CreateItem[] memory items) authorizedOnly virtual override public returns(uint256[] memory itemIds) { uint256 multiplier = 10 ** (18 - decimals(0)); for(uint256 i = 0; i < items.length; i++) { items[i].collectionId = collectionId; uint256[] memory amounts = items[i].amounts; for(uint256 z = 0; z < amounts.length; z++) { amounts[z] = amounts[z] * multiplier; } items[i].amounts = amounts; } return IItemMainInterface(mainInterface).mintItems(items); } function setItemsCollection(uint256[] calldata itemIds, bytes32[] calldata collectionIds) authorizedOnly virtual override external returns(bytes32[] memory oldCollectionIds) { return IItemMainInterface(mainInterface).setItemsCollection(itemIds, collectionIds); } function name() override external view returns(string memory value) { (,value,,) = IItemMainInterface(mainInterface).collection(collectionId); } function symbol() override external view returns(string memory value) { (,,value,) = IItemMainInterface(mainInterface).collection(collectionId); } function plainUri() override public view returns(string memory value) { (,,,value) = IItemMainInterface(mainInterface).collection(collectionId); } function uri() override public view returns(string memory) { return IItemMainInterface(mainInterface).collectionUri(collectionId); } function interoperableOf(uint256 itemId) override public pure returns(address) { return address(uint160(itemId)); } function name(uint256 itemId) override external view returns(string memory) { (,Header memory header,,) = IItemMainInterface(mainInterface).item(itemId); return header.name; } function symbol(uint256 itemId) override external view returns(string memory) { (,Header memory header,,) = IItemMainInterface(mainInterface).item(itemId); return header.symbol; } function decimals(uint256) override public virtual view returns(uint256) { return 18; } function decimals() external override view returns(uint256) { return 18; } function toMainInterfaceAmount(uint256 interoperableInterfaceAmount, uint256 itemId) override public view returns(uint256) { if(interoperableInterfaceAmount == 0) { return 0; } uint256 itemDecimals = decimals(itemId); if(itemDecimals == 18) { return interoperableInterfaceAmount; } uint256 interoperableTotalSupply = IERC20(interoperableOf(itemId)).totalSupply(); uint256 interoperableUnity = 1e18; uint256 interoperableHalfUnity = (interoperableUnity / 51) * 100; uint256 mainInterfaceUnity = 10 ** itemDecimals; if(interoperableTotalSupply <= interoperableUnity && interoperableInterfaceAmount <= interoperableUnity) { return interoperableInterfaceAmount < interoperableHalfUnity ? 0 : mainInterfaceUnity; } return (interoperableInterfaceAmount * mainInterfaceUnity) / interoperableUnity; } function toInteroperableInterfaceAmount(uint256 mainInterfaceAmount, uint256 itemId, address account) override public view returns(uint256) { if(mainInterfaceAmount == 0) { return 0; } if(decimals(itemId) == 18) { return mainInterfaceAmount; } uint256 interoperableInterfaceAmount = mainInterfaceAmount * 10 ** (18 - decimals(itemId)); if(account == address(0)) { return interoperableInterfaceAmount; } uint256 interoperableBalance = IItemMainInterface(mainInterface).balanceOf(account, itemId); if(interoperableBalance == 0) { return interoperableInterfaceAmount; } uint256 interoperableTotalSupply = IERC20(interoperableOf(itemId)).totalSupply(); uint256 interoperableUnity = 1e18; uint256 interoperableHalfUnity = (interoperableUnity / 51) * 100; if(interoperableTotalSupply <= interoperableUnity && interoperableInterfaceAmount == interoperableUnity && interoperableBalance >= interoperableHalfUnity) { return interoperableBalance < interoperableInterfaceAmount ? interoperableBalance : interoperableInterfaceAmount; } return interoperableInterfaceAmount; } function uri(uint256 itemId) override external view returns(string memory) { return IItemMainInterface(mainInterface).uri(itemId); } function itemPlainUri(uint256 itemId) override external view returns(string memory) { (, Header memory header,,) = IItemMainInterface(mainInterface).item(itemId); return header.uri; } function totalSupply(uint256 itemId) override external view returns (uint256) { return IItemMainInterface(mainInterface).totalSupply(itemId); } function balanceOf(address account, uint256 itemId) override external view returns (uint256) { return toMainInterfaceAmount(IItemMainInterface(mainInterface).balanceOf(account, itemId), itemId); } function balanceOfBatch(address[] calldata accounts, uint256[] calldata itemIds) override external view returns (uint256[] memory balances) { balances = IItemMainInterface(mainInterface).balanceOfBatch(accounts, itemIds); for(uint256 i = 0; i < itemIds.length; i++) { balances[i] = toMainInterfaceAmount(balances[i], itemIds[i]); } } function isApprovedForAll(address account, address operator) override external view returns (bool) { return IItemMainInterface(mainInterface).isApprovedForAll(account, operator); } function setApprovalForAll(address operator, bool approved) override external virtual { IItemMainInterface(mainInterface).setApprovalForAllByCollectionHost(collectionId, msg.sender, operator, approved); } function safeTransferFrom(address from, address to, uint256 itemId, uint256 amount, bytes calldata data) override external virtual { require(from != address(0), "required from"); require(to != address(0), "required to"); IItemMainInterface(mainInterface).mintTransferOrBurn(false, abi.encode(msg.sender, from, to, itemId, toInteroperableInterfaceAmount(amount, itemId, from))); ERC1155CommonLibrary.doSafeTransferAcceptanceCheck(msg.sender, from, to, itemId, amount, data); emit TransferSingle(msg.sender, from, to, itemId, amount); } function safeBatchTransferFrom(address from, address to, uint256[] calldata itemIds, uint256[] calldata amounts, bytes calldata data) override external virtual { require(from != address(0), "required from"); require(to != address(0), "required to"); uint256[] memory interoperableInterfaceAmounts = new uint256[](amounts.length); for(uint256 i = 0 ; i < interoperableInterfaceAmounts.length; i++) { interoperableInterfaceAmounts[i] = toInteroperableInterfaceAmount(amounts[i], itemIds[i], from); } IItemMainInterface(mainInterface).mintTransferOrBurn(true, abi.encode(true, abi.encode(abi.encode(msg.sender, from, to, itemIds, interoperableInterfaceAmounts).asSingletonArray()))); ERC1155CommonLibrary.doSafeBatchTransferAcceptanceCheck(msg.sender, from, to, itemIds, amounts, data); emit TransferBatch(msg.sender, from, to, itemIds, amounts); } function burn(address account, uint256 itemId, uint256 amount) override external { burn(account, itemId, amount, ""); } function burnBatch(address account, uint256[] calldata itemIds, uint256[] calldata amounts) override external { burnBatch(account, itemIds, amounts, ""); } function burn(address account, uint256 itemId, uint256 amount, bytes memory) override virtual public { require(account != address(0), "required account"); IItemMainInterface(mainInterface).mintTransferOrBurn(false, abi.encode(msg.sender, account, address(0), itemId, toInteroperableInterfaceAmount(amount, itemId, account))); emit TransferSingle(msg.sender, account, address(0), itemId, amount); } function burnBatch(address account, uint256[] calldata itemIds, uint256[] calldata amounts, bytes memory) override virtual public { require(account != address(0), "required account"); uint256[] memory interoperableInterfaceAmounts = new uint256[](amounts.length); for(uint256 i = 0 ; i < interoperableInterfaceAmounts.length; i++) { interoperableInterfaceAmounts[i] = toInteroperableInterfaceAmount(amounts[i], itemIds[i], account); } IItemMainInterface(mainInterface).mintTransferOrBurn(true, abi.encode(true, abi.encode(abi.encode(msg.sender, account, address(0), itemIds, interoperableInterfaceAmounts).asSingletonArray()))); emit TransferBatch(msg.sender, account, address(0), itemIds, amounts); } } // File: contracts\projection\multiOperatorHost\impl\MultiOperatorHost.sol //SPDX_License_Identifier: MIT pragma solidity >=0.7.0; //pragma abicoder v2; contract MultiOperatorHost is IMultiOperatorHost, ItemProjection { using BytesUtilities for bytes; mapping(uint256 => address) public override operator; constructor(bytes memory lazyInitData) ItemProjection(lazyInitData) { } function _projectionLazyInit(bytes memory lazyInitData) internal override returns(bytes memory) { require(host == address(0), "No host allowed"); (uint256[] memory ops, address[] memory authorized) = abi.decode(lazyInitData, (uint256[], address[])); for(uint256 i = 0; i < ops.length; i++) { _setOperator(ops[i], authorized[i]); } return ""; } function setOperator(uint256 op, address newValue) external override returns(address oldValue) { require(operator[op] == msg.sender, "Unauthorized"); return _setOperator(op, newValue); } function setApprovalForAll(address, bool) authorizedOnly override(ItemProjection, IERC1155) external { revert(); } function setHeader(Header memory value) authorizedOnly override(IItemProjection, ItemProjection) external returns(Header memory oldValue) { value.host = address(this); Header[] memory values = new Header[](1); values[0] = value; bytes32[] memory collectionIds = new bytes32[](1); collectionIds[0] = collectionId; oldValue = IItemMainInterface(mainInterface).setCollectionsMetadata(collectionIds, values)[0]; (address currentHost,,,) = IItemMainInterface(mainInterface).collection(collectionId); require(currentHost == address(this), "Invalid change"); return oldValue; } function safeTransferFrom(address from, address to, uint256 itemId, uint256 amount, bytes calldata data) authorizedOnly override(ItemProjection, IERC1155) external { require(from != address(0), "required from"); require(to != address(0), "required to"); IItemMainInterface(mainInterface).mintTransferOrBurn(false, abi.encode(from, from, to, itemId, toInteroperableInterfaceAmount(amount, itemId, from))); ERC1155CommonLibrary.doSafeTransferAcceptanceCheck(msg.sender, from, to, itemId, amount, data); emit TransferSingle(msg.sender, from, to, itemId, amount); } function safeBatchTransferFrom(address from, address to, uint256[] calldata itemIds, uint256[] calldata amounts, bytes calldata data) authorizedOnly override(ItemProjection, IERC1155) external { require(from != address(0), "required from"); require(to != address(0), "required to"); uint256[] memory interoperableInterfaceAmounts = new uint256[](amounts.length); for(uint256 i = 0 ; i < interoperableInterfaceAmounts.length; i++) { interoperableInterfaceAmounts[i] = toInteroperableInterfaceAmount(amounts[i], itemIds[i], from); } IItemMainInterface(mainInterface).mintTransferOrBurn(true, abi.encode(true, abi.encode(abi.encode(from, from, to, itemIds, interoperableInterfaceAmounts).asSingletonArray()))); ERC1155CommonLibrary.doSafeBatchTransferAcceptanceCheck(msg.sender, from, to, itemIds, amounts, data); emit TransferBatch(msg.sender, from, to, itemIds, amounts); } function burn(address account, uint256 itemId, uint256 amount, bytes memory) authorizedOnly override(ItemProjection, Item) public { require(account != address(0), "required account"); IItemMainInterface(mainInterface).mintTransferOrBurn(false, abi.encode(account, account, address(0), itemId, toInteroperableInterfaceAmount(amount, itemId, account))); emit TransferSingle(msg.sender, account, address(0), itemId, amount); } function burnBatch(address account, uint256[] calldata itemIds, uint256[] calldata amounts, bytes memory) authorizedOnly override(ItemProjection, Item) public { require(account != address(0), "required account"); uint256[] memory interoperableInterfaceAmounts = new uint256[](amounts.length); for(uint256 i = 0 ; i < interoperableInterfaceAmounts.length; i++) { interoperableInterfaceAmounts[i] = toInteroperableInterfaceAmount(amounts[i], itemIds[i], account); } IItemMainInterface(mainInterface).mintTransferOrBurn(true, abi.encode(true, abi.encode(abi.encode(account, account, address(0), itemIds, interoperableInterfaceAmounts).asSingletonArray()))); emit TransferBatch(msg.sender, account, address(0), itemIds, amounts); } function _setOperator(uint256 op, address newValue) private returns(address oldValue) { require(op > 0, "invalid op"); oldValue = operator[op]; operator[op] = newValue; emit Operator(op, oldValue, newValue); } function _subjectIsAuthorizedFor(address subject, address location, bytes4 selector, bytes calldata, uint256) internal virtual override view returns(bool, bool) { //1 = mintItems, 2 = burn, 3 = transfer, 4 = setMetadata, 5 = itemsCollection uint256 op = selector == this.mintItems.selector ? 1 : /*( selector == 0xf5298aca ||//burn(address,uint256,uint256) selector == 0x6b20c454 ||//burnBatch(address,uint256[],uint256[]) selector == 0x8a94b05f ||//burn(address,uint256,uint256,bytes) selector == 0x5473422e //burnBatch(address,uint256[],uint256[],bytes) ) ? 2 : (selector == this.safeTransferFrom.selector || selector == this.safeBatchTransferFrom.selector) ? 3 :*/ (selector == this.setHeader.selector || selector == this.setItemsMetadata.selector) ? 4 : 0; //selector == this.setItemsCollection.selector ? 5 : 0; return(true, op > 0 && location == address(this) && operator[op] == subject); } }