Buy Native SOL - #151
Buy Native SOL#151
Conversation
|
Very interesting bug spotted when preparing the prerelease, see failing test here. It seems our understanding of accounts in an instruction is incorrect. Claude summary of the bug |
…olana-programs into kaze/sc-275-buy-native-sol
native token and a SPL token
|
Suggested test (sorry if it's already there, it's more of a reminder for my review): make sure that if filling a buy order would leave less than the needed rent in the settle PDA. |
I see it happens because the order that the order pdas are supplied changes. Would be nice to have proptests which would cover something like this! Ok probably easiest way to test that this issue is sure to appear is by increasing the number of different orders tested with, so will add that. And for the fix itself, I tried following the second suggestion, but . The first suggestion works pretty simply, but it impacts CU a bit more. Maybe I am over optimizing, but ended up splitting the lamport math into two separate This would still create a arithmetic issue for the unlikely case where the token account being paid out on buy-sol order is the same account being paid on a buy SOL order (ex. the token account's native balance is funded). I think this edge case is minescule |
…olana-programs into kaze/sc-275-buy-native-sol
Folding resolve_buy into resolve passed the self-order use_buffer flag to the buy side too, so a self order's treasury became the buy-mint buffer and the push moved the proceeds from that buffer back into itself. The buy side never draws from a buffer, so always resolve it with use_buffer = false. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Reviewed everything, to the best of my knowledge the comments below are everything that needs to be addressed before merging, and all of them are easy.
One exception:
#151 (comment)
Example code here.
Co-authored-by: Federico Giacon <58218759+fedgiac@users.noreply.github.com>
Co-authored-by: Federico Giacon <58218759+fedgiac@users.noreply.github.com>
Co-authored-by: Federico Giacon <58218759+fedgiac@users.noreply.github.com>
This reverts commit f123430.
…olana-programs into kaze/sc-275-buy-native-sol
…ill-mint-and-account' into kaze/sc-275-buy-native-sol
Description
Adds the ability for a trader to specify the system account rather than a token mint as the
buy_mint, and in doing so, receive native SOL directly from the settlement program.Motivation
Being able to buy and sell native tokens from the settlement program is known to improve. Its relatively simple to support this from the settlement program side.
Changes overview
The
OrderIntentbuy_mintfield may be set to11111..1111(the system program). When this is the case,buy_token_accountis treated as a regular account that receives native lamports rather than a token account that receives tokens.Elsewhere in the solana ecosystem the system program seems to be treated for this very purpose.
Note that the settlement program itself doesn't actually need to be supplied as an input account since its only used as a data marker. Instead, the
source_bufferis set to thestate_pda.Before an account can receive lamports, it must have been created. This requires the user to create the account if it doesn't exist already, the same as they would need to with a token account.
The source "buffer" for lamports is the settlement state pda. Its the most natural choice since it will already be loaded during execution and can be directly debited using lamport math. The solana runtime will prevent the withdrawal of more lamports than are required for rent exemption, so this prevents solvers from withdrawing too much.
To prevent issues with creating orders on the settlement program itself (which is expected to come soon), the
move_lamportsfunction will do nothing if the sender is the same as the receiver. So if thebuy_token_accountis set tostate_pdait works as expected (funds remain in the state pda)Defaultderive was removed fromAssetto prevent "accidents" with using Default for some reason and just ending up with a 0 address. But I still wanted to be able to use Default in the tests, so it became a cfg.This propogated up the chain, all the way to the client lib, so we are still using cfg test fixtures to prevent default from being used outside that case. So if you are seeing cfg sections added for default, that is why.
Gas Impact
Looking at the correct bench report, it seems very small. Unrelated orders use about ~20 more CU on settle, whereas just about every other function somehow saved 1 CU.
Out of scope
For fee collection, lamports cannot directly be taken from the state pda, so a separate instruction will likely need to be created.
Questions
Should we rename
buy_token_accountto simplybuy_account? should we do the same for sell side?