# Trustless token management with Set Protocol

Author: Markus Waas

Published: 2020-12-26T19:33:53.000Z

Updated: 2026-09-13T14:25:30.000Z

Source: [https://soliditydeveloper.com/set-protocol](<https://soliditydeveloper.com/set-protocol>)

## Compatibility and review

Before you start

Historical Set Protocol V2 architecture and early TokenSets product snapshot. Manager, module and governance powers require review for each actual Set. The quoted index weights, governance plans and adapter availability are historical; no current UI, trade or issuance flow was executed.

[Official reference](<https://github.com/SetProtocol/set-protocol-v2>)

With Set Protocol you can create baskets of tokens that give users different levels of exposure to underlying assets (currently only ERC-20 tokens).

Set Protocol and TokenSets are an interesting example of DeFi composability: a manager can act through a defined set of modules. That does not guarantee that funds cannot be lost or mismanaged. Privileged modules can invoke calls and alter positions, so review the manager, enabled modules, adapters, governance and fee controls of the actual Set. Fees alone do not rule out conflicts of interest.

![Set Dino](<https://cdn0.scrvt.com/b095ee27d37b3d7b6b150adba9ac6ec8/5e8e5eb1bc478e2c/3490a5a31b4a/v/bd83f4b32061/sets-dino.png>)

## So what is Set Protocol?

With the Set Protocol you can enable passive managements for ERC-20 tokens on Ethereum. A given set is managed by one or multiple managers that can employ different strategies based on the functionality added to this set. The system is designed in a modular way allowing you to choose which functionality in the form of modules to add to a set. In the future all of the governance inside Set Protocol will be fully decentralized.

![Defi Pulse Set](<https://cdn0.scrvt.com/b095ee27d37b3d7b6b150adba9ac6ec8/59129a7b6896caeb/e99914441d1e/v/b1cfc3fec5fb/Defi-Pulse-Set.png>)

[On the website](<https://www.tokensets.com/explore?show=portfolios>), you can see existing sets and choose to join them. For example the featured Defi Pulse Index currently gives you exposure to

- 19% [Aave](<https://aave.com/>)
- 15% [Yearn](<https://yearn.finance/>)
- 14% [Uniswap](<https://uniswap.exchange/>)
- 13% [Synthetix](<https://www.synthetix.io/>)
- 12.5% [Compound](<http://compound.finance/>)
- 10% [Maker](<https://makerdao.com/en/>)
- 5% [REN](<https://renproject.io/>)
- 4% [Loopring](<https://loopring.org/#/>)
- 4% [Kyber Network](<https://kyber.network/>)
- 2.5% [Balancer](<https://balancer.finance/>)

These portfolio weights were a snapshot when the article was published; they are not current index composition or investment guidance.

Let's explore the relevant components of the underlying protocol...

![Set Overview](<https://cdn0.scrvt.com/b095ee27d37b3d7b6b150adba9ac6ec8/3149c41bc9fc5177/db45879ab279/v/f35c718f199f/Set-Overview.png>)

### 1. The main contract: SetToken

The ERC20 Token contract that allows privileged modules to make modifications to its positions and invoke function calls from the SetToken.

You would create a new [SetToken](<https://github.com/SetProtocol/set-v2/blob/master/contracts/protocol/SetToken.sol>) with the [SetTokenCreator](<https://github.com/SetProtocol/set-v2/blob/master/contracts/protocol/SetTokenCreator.sol>) factory. You can call `create` and pass

- a list of ERC-20 addresses (`_components`)
- a list of quantities for each given token (`_units`)
- a list of modules to be used (`_modules`)
- the manager address (`_manager`)
- the name of the set (`_name`)
- the symbol of the set (`_symbol`)

```solidity
function create(
    address[] memory _components,
    int256[] memory _units,
    address[] memory _modules,
    address _manager,
    string memory _name,
    string memory _symbol
) external returns (address)
```

A concept of virtual and real quantities exist for efficient updating. It's essentially just a multiplier that exists inside the SetToken. A real unit value is calculated as `realUnit ≈ virtualUnit * positionMultiplier / 1e18`. This would allow updating the multiplier to change the real values of each component very efficiently.

### 2. Additional data contracts: Resources

Resources are contracts that provide data, functionality, or permissions that can be drawn upon from.

Those include most notably the controller, registry and price oracle.

#### A. System Controller

The [controller](<https://github.com/SetProtocol/set-v2/blob/master/contracts/protocol/Controller.sol>) is the master manager contract and can be used to

- Add/Remove Modules
- Add/Remove Factories
- Add/Remove Resources
- Remove SetTokens
- Add/Edit/Change Fees
- Edit Fee Recipient

The owner of the controller will eventually be a DAO, thus allowing decentralized governance of sets. Currently it's still a multi-sig contract.

This was the original governance plan and ownership description. Check the actual controller owner and enabled modules for a particular deployment rather than assuming the promised transition occurred.

#### B. Integration Registry

The [IntegrationRegistry](<https://github.com/SetProtocol/set-v2/blob/master/contracts/protocol/IntegrationRegistry.sol>) is used to manage external integrations, like support for the Aave system or an external DEX.

Governance can use this to:

- Add/Edit/Remove Integrations

#### C. Price Oracle

The [PriceOracle](<https://github.com/SetProtocol/set-v2/blob/master/contracts/protocol/PriceOracle.sol>) returns a price for a given token pair. The price is retrieved either directly from an oracle, calculated using common asset pairs, or retrieved from external data.

The governance is allowed to

- Add/Edit/Remove Oracles and Adapters

### 3. Modules

Modules can be added to a SetToken and enable extra functionality. Th modules are optional additions to a SetToken and can be added or removed from a set by the manager.

Let's take a look at three common modules.

#### A. Basic Issuance

The [Basic Issuance](<https://github.com/SetProtocol/set-v2/blob/master/contracts/protocol/modules/BasicIssuanceModule.sol>)module allows users to mint (issue) and redeem a SetToken. The basic flow for this module is:

For each component inside the `_setToken`, do

1. Retrieve ERC-20 address.
2. Retrieve required quantity given the passed `_quantity`.
3. Transfer quantity of given ERC-20 to the SetToken address from sender.

Lastly mint `_quantity` SetToken tokens to the passed `_to` address.

The respective `redeem` function works similarly the other way around and burns the SetTokens again.

```solidity
function issue(
    ISetToken _setToken,
    uint256 _quantity,
    address _to
) external;
```

```solidity
function redeem(
    ISetToken _setToken,
    uint256 _quantity,
    address _to
) external;
```

#### B. Trade

The [Trade](<https://github.com/SetProtocol/set-v2/blob/master/contracts/protocol/modules/TradeModule.sol>) module adds powerful trading functionality to a Set. However you will have to write your own integration for whichever market you want to trade on or you can use the existing Kyber integration.

The trade function can be called to execute a trade for a given SetToken. You will essentially sell the given sendToken in the sendQuantity for the receiveToken. Obviously the token you want to sell must actually exist in the SetToken in sufficient quantity.

Only the token manager may call the trade function.

If you want to write your own DEX integration, have a look at the [KyberExchangeAdapter](<https://github.com/SetProtocol/set-v2/blob/master/contracts/protocol/integration/KyberExchangeAdapter.sol>).

In the linked V2 TradeModule, the send and minimum-receive quantities are *position units per SetToken*, scaled to total notional amounts using the SetToken supply. They are not simply arbitrary total trade amounts. Adapter support must match the deployment.

```solidity
function trade(
    ISetToken _setToken,
    string memory _exchangeName,
    address _sendToken,
    uint256 _sendQuantity,
    address _receiveToken,
    uint256 _minReceiveQuantity,
    bytes memory _data
)
```

#### C. Tokenset Governance

Tokens these days are commonly used for governance as well, just remember when we look at the [COMP governance](<https://soliditydeveloper.com/comp-governance>). This is exactly what you can do with the [Governance Module](<https://github.com/SetProtocol/set-v2/blob/master/contracts/protocol/modules/GovernanceModule.sol>). Intended governance protocols are Compound, Uniswap and Maker, but theoretically any system that complies to the same functions could be used here.

The functionality includes

- `delegate`: Delegate voting power.
- `propose`: Create a new proposal.
- `vote`: Cast a vote on a proposal.

For more details on those functions and governance, take a look at the above mentioned COMP governance article.

Once again only the manager of the TokenSet may call any of those functions.

### 4. Rebalancing Sets

One interesting feature of sets is rebalancing. Usually with any assets you have the ratio of exposure you get from them can change dramatically over time given the price changes. Just imagine you have three tokens of projects you really like. Let's call them SuperCoolToken, SuperInterestingToken and SuperUsefulToken. You think all projects at the time of investing are valued at equally good prices, so you choose an even split of 33%.

Now you create a TokenSet with

- 33% SuperCoolToken
- 33% SuperInterestingToken
- 33% SuperUsefulToken

Now after a few months, SuperCoolToken mooned and went 10x, while SuperInterestingToken stayed the same and SuperUsefulToken actually went down by 50%. Your ratio now would be

- 87% SuperCoolToken
- 9% SuperInterestingToken
- 4% SuperUsefulToken

But you might still think all projects are still equally promising. Or you just want a more diversified exposure. In this case, wouldn't it be useful to have a mechanism automatically rebalance it to the original ratio?

It's explained in further details inside the [Whitepaper](<https://www.setprotocol.com/pdf/set_protocol_whitepaper.pdf>). However, I'm curious as to what the current state for this is.

According to the Whitepaper the rebalancing works either via automated trading on DEX's or a system internal dutch auction. I can already see a rebalance overview site on [https://www.tokensets.com/rebalance](<https://www.tokensets.com/rebalance>) which is in fact listing auctions. However I could not find any smart contract code in the repository which contains the auction code. So if you know what's going on, please let me know.

The auction description belongs to the original Set architecture. The V2 repository discussed here uses modular position management; its rebalancing modules need not implement that old auction design. The two repositories describe different generations.

There is however one module called [SingleIndexModule](<https://github.com/SetProtocol/set-v2/blob/master/contracts/protocol/modules/SingleIndexModule.sol>) which can be used for rebalancing functionality. It doesn't start auctions, but uses the defined DEX's to initiate a rebalancing.

There you have it, I find Set Protocol a fascinating idea and looking forward to where this develops in the future. Have you used Set Protocol before as a user? Or have you even interacted with the contracts directly? Let me know in the comments below.
