Treasury Manager
Contract name
Github
Deployed contract address
Contract implemented
Initialization data
TreasuryManager
Coming soon
Coming soon
ITreasuryManager, IERC721Receiver, IERC1155Receiver, LazyInitCapableElement
LazyInitCapableElement init data
The Treasury Manager is a passive--i.e, inactive--Component; it is attached to the Organization, but doesn't need to write on other Components or the Organization core. When called by other Components, it performs operations on itself.
It manages the Organization's funds, allowing it to receive, store and send tokens. Only active Components of the Organization can ask the Treasury Manager to transfer funds.
Currently, the following token standards are natively supported:
  • Ethereum
  • Items
  • ERC20
  • ERC721
  • ERC1155
But the Treasury Manager can easily be extended to support other present and future standards.

Modify the Treasury Manager's Operations

If you want to change the Treasury Manager Component, you don't need to replace it; you can just add new functions to it, extend or limit its current ones, or replace them altogether.
For example:
Limit -> the Root Layer does not want to receive any ether, or it just doesn't want to receive any from one or more specified addresses. This can be done by replacing the Treasury manager's ether receive function with a new one.
Extend -> the Root Layer wants to manage more token standards. This can be done by replacing the Treasury Manager's receive and transfer functions with new ones.
Beyond these examples, there are infinite use cases in limiting and extending operations.

Adding, Replacing and Removing Functions

The TreasuryManager contract includes the AdditionalFunctionsServerManager contract, which manages all added functions. It is created and initialized automatically the first time a new function is added to the TreasuryManager through the setAdditionalFunction function.
setAdditionalFunction takes a server contract, which contains one or more functions, and adds one of those functions to the TreasuryManager. During this process, the function is represented by a selector, and replaces any function that is already in the TreasuryManager represented by the same selector.
A selector is the first four bytes of the Keccak-256 (SHA-3) hash of the function's signature. To add multiple functions contained in the same same server, you have to call setAdditionalFunction for each, passing the same server address but the right selector.
setAdditionalFunction can also be used to replace an additional function already in the TreasuryManager with another additional function, via a server, with the same selector.
To simply remove a function, pass its selector with address(0) as the server address.
When a TreasuryManager function is called, a check is done to see if a newer version has been added. If so, the updated version is executed; if not, the original one is.

Managing Different Token Standards

The TreasuryManager can receive, store and send all supported token standards, both those that are supported natively (ETH, Item, ERC20, ERC721 and ERC1155) and any that have been added (which is done via an additional function).
Transferring funds from the TreasuryManager to another contract can be executed via the transfer and batchTransfer functions.
As input, batchTransfer takes an array of TransferEntry structs, each of which is composed as follows:
  • address token
  • uint256[] objectIds
  • uint256[] values
  • address receiver
  • uint256
  • bool safe
  • bool batch
  • bool withData
  • bytes data
For a transfer function, the inputs are the same as the TransferEntry parameters, except for:
  • there is no batch parameter.
  • there is an extra parameter called tokenType.
All transfer and batchTransfer operations use the unique _transfer utility function for all supported standards, native and otherwise.
Only active components of an organization can call transfer and batchTransfer.
Depending on the parameters passed in a TransferEntry struct, a transfer action will be performed for a specific token standard:
  • For an ETH transfer
required parameters using transfer: tokenType==0, token address == address(0).
required parameters using batchTransfer: objectId==0, token address == address(0).
The first value of the values[](at position 0) is taken.
  • For an ERC20 transfer
required parameters using transfer: tokenType==0, token address != address(0) and objectIds[] empty.
required parameters using batchTransfer: objectId==0, token address != address(0)
The first value of the values[](at position 0) is taken.
  • For an ERC721 transfer
required parameters using transfer: tokenType==1, token address != address(0), values[] empty, objectIds[] populated and safe parameter as false.
required parameters using batchTransfer: token address != address(0), values[] empty, objectIds[] populated and safe parameter as false.
The first value of the objectIds [](at position 0) is taken.
  • For an ERC721 safeTransferFrom
required parameters using transfer: tokenType==1, token address != address(0), values[] empty, objectIds[ ] populated and safe parameter as true.
required parameters using batchTransfer: token address != address(0), values[] empty, objectIds[ ] populated and safe parameter as true.
The first value of the objectIds [](at position 0) is taken.
  • For an ERC721 safeTransferFrom with data
required parameters using transfer: tokenType==1, token address != address(0), values[] empty, objectIds[] populated, safe parameter as true and withData parameter as true.
required parameters using batchTransfer: token address != address(0), values[] empty, objectIds[] populated, safe parameter as true and withData parameter as true.
The first value of the objectIds [](at position 0) is taken.
  • For an ERC1155 safeTransferFrom
required parameters using transfer: tokenType>=2, token address != address(0), values[] populated, objectIds[] populated and batch parameter as false.
required parameters using batchTransfer: token address != address(0), values[] populated, objectIds[] populated and batch parameter as false.
  • For an ERC1155 safeBatchTransferFrom
required parameters using transfer: tokenType>=2, token addresses != address(0), values[] populated, objectIds[] populated and batch parameter as true.
required parameters using batchTransfer: token address != address(0), values[] populated, objectIds[] populated and batch parameter as true.
If a new Treasury Manager is linked to the organization using the same key as the current one, the current Treasury Manager is deprecated as an old version. However, it can still be called by the organization's active components if it is still attached to the organization (i.e, still has internal references to the organization) in order to manage any funds left in the (now old) Treasury Manager.