-
Notifications
You must be signed in to change notification settings - Fork 2
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: whitelist and unwhitelist SPL tokens #41
Conversation
Co-authored-by: skosito <[email protected]>
Co-authored-by: skosito <[email protected]>
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #41 +/- ##
========================================
+ Coverage 8.30% 9.16% +0.85%
========================================
Files 1 1
Lines 253 262 +9
========================================
+ Hits 21 24 +3
- Misses 232 238 +6 ☔ View full report in Codecov by Sentry. |
// whitelisting SPL tokens | ||
pub fn whitelist_spl_mint(_ctx: Context<AddToWhitelist>) -> Result<()> { | ||
Ok(()) | ||
} | ||
|
||
pub fn de_whitelist_spl_mint(_ctx: Context<DeleteFromWhitelist>) -> Result<()> { | ||
Ok(()) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unclear what these are for
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i think all logic for this is in the accounts definition, when you whitelist new one is created (with init
), when you unwhitelist its closed (with close
)
@@ -414,6 +428,51 @@ pub struct UpdatePaused<'info> { | |||
pub signer: Signer<'info>, | |||
} | |||
|
|||
#[derive(Accounts)] | |||
pub struct AddToWhitelist<'info> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should use consistent terminology with Solidity contracts:
- whitelist
- unwhitelist
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
changed to whitelist/unwhitelist across the board
e905e67
@@ -19,6 +19,56 @@ const keyPair = ec.keyFromPrivate('5b81cdf52ba0766983acf8dd0072904733d92afe4dd34 | |||
|
|||
const usdcDecimals = 6; | |||
|
|||
async function mintSPLToken(conn: anchor.web3.Connection, wallet: anchor.web3.Keypair, mint: anchor.web3.Keypair) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we should remove all console.log in the test, logging in tests should be minimal by default, should printing passing tests
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
disabled console.log in the test
e905e67
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
not sure if its ok to overwrite console.log like this, i think the point was to just remove all console.logs calls as they are just useful while tests are being written or during debugging
if there is console.log that is absolutely needed, it is probably better to replace it with assertion
#[account(seeds=[b"whitelist", mint_account.key().as_ref()], bump)] | ||
pub whitelist_entry: Account<'info, WhitelistEntry>, // attach whitelist entry to show the mint_account is whitelisted | ||
|
||
pub mint_account: Account<'info, Mint>, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What does mint mean?
There should be no minting involved since we lock/unlock SPL tokens?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
according to description Whitelisting is implemented as a special PDA for each mint account (SPL token id).
is needed to create pda for mint account and existence of that pda marks that token is whitelisted
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What does mint mean?
There should be no minting involved since we lock/unlock SPL tokens?
mint (short for mint account) is the Solana equivalent for ERC20 contract address.
This is Solana jargon.
@@ -423,6 +482,9 @@ pub struct Pda { | |||
deposit_paused: bool, | |||
} | |||
|
|||
#[account] | |||
pub struct WhitelistEntry {} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
just curious if is there a pros/cons for whitelisting in 2 following ways:
- init/close account
- store flag within pda marking if its whitelisted or not
is it because having long lived pda in solana is not efficient if not needed because of rent, or something else?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For whitelisting we really need is a mapping like Ethereum address=>bool
But Solana does not have mapping as a data structure like Ethereum mapping.
You'll need to roll your own. Say you want to create a mapping data account
and then store a hashmap or list in the PDA to implement the mapping.
There are two issues:
- size of the data structure and therefore the account size could dynamically change;
- hard to get deterministic constant access time (key-value lookup)
The PDA for each key-value pair is the idiomatic way to do Ethereum mapping on Solana.
Think of part of the seed as the key (mint account address), and value is the PDA account.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
good explanation
#[account(mut, seeds = [b"meta"], bump, has_one = authority)] | ||
pub pda: Account<'info, Pda>, | ||
#[account(mut)] | ||
pub authority: Signer<'info>, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It means the signer (the authority
) of the Whitelist
instruction must be one of the fields in pda
struct?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes,
the b"meta" PDA contains the authority.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
looks good
README.md
Outdated
@@ -1,6 +1,7 @@ | |||
|
|||
**Note**: Mainnet-beta, testnet, devnet gateway program address: | |||
|
|||
Mainnet-beta, testnet, devnet gateway program address: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
seems like changes in this file are from merge with main, probably should be reverted
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
reverted
@@ -19,6 +19,56 @@ const keyPair = ec.keyFromPrivate('5b81cdf52ba0766983acf8dd0072904733d92afe4dd34 | |||
|
|||
const usdcDecimals = 6; | |||
|
|||
async function mintSPLToken(conn: anchor.web3.Connection, wallet: anchor.web3.Keypair, mint: anchor.web3.Keypair) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
not sure if its ok to overwrite console.log like this, i think the point was to just remove all console.logs calls as they are just useful while tests are being written or during debugging
if there is console.log that is absolutely needed, it is probably better to replace it with assertion
removed the console logs in the next PR. Don't want to create merging issue later so maybe let's put the console logs aside for this one. |
closes #42
Add whitelisting function to SPL tokens to be deposited into the program PDA.
Right now the
authority
are authorized to whitelist/de-whitelist SPL token.The integration tests are also refactored somewhat to increase code reuse.
Only
deposit_spl_token*()
instructions need to provide evidence of whitelisting.withdraw_spl_token
is not encumbered by whitelisting for the following reasons:no way to withdraw; there is no need for witheraw_spl_token to respect whitelisting;
pause deposit, and allow withdraw otherwise the deposited SPL tokens will be stuck.
Whitelisting is implemented as a special PDA for each mint account (SPL token id).
Whitelisting creates a PDA derived from the
mint_account
of the whitelisted SPL token.When a user deposits the whitelisted token, she must provide evidence, i.e. provide the PDA whitelist entry
in the accounts:
This way, the existence of the PDA
whitelist_entry
is the evidence of themint_account
being whitelisted.De-whitelisting closes the PDA whitelist_entry so that deposit spl token will error with
AccountNotInitialized
.query whitelisted status
To query whether a SPL token is whitelisted by the program off-chain, derive the
whitelist_entry
PDA accountfrom seeds
[b"whitelist", mint_account.key().as_ref()]
and access the PDA account. The existence of thisPDA account means whitelisted; otherwise not whitelisted.
To query whether a SPL token is whitelisted by the program on-chain, add evidence whitelist_entry
to the accounts of the instruction. Anchor constraints ensures that
whitelist_entry
must exists (and initialized)which means the referenced
mint_account
must be whitelisted.testing
both positive and negative tests are in the integration test suite.