Skip to content
This repository was archived by the owner on Mar 11, 2025. It is now read-only.

Allow native SOL to be represented as a token #67

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions token/src/instruction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,24 @@ pub enum TokenInstruction {
/// 2. `[writable]` Token being burned.
/// 3. Optional: `[writable]` Source account if key 1 is a delegate account.
Burn(u64),

/// Initialize a wrapped SOL token account. The full SOL balance in the uninitialized account
/// will be wrapped.
///
/// The `InitializeWrappedAccount` instruction requires no signers and MUST be included within
/// the Transaction that creates the uninitialized account with the system program. Otherwise
/// another party can acquire ownership of the uninitialized token account.
///
/// 0. `[writable]` An uninitialized token account
/// 1. `[]` Initial owner for the token account.
///
InitializeWrappedAccount,

/// Deallocate and release all native SOL held by a token account
/// 0. `[signer]` Owner of the token account.
/// 1. `[writable]` Token account to release.
/// 2. `[writable]` Destination account to receive the full SOL balance of the account.
ReleaseAccount,
Copy link
Contributor Author

Choose a reason for hiding this comment

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

ReleaseAccount works for non-wrapped token accounts as well, and thus is effectively a replacement for Burn(u64) but also:

  1. Prevents a zero-balance token account that floats around forever
  2. Assumes that we'll redefine the supply field according to Add rent awareness to spl-token #66 (comment) such that it never decreases

Copy link
Contributor

Choose a reason for hiding this comment

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

If we don't have the requirement to partial burn tokens from an account then we should remove the burn instruction :-)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yeah, totally agree! And you can still do a partial burn by transferring to a new token account then ReleaseAccounting it.

Copy link
Contributor

Choose a reason for hiding this comment

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

Though that is a two-step process (one transaction), will have a performance impact depending on how fast folks want to burn stuff

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I feel this is unlikely to be an issue, but let's see what comes out of that slack thread.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ok fine, no changes to Burn since partial burns seem to be a little popular.

For a normal non-wrapped token, we could:

  1. Consider ReleaseAccount to also act as a full Burn
  2. Require the non-wrapped token have a zero token balance before ReleaseAccount can be called on it
  3. Only allow ReleaseAccount on wrapped tokens, which means a rent-exempt non-wrapped token account will always live forever.

I prefer 1.

Copy link
Contributor

Choose a reason for hiding this comment

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

I prefer 1 also

}
impl TokenInstruction {
/// Deserializes a byte buffer into an [TokenInstruction](enum.TokenInstruction.html)
Expand Down
1 change: 1 addition & 0 deletions token/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,4 @@ pub mod instruction;
pub mod option;
pub mod processor;
pub mod state;
pub mod native_token;
3 changes: 3 additions & 0 deletions token/src/native_token.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@

/// The token type for wrapped native SOL
solana_sdk::declare_id!("So11111111111111111111111111111111111111111");
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's no Mint account for wrapped SOL. But the Account::token value is set to So11111111111111111111111111111111111111111 so that the Transfer instruction can do the right thing if it's wrapped and for RPC inspection.