I was motivated by my own personal desire to build a portfolio of different tokens that would rebalance automatically over time. I saw what Shrimpy had done as a custodial solution, but I wanted to build something that was non-custodial - not your keys, not your crypto!

What it does

The dapp allows users to deposit USDC, which then gets automatically divided between four different crypto tokens (WBTC, WETH, WMATIC, SAND). The user is allocated 'shares' representing their share of the total portfolio. This portfolio is then rebalanced periodically (e.g. weekly or monthly). The user can withdraw their tokens at any point, which they receive back in USDC again.

How we built it

The dapp was built with one basic smart contract, called autoBalancer.sol. The Front End is a very simple Javascript implementation, with some Bootstrap CSS.

The details of the smart contract are in how the incoming deposits are divided up into the portfolio, and how withdrawals are processed. Share tracking of users is also a key part of the design.

The Chainlink price oracles were key to the rebalancing of the portfolio, as the portfolio needs to be rebalanced relative to a currency (USD in this case), and the respective oracles give us the USD prices of the different tokens. The price oracle was implemented within the smart contract.

The Chainlink keepers were also key to the design in order to automate the rebalancing. The keepers were implemented in the smart contract as well. What's great about the keeper design is that one can do a lot of your computation off-chain (in this case computing the swap paths and amounts for each rebalance). This computation would be gas-intensive and thus expensive if done on-chain. The keeper then passes the parameters back to the smart contract, and the required swaps are carried out on-chain.

It's also important to note that a protocol like this is only really feasible (currently) on a low-fee chain like polygon. This is especially true for users who only want to invest small amounts - on mainnet the transaction fees of the rebalancing would be prohibitive.

Challenges we ran into

Developing the code to keep track of shares and allocate new incoming shares was challenging. Getting the oracles and keepers implemented was not too bad, as there was lots of good information online, although it did take a while to get familiar with how keepers work and how to implement a keeper compatible contract.

One of the key challenges was refactoring the rebalance logic from JS to solidity, in order to fit it into the CheckUpkeep function. Given that CheckUpkeep is a view function and can't change state, there were some tricky limitations on the kinds of arrays we had access to, and this presented some challenges. There were also some unexpected solidity challenges with the variable types that were required at different points in the rebalancing algorithm.

In addition, I had to solve for a few 'stack too deep' issues in the smart contract, particularly in implementing the rebalancing logic.

Accomplishments that we're proud of

Essentially, recreating something that a major custodial protocol like Shrimpy has built with a large dev team and funding. This is a protocol that I would use myself, is cost effective, simple and yet powerful.

What we learned

Lots of useful stuff about how Chainlink's oracles and keepers actually work, plus some in-depth knowledge of Solidity arrays and variable types.

What's next for Automated Rebalancer

Refactoring the smart contract to make it more readable and modular! (ran out of time!)

Improving the front end, and continuing to enhance the security of the smart contract against any possible hacks.

I would like to make it possible for users to create their own portfolio by choosing from different tokens. They should also be able to choose what type of rebalancing they prefer (e.g. time-based versus threshold based). This would bring the dapp closer to the functionality level of Shrimpy.

Built With

Share this project: