TreasurySplitter Manager

The TreasurySplitter Manager is a component that receives funds from an organization (of either root or governance layer), splits them into percentage amounts, and then distributes those amounts to the organization's Treasury Managers (at either layer).

For example, funds can be received from:

  • Routine Covenant operations; e.g., as earnings from fixed-interval inflation sales of the Organization's governance token(s).

  • Irregular operations; e.g., as fee earnings from use by external parties of the organization's factories or general fee earnings.

And then they can be split and distributed, for example, to the DelegationsManagerTreasury (from where they can then, in turn, be distributed to Delegations); to the InvestmentsManager Treasury (from where they can, in turn, be used to carry out investments); to the Organization Treasury to store funds in order to manage future emergencies or to boost the development of new features and so on.

Treasury Splitter Initialization

The TreasurySplitter Manager is a LazyInitCapableElement, and therefore must be initialized following the pattern explained here, passing these parameters:

function _lazyInit(bytes memory lazyInitData) internal override virtual returns (bytes memory) {
    uint256 firstSplitBlock;
    (firstSplitBlock, splitInterval, _keys, _percentages, _flushKey, flushExecutorRewardPercentage, executorRewardPercentage) = abi.decode(lazyInitData, (uint256, uint256, bytes32[], uint256[], bytes32, uint256, uint256));
    _setKeysAndPercentages(_keys, _percentages);
    lastSplitBlock = firstSplitBlock < splitInterval ? firstSplitBlock : (firstSplitBlock - splitInterval);
    return "";
}
  • uint256 firstSplitBlock -> this is the first block at which the splitTreasury function can be called.

  • uint256 splitInterval -> this is how many blocks must pass between each execution of splitTreasury.

  • bytes32[] _keys -> this parameter represents the receiver(s) of the split funds. This parameter must be passed as the key(s) of the receivers(s) Component(s). Multiple keys can be passed in the array.

  • uint256[] _percentages -> these are the percentage amounts of split funds to be distributed among the receivers listed in the above parameter.

  • bytes32 _flushKey -> this is where the funds are sent when a 'flush' is performed. This parameter represents the receiver of the flush call. This parameter must be passed as the key of the receiver Component.

  • uint256 flushExecutorRewardPercentage -> this is the percentage of the split funds that the flushERC20Tokens function caller--AKA, the msg.sender--will receive as a reward.

  • uint256 executorRewardPercentage -> this is the percentage of the split funds that the splitTreasury function caller--AKA, the msg.sender--will receive as a reward.

Split Operation

The Treasury Splitter can receive, split and distribute ETH, ERC20s and Items (the latter via their Interoperable Interfaces). Upon reaching the initial block, the operation can be executed, by calling the splitTreasury function:

 function splitTreasury(address executorRewardReceiver) external;

The function can be called every time the set interval in blocks is reached (splitInterval).

Anyone can call it, and whoever does receives a reward (which serves as an economic incentive).

As input, it takes the address of the executorReward receiver address, which is msg.sender unless the caller specifies otherwise.

The executorReward is calculated as (the amount to be split x executorReward percentage).

The percentage amounts to be sent to each receiver are then calculated.

If the sum of all percentages does not equal 100%, the residual amount is automatically sent to the Treasury Manager of the Organization to which the TreasurySplitter is attached as a component. If no receivers have been set up (in the _keys parameter during initialization of the TreasurySplitter) to receive the split funds the entire amount is automatically sent to the Treasury Manager of the Organization to which the TreasurySplitter is attached as a component.

Flush Operation

The flushERC20Tokens function is used to transfer all dormant ERC20 and ETH funds out from the Treasury Splitter in emergency situations or simply to transfer received ERC20 tokens out of the Splitter. The funds can be sent to:

  • The receiver set (_flushKey)

  • If no receiver was specified, the funds are sent to the Treasury Manager of the Organization to which the TreasurySplitter is attached as a component.

function flushERC20Tokens(address[] calldata tokenAddresses, uint256[] calldata values, address executorRewardReceiver) external;

Anyone can call the function, and its caller receives a percentage of the amount 'flushed' as a reward (which serves as an economic incentive).

The flushExecutorReward amount is calculated as (the amount to flush * flushExecutorReward percentage).

As input, the function takes:

  • address[] tokenAddresses -> these are the addresses of the tokens to transfer. To transfer ETH, pass address(0).

  • uint256[] values -> this is the amount of each to transfer. The position of each value in the array corresponds to the same position in the tokenAddress array.

  • address executorRewardReceiver -> this is the address of the receiver of the flushExecutorReward.

Modify Treasury Splitter Settings

Split receivers, ERC20 receiver (flushERC20Tokens), receivers percentages, and executor reward cannot be changed once set. Therefore it is necessary to create a new version of the Splitter.

Last updated