[Update] - Smart Treasury - Progress Update

Smart Treasury - Update 1

Hi everyone, it’s been a while since I’ve given an update on the forum, so I thought it was best to summarise the progress for the development of the smart contract over the past week in a forum post.

Over the past week I have been developing the smart contract for the smart treasury, as mentioned in the this post [Grant] - Develop a Smart Treasury, there are two components which are required for the smart treasury.

  1. The FeeCollector Smart Contract
  2. The Bootstrapping Smart Contract

A prototype for both of these contracts is now available on the github repository: GitHub Repo. I have also deployed a initial test smart treasury to kovan, which can be inspected here Link. (The swap fee is incorrect though) This initial prototype has some technical differences from the initial design which was suggested in the grant, and I hope to be able to go through the changes in this post.

Smart Contract Updates

Fee Collector

  1. The Fee Collector only supports up to 15 deposit tokens, to cap gas costs
  2. The Fee Collector swaps directly into WETH
  3. The Fee Collector holds the Balancer Smart Pool Token, and can withdraw the token, or the underlying

Bootstrap

  1. Initial weights no longer 99/1. Instead weights will be determined as ratio of initial IDLE deposit, and FeeTreasury deposit. Weights will still gradually update to 90/10 for the initial bootstrap. (This is over a 3 month period, perhaps this can be reduced?)
  2. Price oracle for IDLE/WETH value will be set by multisig rather than on-chain. Direct on-chain oracles are unreliable, and vulnerable to manipulation, this change reduces the surface area of attack. The only use for the oracle would be to configure the initial weights of the pool in anycase.
  3. The owner of the bootstrap contract will be deligated to the idle multisig before governance vote.
    • After which the multisig will call swap(), initialise(), bootstrap(), renounce() in that order.

The use of the multisig is mainly a gas saving measure, as the on-chain proposal would likely run out of gas if it were to execute all of these functions from one transaction.

Where to go from here

The initial prototype is ready, but that doesn’t mean its ready for proposal yet, I will be continuing to test the smart contract and writing unit tests and integration tests, and adding better documentation. In addition to this (with some help from @william) I will be testing the proposal to submit on-chain.

Before this happens perhaps a new grant should be created to audit the code before it goes on-chain (as suggested by @Teo in his post :date: IdleGov Biweekly Update – 12/28/2020 [BW2].

We can also go through the process of having $IDLE listed on balancer, so that it will show up on their UI once the pool is deployed. This should also allow the pool to be eligable for $BAL rewards.

I will create a new system diagram in the coming days to illustrate how IDLE, FeeCollector, and SmartTreasury interact, in addition to the deployment steps so the development process is as transparent as can be for the community.

Hope everyone is enjoying their Christmas break, and looking forward to reading your comments :smile:.

11 Likes

Thanks for the update @8bitporkchop

It seems like we’re on the right track here – I’ll leave @william to give feedback on the tech part but I’d like to ask a couple of questions.

  • Re initial weights, can you expand a bit more on the bootstrapping process? My understanding is that we would start from 98/2 (2% should be the minimum size for weights) and then gradually move to 90/10 (by calling updateWeight function). How will the exact initial ratio determined? How would this weights adjustment (from 98/2 to 90/10) work? (eg linear?) What would be the difference if we lower down the 3-mo period to 2-mo?

  • Re the bootstrap and smart pool itself, we are planning to use 1% of the Ecosystem Fund (130’000 IDLE). Idle FeeTreasury is now at about $40k. If we suppose 1 IDLE = 0.003 ETH as reference/oracle price, 130’000 IDLE * 0.003 = 390 ETH, these 390 ETH (which are in IDLE) represents 98% of the pool, and the other 2% will be taken from the Treasury and added to the Smart Pool in ETH (~8 ETH, ~$5’760 at the time of writing, ~15% of the treasury). What about the rest of the treasury? How do we handle the automatic buyback (aka sending ETH) to Smart Treasury (every time it hits a threshold, say $5k in ETH, or on a periodic basis?)

I saw you already requested to whitelist $IDLE in Balancer. Do you have any updates for it? Happy to poke Balancer team in Discord as well next week to move forward with that process :slightly_smiling_face:

About the audit, our option here would be to spin off a security grant and open up the applications for auditing firms to get some quotes. Then governance can then vote through a Snapshot poll for it. We can coordinate early next week for it.

Additionally, as just discussed here, we are planning to have a Treasury Committee and we might already think to route part of the protocol proceeds to the Smart Treasury, and part to the Committee. We might initially reserve 15% to Smart Treasury Bootstrap, 35% to the first automatic buyback operations, and 50% to this initial Treasury Committee? We can then have 50% of fees going to the FeeCollector and 50% going to Treasury Committee (@william @Davide @ETM612 @simoneconti would love to hear your feedback about this as well)

Anyhow, I’m amped to see this Smart Treasury at work!! Great job Asaf :smiley:

3 Likes

Hi Matteo,

Thanks for your comment, there’s quite a lot of points here that I would like to talk about, so I will try to break them up individually as much as possible.

Happy to do so, when we were first discussing the implementation of the smart treasury, one of the problems was getting the funds to bootstrap this treasury since the fee treasury only had ~5K, so a 99/1 or 98/2 (IDLE/WETH) initial pool was a good option, there were also discussions of selling some of the IDLE on the open market to reach these required funds [However, this is not an ideal scenario].

The updated bootstrapping process will work as follows

  1. Deploy Bootstrap contract
    1.1 Configure bootstrap contract with fee tokens and network addresses
  2. Set owner as multisig address
  3. Wait for onchain proposal to transfer funds from fee treasury and ecosystem fund
  4. Swap all fee tokens to WETH
  5. Set idle price (in weth)
  6. Initialise Pool [Using the idle price in WETH it is possible to calculate the total value the smart treasury will hold. Since we also know the balances of IDLE and WETH, the exact initial weights can be calculated]
  7. Bootstrap Pool [In this step the funds are actually sent to the smart treasury, and updateWeightsGradually() is called, which linearly updates the weights over a given time period]
  8. Renounce ownership from bootstrap contract Set governance as pool controller, and send pool liquidity tokens to fee collector.

This diagram summaries this.

Some notes on step 6 and 7.

Say 130,000 IDLE is transferred, and the equivalent of 20 ETH is transferred.
And the price of 1 ETH = 260 IDLE.

Therefore the IDLE value is worth 500 ETH.
And the pool has a total balance of [Expressed in ETH]
20 ETH + 500 ETH = 520 ETH

The weight of IDLE is 500/520 = ~96.2%
The weights of WETH is 20 / 520 = ~3.8%

After the pool is bootstrapped the weights will be gradually updated to the goal weight of 90/10 IDLE/WETH.

There wouldnt be much of a difference between 3 months vs 2 months, and I would even argue 1 month. The shorter the duration, the faster the treasury is selling IDLE, so too short of a duration wouldn’t be good.

If we use the example from the notes, with all things being equal, the final weghts and balances of the pool should be

Total value: 520 ETH
IDLE: 90% = 468 ETH = 121,680 IDLE
WETH:10% = 52 ETH

The difference in IDLE is 130,000 - 121,680 = 8,320 IDLE
So a duration of 1 month for the updateWeightsGradually() call means that ~277 IDLE will be “sold per day” until the weights have reached the desired level.

If the liquidity which is added to the pool is >277 IDLE per day, then the treasury is acting as a buy back machine.

A longer duration would reduce the amount “sold” per day. And a shorter duration would increase it. Note: This is also affected by how much ETH is deposited at bootstrap.

On average the fee treasury has been making about $1000 / day (from governance launch). Which at current prices is around [$2.14/IDLE] is 467 IDLE / day. Which if fully redirected will be bought back by the smart treasury. Perhaps some further analysis can determine an optimal period.

We are planning on using 10% of the ecosystem fund, which is 1% of total supply.

The fee treasury can remain as is. The idea for the feeCollector was that a ratio can be set for how much of the fees goto the fee treasury, and how much goto the smart treasury. However as you mentioned in your discussion for the treasury committee, perhaps the ownership of the fee treasury can be migrated from governance to the treasury committee for this purpose (@william can confirm if this is possible).

The way I’ve coded the buy back mechanism (check deposit() function) is that it will swap all fee tokens in the feeCollector contract to WETH for the automatic buyback. Therefore it would be best to call this at a given threshold. $5k equivalent in fees sounds good to me. Though this will have to be done through a whitelisted account.

I raised a request, wouldn’t hurt to bump it on the discord.

Happy to work with you on this.

See previous comments, but I think its fine to split up the funds in the fee treasury perhaps 50/50 to bootstrap and treasury commitee. then setup 80/20 ratio for the FeeCollector to smartTreasury/treasury commitee. Noting that funds from the smart treasury can also be withdrawn by governance vote.

4 Likes

This all sounds really good. I think 50/50 split is fine but would like more to go to bootstrap. Excited to see the results!

1 Like

I have created a gnosis safe multisig address here Contract Address 0xe8eA8bAE250028a8709A3841E0Ae1a44820d677b | Etherscan

@william can you please share a public address so I can add idle as a signer also.

1 Like

You can use Idle Deployer Address 0xe5dab8208c1f4cce15883348b72086dbace3e64b | Etherscan I’ll get back on everything later today. Thanks for the update!

1 Like

Thanks for this extensive update @8bitporkchop .

Regarding Smart Contract Updates:
For the FeeCollector changes seems ok to me.
For the Bootstrap contract

that’s ok for me and should simplify the contract a bit

That’s fine too or better we can directly use the multisig you created here

The fees for deployment should be refunded to whoever makes the actual txs, probably direcly from the Treasury (or later through something like the commitee proposed).

A lot of progress have been made so far, great job @8bitporkchop! Once the code is ready we can leverage even more Kovan testnet to test also the submission of the proposal there and I’m glad to help on that side (the same approach can then be used to test everything also in mainnet fork).

Security should be for sure something to focus on but we should also consider the scope of the proposal and weight the potential downsides in terms of costs and time.
In terms of changes we are not making any change to the main idleToken contract or other contracts already deployed, we will only change the feeAddress for all pools (through a method call), so no user funds will be directly at risk after the update. The other action that we are doing is the withdraw of 130000 IDLE from the ecosystem fund and the fees from the Treasury, so the worst case scenario would be to potentially have those funds stuck in some way, but we can code an emergency withdraw method that only the governance can call to be safe, so just in case we can withdraw funds from the old treasury fix it if needed and redeploy it.
All of this is just to say that we may also consider to not perform a full audit, but rather a security review with an auditing firm or a public peer review of the contracts. In either cases I’m happy to provide further support and reviews.

I think that this is a good idea, but maybe it would be better to start a more formal discussion about this and implement it after the Smart treasury is out, what do you think?

Btw once you set the FeeCollector as the fee receiver for each idleToken then you can redirect funds where you want from the FeeCollector, so I would say that it would be better to send part of the funds to a multi-sig (treasury committee), part to the FeeTreasury (which would still be owned by the governance) and part to the SmartTreasury (to avoid having the Treasury committee controlling all earned fees with unlimited powers) with allocations TBD. This would require a slightly change in the spec / code for the proposal so @8bitporkchop let us know if you think it can be added directly

I think some further analisys is needed to find the optimal solution, maybe it’s also worth considering the decrease of AUM and the increase of avg APY of each pool

The ecosystem fund has 1.950.000 IDLE so should be 6.66% of the ecosystem fund or 1% of the total supply, but in any case we all agree that are 130.000 IDLE :slight_smile:

This needs to be setup somewhere and a keeper is needed (with funding to call the deposit() method). We already have a keeper bot which performs rebalances for all pools so it can be hooked up there but some funding for gas cost needs to be accounted (and in the long run also for rebalances but that’s another story :slight_smile: )

3 Likes

Added a first review for the SmartTreasuryBootstrap.sol here SmartTreasuryBootstrap first review · Issue #1 · AsafSilman/idle-smart-treasury · GitHub

3 Likes

Congrats Asaf for the amazing job, not only for developing it but also for the proposed improvements!

Despite the tech part is not my sector, I’d like to better understand how the multisig would interact with the Smart Treasury, how it calculates IDLE/WETH ratio and who will be the owner of such multisig.

I’ve worked out some scenarios, and a possible solution might be the setting of a 90/10 pool since the beginning. This was not possible at the time of brainstorming, with few thousands of dollars.
Right now we have $ 40k in the FeeTreasury, and at the current value (1 IDLE = 0.0027 ETH), the 90/10 can be deployed.
In this way, no tokens would be released on the open market and the buyback machine could immediately start.

This is true up to 0.0028 ETH, while on higher ratios the 90/10 is reached in some days.
The chart below shows the balances according to the IDLE value.

The 1000/day fee flow can not be used as reference, as in the past month TVL changed a lot (and also the balances between the assets). For reference, in the last 5 days (30th Dec- 4th Jan) FeeTreasury increased only by 1000 in total. That’s why a 98/2 might require a lot of time if accrued fees are not enough (pending fees are much higher, but not available as periodic cash flow).

If we use $40k for the Smart Treasury, the Treasury Committee has to manage $IDLE funds in the bootstrap phase and we have to take these tokens from the Ecosystem fund. The implication is a small increase of the circulating supply, but the Balancer pool might mitigate this uptrend by bringing the tokens under the Governance control with buybacks.

In the long-term, I expect that the ecosystem is preserved as much as possible and fees are split between ordinary FeeTreasury, Smart Treasury and multisg Committee.
This split should be dynamically changed by the Governance according to the needs.

Any thoughts on this?

5 Likes

Hi Davide,

I guess this depends on how much of the fee treasury will be used for the bootstrap of the smart treasury vs treasury committee. The more that is used for the bootstrap, the sooner the buy-back mechanism (up to a threshold as you described above). Perhaps this should go to a snapshot vote?

As a note, if the weights of the balancer pool exceeded the goal weights say 88/12 IDLE/ETH because too many fees were bought, the pool will still gradually adjust to 90/10, but in this case it would be “buying IDLE”, instead of “selling”.

Regarding the fee split 3 ways. I have implemented this now into the fee collector smart contract, so it is possible to split fees up for up to 5 ‘beneficiaries’. with the smart treasury always being the first beneficiary. So in this way it is possible to split the fees into smart treasury, fee treasury and multisig. and in the future up to 2 more addresses.

5 Likes

Multisig account has been updated to a 2 of 2 multisig, myself and the idle deployer. As a minor update, I am still working on the testing for the smart treasury. I will post an update in the coming days :slight_smile: .

6 Likes