Giter Club home page Giter Club logo

solana-program-library's Introduction

Solana Program Library

The Solana Program Library (SPL) is a collection of on-chain programs targeting the Sealevel parallel runtime. These programs are tested against Solana's implementation of Sealevel, solana-runtime, and some are deployed to Mainnet Beta. As others implement Sealevel, we will graciously accept patches to ensure the programs here are portable across all implementations.

For more information see the SPL documentation and the Token TypeDocs.

Deployments

Only a subset of programs within the Solana Program Library repo are deployed to the Solana Mainnet Beta. Currently, this includes:

Program Version
token 3.4.0
associated-token-account 1.1.0
token-2022 1.0.0
governance 3.1.0
stake-pool 1.0.0
account-compression 0.1.3
shared-memory 1.0.0
feature-proposal 1.0.0
name-service 0.3.0
memo 3.0.0

In addition, one program is planned for deployment to Solana Mainnet Beta:

Program Version
single-pool 1.0.1

Audits

Only a subset of programs within the Solana Program Library repo are audited. Currently, this includes:

Program Last Audit Date Version
token 2022-08-04 (Peer review) 4fadd55
associated-token-account 2022-08-04 (Peer review) c00194d
token-2022 2023-11-03 e924132
stake-pool 2023-12-31 a17fffe
account-compression 2022-12-05 6e81794
shared-memory 2021-02-25 b40e0dd
single-pool 2024-01-02 ef44df9

All other programs may be updated from time to time. These programs are not audited, so fork and deploy them at your own risk. Here is the full list of unaudited programs:

More information about the repository's security policy at SECURITY.md.

The security-audits repo contains all past and present program audits.

Program Packages

Package Description Version Docs
spl-token ERC20-like token program on Solana Crates.io Docs.rs
spl-token-2022 Token program compatible with spl-token, with extensions Crates.io Docs.rs
spl-associated-token-account Stateless protocol defining a canonical "associated" token account for a wallet Crates.io Docs.rs
spl-governance DAO program using tokens for voting Crates.io Docs.rs
spl-account-compression Program for managing compressed accounts stored in an off-chain merkle tree Crates.io Docs.rs
spl-feature-proposal Program using tokens to vote on enabling Solana network features Crates.io Docs.rs
spl-noop Program that does nothing, used for logging instruction data Crates.io Docs.rs
spl-memo Program for logging signed memos on-chain Crates.io Docs.rs
spl-name-service Program for managing ownership of data on-chain Crates.io Docs.rs
spl-shared-memory Program for sharing data between programs Crates.io Docs.rs
spl-stake-pool Program for pooling stake accounts, managed by another entity Crates.io Docs.rs
spl-instruction-padding Program to padding to other instructions Crates.io Docs.rs
spl-concurrent-merkle-tree Library for on-chain representation of merkle tree Crates.io Docs.rs
spl-math Library for on-chain math Crates.io Docs.rs
spl-token-lending Over-collateralized lending program for tokens Crates.io Docs.rs
spl-token-swap AMM for trading tokens Crates.io Docs.rs
spl-token-upgrade Protocol for burning one token type in exchange for another Crates.io Docs.rs

CLI Packages

Package Description Version
spl-token-cli CLI for the token, token-2022, and associated-token-account programs Crates.io
spl-stake-pool-cli CLI for the stake-pool program Crates.io
spl-feature-proposal-cli CLI for the feature-proposal program Crates.io
spl-token-lending-cli CLI for the token-lending program Crates.io
spl-token-upgrade-cli CLI for the token-upgrade program Crates.io

JavaScript Packages

Package Description Version Docs
@solana/spl-token Bindings for the token, token-2022, and associated-token-account programs npm Docs
@solana/spl-governance Bindings for the governance program npm N/A
@solana/spl-account-compression Bindings for the account-compression program npm Docs
@solana/spl-memo Bindings for the memo program npm N/A
@solana/spl-name-service Bindings for the name-service program npm N/A
@solana/spl-stake-pool Bindings for the stake-pool program npm N/A
@solana/spl-token-lending Bindings for the token-lending program npm N/A
@solana/spl-token-swap Bindings for the token-swap program npm N/A

Development

Environment Setup

  1. Install the latest Solana tools.
  2. Install the latest Rust stable. If you already have Rust, run rustup update to get the latest version.
  3. Install the libudev development package for your distribution (libudev-dev on Debian-derived distros, libudev-devel on Redhat-derived).

Build

Build on-chain programs

# To build all on-chain programs
$ cargo build-sbf

# To build a specific on-chain program
$ cd <program_name>/program
$ cargo build-sbf

Build clients

# To build all clients
$ cargo build

# To build a specific client
$ cd <program_name>/cli
$ cargo build

Test

Unit tests contained within all projects can be run with:

$ cargo test      # <-- runs host-based tests
$ cargo test-sbf  # <-- runs BPF program tests

To run a specific program's tests, such as SPL Token:

$ cd token/program
$ cargo test      # <-- runs host-based tests
$ cargo test-sbf  # <-- runs BPF program tests

Integration testing may be performed via the per-project .js bindings. See the token program's js project for an example.

Common Issues

Solutions to a few issues you might run into are mentioned here.

  1. Failed to open: ../../deploy/spl_<program-name>.so

    Update your Rust and Cargo to the latest versions and re-run cargo build-sbf in the relevant <program-name> directory, or run it at the repository root to rebuild all on-chain programs.

  2. Error while loading shared libraries. (libssl.so.1.1)

    A working solution was mentioned here. Install libssl.

    wget http://nz2.archive.ubuntu.com/ubuntu/pool/main/o/openssl/libssl1.1_1.1.1l-1ubuntu1.2_amd64.deb
    sudo dpkg -i libssl1.1_1.1.1l-1ubuntu1.2_amd64.deb
  3. CPU or Memory usage at 100%

    This is to be expected while building some of the programs in this library. The simplest solution is to add the --jobs 1 flag to the build commands to limit the number of parallel jobs to 1 and check if that fixes the issue. Although this will mean much longer build times.

Clippy

$ cargo clippy

Coverage

$ ./coverage.sh  # Help wanted! Coverage build currently fails on MacOS due to an XCode `grcov` mismatch...

MacOS

You may need to pin your grcov version, and then rustup with the apple-darwin nightly toolchain:

$ cargo install grcov --version 0.6.1
$ rustup toolchain install nightly-x86_64-apple-darwin

Release Process

SPL programs are currently tagged and released manually. Each program is versioned independently of the others, with all new development occurring on master. Once a program is tested and deemed ready for release:

Bump Version

  • Increment the version number in the program's Cargo.toml
  • Run cargo build-sbf <program> to build binary. Note the location of the generated spl_<program>.so for attaching to the Github release.
  • Open a PR with these version changes and merge after passing CI.

Create Github tag

Program tags are of the form <program>-vX.Y.Z. Create the new tag at the version-bump commit and push to the solana-program-library repository, eg:

$ git tag token-v1.0.0 b24bfe7
$ git push upstream --tags

Publish Github release

  • Go to GitHub Releases UI
  • Click "Draft new release", and enter the new tag in the "Tag version" box.
  • Title the release "SPL vX.Y.Z", complete the description, and attach the spl_<program>.so binary
  • Click "Publish release"

Publish to Crates.io

Navigate to the program directory and run cargo package to test the build. Then run cargo publish.

Disclaimer

All claims, content, designs, algorithms, estimates, roadmaps, specifications, and performance measurements described in this project are done with the Solana Labs, Inc. (โ€œSLโ€) best efforts. It is up to the reader to check and validate their accuracy and truthfulness. Furthermore nothing in this project constitutes a solicitation for investment.

Any content produced by SL or developer resources that SL provides, are for educational and inspiration purposes only. SL does not encourage, induce or sanction the deployment, integration or use of any such applications (including the code comprising the Solana blockchain protocol) in violation of applicable laws or regulations and hereby prohibits any such deployment, integration or use. This includes use of any such applications by the reader (a) in violation of export control or sanctions laws of the United States or any other applicable jurisdiction, (b) if the reader is located in or ordinarily resident in a country or territory subject to comprehensive sanctions administered by the U.S. Office of Foreign Assets Control (OFAC), or (c) if the reader is or is working on behalf of a Specially Designated National (SDN) or a person subject to similar blocking or denied party prohibitions.

The reader should be aware that U.S. export control and sanctions laws prohibit U.S. persons (and other persons that are subject to such laws) from transacting with persons in certain countries and territories or that are on the SDN list. Accordingly, there is a risk to individuals that other persons using any of the code contained in this repo, or a derivation thereof, may be sanctioned persons and that transactions with such persons would be a violation of U.S. export controls and sanctions law.

solana-program-library's People

Contributors

2501babe avatar alexanderray avatar arrowana avatar atharmohammad avatar buffalojoec avatar criesofcarrots avatar dankelleher avatar dependabot-preview[bot] avatar dependabot[bot] avatar dmakarov avatar eventhorizonpl avatar garious avatar jackcmay avatar joeaba avatar jon-chuang avatar joncinque avatar jordaaash avatar jstarry avatar mvines avatar ngundotra avatar ochaloup avatar paul-schaaf avatar ryoqun avatar samkim-crypto avatar sebastianbor avatar t-nelson avatar tonton-sol avatar wjthieme avatar yihau avatar ysavchenko avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

solana-program-library's Issues

token: Simplify InitializeMint instruction

  1. Remove amount: u64 argument. Instead the user can issue a MintTo instruction immediately after InitializeMint. This allows the removal of the first account key
  2. Remove the second account key. The supply can be fixed by issuing a SetAuthority(AuthorityType::MintTokens, None) instruction after MintTo

These changes have no affect on expressibility and will reduce a number of branches from InitializeMint

Token init instructions don't check if accounts are signers

Problem

A bad client might issue the "create account" and "init mint" in separate transactions. An attacker could front run and initialize the mint with themselves as owner and the original creator might not realize this. Then, the attacker could mint tokens whenever they please

This is applies to init multisig and init token account as well

Suggested Fix

Reject init instructions if initialized account is not a signer

token-swap: Include token A and B pubkeys in `create_program_address` creation

Problem

In the js client and processor, when creating and validating the program address to be used by the swap account, we only include the swap account's public key as a seed. This could create a situation in which we have multiple swap accounts and pool tokens to cover swaps from A to B, which would create arbitrage opportunities, along with a confusing user experience.

Solution

Include the token pubkeys as seeds in create_program_address. Also, the token pubkeys should be sorted deterministically (perhaps just alphabetically) in order to avoid having two separate swap accounts for A/B and B/A. I considered also including the pool token as a seed, but that wouldn't solve the problem, since anyone could just mint a new pool token and create a new token swap account for an existing pair.

Token test script fails against devnet

https://travis-ci.org/github/solana-labs/solana-program-library/builds/694862433

Run test: loadTokenProgram
Connection to cluster established: http://devnet.solana.com { 'solana-core': '1.2.1 56e8319a' }
Loading Token program...
Error: failed to send transaction: Transaction simulation failed: TransactionError::BlockhashNotFound
    at Connection._callee31$ (/home/travis/build/solana-labs/solana-program-library/token/node_modules/@solana/web3.js/src/connection.js:1437:13)
    at tryCatch (/home/travis/build/solana-labs/solana-program-library/token/node_modules/@babel/runtime/node_modules/regenerator-runtime/runtime.js:45:40)
    at Generator.invoke [as _invoke] (/home/travis/build/solana-labs/solana-program-library/token/node_modules/@babel/runtime/node_modules/regenerator-runtime/runtime.js:271:22)
    at Generator.prototype.<computed> [as next] (/home/travis/build/solana-labs/solana-program-library/token/node_modules/@babel/runtime/node_modules/regenerator-runtime/runtime.js:97:21)
    at asyncGeneratorStep (/home/travis/build/solana-labs/solana-program-library/token/node_modules/@babel/runtime/helpers/asyncToGenerator.js:3:24)
    at _next (/home/travis/build/solana-labs/solana-program-library/token/node_modules/@babel/runtime/helpers/asyncToGenerator.js:25:9)
    at processTicksAndRejections (internal/process/task_queues.js:97:5)
The command "npm run start --prefix token" exited with 0.

Developers not familiar with node/js frustrated by it being required to build programs

Reisen from Chrous One provided the following feedback (continued from https://github.com/solana-labs/solana-com/issues/390)

  1. Opening both of these have decent README's but include a lot of web stuff, where I only want to build a contract.
  2. Looking at build:bpf-rust to see how I can create a new project with JUST the BPF compilation step lands me here: https://github.com/solana-labs/example-tictactoe/tree/master/program-bpf-rust
  3. I see do.sh, realise I need node/npm installed, and that this script runs a script located under node_modules.
  4. I didn't want to dig further.

At this point I just cd'd into the C BPF folder and ran make and embraced the darkness of C.

The only dependency required to build the program is the bpf-sdk which node currently downloads, we could obtain the bpf-sdk other ways and give developers a non-node path to program development. For end-to-end testing/development, the client is still based on Solana-web3.js which requires node/js

token: move program2/ into program/.

The current user of program/ has agreed to upgrade to program2/, so we don't need to keep the old program/ around anymore.

We can save program2/ for the next token upgrade

No mechanism for freezing token accounts

An authority may want the ability to "freeze" specific accounts.

Add a new authority to the mint and a new flag in accounts. The authority is able to toggle that flag. Setting the flag to "frozen" disables the account owner and delegate's authority.

token: Reconsider unsafe usage for instruction pack/unpack

The use of unsafe typecasting in instruction pack/unpack significantly reduces the instruction count over alternatives but is also scary to look at and is more likely it contain bugs (or have bugs accidentally introduced). Further this is not a general pattern we want to see in all Solana contracts.

Consider alternatives that either make the unsafe go away entire, or pushes the unsafe into macros or generic libraries where the possibility of human error is reduced.

Add rent awareness to spl-token

Current spl-token is completed rent unaware, which leads to a couple problems:

  1. If the Token account is not rent-exempt,
    pub struct Token {
    /// The total supply of tokens.
    pub info: TokenInfo,
    /// Optional token owner, used to mint new tokens. The owner may only
    /// be provided during token creation. If no owner is present then the token
    /// has a fixed supply and no further tokens may be minted.
    pub owner: COption<Pubkey>,
    }
    and if it's rent collected then all the basic information about the token is lost, as well as the ability to mint new tokens or burn existing tokens
  2. If the Account account is not rent-exempt,
    pub struct Account {
    /// The type of token this account holds.
    pub token: Pubkey,
    /// Owner of this account.
    pub owner: Pubkey,
    /// Amount of tokens this account holds.
    pub amount: u64,
    /// If `delegate` is None, `amount` belongs to this account.
    /// If `delegate` is Option<_>, `amount` represents the remaining allowance
    /// of tokens this delegate is authorized to transfer from the `source` account.
    pub delegate: COption<AccountDelegate>,
    }
    and if it's rent collected then the supply field in the Token account is now wrong.

(1) is probably not a big issue, but (2) certainly is.

Possible solution:
a) Require the Token account to be rent-exempt
b) Remove the supply field from Token account so that an Account account that is not rent-exempt cannot poison the supply. This increases the burden on Rpc and other clients, as the token supply must now be calculated by enumerating all the Account accounts for a given token

No way track how long a the user has held a balance

Problem

Token's are a great way to implement a voting system. For the system to work we need a "hold" time component as well.

Solution

Add a instruction that sets the current slot

  • InitializeHODLSlot

Any withdrawals reset the HODLSlot to None.

A vote program can then generate a ballot from a checkpoint of the tokens balance, and the HODLSlot. To Vote the same token must be presented with the ballot with its HODLSlot set to the expected value.

tag: @jackcmay @CriesofCarrots

[spl-token] Transfer method ignores signers if authority is an account

Problem

The transfer method accepts authority as a public key or an account. If it is an account, it does not sign with all accounts in multiSigners

async transfer(
source: PublicKey,
destination: PublicKey,
authority: Account | PublicKey,
multiSigners: Array<Account>,
amount: number | u64,
): Promise<?TransactionSignature> {
let ownerPublicKey;
let signers;
if (authority instanceof Account) {
ownerPublicKey = authority.publicKey;
signers = [authority];
} else {
ownerPublicKey = authority;
signers = multiSigners;
}

Proposed Solution

  • Only accept authority as an account and use multiSigners consistently

Missing smart contracts example

Problem

Solana distinguishes programs from smart contracts, but the SPL doesn't contain an example of that.

Proposed Solution

Add Budget from the Solana repo.

Token program doesn't need to take a destination account when creating a new token

The NewToken instruction expects a destination account that accepts the newly minted tokens. But for mintable tokens (non-fixed supply) the initial supply could be zero with the expectation that tokens will be minted later via MintTo. In that case, no destination account is necessary.

Proposed changes:

  • Change the NewToken instruction to not expect a destination account if supply is zero
  • If the initial supply is zero the owner account will be mandatory.

cbindgen outputs different headers for same source

Running the following in a loop produces different versions of token.h occasionally:

rm token/program/inc/token.h
SPL_CBINDGEN=1 ./do.sh build-lib token -D warnings

The ci check to catch header changes has been disabled: #262

token-swap: Initialize number of pool tokens at geometric mean of provided accounts

Problem

This actually contains two problems with one solution. When a new token-swap is initialized between token A and B, we assume that the two token accounts have the same quantity without doing a check: https://github.com/solana-labs/solana-program-library/blob/master/token-swap/program/src/processor.rs#L195

Solution

The simplest solution would be to add a check to make sure that token_a.amount == token_b.amount and keep the code as is, but even better would be to use the geometric mean of the two provided accounts, ie. sqrt(token_a.amount * token_b.amount). This is recommended by Uniswap v2 in the whitepaper https://uniswap.org/whitepaper.pdf section 3.4, to protect the intializer of the swap in the case where the initial provided amounts are off the market.

Other token accounts can be mistaken for multisig accounts

Problem

Accounts are determined to be multisig if their data size equals the size of a multisig account. There is no restriction on non-multisig accounts that they must not equal the size of a multisig account so other token account types could be mistaken as a multisig account if they are big enough and are set as a token account owner

Doesn't seem likely that this would happen in practice, but if it did, it could result in an owner account that has always passes the owner validation check if m is 0.

Proposed Change

  • Assert that token account types are different sizes
  • Require token accounts to have a specific size

Separate Cargo.lock per program

Problem

The separate Cargo.lock per program will mean we can't share lib dependencies. For example, if the Token program wants to include a Memo, it should add spl-memo as a dependency, but if it does that while there's a Cargo.lock file, all those dependencies will need to match perfectly.

Proposed solution

Add a top-level Cargo.toml and Cargo.lock, delete the nested ones

spl-token does not permit transfers to itself

It's useful to transfer funds to yourself during testing. We added this support recently to system transfers, and should do the same for spl-token.

Example failure:

$ spl-token transfer 5jYj95QRJt5KSvS3naU7vMDnaNT2aXzacyY2waRdJwCg 1 5jYj95QRJt5KSvS3naU7vMDnaNT2aXzacyY2waRdJwCg
Transfer 1 tokens
  Sender: 5jYj95QRJt5KSvS3naU7vMDnaNT2aXzacyY2waRdJwCg
  Recipient: 5jYj95QRJt5KSvS3naU7vMDnaNT2aXzacyY2waRdJwCg
rpc request error: RPC Error response: {"code":-32002,"message":"Transaction simulation failed: Error processing Instruction 0: custom program error: 0xb9f0002"}

token: require all token accounts be rent-exempt and restore total supply field in the mint

We lost the total supply field in the mint when we realized that if token accounts aren't created rent-exempt, they could just disappear and cause the total supply to be inflated.

However we've failed to discover a compelling reason to permit non-rent-exempt token accounts. Additionally with the new CloseAccount instruction, you can reclaim your SOL from a token account at any time.

Requiring rent exemption also simplifies wallets and other token clients, as they no longer need to be considered about a token account disappearing because it was underfunded, either by accident or maliciously.

Tokens can be initialized with invalid mint accounts

Problem

InitializeAccount doesn't check if mint_info is valid (exists, initialized, and owned by token program) and so tokens can be created with invalid mints. These token accounts are useless because without a valid mint, they can never hold a token balance.

Suggested Changes

  • For developer experience, we should fail fast on token creation to avoid later confusion when token accounts are attempted to be minted to.
  • Consider forcing mint accounts rent exempt so that token accounts are always valid

SPL is hogging CI resources

Problem

A couple dependabot PR's on this repo is all it takes to get the solana CI queue backed up to 50+ tasks

Proposed Solution

Switch to Github actions

Token account delegation is expensive, requiring three steps and two accounts.

Token delegation is one way that an account owner can give authority to a program to issue transfer instructions.

Token account delegation requires three steps

  • Allocate a new account via 'System' program
  • Issue TokenInstruction::NewAccount to create the delegate token account
  • issue 'TokenInstruction::Approve' to approve the delegate

Using a delegate requires both the delegate and the original source account to be present when performing a transfer. This gets especially painful for programs like token-swap that perform transfers from multiple accounts

Delegation accounts also have a typically short lifespan and there is not defund instruction to reclaim any lamports held in them. If they are included in the rent exemption enforcement being proposed there should probably be a defund instruction, though that adds another step to the delegation process.

Delegation could be reduced to a simple step and single account if the token account itself held one delegation public key and amount. If all of the amount is transferred delegation ends or if a new delegation instruction is issued it would replace any existing delegation. Canceling delegation could also occur by specifying the primary owner in a delegate instruction.

Single-step delegation would also be more conducive to transactions performing an atomic delegation and operation transaction.

Token program should support to tokens with unlimited supply

Currently, the total supply of tokens is created upon the NewToken instruction. But there are some tokens that require an unlimited supply and the ability to mint new tokens at any time (BRRR).

One suggestion is that at token creation time, an admin key is stored in the token account. Only the admin key can then invoke a Mint instruction to create new supply, perhaps with another instruction to replace the admin key

Upgrading to latest solana-bpf-loader-program is incompatible with token program

Building the token program requires the program feature when building the Solana SDK, but the latest solana-bpf-loader-program depends on the full Solana SDK for things like Transaction and Signature. These dependencies were added while supporting cross-program invocations.

The Token program's benches were removed due to this conflict when the Token program upgraded to Solana SDK 1.2.

The token program's benches need to be added back

token: non-fungible and semi-fungible proposal

spl-token currently only supports fungible tokens. With some minor tweaks it can also support non-fungible and semi-fungible tokens.

Proposed changes:

  1. Each Token Account has an additional field: item: u64
  2. Transfer instruction now only permits the transfer between (a) source and destination token accounts with the same item, or (b) a destination token account with an amount of 0, which point the destination item is overwritten by the source token account's item
  3. Approve/Revoke/SetOwner/CloseAccount are item agnostic
  4. MintTo is expanded to include an item field. The destination account to mint into must either (a) have the same item field or (b) an amount of 0, which point the destination item is overwritten by the MintTo's item field

Note: this description assumes #308 has been implemented.

Fungible Minting

Use existing workflow, always MintTo with an item of 0 (by convention all fungible tokens should not mint tokens with an item other than 0)

Non-Fungible Minting

  1. InitializeMint { decimals: 0, .. } <-- init the collection (no fractional items)
  2. MintTo { amount: 1, item: 0 } <-- create the first item
  3. MintTo { amount: 1, item: 1 } <-- create the second item
  4. MintTo { amount: 1, item: 2 } <-- create the third item
  5. SetAuthority(AuthorityType::MintTokens, None) <-- no more items may be minted

A separate MintTo instruction for each item feels heavy handed, but I don't see a better way. The associated SystemInstruction::CreateAccount and InitializeAccount instructions are not shown but are also required before each MintTo

To send one NFT to another party:

  1. SetOwner the token account to them
  2. Transfer into their token account. Destination account which must be initialized with an amount of 0

Semi-Fungible Minting

  1. InitializeMint { decimals: 0, .. } <-- init the collection (no fractional items)
  2. MintTo { amount: 10, item: 0 } <-- create 10 of the first item
  3. MintTo { amount: 1, item: 1 } <-- create 1 of the second item
  4. MintTo { amount: 100, item: 2 } <-- create 100 of the third item
  5. SetAuthority(AuthorityType::MintTokens, None) <-- no more items may be minted

To send Semi-Fungible Tokens to another party:

  1. SetOwner the token account to them, which will transfer the full amount of your item.
  2. Transfer one or more of your items into their token account. Destination account which must be initialized with an amount of 0, or already hold one or more items of the same item.

token: Consider adding an expected decimals input to all token instructions that deal with an amount

The user of a token program, such as a generic wallet or the spl-token command-line, doesn't generically have trusted way to determine the correct decimals value for a given token. RPC will tell it, but maybe RPC is lying. The user might know and can provide it, but maybe they are mistaken.

As a safety/sanity check, if the decimals are provided as input into each instruction alongside the amount, the program itself can confirm the decimals are correct before performing the operation.

Reorganize source tree layout based on program version

The current program source layout is inadequate for working on newer version of a SPL program while maintaining the existing deployed versions.

Proposal is to refactor up the current token/ directory into:

token-1.0/  <-- represents the 1.0.0 token that has already been deployed to mainnet-beta
token-dev/ <-- the 1.1.0 token that will be deployed sometime in the future.

When token-dev/ is ready to be deployed, it's copied into token-1.1/ and then token-dev/ moves up to "1.2.0".

The benefit of this approach is a clear representation of the on-chain source code for a given token version while retaining the ability to ship new patch releases for each token crate. Of course since token 1.0.0 program is deployed, it can't be changed but the client portion of the 1.0.0 token may still need to change from time to time (such as if we ship a breaking change in the solana-sdk crate).

The same model applies to the other SPL programs. For token-swap there would only be a token-swap-dev since 1.0.0 has not shipped yet.

token-swap: re-enable CI tests

Once solana-labs/solana#11745 lands and ships in a Solana 1.3 release, restore the token-swap tests:

# TODO: Remove once "Undefined symbols for architecture x86_64: _sol_create_program_address" is resolved
_ echo "SKIPPED token-swap test due to: Undefined symbols for architecture x86_64: _sol_create_program_address"

and
# TODO: Uncomment once https://github.com/solana-labs/solana/issues/11465 is resolved
# npm run cluster:localnet
# npm run localnet:down
# npm run localnet:update
# npm run localnet:up
# npm run start
# npm run localnet:down

Token Multisignature Support

Downstream users would like to be able to ultilize multisignature on Token Accounts. A Multisig program would be an option down the road, when cross-program invocations are enabled.
In the meantime, the shortest path seems to be to add M-of-N multisig support in Token.

Instead of just one account owner, enable configuration of each Token account to have N authorities (1 <= N <= 11) and M required signers for transfers and updates to authorities and num-required-signers.

Provide token program cross-program-invocation wrappers

Could use a trait object:

    pub fn token_transfer(                                                                            
        &self,
        accounts: &[AccountInfo],                                                                     
        token: &Pubkey,
        destination: &Pubkey,                                                                         
        amount: u64,
    ) -> Result<(), ProgramError> {
        let swap_string = self.self_pubkey.to_string();                                               
        let signers = &[&[&swap_string[..32]][..]];                                                   
        let ix = spl_token::instruction::transfer(                                                    
            self.token_program,                                                                       
            self.authority,                                                                           
            token,
            destination,                                                                              
            amount,                                                                                   
        )?;
        invoke_signed(&ix, accounts, signers)                                                         
    } 

do.sh build all doesn't strip .so files

Because targetDir is defined outside perform_action, it keeps the positional argument $2 from the original command. In the case of ./do.sh build all, this is all. Therefore this check fails:

if [ -f "$so_path/${so_name}.so" ]; then

because ~/solana-program-library/all/target/bpfel-unknown-unknown/release does not exist.

token: add a new metadata address to the end of the Mint account

Clients dealing with a token generically need to find metadata about that token: name, icon, web presence of the issuer, etc. The various ERC token standards have a lot to say about this, we can probably reuse most/all of those specs

However in the token2 timeframe, we don't need to actually define what the metadata is. This can come later. For token2, we just need a reserve place in the Mint to hold the details about how to locate the metadata.

Proposal:

  1. Add the field metadata_authority: COption<Pubkey> to the end of the Mint account
  2. New metadata_authority parameter to the InitializeMint instruction
  3. New AuthorityType for metadata
  4. Support for changing the metadata address through SetAuthority

A couple possible metadata implementations (to be fully designed later):
a) The metadata_authority points to an account with inline CBOR data describing the token's metadata
b) The metadata_authority points to an account with an https/ipfs URL to the token's metadata

token-swap: Consider having all pairs go through SOL

Problem

With a proliferation of SPL tokens, creating all possible cross-pairs on token-swap could mean liquidity is very spread out, creating arbitrage opportunities.

Solution

A simple solution, and the one used by Uniswap v1, is to have every pair include the native token, e.g. A/B is traded by going through A/SOL and B/SOL. The negative aspect of this is a higher cost of trading. This issue has been submitted to start the discussion.

token: Add `CloseAccount` authority

There are cases when the SOL required for rent at the creation of an SPL token account will be subsidized by a 3rd party.

However upon assigning ownership of the token account to the targeted user, the subsidizer loses control of their rent payment. This opens the door for a financial attack where users request token accounts from the subsidizer only to immediately close them in order to drain SOL from the subsidizer:


The subsidizer can perform rate limiting or employ other techniques to limit the number of newly created token accounts, and should do so regardless. However taking away the incentive for users to close their token accounts to obtain rent SOL would be a nice additional protection against abuse.

The ability of the subsidizer to reclaim the SOL would also incentivize them to "garbage collect" abandoned token accounts of 0 balance.


Adding a new CloseAccount authority to a token account would resolve the above concerns: close_authority: Option<Pubkey>. If close_authority is None (default), the token account holder may close the account (current behaviour). However the SetAuthority instruction (going in via #297) could be used to change the CloseAccount authority to any other address.

Dependabot couldn't find a package.json for this project

Dependabot couldn't find a package.json for this project.

Dependabot requires a package.json to evaluate your project's current JavaScript dependencies. It had expected to find one at the path: /package.json.

If this isn't a JavaScript project, or if it is a library, you may wish to disable updates for it in the .github/dependabot.yml file in this repo.

View the update logs.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.