Attaching and Detaching Delegations

The DelegationsManager allows Delegations to attach themselves to the Organization.

Consequently, a Delegation can autonomously decide to attach itself (the Organization cannot attack it) but it can only be detached from the Organization (a Delegation cannot detach itself).

Attach and Detach a Delegation

Attach

A Delegation must use the DelegationsManagerAttacherProposal (explained here) to attach itself.

Stake Insurance

In order for a Delegation to attach itself to an Organization, it must first stake an amount of tokens defined by the Organization itself (by the _attachInsurance or _attachInsuranceRetriever parameters set at the time of Delegations Manager initialization, here more info) called insurance.

The token to be staked is the token supported by the Organization (defined by the _collection and _objectId parameters when initializing the Delegations Manager) and matches the token which can then be wrapped by users to get the Delegation Items to vote the Delegation's proposals.

Tokens can be staked by the Delegation host (also called Delegation representative) or by any other address that wants to stake for the Delegation and the staking is cumulative meaning that multiple addresses can stake tokens for a Delegation to reach the amount required by the insurance.

Stake ERC20/ETH

The payFor function can be used to stake ERC20/Item Interoperable Interface and ETH:

function payFor(address delegationAddress, uint256 amount, bytes memory permitSignature, address retriever) external payable;

It takes as input:

  • delegationAddress -> address of the delegation for which you are staking tokens

  • amount -> amount to be staked

  • permitSignature -> bytes parameter containing the encoded v, r, s and deadline parameters to perform a permit approval. If permitSignature is passed empty, the classic approve will be required.

  • retriever -> address that will take back the staked tokens once the Delegation is removed from the Organization. Pass as address(0) to set the retriever as msg.sender.

Stake ERC1155

To stake an ERC1155 (or an Item using the Main Interface), the safeTransferFrom function is used (or safeBatchTransferFrom, if staking multiple ERC1155s for multiple Organizations) to send the amount of tokens to the DelegationsManager contract, which implements the onERC1155Received and onERC1155BatchReceived methods.

To stake a single 1155, the following encoded parameters must be passed as data in the safeTransferFrom function:

(address delegationAddress, address retriever) = abi.decode(payloads[i], (address, address));
  • delegationAddress -> address of the delegation for which you are staking tokens

  • retriever -> address that will take back the staked tokens once the Delegation is removed from the Organization. Pass as address(0) to set the retriever as msg.sender.

When staking multiple ERC1155s, an encoded array of bytes containing the following parameters for each ERC1155 (i.e, for each id) must be passed as data in the safeBatchTransferFrom function:

bytes[] memory datas = abi.decode(data, (bytes[]));
(address delegationAddress, address retriever) = abi.decode(payloads[i], (address, address));
  • delegationsManagerAddress -> this is the address of the Organization's DelegationsManager.

  • retriever -> address that will take back the staked tokens once the Delegation is removed from the Organization. Pass as address(0) to set the retriever as msg.sender.

Detach

The Organization must use the remove/removeAll or ban functions to detach an Organization.

Remove/RemoveAll

Using the remove or removeAll functions, the Organization detaches the Delegations, and the amount of tokens staked for the Delegation returns to the staker address (orretriever address if set).

The remove function removes one or multiple Delegations taking as input an array of Delegation addresses:

function remove(address[] calldata delegationAddresses) external returns(DelegationData[] memory removedDelegations);

The removeAll function removes removes all delegations attached to the Organization:

function removeAll() external;

Ban

Using the ban function, the Organization detaches and bans the Delegations, and the amount of tokens staked for the Delegation are burned (the staker address does not receive the tokens back).

The ban function removes one or multiple Delegations taking as input an array of Delegation addresses:

function ban(address[] memory productAddresses) external;

Withdraw Insurance

If the Delegation has been banned, the amount of tokens staked for insurance is automatically burned.

If the Delegation is active, the staked amount cannot be removed until the Delegation is removed.

If the Delegation has been removed, the amount staked from each retriever can be withdrawn using the retirePayment function:

function retirePayment(address delegationAddress, address receiver, bytes memory data) external;
  • delegationAddress -> represents the removed delegation for which you are withdrawing,

  • receiver -> represents the address receiving the tokens, pass as address(0) to set the receiver as msg.sender (it corresponds to the retriever address calling the function).

  • data -> represents the eventual data to execute in case you're withdrawing ERC1155 (data is a parameter of the safeTransferFrom of ERC1155).

The retriever withdraws the whole amount he has staked, he cannot withdraw a part of it.

Valid Delegation

When a Delegation is attached to the DelegationsManager of an Organization, the DelegationsManager performs a check to see if the Delegation is valid.

What does that imply?

  • A Delegation that has not previously staked the insurance token amount cannot attach itself to the DelegationsManager.

  • A previously banned Delegation can never reattach itself to the DelegationsManager of that Organization.

  • A Delegation deployed by a Factory previously blacklisted by the Organization cannot attach itself to the DelegationsManager of that Organization.

See here for more info.

Maximum Number of Delegations

By default, there is no maximum number of Delegations that can be attached to a DelegationsManager. However, the DelegationsManager can set one with the setMaxSize function. If one is defined, and a Delegation attempts to attach itself to the Organization, a check is done to see whether the maximum is already reached, and therefore whether or not the Delegation can be attached.

require(maxSize == 0 || size < maxSize, "full");

Last updated