Bonus: Token Assets
In this optional lesson, we will move some USDC on Solana. This introduces the asset concept in more depth. You can skip this lesson and go to the next chapter if you are more interested in security and the access policy.
Set up USDC
By default, Treasury is loaded with the supported chains and their corresponding native assets. You can list all of each with the commands chains
and assets
, or specifically look at Solana:
- CSL
chain SOL
native chain SOL { confirmations = 4, priority = "market" }
- CSL
assets for SOL
native asset SOL for SOL { decimals = 9 }
Note that we use the symbol of the native asset also as symbol for the underlying chain. This is currently not configurable.
Token assets exists on most chains, and are identified by the address of a smart contract. To use these, they need to be registered:
- CSL
USDC = create token asset 4zMMC9srt5Ri5X14GAgXhaHii3GnPAEERYPJgZJDncDU for SOL { decimals = 6 }
token asset 4zMMC9srt5Ri5X14GAgXhaHii3GnPAEERYPJgZJDncDU for SOL { version = 1, decimals = 6 }
This command requires the token address as an argument, but also the number of decimals of the asset.
You can list all token assets registered so far:
- CSL
assets | variant = "token"
token asset 4zMMC9srt5Ri5X14GAgXhaHii3GnPAEERYPJgZJDncDU for SOL { version = 1, decimals = 6 }
Load Funds
Similar to the earlier lesson, you can visit https://faucet.circle.com in your browser, select "Solana Devnet" as network, enter the the "funded" Solana address, and receive 10 USDC shortly after. Confirm this by visiting https://explorer.solana.com/?cluster=devnet for the address and inspecting the "Tokens" tab.
Move USDC
After the above setup, moving USDC works the same way as moving SOL:
- CSL
create transfer { from = $funded, to = $unfunded, asset = $USDC, amount = "1" }
Permission Denied: 7: transfer policy did not pass
However, our transfer rule from the previous lesson only allowed moving SOL, but not tokens such as USDC.
Run:
- CSL
transfer policy
allow transfer-rule 8 { version = 1, asset = "chains/SOL/assets/SOL", from = "chains/SOL/addresses/CirHy2hKuR3Yajy5K6qXo4xEkobftHCFNJKQswswdc1A", to = "chains/SOL/addresses/Vihj2YEBxvbAJM6iSxDAGC1ANESmGsiStdk8cJquJfW" }
to find the name of the transfer rule, and modify it to allow any asset:
- CSL
update transfer rule 8 { asset = "any/asset" }
allow transfer-rule 8 { version = 2, asset = "any/asset", from = "chains/SOL/addresses/479NqsSroFxiEw85P8pt7nxW3M9G7xdnJ9dWA2jUSz7o", to = "chains/SOL/addresses/689Zowcs7z4EQYRAdEhqcL2tmedoabAQg1eWqsV3kDA1" }
Now, the transfer is allowed and will work:
- CSL
create transfer { from = $funded, to = $unfunded, asset = $USDC, amount = "1" }
preparing transfer 12 { version = 1, from = "chains/SOL/addresses/CirHy2hKuR3Yajy5K6qXo4xEkobftHCFNJKQswswdc1A", to = "chains/SOL/addresses/Vihj2YEBxvbAJM6iSxDAGC1ANESmGsiStdk8cJquJfW", asset = "chains/SOL/assets/4zMMC9srt5Ri5X14GAgXhaHii3GnPAEERYPJgZJDncDU", amount = "1", symbol = "chains/SOL/symbols/USDC", last_transaction = "transfers/12/transactions/13" }