Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Sip 026 - Clarity DeFi Vault SIP #153

Open
wants to merge 10 commits into
base: main
Choose a base branch
from
97 changes: 97 additions & 0 deletions sips/sip-026/sip-026-clarity-defi-vault.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
# Preamble

SIP-Number: SIP-026
Title: Clarity DeFi Vault
Author: Tycho Onnasch, Fernando Foy, Philip de Smedt, Christian Hresko
Consideration: Technical
Type: Standard
Status: Accepted
Created: Sep 7, 2023
Last-Modified: Sep 7, 2023
Sign-off:
Discussions-To: https://forum.stacks.org/t/clarity-defi-vault-sip/15567
License: Creative Commons CC0 1.0 Universal license
Layer: Trait

# Abstract

This Stacks Improvement Proposal (SIP) aims to address the issue of commingled collateral positions on the Stacks blockchain's Clarity-based DeFi applications. Currently, due to Clarity's design, it is challenging for users to identify their specific collateral positions within the Stacks Explorer. This SIP proposes the creation of a common interface for contracts that hold SIP-010 assets. Implementing this interface will enable users to view their collateral positions distinctly, improving the overall user experience of Stacks DeFi applications.

# License and Copyright

This SIP is made available under the terms of the Creative Commons CC0 1.0 Universal license, available at https://creativecommons.org/publicdomain/zero/1.0/. This SIP's copyright is held by the Stacks Open Internet Foundation.

# Introduction

#### Problem Statement
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When mentioning how Ethereum has resolved this problem, can you add a link to an exmple contract/etherscan tx etc?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here's an example of a pool deployed by a transaction: https://etherscan.io/address/0xc1dd3f011290f212227170f0d02f511ebf57e433#code

Users can mint, burn and deploy assets to the pool and can follow the assets stored in the pool by looking at the balance in the explorer.

Clarity, the smart contract language of the Stacks blockchain, presents a challenge in providing users with the ability to identify their collateral positions within Clarity-based DeFi applications. Unlike other blockchain ecosystems like Ethereum, where users can distinctly view their collateral in separate smart contracts on the chain's explorer, Clarity currently lacks this capability.

As a result, users who post collateral on Stacks DeFi apps might perceive their collateral funds as commingled with other users' collateral, leading to a suboptimal user experience. The ability to natively inspect collateral positions on-chain is a crucial value proposition of DeFi over CeFi.

#### Technical Background of the Problem
In Solidity, the Ethereum smart contract language, contracts can be deployed by executing Solidity code in transactions. This allows the deployment of contracts that represent vaults holding ERC-20s separately. These distinct collateral-holding contracts can be effortlessly looked up on explorers such as Etherscan, facilitating users' oversight of DeFi protocol collateralization.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
In Solidity, the Ethereum smart contract language, contracts can be deployed by executing Solidity code in transactions. This allows the deployment of contracts that represent vaults holding ERC-20s separately. These distinct collateral-holding contracts can be effortlessly looked up on explorers such as Etherscan, facilitating users' oversight of DeFi protocol collateralization.
In Ethereum's smart contract language Solidity, contracts can be deployed by executing Solidity code in transactions. This allows the deployment of contracts that represent vaults holding ERC-20s separately. These distinct collateral-holding contracts can be effortlessly looked up on explorers such as Etherscan, facilitating users' oversight of DeFi protocol collateralization.


However, Clarity's design differs significantly. It does not allow contract deployment during transaction execution to maintain deterministic behavior and avoid infinite recursion. Consequently, representing entities that hold SIP-010 assets requires implementing logic within a single contract address.

# Specification
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it would be good to talk about event production (via print) for vaults.

I imagine that a standardized deposit/withdraw event for vaults could eventually be used by explorers to display a more detailed event outcome for a transaction. For example, rather than transfered FOO to SP1VFTXPFH4S8T99NHWQBJ8BECKZFQ3YFXRN4NJY8.bns it could say transfered FOO to SP1VFTXPFH4S8T99NHWQBJ8BECKZFQ3YFXRN4NJY8.bns, depositing in vault 10 or whatever. But it can only do that if the vault events are standardized.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that the SIP would be improved with 2 simple example contracts that implement "normal vaults" and "vaults grouped by principal".

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should they be included in the SIP or linked to in the SIP?

The proposed solution is to create a common interface for contracts that hold SIP-010 assets. While Clarity does not permit contract deployment during transactions, different entities can be logically separated within the same contract. This is used in the Arkadiko protocol contracts to differentiate between different vaults. If the Stacks Explorer implements this common interface, users will be able to view their collateral positions distinctly, providing a user experience similar to DeFi on other blockchain platforms like Ethereum and Solana.

New vault IDs are generated incrementally starting from 0. Vaults are separated logically based on this ID with a numerical value.

The SIPXXX Vault trait, `sipxxx-vault-trait`, has 3 functions. These functions
do not update state, they are view-only and they allow for a common interface:
## Trait functions
### asset-contract

`(asset-contract ((vault-id uint)) (response principal uint))`

Returns the principal of the asset being held by the vault identified by `vault-id`.

Returns the token type balance `token-id` of a specific principal `who` as an
unsigned integer wrapped in an `ok` response. It has to respond with `u0` if the
principal does not have a balance of the specified token or if no token with
`token-id` exists. The function should never return an `err` response and is
recommended to be defined as read-only.
Comment on lines +62 to +70
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The purpose of this function isn't super clear to me from this description.

I think it is supposed to return the contract that controls the asset in the given vault, but the description of the function here seems like it maybe is describing something else (i.e., what is the token type balance referring to?).


### holdings

`(holdings ((vault-id uint) (asset <sip-010-trait>)) (response uint uint))`

Returns the total amount of the underlying asset held by the vault identified by `vault-id`.

### holdings-of

`(holdings-of ((vault-id uint) (asset <sip-010-trait>) (owner principal)) (response uint uint))`

Returns the total amount of the underlying asset held by the vault identified by
their vault ID for `owner`. This is used when underlying assets are divided by vault id
and are grouped by the principal of `owner`.
Comment on lines +82 to +84
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This SIP needs more detail on the difference between "normal vaults" and "vaults grouped by principal". It's not clear in the text what the difference between those models is and what should be possible. For example does it make sense to use the same vault id with two different principals? That is, could (holdings-of u10 <asset> alice) return (ok u10) and also (holdings-of u10 <asset> bob) return (ok u5)?


If the implementation does not group the vault assets by owner, return `0`.


```clarity
(use-trait sip-010-trait .sip-010-trait-ft-standard.sip-010-trait)

(define-trait vault-trait
(
(asset-contract (uint) (response principal uint))

(holdings (uint) (response uint uint))

(holdings-of (uint principal) (response uint uint))
Comment on lines +93 to +97
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would suggest all of the trait functions be prefaced with vault- because they have to share the function namespace with the rest of the contract.

)
)
```
# Related Work
The dicussion on a vault Solidity implementation can be found here [Forum Discussion](https://www.usenix.org/conference/atc16/technical-sessions/presentation/ali)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this the right link? Doesn't link to any Solidity example but a dated Blockstack paper?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.


# Backwards Compatibility
The vault implementation was inspired by the vaults used in the Arkadiko protocol. Specifically, the Vault manager contract that is meant to abstract the data used in Arkadiko vaults. A vault trait contract can be deployed to interface with the Vault manager contract to be compliant with the standard (wrapping the original contract).

# Activation

This trait will be considered activated when this trait is deployed to mainnet, and 3 different implementations of the trait have been deployed to mainnet, no later than Bitcoin block 900000.
# Reference Implementation
The reference implementation of this SIP can be found in the following GitHub repository:
GitHub: https://github.com/FriendsFerdinand/sips/blob/vault-standard/sips/sip-vault/sip-vault.md
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a dead link. In my opinion, because this SIP is a trait proposal, it is probably sufficient just to include the text of the trait definition here.