The Audit has Come to an End; The Journey Ahead
Code4rena Audit & Its effects on the Timeline
We recently finished our Code4rena contest. Many bugs were squashed, and improvements were made. Now, two or three cockroaches stand between us and the launch. Keep reading to find out what it is, how we’re dealing with it, and what you can expect for the launch.
The issue preventing our launch was unearthed by the brilliant minds that work tirelessly at Code4rena. Thanks gents. 🙏
Like most pesty bugs, ours deals with extreme edge cases. In our case — negative yield. As it stands, how it deals with loss is the same as a traditional bank. We want to do better.
The Bugs 🪲
Here’s a glimpse into our share accounting mechanism and how it works.
Alice, Bob, and Elizabeth created a foundation. All of them collectively decided to allocate their yield to Carol’s wallet. Lucky her! The red dashed line delineates the principal. Everything over this line is considered yield. Total value, as you’ve certainly guessed, is the sum between principal and yield.
Some time has elapsed and the vault’s APY is quite high—yield has been generated. Carol, who had been allocated all the yield, decided to claim all of it. The Total Value of the vault has decreased as intended, and principal limit remained the same. Unlike rDai, which only lets you claim once, Sandclock’s yield allocation is continuous—one can claim as many times as they want, so now Carol needs only wait for more yield to be generated before she can claim again.
Bob decided he needed liquidity and thus withdrew from the vault at roughly the same time. As expected, Total Value went down, as did Principal Limit. The yield that has been allocated to Carol is now considerably lower, which seems reasonable.
But wait, for some reason, the APY% flipped—the vault lost 50% of its capital.
As you can see, the vault contains the same number of shares (12), but because it lost money, each circle is smaller.
So what happens if Alice withdraws?
She did! And Elizabeth was left with nothing despite still having a claim. In such a situation, the most optimal game-theoretic scenario for an individual actor is to trigger a bank run — rush to the exit all at once in order to have liquidity, leaving would-be withdrawers unprotected. Unfortunately, this is also how banks operate these days, under the veil of fractional reserve banking.
This is unjust. Under fair rules, Elizabeth and Alice would have shared the 50% loss proportional to their initial deposits.
Could the vault incur a loss?
The silver lining. This negative yield scenario is impossible under normal circumstances, but it’s important to be able to handle even the most extreme circumstances in order to protect you. So, could it, or could it not?
It is extremely unlikely.
Our contracts use Anchor Protocol to generate yield. Anchor’s interest rate is defined as a function of the utilization rate at time t. The total amount of rewards claimable by the user are the summation between interest and Proof-of-Stake yield rewards accrued as a function of your share of the total deposits.
By all accounts, negative yield is outright impossible. So how, and why do we care?
Exploits. If Anchor is exploited, even if only partially, it is possible for yield to be negative, forcing Sandclock’s depositors to take a hit proportional to the loss incurred, should they not wait for yield generation to cover the losses. Under the current architecture, this could trigger a bank run. We’re making it better.
It seems obvious that the solution is to socialize the loss. Under this new model, all depositors would be able to withdraw half of their initial deposit. Much fairer. How can we accomplish this without radically changing the architecture?
When the yield is positive, users are able to withdraw their principal amount based on the underlying amount. When yield is negative, users are able to withdraw their principal amount based on their shares.
Yield is positive and your initial deposit was $1,500? You withdraw $1,500. Vault incurred a 10% loss? You withdraw $1,350.
Given the likelihood of such event transpiring, it may seem like we are being overzealous. After all, if everything works as intended, there is no reason for the vault to ever incur a loss. However, it is important to be able to handle a wide range of scenarios, no matter how unlikely they seem. Our engineers are working tirelessly to implement this solution, write tests, fuzz it, and audit it. We can never be too careful.
It is important to remember that what we’re building at Sandclock does not exist. We are building it from the ground up, with no inspiration from other projects. We are not forking an existing protocol. Other attempts at doing this have catastrophic bugs or are fundamentally different. Innovating at the forefront of a space that develops at breakneck speed is scary, obstacles routinely get in the way, and it is our mission to communicate them and tackle them.
There were other bugs found, as you would expect from an audit—we are fixing them as we speak. One of them is either enabling partial withdrawals (we don’t want that), or enabling trustless withdrawals when there’s not enough liquidity in the vault contract since depositing to Anchor is an async operation.
All in all, doable stuff and we should have no problem patching them up.
We are delaying the launch.
… And also doing away with the traditional concept of “deadlines” in favor of “probabilistic outcomes”. This is how most projects do it anyway.
Deadlines are harmful. For the community and the team. They create pressure to push out code that may not be production ready, and disappointment if postponement is necessary, which is unfair and frustrating for the community.
But we don’t want to lose your trust. We want to remove the barrier between community and team. When something happens, you’ll know about it at the same time as us.
This is why we’ve made the choice to open source all our GitHub repositories, as well as our Jira. We want the entire workflow of the Sandclock team to be as transparent as possible so that you can follow along, and so that we can more easily onboard brilliant developers to join our team and help solve any hurdles that may come our way.
Every quarter we will release a short term product planning roadmap. This roadmap will include estimates for the deliverables listed within, and its qualitative probability of happening within the quarter.
We can officially tell you that we have begun implementation on our website. Expect a grand reveal in the next month or so.
The rumors are true. Sandclock has signed a contract with a Tier-1 centralized exchange, ready to go for launch. For legal reasons, we can’t tell you which one or offer exact dates, but rest assured, it’s in the works.
We’ve made several impactful improvements based on our first phase of UX testing. While we are happy with our design, it’s always helpful to get more eyes on it, especially considering the changes. This extra time is an unexpected opportunity to involve more of you in the UX testing process. More Quartz Knights will get their hands on the UX, and we will welcome their feedback graciously. We will also publicly release more sneak peaks, including our dashboard design and more.
Hosting more public events
We promise to give you even more opportunities to speak directly with the Sandclock team to truly understand our challenges, concerns, and thought-process, and also ask questions.
Our next Twitter Spaces will be held on Monday at 7pm UTC. You’ll have the chance to talk with Cristiano, Elizabeth, and one of Sandclock’s technical masterminds, Gabriel Poça. Get your questions ready.
This is just a tiny hiccup in the grand scheme of things
Sandclock’s future is not on Layer 1 Ethereum. Most projects grew tremendously during DeFi summer when gas fees were relatively low, and ETH was nearly 10x cheaper ($200–400). We do not expect new projects to experience tremendous adoption on Layer 1 Ethereum, and Sandclock’s adoption will only truly sky rocket when we make it seamless for non-crypto natives, to an unprecedented level. Gas fees are silent killers of your gains, and make it expensive for projects to operate efficiently and scale. A simple deposit can cost hundreds of dollars, pricing out all but a select few group of elites.
Probably around late Q3, Sandclock will be on Starknet and Terra. Yes, you will still be able to use our Layer 1 Ethereum vaults, but why would you? Starknet is a Layer 2 Ethereum solution that will allow Sandclock to scale and thrive. Cairo, its programming language, is more powerful and allows for more expressive ways of writing code. Computation is cheaper, gas is hundreds of times cheaper, and we haven’t even realized a third of Ethereum’s rollup centric roadmap. Once we have, you can expect transactions to be fractions of a penny.
So why develop on Layer 1 Ethereum at all? We will be able to deploy Sandclock on any EVM-compatible rollup. Think Metis, Optimism, ZkSync, Arbitrum. Any EVM-compatible Layer 2 rollup with a source of yield. We are also able to test out our UX more rapidly since this is where the majority of users are at present, and iterate, iterate, iterate. Furthermore, love it or hate it, Solidity is a mature smart contract language and our engineers are able to iterate on smart contract designs faster, and test them more efficiently. Once we finish adding the final touches to the architecture, we will be ready to port the contracts to the Cairo language.
Thanks for all your support, and remember... we are building production code for the next 100 years.
Cristiano and the Sandclock team