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

ARC-0012: Standard for Claimable Algorand Standard Assets (ASA) #130

Merged
merged 12 commits into from Apr 19, 2023

Conversation

joe-p
Copy link
Contributor

@joe-p joe-p commented Sep 20, 2022

The goal of this standard is to establish a standard in the Algorand ecosytem by which ASAs can be sent to an intended receiver even if their account is not opted in to the ASA.

If integrated into ecosystem technologies including wallets, explorers, and dApps, this standard can provide enhanced capabilities around ASAs which are otherwise strictly bound at the protocol level to require opting in to be received. This also enables the ability to "burn" ASAs by sending them to the claimable ASA vault associated with the global Zero Address.

@nullun
Copy link
Contributor

nullun commented Sep 21, 2022

I noticed in the TEAL for the subroutines (handle_optin and handle_claim_axfer) that they both contain a duplicate check as their first assert. It's the same condition that was used to enter in the first place. Is this for readability or pre-optimising? Great stuff 👍

@nullun
Copy link
Contributor

nullun commented Sep 21, 2022

Nice work @joe-p and @SilentRhetoric!

What's the reason behind returning the 0.2 Algo to the ASA creator address on redemption of the ASA? If I send USDC to someone who has yet to optin to it, why should Circle get 0.2 Algo when it's claimed? I understand that sending it back to the original sender isn't possible without state, but I'd have thought hardcoding the intended receiver of the ASA would be easier? I think this might also eliminate the need for a smart contract?

Additionally would the 2*MBR requirement only be for the first time the smart signature is used, and subsequent uses only require 0.1 Algo? If I'm nice I'd like to already prefund my address with 0.1 Algo so that all senders would only need to pay 0.1 Algo for the ASA they're choosing to send.

Copy link
Contributor

@barnjamin barnjamin left a comment

Choose a reason for hiding this comment

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

Started taking a pass and looks good.

Most of the comments here are tweaking working and removing any words we can without losing clarity.

ARCs/arc-0012.md Outdated

TEAL stateless smart signature contract accounts corresponding to any Algorand account serve as a claimable ASAs account with logic that permits opting into incoming ASAs and subsequently for only the intended receiver to claim the ASA into their normal account. A single associated stateful application on the network enables a cost--the minimum balance requirement to create an account and hold an ASA--to be refunded to the ASA creator when the asset is claimed by the receiver.

If integrated into ecosystem technologies including wallets, epxlorers, and dApps, this standard can provide enhanced capabilities around ASAs which are otherwise strictly bound at the protocol level to require opting in to be received. This also enables the ability to "burn" ASAs by sending them to the claimable ASAs account associated with the global Zero Address.
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
If integrated into ecosystem technologies including wallets, epxlorers, and dApps, this standard can provide enhanced capabilities around ASAs which are otherwise strictly bound at the protocol level to require opting in to be received. This also enables the ability to "burn" ASAs by sending them to the claimable ASAs account associated with the global Zero Address.
If integrated into ecosystem technologies including wallets, explorers, and dApps, this standard can provide enhanced capabilities around ASAs which are otherwise strictly bound at the protocol level to require opting in to be received. This also enables the ability to "burn" ASAs by sending them to the claimable ASAs account associated with the Zero Address.

ARCs/arc-0012.md Outdated Show resolved Hide resolved
ARCs/arc-0012.md Outdated Show resolved Hide resolved
ARCs/arc-0012.md Outdated Show resolved Hide resolved
ARCs/arc-0012.md Outdated

### TEAL Smart Contracts

There are two smart contracts being used for ARC-0012. A [smart signature](../assets/arc-0012/claimable_lsig.teal) and a [stateful application](../assets/arc-0012/claim_app.teal). In summary, the smart signature is the account used for holding the ASA and handling opt-in and claim logic. The stateful application is used atomically upon claim to ensure the creator of the ASA is paid 0.2 ALGO.
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
There are two smart contracts being used for ARC-0012. A [smart signature](../assets/arc-0012/claimable_lsig.teal) and a [stateful application](../assets/arc-0012/claim_app.teal). In summary, the smart signature is the account used for holding the ASA and handling opt-in and claim logic. The stateful application is used atomically upon claim to ensure the creator of the ASA is paid 0.2 ALGO.
There are two smart contracts specified for ARC-0012:
1. A [smart signature](../assets/arc-0012/claimable_lsig.teal) is the account used for holding the ASA and handling opt-in and claim logic.
2. A [stateful application](../assets/arc-0012/claim_app.teal). is used atomically upon claim to ensure the creator of the ASA is paid 0.2 ALGO.

ARCs/arc-0012.md Outdated

#### Smart Contract (Stateful App)

The application is used to ensure the creator is payed upon ASA claiming. A stateful application must be used to get the creator of the ASA. The application logic is broken down into multiple sections.
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
The application is used to ensure the creator is payed upon ASA claiming. A stateful application must be used to get the creator of the ASA. The application logic is broken down into multiple sections.
The application is used to ensure the creator is refunded upon ASA claiming. A stateful application must be used to get the creator of the ASA. The application logic is broken down into multiple sections.

@joe-p
Copy link
Contributor Author

joe-p commented Sep 21, 2022

What's the reason behind returning the 0.2 Algo to the ASA creator address on redemption of the ASA? If I send USDC to someone who has yet to optin to it, why should Circle get 0.2 Algo when it's claimed? I understand that sending it back to the original sender isn't possible without state, but I'd have thought hardcoding the intended receiver of the ASA would be easier? I think this might also eliminate the need for a smart contract?

There are a couple options with the MBR amount after claim.

Send it back to the sender - As you mentioned, this is not possible right now due to storage limitations.

Give it to receiver - This is not ideal since this could be used to farm ALGO. For example, if a project wants to onboard new users with their ASA someone could make unlimited wallets to farm the 0.2 ALGO and then just opt out of the ASA afterwards.

Leave it locked in the contract - This would result in a lot of ALGO being lost forever

Send to FeeSink/RewardsPool - This makes sense in the context of things like USDCa onboarding from exchanges, but makes airdrops very expensive.

Send it to creator - This makes a lot of sense for token creators airdropping their own tokens as they would eventually get the funds back. For uses like onboarding USDCa it makes less sense, but the cost for the sender is the same as sending to FeeSink/Rewards pool

Additionally would the 2*MBR requirement only be for the first time the smart signature is used, and subsequent uses only require 0.1 Algo? If I'm nice I'd like to already prefund my address with 0.1 Algo so that all senders would only need to pay 0.1 Algo for the ASA they're choosing to send.

Let's say Charlie is new to Algorand and has a 0 ALGO wallet. Alice sends Charlie 1 Alice-Coin for 0.2 ALGO via the claimable ASA account. Then Bob sends Charlie 1 Bob-Coin for 0.1 ALGO via the claimable ASA account. If Charlie wants to claim Alice-Coin, but not Bob-Coin, then he will claim Alice-Coin but only 0.1 ALGO can be sent to Alice since Charlie's claimable ASA account still needs 0.2 ALGO (0.1 ALGO for account MBR, 0.1 ALGO for Alice-Coin). This basically means Alice paid 0.1 ALGO for Charlie to hold Bob-Coin in the claimable account. Since the order of claiming can't be guaranteed, it makes the most sense to make every sender send 0.2 ALGO.

Requiring the user to pre-fund their claimable account adds more friction to the onboarding experience, which is what we're trying to avoid in the first place.

@joe-p
Copy link
Contributor Author

joe-p commented Sep 21, 2022

One concern with the current implementation is that a claimable account could get spammed with unwanted assets. The problem is that if one wanted to get rid of the assets at the protocol-level, they would need to claim the asset which would send the 0.2 ALGO back to the creator meaning there isn't a lot of risk involved in sending spam assets, assuming people would like to keep their claimable ASA account clean.

To counter this, we could implement an alternative action to claiming that the receiver can take. Instead of just being able to claim an ASA to their own personal account, we could make it so the smart signature can burn the token with the ALGO going to the FeeSink/RewardsPool instead of back to the creator. This would add more risk to sending spam assets, because spammers could loose that 0.2 ALGO forever. Thoughts?

@PFunk420
Copy link

One concern with the current implementation is that a claimable account could get spammed with unwanted assets. The problem is that if one wanted to get rid of the assets at the protocol-level, they would need to claim the asset which would send the 0.2 ALGO back to the creator meaning there isn't a lot of risk involved in sending spam assets, assuming people would like to keep their claimable ASA account clean.

To counter this, we could implement an alternative action to claiming that the receiver can take. Instead of just being able to claim an ASA to their own personal account, we could make it so the smart signature can burn the token with the ALGO going to the FeeSink/RewardsPool instead of back to the creator. This would add more risk to sending spam assets, because spammers could loose that 0.2 ALGO forever. Thoughts?

I like this idea. Perhaps there should be 3 options for the receiver:

  1. Accept - ASA goes to receiver, fee goes to creator
  2. Deny and return to creator - ASA and fee both go to creator
  3. Deny and burn - ASA goes to burn, fee goes to FeeSink/RewardsPool

@PFunk420
Copy link

Let's say Charlie is new to Algorand and has a 0 ALGO wallet. Alice sends Charlie 1 Alice-Coin for 0.2 ALGO via the claimable ASA account. Then Bob sends Charlie 1 Bob-Coin for 0.1 ALGO via the claimable ASA account. If Charlie wants to claim Alice-Coin, but not Bob-Coin, then he will claim Alice-Coin but only 0.1 ALGO can be sent to Alice since Charlie's claimable ASA account still needs 0.2 ALGO (0.1 ALGO for account MBR, 0.1 ALGO for Alice-Coin). This basically means Alice paid 0.1 ALGO for Charlie to hold Bob-Coin in the claimable account. Since the order of claiming can't be guaranteed, it makes the most sense to make every sender send 0.2 ALGO.

Doubling the fee for every transaction to be fair to the first person to send to a wallet seems overkill IMO. I think it would be more desirable in the long run to lower overall fees for everyone even if it means "first senders" pay more. The "first sender" .1 Algo only gets paid once per wallet. If I'm doing an airdrop and have to send to 1000 wallets, 800 of which have their contract primed already, and 200 of which have not, I'm still paying overall less for my airdrop.

@joe-p
Copy link
Contributor Author

joe-p commented Sep 21, 2022

Deny and return to creator - ASA and fee both go to creator

The problem is that the creator could be opted out by the time the ASA is returned and there isn't a (easy) way to get the creator's claimable ASA account address on-chain, which would be necessary to ensure the ASA is going to the correct account.

Doubling the fee for every transaction to be fair to the first person to send to a wallet seems overkill IMO. I think it would be more desirable in the long run to lower overall fees for everyone even if it means "first senders" pay more. The "first sender" .1 Algo only gets paid once per wallet. If I'm doing an airdrop and have to send to 1000 wallets, 800 of which have their contract primed already, and 200 of which have not, I'm still paying overall less for my airdrop.

Yeah I can see the argument here. The only thing is that this adds yet another query the wallet will need to do before sending an ASA. Granted this probably isn't a huge deal.

My initial thinking was that sending 0.2 ALGO every time made the cost more predictable, but if you really wanted a predictable cost you could just send 0.2 ALGO for every account regardless if they need the extra .1 ALGO or not.

@jannotti
Copy link
Contributor

Deny and return to creator - ASA and fee both go to creator

The problem is that the creator could be opted out by the time the ASA is returned ...

I'm not sure I followed the entire conversation, but I wanted to point out that creators can not opt out of an ASA they created.

@joe-p
Copy link
Contributor Author

joe-p commented Sep 21, 2022

Deny and return to creator - ASA and fee both go to creator

The problem is that the creator could be opted out by the time the ASA is returned ...

I'm not sure I followed the entire conversation, but I wanted to point out that creators can not opt out of an ASA they created.

Ah ok yeah wasn't sure on that one. In which case I like @PFunk420's idea of having three options

  1. Claim: ASA -> claimer & 0.2 ALGO -> creator
  2. Reject: ASA -> creator & 0.2 ALGO -> creator
  3. Burn: ASA -> burn address & 0.2 ALGO -> FeeSink/RewardPool

ARCs/arc-0012.md Outdated

### Burning Tokens

Additionally, the smart sending tool can be used to burn ASAs by entering the global Zero Address `AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAY5HFKQ` as the intended recipient. The app will automatically re-route the ASA to the unique "UN-claimable" ASAs account corresponding to the Zero Address. An ASA sent here can never be claimed by anyone, rendering the transferred quantity permanently irretrievable and effectively "burned" in a verifiable way.
Copy link
Contributor

@cusma cusma Sep 22, 2022

Choose a reason for hiding this comment

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

So there will 1 Burner Account for 1 ASA?

Reasoning on "ASA irreversible burn" I was inclined to have 1 single "ASA sink", well known in the ecosystem, that could only opt-in into ASA with no Clawback Address, so that anyone would now that is ASA is sent to the known App ID 123 is burned for sure (without having to check the specific burner logic).

WDYT?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

There will be one smart signature that can be used to burn any ASA. To verify how much of an ASA is burned, one would need to simply check the balance of that one account. The logic for this contract will show it is claimable by the zero address AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAY5HFKQ, but since this account cannot send transactions it is considered burnt.

Copy link
Contributor

Choose a reason for hiding this comment

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

Can the bruner address opt-in ASAs with non-null Clawback Address?

Copy link
Contributor

Choose a reason for hiding this comment

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

Yes, but this intent of this ARC is not to neutralize Clawback as a protocol-level feature.

Copy link
Contributor

Choose a reason for hiding this comment

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

I'm not proposing to neutralize it. I'm just trying to understand if the proposed solution guarantees an irreversible burning of ASAs.

Copy link
Contributor

Choose a reason for hiding this comment

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

This solution cannot guarantee that, no. We can add some language to clarify explicitly that it is not possible to permanently burn a clawback-enabled ASA under any circumstances (as far as I am aware). This should help avoid any misunderstanding about the fact that this logicSig mechanism cannot override clawback.

@TTogle
Copy link

TTogle commented Oct 6, 2022

What about a workaround to ASA opt-in if the ASA was created by an App opt-in to the app and opt-in to all assets the escrow creates?

@fernando-deka
Copy link

What would happen if the asset is a Smart Asset ARC-0020 which is frozen by default?

@SilentRhetoric
Copy link
Contributor

What would happen if the asset is a Smart Asset ARC-0020 which is frozen by default?

I think that will require a different solution, as ARC-0020 assets really only exist in the state data of an application. What we are contemplating here would not solve for that; it would probably require a separate proposal.

@joe-p
Copy link
Contributor Author

joe-p commented Oct 14, 2022

Just to provide an update: We are currently working on a new proposal using smart contracts and boxes to allow the MBR to be sent back to the sender.

Basic idea is that a single master contract is called when sending someone an ASA. The master contract then either calls or creates a child contract that holds the ASA(s) for the intended receiver while recording who the sender is and how much the MBR was. The master contract is called when claiming an ASA and the master contract will call the child to trigger an inner transaction that sends the ASA to the end-user.

@spencercap
Copy link

this assumes that the ASA receiver has a bit of $ALGO and is not a completely new acct, yes?

min bal needed being... 0.201 = 0.1 (for existing on-chain) + 0.1 (for holding the asset) + 0.001 (for making the txn)

@github-actions
Copy link

There has been no activity on this pull request for 2 weeks. It will be closed after 3 months of inactivity. If you would like to move this PR forward, please respond to any outstanding feedback or add a comment indicating that you have addressed all required feedback and are ready for a review.

@github-actions github-actions bot added w-stale and removed w-stale labels Nov 11, 2022
@github-actions
Copy link

There has been no activity on this pull request for 2 weeks. It will be closed after 3 months of inactivity. If you would like to move this PR forward, please respond to any outstanding feedback or add a comment indicating that you have addressed all required feedback and are ready for a review.

@github-actions github-actions bot added w-stale and removed w-stale labels Nov 27, 2022
ARCs/arc-0012.md Outdated

##### init_scratch

Initializes scartch variables

Choose a reason for hiding this comment

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

Suggested change
Initializes scartch variables
Initializes scratch variables

@github-actions
Copy link

There has been no activity on this pull request for 2 weeks. It will be closed after 3 months of inactivity. If you would like to move this PR forward, please respond to any outstanding feedback or add a comment indicating that you have addressed all required feedback and are ready for a review.

@github-actions github-actions bot added w-stale and removed w-stale labels Dec 24, 2022
@robdmoore
Copy link

Huge +1 for this, I'm building an experience where users get issued certificates and it would be really handy if I can airdrop them into a "claiming account". It'll make the UX and code way simpler.

What's the current status of this one? It's not entirely clear from the PR.

@joe-p
Copy link
Contributor Author

joe-p commented Jan 19, 2023

The ARC has been updated with information about the latest implementation that uses box storage. The current implementation is likely close to the final version unless major feedback needs to be implemented. Next steps are to consult with wallets and dApps in the ecosystem and then get the code audited.

@fergalwalsh
Copy link

As far as I understand this ARC proposes a specific app will be used as the Master. I think it would be worth clarifying in the spec that a single well known app id will be used. There should be a space in the doc to be updated with the exact ID once it is deployed. In this case also the code provided isn't a reference implementation but the actual only implementation (unlike most other ARCs). This is a great thing in my view but it needs to be made explicit.

@BurnusWolf
Copy link

Hi @joe-p!
I think this ARC is a great idea and makes a lot of sense.
I just have a few concerns for some of the edge-cases that might arise from its implementation. More specifically:

  1. AFAIU, there’ll be 3 options here for the users to handle these requests: Accept | Reject | Destroy.
    In the destroy option, the ASA creator can still claw back the ASA amount, meaning that they’ve actually only lost the 0.1 Algo that gets sent to the FeeSink/RewardPool. This might still not be expensive enough to stop spamming behaviors directed to well-known accounts (i.e. I try to get established ecosystem projects to opt-in to a created ASA so that everyone will think they support that asset).
  2. What happens if the ASA creator claws back the asset amount from the escrow account, before the user accepts it?

@joe-p
Copy link
Contributor Author

joe-p commented Jan 25, 2023

Great point @fergalwalsh I'll update the ARC to reflect the official app ids for respective networks.

@BurnusWolf

AFAIU, there’ll be 3 options here for the users to handle these requests: Accept | Reject | Destroy.
In the destroy option, the ASA creator can still claw back the ASA amount, meaning that they’ve actually only lost the 0.1 Algo that gets sent to the FeeSink/RewardPool. This might still not be expensive enough to stop spamming behaviors directed to well-known accounts (i.e. I try to get established ecosystem projects to opt-in to a created ASA so that everyone will think they support that asset).

Just to clarify, claim and reject are the only two options for the end-user. Reject does what you seem to be describing for destroy.

I agree, 0.1 ALGO isn't a significant mitigation for targeted spam, but I would argue that people should not consider ASAs in a vault to represent the desired ASAs of the end-user since the ASAs can't be transfered or utilized until they are claimed by the end-user. Also, since rejecting is completely free, one could create a off-chain filter that automatically rejects specific assets.

What happens if the ASA creator claws back the asset amount from the escrow account, before the user accepts it?

This is a good question that I've been thinking about recently after someone recently brought it up in a meeting. In the current implementation, the end-user would still have to claim/reject the asset even if the balance was zero. If the balance is zero, it would make sense for front-ends to only allow rejects which are free for the end-user. I'm curious if anyone can come up with additional concerns regarding clawbacks...

@emg110
Copy link

emg110 commented Jan 25, 2023

Even after the update and use of the new APPLICATION VAULT approach and using boxes (great idea by the way!) is KNOWING THE USER ACCOUNT ADDRESSES still a requirement to send arc12 ASAs? I mean do target accounts need to exist and addresses known before ASA distribution?

@joe-p
Copy link
Contributor Author

joe-p commented Jan 25, 2023

@emg110 It depends on what you mean by "exist". The account doesn't need to be on the ledger (can have 0 ALGO), but you do need to know the address to reserve the ASA for that particular account.

For example, if an app is onboarding a new user, they must do keypair generation to get the address, but the account doesn't actually need to be funded until they are ready to claim the ASA.

@github-actions
Copy link

github-actions bot commented Feb 9, 2023

There has been no activity on this pull request for 2 weeks. It will be closed after 3 months of inactivity. If you would like to move this PR forward, please respond to any outstanding feedback or add a comment indicating that you have addressed all required feedback and are ready for a review.

@github-actions github-actions bot added w-stale and removed w-stale labels Feb 9, 2023
@github-actions
Copy link

There has been no activity on this pull request for 2 weeks. It will be closed after 3 months of inactivity. If you would like to move this PR forward, please respond to any outstanding feedback or add a comment indicating that you have addressed all required feedback and are ready for a review.

@github-actions github-actions bot added w-stale and removed w-stale labels Feb 25, 2023
@github-actions
Copy link

There has been no activity on this pull request for 2 weeks. It will be closed after 3 months of inactivity. If you would like to move this PR forward, please respond to any outstanding feedback or add a comment indicating that you have addressed all required feedback and are ready for a review.

Co-authored-by: Ben Guidarelli <ben.guidarelli@gmail.com>
@github-actions github-actions bot removed the w-stale label Mar 14, 2023
@github-actions
Copy link

There has been no activity on this pull request for 2 weeks. It will be closed after 3 months of inactivity. If you would like to move this PR forward, please respond to any outstanding feedback or add a comment indicating that you have addressed all required feedback and are ready for a review.

@github-actions github-actions bot added w-stale and removed w-stale labels Mar 28, 2023
@SudoWeezy SudoWeezy merged commit 794a93b into algorandfoundation:main Apr 19, 2023
4 of 5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet