-
Notifications
You must be signed in to change notification settings - Fork 84
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
Add SIP: Composable Fungible Tokens with Allowance #154
base: main
Are you sure you want to change the base?
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you for putting this together. I am not 100% convinced that we need it. I'd like to see a better rational.
Also phishing, security threats and composability could be explained in more details.
(Some typos to fix.)
|
||
## Abstract | ||
|
||
This proposal extends the SIP-010 standard trait for fungible tokens on the Stacks blockchain to support composable fungible tokens with allowances. It addresses the limitations of the previous standard, which did not provide sufficient support for composability and security. The new trait includes functions for transferring tokens, approving allowances, checking allowances, and transferring tokens using allowances. The recommended implementation of `approve` used incremental allowances to avoid rance conditions and double transfering. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It addresses the limitations of the previous standard, which did not provide sufficient support for composability and security.
SIP-10 is the bare minimum to have a standard for a fungible token. It allows to implement anything you want. I'd highlight the features and uses cases of the new standard, that is to let third parties control parts of your tokens.
The recommended implementation of
approve
used incremental allowances to avoid rance conditions and double transfering.
The recommended implementation of approve
uses incremental allowances to avoid race conditions and double transferring.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ran a spell checking now
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I will mention that SIP10 allows your to do basic transfers but the payments is limited or unsafe in the current form.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
improved abstract. Can I include you as a co-author, the Reference implementation if heavily based on your implementation?, although it has some syntax errors still.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I improved the Rationale with 3 current approaches to Compose DeFi that Fails if i am not wrong.
5. The User sign the `example-defi-service` and submits to blockchain. | ||
6. The Dapp _D_ executes `example-defi-service` on-chain, this includes calling `transfer-from` to retrieve the tokens from User and, eventually, forwarding the tokens to a third-party service with `approve`, thus allowing for _Composability_. | ||
|
||
## Backwards Compatibility |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There are SIP-10 token contracts on mainnet like vibe tokens
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What I see is that without allowances you are giving total control to any DeFi service (that only checks tx-sender
) to grab any amount of any of your SIP10 Tokens?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Cool, there are 40 contracts with approve
function, but sometimes they use it for access control or the signature is different, they also include the owner in the signature.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For that we have post conditions @jo-tm
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
only 5 tokens seems to have allowance
or allowance-of
I think the rest uses approve
for Access Control Roles.
|
||
## Backwards Compatibility | ||
|
||
This proposal aims to maintain compatibility with the existing SIP-010 standard while introducing new functionality. Existing fungible token contracts can continue to use the SIP-010 functions without modification. Contracts that wish to utilize allowances and composable fungible tokens can implement the extended trait. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not clear whether SIP-10 tokens that use tx-sender are compatible with this SIP. Could you elaborate?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Initially I wanted to limit the transfer(from, to, amount)
to (transfer (to, amount))
and the sender is always contract-caller
, removing first parameter I kept the from
parameter to maintain compatibility with current approach.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The signature is the same but the security model is not, therefore it is not compatible any more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The current SIP10 Tokens are only compatibles in that they both will work on Leather Wallet using the same transfer(user,recipient,amount)
. Also to use a Single DeFi service, no Composability. If you use transfer
to use a simple DeFi service like current approaches it will work. Not sure what the Stacks Swap Dapps are doing.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
improved backwards compatiblity section
sip-0xx-improve-sip10/sip-0xx-composable-fungible-token-standard.md
Outdated
Show resolved
Hide resolved
|
||
### DeFi Composability Pattern | ||
|
||
The most common DeFi pattern, that is supported by this new standard is: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't see how this can't be done with SIP-10. In 5. the user could also transfer the amount of tokens required for example-defi-service
. Are there blocks between 5. and 6.?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it can be done with SIP10 with transfer
only if tokens check tx-sender
, if lets say DeFiA uses DeFiB and DeFiA transfer your tokens from your wallet to DeFiB. Then you give total control to the DeFiA and also to DeFiB called by DeFiA. Not sure your tokens can be retrieved properly because your tokens are jumping from your wallet to DeFiB.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So, why do we need allowances? Is it only about the issue of tx with allow mode?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if you have DeFiA is a YieldAggregator and DeFiB is a YieldService, then the following 3 current approaches does not work I think:
a) User calls defi-service
from DeFiA.
b) DeFiA does transfer(User,DeFiA)
, good tx-sender.
c) In the same transaction DeFiA cannot do transfer(DeFiA,DefiB)
because the tx-sender is still User.
a) User calls defi-service
from DeFiA.
b) DeFiA does transfer(User,DeFiB)
, good tx-sender directly from User.
c) Incorrect, DeFiB does not supports receiving random token from third parties without calling another-defi-service
from DeFiB.
a) User calls defi-service
from DeFiA.
b) DeFiA does transfer(User,DeFiA)
, good tx-sender.
c) DeFiA calls another-defi-service
from DeFiB.
d) Incorrect, tx-sender is still User, if DeFiB calls transfer(DeFiA,DeFiB)
it has no permission.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In 1. c) DeFiA can use as-contract
to switch context, but needs to be careful. Furthermore, the token can allow transfers where sender is contract-caller OR tx-sender. Then no context switch is necessary.
In 3. c) Similarily, DeFiA can use as-contract
to switch context, but needs to be careful.
In 3. DeFiA could not do b) (transfer tokens from User to DeFiA), but let DeFiB do it in d).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
okey, so the solution for you is to change tx-sender
to local contract by using as-contract
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
sip-0xx-improve-sip10/sip-0xx-composable-fungible-token-standard.md
Outdated
Show resolved
Hide resolved
|
||
The extension of the SIP-010 trait with allowances and the ability to transfer tokens using allowances addresses the limitations of the previous standard. By introducing allowances, users can grant explicit permission for third parties to spend tokens on their behalf, improving the security and composability of DeFi contracts. The inclusion of additional functions from SIP-010 ensures compatibility with existing standards. | ||
|
||
### Limiting Phishing |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is Phishing? Could you elaborate?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I will include more information in the doc.
These days is mainly a Fake Airdrop, read but you probably have alread read it https://www.coinfabrik.com/blog/tx-sender-in-clarity-smart-contracts/
|
||
The new trait should also include the functions defined in SIP-010, including `get-name`, `get-symbol`, `get-decimals`, `get-balance`, `get-total-supply`, and `get-token-uri`. | ||
|
||
## Trait Implementation |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would defined only the newly added functions in the trait. Contracts can implement both the sip-10 trait and this trait.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I though about doing that, but I felt it was better to replace the whole trait altogether to avoid the hazzle of implementing 2 traits and avoid the confusion with tx-sender
that is one of the main points of the SIP. I was afraid that people implement both traits but continue checking tx-sender
and avoding the new functions. From my point of view is easy to do a simpler SIP without the other functions but I was afraid that it will not replace the prev standard.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would defined only the newly added functions in the trait. Contracts can implement both the sip-10 trait and this trait.
Currently, I think I might limit this Improve Proposal to newly added functions, then the market can decide if they want to use allowances or limit to current approach. We can publish Best Practices for SIP10 that should be a combination of: tx-sender OR contract-caller
check, post-conditions. If the main web3 apps do not embrace allowances no one will probably do it.
|
||
Approve an incremental allowance for a specific principal or contract to spend a certain amount of tokens on behalf of the sender. This function is similar to signing a check, granting permission for a third party to make token transfers within the specified limit. This allowance must be incremental (it adds on top of previous allowances) to avoid race condition situations where and `transfer-from` call is executed before the `approve` and then another after the `approve` call. | ||
|
||
#### revoke |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe disallow-contract-caller
like in pox contract
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
seems a bit long, maybe disallow
??
|
||
Transfer a specified amount of tokens from one principal to another using an allowance. The `from` principal must have previously approved the allowance for the `to` principal to transfer tokens on their behalf. This function facilitates composability by allowing third-party transfers within the approved limits. | ||
|
||
#### approve |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe allow-contract-caller
like in pox contract
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
seems too long, what about allow
?
This approach decrease UX, doesn't fix any security issue and creates new ones. When we're talking about tokens (both FT and NFT), the use of |
sip-0xx-improve-sip10/sip-0xx-composable-fungible-token-standard.md
Outdated
Show resolved
Hide resolved
improved backwards compatiblity
certain security model
improved abstract
@LNow thanks for you comment. I improved the Rationale with 3 cases where the current approach for doing a 2-hop DeFi Composability (User using a Yield Aggregator service using a Yield service). The current de-facto approach of checking |
In order to steal any tokens from user first you have to convince him/her to sign a transaction with either no post-conditions at all (aka. TX with With your proposal - all you have to do is convince user to sign TX that will not move any tokens (allowance TX have no side effects). And it is much easier than you might think. When it comes to draining Token Swap platforms, I've covered this topic quite a few times (with some projects). There are ways to build contracts in such way, that it is almost impossible to drain them, and even if it is possible you can limit it to single pair of assets. You just need to understand the security model used in Stacks. In my opinion this proposal tries to bypass this model without bringing any real benefits (from the security standpoint).
IMHO a lot of cons and risks, and no real benefits. |
Post conditions in clarity for |
Can we evolve this SIP to a post about best practices for defi protocols on stacks? |
This line by @LNow gets to the core of the issue. If there SIP were activated and implemented then it will become quite a bit easier to steal tokens. You can either hide a call to |
@MarvinJanssen you cannot call |
That is only possible if you sign a transaction created in
Either you use proper post conditions, or you create TX in |
If the approval checks for contract-caller, then contracts need to use as-contract and are in the same position as with transfer and we haven't won anything. |
Updated: yep, you are right xD got confused. If the user calls contract 1 and contract2 calls tokenA then there is not way checking only |
thanks for comment @LNow, I will research more on
I thinks PCs are a great addendum to security but in case a third-party want to integrate my Web3 service I cannot enforce them to call my service with |
From my personal notes:
Correct. You have no control over how TX that interact with your contract will be created. TX created in |
@jo-tm Can you help me understand why this is a problem? Because Clarity is a decidable language, it's tractable to enumerate all of the halting states of a contract-call's execution. Thus, it's computable which token-transfers could be reached from a contract-call, so your wallet could automatically generate post-conditions for them. Am I missing something? |
@jcnelson I wasn't sure that checking |
While checking Now, do post-conditions today go far enough? No; I think they can be extended to do a lot more. For example, they could be extended to place constraints on who received tokens and NFTs, as well as who sent them. As another example, they could be scoped to only apply to specific contracts, or in specific functions. Both of these extensions are consistent with the intent of PCs -- they empower users to protect themselves from developers. Does any Stacks wallet try to statically analyze the contract call graph in order to generate useful post-conditions? Not that I know of. However, this could be added due to the aforementioned reason that Clarity is decidable. Unlike Solidity, you can know the effects of a transaction before you run it. I think wallets should be in the business of doing this, but that's a topic for another day. |
Something that might be worth to consider is a middle ground between So if I want to swap token |
@jcnelson @LNow I think this is a productive discussion. Something that can also be secure in my opinion is to have post-conditions in Traits, so you implement SIP10 or a trait with something like |
Abstract
This proposal extends the SIP-010 standard trait for fungible tokens on the Stacks blockchain to support composable fungible tokens with allowances. It addresses the limitations of the previous standard, which did not provide sufficient support for composability and security. The new trait includes functions for transferring tokens, approving allowances, checking allowances, and transferring tokens using allowances. The recommended implementation of
approve
used incremental allowances to avoid rance conditions and double transfering.