-
Notifications
You must be signed in to change notification settings - Fork 305
Update signer-auth.md #473
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -7,7 +7,7 @@ objectives: | |
- Implement signer checks using Anchor’s `Signer` type | ||
- Implement signer checks using Anchor’s `#[account(signer)]` constraint | ||
description: | ||
"Ensure instructions are only ran by authorized accounts by implmementing | ||
"Ensure instructions are only run by authorized accounts by implementing | ||
Signer checks." | ||
--- | ||
|
||
|
@@ -92,8 +92,8 @@ pub struct Vault { | |
|
||
#### Add signer authorization checks | ||
|
||
All you need to do to validate that the `authority` account signed is to add a | ||
signer check within the instruction. That simply means checking that | ||
All you need to do to validate that the `authority` account is signed is to add a | ||
signer check within the instructions. That simply means checking that | ||
`authority.is_signer` is `true`, and returning a `MissingRequiredSignature` | ||
error if `false`. | ||
|
||
|
@@ -199,7 +199,7 @@ performed. | |
#### Use Anchor’s `#[account(signer)]` constraint | ||
|
||
While in most cases, the `Signer` account type will suffice to ensure an account | ||
has signed a transaction, the fact that no other ownership or type checks are | ||
has signed a transaction, the fact that no other ownership or type of checks are | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. No. We want to say that there are no other checks regarding ownership or types. If you like, you can re-word this sentence to make it clearer. |
||
performed means that this account can’t really be used for anything else in the | ||
instruction. | ||
|
||
|
@@ -210,7 +210,7 @@ underlying data as well. | |
|
||
As an example of when this would be useful, imagine writing an instruction that | ||
you expect to be invoked via CPI that expects one of the passed in accounts to | ||
be both a **\*\***signer**\*\*** on the transaciton and a \***\*\*\*\*\*\***data | ||
be both a **\*\***signer**\*\*** on the transaction and a \***\*\*\*\*\*\***data | ||
source\***\*\*\*\*\*\***. Using the `Signer` account type here removes the | ||
automatic deserialization and type checking you would get with the `Account` | ||
type. This is both inconvenient, as you need to manually deserialize the account | ||
|
@@ -299,6 +299,11 @@ While this is somewhat contrived in that any DeFi program with a vault would be | |
more sophisticated than this, it will show how the lack of a signer check can | ||
result in tokens being withdrawn by the wrong party. | ||
|
||
additional checks ensure: | ||
a. The withdraw amount is not zero. | ||
b. There are sufficient funds in the account. | ||
c. The withdraw destination is not the same as the vault's token account. | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We're trying to focus on just signer checks in this chapter. I'm not totally sure adding other checks helps. |
||
```rust | ||
use anchor_lang::prelude::*; | ||
use anchor_spl::token::{self, Mint, Token, TokenAccount}; | ||
|
@@ -316,8 +321,20 @@ pub mod signer_authorization { | |
} | ||
|
||
pub fn insecure_withdraw(ctx: Context<InsecureWithdraw>) -> Result<()> { | ||
let amount = ctx.accounts.token_account.amount; | ||
// Check if the amount is greater than zero | ||
if amount == 0 { | ||
return Err(ProgramError::InvalidArgument.into()); | ||
} | ||
|
||
// Check if there are enough tokens in the account | ||
if ctx.accounts.token_account.amount < amount { | ||
return Err(ProgramError::InsufficientFunds.into()); | ||
} | ||
|
||
// Check if the withdraw destination is different from the vault's token account | ||
if ctx.accounts.token_account.key() == ctx.accounts.withdraw_destination.key() { | ||
return Err(ProgramError::InvalidArgument.into()); | ||
} | ||
let seeds = &[b"vault".as_ref(), &[*ctx.bumps.get("vault").unwrap()]]; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can ensure the code is properly formatted (4 spaces per CONTRIBUTING.md)? Looks like you're in one level too far left. |
||
let signer = [&seeds[..]]; | ||
|
||
|
@@ -424,7 +441,7 @@ describe("signer-authorization", () => { | |
}) | ||
``` | ||
|
||
Run `anchor test` to see that both transactions will complete successfully. | ||
Run `anchor test` to see that both transactions will be completed successfully. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm not sure this is clearer than the old language. |
||
|
||
```bash | ||
signer-authorization | ||
|
@@ -553,7 +570,7 @@ the remainder of the lessons on security vulnerabilities, the Challenge for each | |
lesson will be to audit your own code for the security vulnerability discussed | ||
in the lesson. | ||
|
||
Alternatively, you can find open source programs to audit. There are plenty of | ||
Alternatively, you can find open-source programs to audit. There are plenty of | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. No dash needed, see https://opensource.org/ |
||
programs you can look at. A good start if you don't mind diving into native Rust | ||
would be the | ||
[SPL programs](https://github.com/solana-labs/solana-program-library). | ||
|
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 had to double check the grammar here but you're correct. 👍