|
| 1 | +--- |
| 2 | +simd: "0266" |
| 3 | +title: "p-token: Efficient Token program" |
| 4 | +authors: |
| 5 | + - febo (Anza) |
| 6 | + - Jon Cinque (Anza) |
| 7 | +category: Standard |
| 8 | +type: Core |
| 9 | +status: Review |
| 10 | +created: 2025-03-19 |
| 11 | +feature: (fill in with feature tracking issues once accepted) |
| 12 | +--- |
| 13 | + |
| 14 | +## Summary |
| 15 | + |
| 16 | +Replace the current version of SPL Token |
| 17 | +(`TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA`) program by a CU-optimized one |
| 18 | +(`p-token`). |
| 19 | + |
| 20 | +## Motivation |
| 21 | + |
| 22 | +About `~10%` of block compute units is used by the Token program instructions. |
| 23 | +Decreasing the CUs used by Token program instructions creates block space for |
| 24 | +other transactions to be executed – i.e., less CUs consumed by Token program, |
| 25 | +more CUs for other transactions. |
| 26 | + |
| 27 | +As an example, if we reduce the CUs consumed by Token instructions to `1/20th` |
| 28 | +of their current value, `10%` of block CUs utilized becomes `0.5%`, resulting in |
| 29 | +a `9.5%` block space gain. |
| 30 | + |
| 31 | +Additionally, there are benefits to downstream programs: |
| 32 | + |
| 33 | +- Better composability since using the Token program instructions require less |
| 34 | + CUs. - Cheaper (in terms of CU) cross-program invocations. |
| 35 | + |
| 36 | +## New Terminology |
| 37 | + |
| 38 | +N/A. |
| 39 | + |
| 40 | +## Detailed Design |
| 41 | + |
| 42 | +`p-token` |
| 43 | +([repository](https://github.com/solana-program/token/tree/main/p-token)) is a |
| 44 | +like-for-like efficient re-implementation of the Token program. It is `no_std` |
| 45 | +(no heap memory allocations are made in the program) and uses zero-copy access |
| 46 | +for instruction and account data. Since it follows the same instructions and |
| 47 | +accounts layout, it does not require any changes to client code – it works as a |
| 48 | +drop-in replacement. |
| 49 | + |
| 50 | +Apart from the original SPL Token instructions, this proposal adds two |
| 51 | +additional instructions to the program: |
| 52 | + |
| 53 | +1. [`withdraw_excess_lamports`](https://github.com/solana-program/token/blob/main/p-token/src/processor/withdraw_excess_lamports.rs) |
| 54 | + (instruction discriminator `38`): allow recovering "bricked" SOL from mint |
| 55 | + (e.g., USDC mint as `~323` SOL in excess) and multisig accounts. The logic of |
| 56 | + this instruction is the same as the current SPL Token-2022 instruction. There |
| 57 | + could be economic consequences depending on the amount of "unbricked" SOL |
| 58 | + — the total amount of SOL that could be freed up this way has not been |
| 59 | + calculated. |
| 60 | +2. [`batch`](https://github.com/solana-program/token/blob/main/p-token/src/processor/batch.rs) |
| 61 | + (instruction discriminator `255`): enable efficient CPI interaction with the |
| 62 | + Token program. This is a new instruction that can execute a variable number on |
| 63 | + Token instructions in a single invocation of the Token program. Therefore, the |
| 64 | + base CPI invoke units (currently `1000` CU) are only consumed once, instead of |
| 65 | + for each CPI instruction – this significantly improves the CUs required to |
| 66 | + perform multiple Token instructions in a CPI context. Almost every DeFi protocol |
| 67 | + on Solana performs multiple CPIs to the Token program in one instruction. For |
| 68 | + example, an AMM performs two transfers during swap, or transfers tokens and |
| 69 | + mints others during an LP deposit. Programs can use the batch instruction for |
| 70 | + even more CU gains. |
| 71 | + |
| 72 | +Note that `withdraw_excess_lamports` discriminator matches the value used in SPL |
| 73 | +Token-2022, while `batch` has a driscriminator value that is not used in either |
| 74 | +SPL Token nor Token-2022. |
| 75 | + |
| 76 | +The program will be loaded into an account |
| 77 | +(`ptokNfvuU7terQ2r2452RzVXB3o4GT33yPWo1fUkkZ2`) prior to enabling the feature |
| 78 | +gate that triggers the replacement. |
| 79 | + |
| 80 | +When the feature gate `ptokSWRqZz5u2xdqMdstkMKpFurauUpVen7TZXgDpkQ` is enabled, |
| 81 | +the runtime needs to: |
| 82 | + |
| 83 | +- Replace `TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA` program with |
| 84 | + `ptokNfvuU7terQ2r2452RzVXB3o4GT33yPWo1fUkkZ2` using the Upgradable Loader `v4`. |
| 85 | + |
| 86 | +## Alternatives Considered |
| 87 | + |
| 88 | +As an alternative to replace the current version of SPL Token, `p-token` could |
| 89 | +be deployed to a new address and people can be encouraged to transition to that |
| 90 | +program. This would hinder its adoption and benefits, since people would be very |
| 91 | +slow to adopt the new program, if they adopt it at all. |
| 92 | + |
| 93 | +Another point considered was to whether keep the current logs on the program or |
| 94 | +not. Logs are limited to show the name of the instruction being executed, e.g.: |
| 95 | + |
| 96 | +``` |
| 97 | +Program Tokenkeg...623VQ5DA invoke [1] |
| 98 | +Program log: Instruction: Transfer |
| 99 | +Program Tokenkeg...623VQ5DA consumed 249 of 200000 compute units |
| 100 | +Program Tokenkeg...623VQ5DA success |
| 101 | +``` |
| 102 | + |
| 103 | +Logging the instruction name consumes around `103` compute units, which in some |
| 104 | +cases reprensents almost the same amount required to execute the instruction, |
| 105 | +although removing the logs can be too disruptive to anyone relying on them. |
| 106 | + |
| 107 | +## Impact |
| 108 | + |
| 109 | +The main impact is freeing up block CUs, allowing more transactions to be packed |
| 110 | +in a block; dapp developers benefit since interacting with the Token program |
| 111 | +will consume significantly less CUs. |
| 112 | + |
| 113 | +Below is a sample of the CUs efficiency gained by `p-token` compared to the |
| 114 | +current SPL Token program. In bracket is the percentage of CUs used in relation |
| 115 | +to the current SPL Token consumption — the lower the percentage, the |
| 116 | +better the gains in CUs consumption. |
| 117 | + |
| 118 | +| Instruction | CU (`p-token`) | CU (`p-token`) + logging |CU (`spl-token`) | |
| 119 | +|-------------|----------------|--------------------------|-----------------| |
| 120 | +| `InitializeMint` | 118 (4%) | 221 (7%) | 2967 | |
| 121 | +| `InitializeAccount` | 170 (4%) | 273 (6%) | 4527 | |
| 122 | +| `InitializeMultisig` | 239 (8%) | 348 (12%) | 2973 | |
| 123 | +| `Transfer` | 146 (3%) | 249 (5%) | 4645 | |
| 124 | +| `Approve` | 150 (5%) | 268 (9%) | 2904 | |
| 125 | +| `Revoke` | 124 (5%) | 237 (9%) | 2677 | |
| 126 | +| `SetAuthority` | 159 (5%) | 261 (8%) | 3167 | |
| 127 | +| `MintTo` | 144 (3%) | 247 (5%) | 4538 | |
| 128 | +| `Burn` | 202 (4%) | 316 (7%) | 4753 | |
| 129 | +| `CloseAccount` | 152 (5%) | 255 (9%) | 2916 | |
| 130 | +| `FreezeAccount` | 170 (4%) | 287 (7%) | 4265 | |
| 131 | +| `ThawAccount` | 169 (4%) | 283 (7%) | 4267 | |
| 132 | + |
| 133 | +## Security Considerations |
| 134 | + |
| 135 | +`p-token` must be guaranteed to follow the same instructions and accounts |
| 136 | +layout, as well as have the same behaviour than the current Token |
| 137 | +implementation. |
| 138 | + |
| 139 | +Any potential risk will be mitigated by extensive fixture testing (_status_: |
| 140 | +[completed](https://github.com/solana-program/token/blob/main/.github/workflows/main.yml#L284-L313)), |
| 141 | +formal verification (_status_: started) and audits (_status_: scheduled). Since |
| 142 | +there are potentially huge economic consequences of this change, the feature |
| 143 | +will be put to a validator vote. |
| 144 | + |
| 145 | +The replacement of the program requires breaking consensus on a non-native |
| 146 | +program. However, this has been done in the past many times for SPL Token to fix |
| 147 | +bugs and add new features. |
| 148 | + |
| 149 | +## Drawbacks |
| 150 | + |
| 151 | +N/A. |
| 152 | + |
| 153 | +## Backwards Compatibility |
| 154 | + |
| 155 | +Fully backwards compatible, no changes are required for users of the program. |
| 156 | +```` |
0 commit comments