lang: fix missing ATA owner check (#1240)
This commit is contained in:
parent
35c8200010
commit
e026e9e874
|
@ -13,6 +13,7 @@ incremented for features.
|
|||
|
||||
### Fixes
|
||||
|
||||
* lang: Add missing owner check when `associated_token::authority` is used ([#1240](https://github.com/project-serum/anchor/pull/1240)).
|
||||
* ts: Add type declarations for conditional `workspace` and `Wallet` exports ([#1137](https://github.com/project-serum/anchor/pull/1137)).
|
||||
* ts: Change commitment message `recent` to `processed` and `max` to `finalized` ([#1128](https://github.com/project-serum/anchor/pull/1128))
|
||||
* ts: fix `translateAddress` which currently leads to failing browser code. Now uses `PublicKey` constructor instead of prototype chain constructor name checking which doesn't work in the presence of code minifying/mangling([#1138](https://github.com/project-serum/anchor/pull/1138))
|
||||
|
|
|
@ -395,6 +395,9 @@ fn generate_constraint_associated_token(
|
|||
let wallet_address = &c.wallet;
|
||||
let spl_token_mint_address = &c.mint;
|
||||
quote! {
|
||||
if #name.owner != #wallet_address.key() {
|
||||
return Err(anchor_lang::__private::ErrorCode::ConstraintTokenOwner.into());
|
||||
}
|
||||
let __associated_token_address = anchor_spl::associated_token::get_associated_token_address(&#wallet_address.key(), &#spl_token_mint_address.key());
|
||||
if #name.key() != __associated_token_address {
|
||||
return Err(anchor_lang::__private::ErrorCode::ConstraintAssociated.into());
|
||||
|
|
|
@ -614,65 +614,117 @@ describe("misc", () => {
|
|||
assert.equal(account2.idata, 3);
|
||||
});
|
||||
|
||||
let associatedToken = null;
|
||||
|
||||
it("Can create an associated token account", async () => {
|
||||
associatedToken = await Token.getAssociatedTokenAddress(
|
||||
ASSOCIATED_TOKEN_PROGRAM_ID,
|
||||
TOKEN_PROGRAM_ID,
|
||||
mint.publicKey,
|
||||
program.provider.wallet.publicKey
|
||||
);
|
||||
|
||||
await program.rpc.testInitAssociatedToken({
|
||||
accounts: {
|
||||
token: associatedToken,
|
||||
mint: mint.publicKey,
|
||||
payer: program.provider.wallet.publicKey,
|
||||
rent: anchor.web3.SYSVAR_RENT_PUBKEY,
|
||||
systemProgram: anchor.web3.SystemProgram.programId,
|
||||
tokenProgram: TOKEN_PROGRAM_ID,
|
||||
associatedTokenProgram: ASSOCIATED_TOKEN_PROGRAM_ID,
|
||||
},
|
||||
});
|
||||
const client = new Token(
|
||||
describe("associated_token constraints", () => {
|
||||
let associatedToken = null;
|
||||
// apparently cannot await here so doing it in the 'it' statements
|
||||
let client = Token.createMint(
|
||||
program.provider.connection,
|
||||
mint.publicKey,
|
||||
TOKEN_PROGRAM_ID,
|
||||
program.provider.wallet.payer
|
||||
program.provider.wallet.payer,
|
||||
program.provider.wallet.publicKey,
|
||||
program.provider.wallet.publicKey,
|
||||
9,
|
||||
TOKEN_PROGRAM_ID
|
||||
);
|
||||
const account = await client.getAccountInfo(associatedToken);
|
||||
assert.ok(account.state === 1);
|
||||
assert.ok(account.amount.toNumber() === 0);
|
||||
assert.ok(account.isInitialized);
|
||||
assert.ok(account.owner.equals(program.provider.wallet.publicKey));
|
||||
assert.ok(account.mint.equals(mint.publicKey));
|
||||
});
|
||||
|
||||
it("Can validate associated_token constraints", async () => {
|
||||
await program.rpc.testValidateAssociatedToken({
|
||||
accounts: {
|
||||
token: associatedToken,
|
||||
mint: mint.publicKey,
|
||||
wallet: program.provider.wallet.publicKey,
|
||||
},
|
||||
it("Can create an associated token account", async () => {
|
||||
const localClient = await client;
|
||||
associatedToken = await Token.getAssociatedTokenAddress(
|
||||
ASSOCIATED_TOKEN_PROGRAM_ID,
|
||||
TOKEN_PROGRAM_ID,
|
||||
localClient.publicKey,
|
||||
program.provider.wallet.publicKey
|
||||
);
|
||||
|
||||
await program.rpc.testInitAssociatedToken({
|
||||
accounts: {
|
||||
token: associatedToken,
|
||||
mint: localClient.publicKey,
|
||||
payer: program.provider.wallet.publicKey,
|
||||
rent: anchor.web3.SYSVAR_RENT_PUBKEY,
|
||||
systemProgram: anchor.web3.SystemProgram.programId,
|
||||
tokenProgram: TOKEN_PROGRAM_ID,
|
||||
associatedTokenProgram: ASSOCIATED_TOKEN_PROGRAM_ID,
|
||||
},
|
||||
});
|
||||
|
||||
const account = await localClient.getAccountInfo(associatedToken);
|
||||
assert.ok(account.state === 1);
|
||||
assert.ok(account.amount.toNumber() === 0);
|
||||
assert.ok(account.isInitialized);
|
||||
assert.ok(account.owner.equals(program.provider.wallet.publicKey));
|
||||
assert.ok(account.mint.equals(localClient.publicKey));
|
||||
});
|
||||
|
||||
await assert.rejects(
|
||||
async () => {
|
||||
await program.rpc.testValidateAssociatedToken({
|
||||
accounts: {
|
||||
token: associatedToken,
|
||||
mint: mint.publicKey,
|
||||
wallet: anchor.web3.Keypair.generate().publicKey,
|
||||
},
|
||||
});
|
||||
},
|
||||
(err) => {
|
||||
assert.equal(err.code, 2009);
|
||||
return true;
|
||||
}
|
||||
);
|
||||
it("Can validate associated_token constraints", async () => {
|
||||
const localClient = await client;
|
||||
await program.rpc.testValidateAssociatedToken({
|
||||
accounts: {
|
||||
token: associatedToken,
|
||||
mint: localClient.publicKey,
|
||||
wallet: program.provider.wallet.publicKey,
|
||||
},
|
||||
});
|
||||
|
||||
let otherMint = await Token.createMint(
|
||||
program.provider.connection,
|
||||
program.provider.wallet.payer,
|
||||
program.provider.wallet.publicKey,
|
||||
program.provider.wallet.publicKey,
|
||||
9,
|
||||
TOKEN_PROGRAM_ID
|
||||
);
|
||||
|
||||
await assert.rejects(
|
||||
async () => {
|
||||
await program.rpc.testValidateAssociatedToken({
|
||||
accounts: {
|
||||
token: associatedToken,
|
||||
mint: otherMint.publicKey,
|
||||
wallet: program.provider.wallet.publicKey,
|
||||
},
|
||||
});
|
||||
},
|
||||
(err) => {
|
||||
assert.equal(err.code, 2009);
|
||||
return true;
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
it("associated_token constraints check do not allow authority change", async () => {
|
||||
const localClient = await client;
|
||||
await program.rpc.testValidateAssociatedToken({
|
||||
accounts: {
|
||||
token: associatedToken,
|
||||
mint: localClient.publicKey,
|
||||
wallet: program.provider.wallet.publicKey,
|
||||
},
|
||||
});
|
||||
|
||||
await localClient.setAuthority(
|
||||
associatedToken,
|
||||
anchor.web3.Keypair.generate().publicKey,
|
||||
"AccountOwner",
|
||||
program.provider.wallet.payer,
|
||||
[]
|
||||
);
|
||||
|
||||
await assert.rejects(
|
||||
async () => {
|
||||
await program.rpc.testValidateAssociatedToken({
|
||||
accounts: {
|
||||
token: associatedToken,
|
||||
mint: localClient.publicKey,
|
||||
wallet: program.provider.wallet.publicKey,
|
||||
},
|
||||
});
|
||||
},
|
||||
(err) => {
|
||||
assert.equal(err.code, 2015);
|
||||
return true;
|
||||
}
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
it("Can fetch all accounts of a given type", async () => {
|
||||
|
|
Loading…
Reference in New Issue