Skip to content

fix(svm): M-01 Deposit Tokens Transferred from Depositor Token Account Instead of Signer #958

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

Conversation

md0x
Copy link
Contributor

@md0x md0x commented Apr 16, 2025

OZ identified the followin issue:

A deposit action to the SpokePool program is meant to [pull tokens from the caller](https://github.com/across-protocol/contracts/blob/71e990b3f908ecf994be8723e041b584c7d49318/programs/svm-spoke/src/lib.rs#L213) (i.e., the [signer](https://github.com/across-protocol/contracts/blob/71e990b3f908ecf994be8723e041b584c7d49318/programs/svm-spoke/src/instructions/deposit.rs#L30)) which may be deposited on behalf of any depositor account. However, when the signer is not the depositor, a transfer_from operation is performed with the [depositor token account as the source address](https://github.com/across-protocol/contracts/blob/71e990b3f908ecf994be8723e041b584c7d49318/programs/svm-spoke/src/instructions/deposit.rs#L105). Such an operation would fail unless the depositor had delegated at least the input amount to the state PDA. This presents two consequences:

The signer will not be able to deposit for another account, disabling the intended feature of an [account being able to deposit on behalf of someone else](https://github.com/across-protocol/contracts/blob/71e990b3f908ecf994be8723e041b584c7d49318/programs/svm-spoke/src/lib.rs#L210).

If any token account delegates to the state PDA, then it is possible for anyone to call the deposit function, passing the victim's account as the [depositor_token_account](https://github.com/across-protocol/contracts/blob/71e990b3f908ecf994be8723e041b584c7d49318/programs/svm-spoke/src/instructions/deposit.rs#L45) and performing a successful deposit with arbitrary arguments other than the input token and amount. A malicious user could then submit a deposit with their own recipient address to steal depositor funds. This is possible due to the state PDA being passed as the [authority and signer seed](https://github.com/across-protocol/contracts/blob/71e990b3f908ecf994be8723e041b584c7d49318/programs/svm-spoke/src/utils/transfer_utils.rs#L19-L28) to the transfer_checked call, which, when delegated to, will pass [the transfer validation logic](https://docs.rs/spl-token/latest/src/spl_token/processor.rs.html#274). Note that this scenario is mitigated by the fact that native instruction batching in Solana transactions would typically involve delegation and transferring in one operation, making such a front-running scenario less likely but still possible.

Consider validating the signer token account in the same way as depositor_token_account, and performing the transfer from the signer token account.

We replaced the one “state” PDA with two distinct PDAs—one for deposit and one for fill_relay. Now users must explicitly delegate to the correct PDA before anyone can pull their tokens, restoring safe third‑party deposits and eliminating the risk of a single authority being misused to steal funds.

Copy link

linear bot commented Apr 16, 2025

md0x added 9 commits April 17, 2025 14:38
Signed-off-by: Pablo Maldonado <[email protected]>
Signed-off-by: Pablo Maldonado <[email protected]>
Signed-off-by: Pablo Maldonado <[email protected]>
Signed-off-by: Pablo Maldonado <[email protected]>
Signed-off-by: Pablo Maldonado <[email protected]>
Signed-off-by: Pablo Maldonado <[email protected]>
Signed-off-by: Pablo Maldonado <[email protected]>
@md0x md0x marked this pull request as ready for review April 17, 2025 18:31
@md0x md0x changed the title fix(svm): M-01 Deposit Tokens Transfers fix(svm): Deposit Tokens Transferred from Depositor Token Account Instead of Signer Apr 18, 2025
@md0x md0x changed the title fix(svm): Deposit Tokens Transferred from Depositor Token Account Instead of Signer fix(svm): M-01 Deposit Tokens Transferred from Depositor Token Account Instead of Signer Apr 18, 2025
md0x added 5 commits April 18, 2025 18:30
Signed-off-by: Pablo Maldonado <[email protected]>
Signed-off-by: Pablo Maldonado <[email protected]>
Signed-off-by: Pablo Maldonado <[email protected]>
Signed-off-by: Pablo Maldonado <[email protected]>
Signed-off-by: Pablo Maldonado <[email protected]>
@md0x md0x marked this pull request as draft April 19, 2025 08:41
md0x and others added 4 commits April 20, 2025 11:15
Signed-off-by: Pablo Maldonado <[email protected]>
Signed-off-by: Pablo Maldonado <[email protected]>
Signed-off-by: Pablo Maldonado <[email protected]>
Signed-off-by: Pablo Maldonado <[email protected]>
@md0x md0x requested a review from Reinis-FRP April 20, 2025 09:47
md0x added 2 commits April 20, 2025 11:49
Signed-off-by: Pablo Maldonado <[email protected]>
Signed-off-by: Pablo Maldonado <[email protected]>
@md0x md0x force-pushed the pablo/acx-4021-m-01-deposit-tokens-transferred-from-depositor-token-account branch from 890b05f to 39711a4 Compare April 21, 2025 16:50
@md0x md0x force-pushed the pablo/acx-4021-m-01-deposit-tokens-transferred-from-depositor-token-account branch from 39711a4 to 5d34e89 Compare April 21, 2025 16:53
Signed-off-by: Pablo Maldonado <[email protected]>
@md0x md0x force-pushed the pablo/acx-4021-m-01-deposit-tokens-transferred-from-depositor-token-account branch from 410c01a to 23cafcc Compare April 21, 2025 17:02
md0x added 3 commits April 21, 2025 19:31
Signed-off-by: Pablo Maldonado <[email protected]>
Signed-off-by: Pablo Maldonado <[email protected]>
@md0x md0x requested a review from Reinis-FRP April 21, 2025 20:29
Reinis-FRP and others added 2 commits April 22, 2025 08:57
Signed-off-by: Pablo Maldonado <[email protected]>
@md0x md0x requested a review from Reinis-FRP April 22, 2025 09:27
Copy link
Contributor

@Reinis-FRP Reinis-FRP left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nice!

@md0x md0x merged commit d6497e3 into master Apr 23, 2025
9 checks passed
@md0x md0x deleted the pablo/acx-4021-m-01-deposit-tokens-transferred-from-depositor-token-account branch April 23, 2025 13:04
@md0x md0x restored the pablo/acx-4021-m-01-deposit-tokens-transferred-from-depositor-token-account branch April 23, 2025 13:13
Reinis-FRP added a commit that referenced this pull request May 9, 2025
…t Instead of Signer (#958)

* fix(svm): M-01 Deposit Tokens Transfers

Signed-off-by: Pablo Maldonado <[email protected]>

* feat: use unchecked account

Signed-off-by: Pablo Maldonado <[email protected]>

* feat: remove system acc

Signed-off-by: Pablo Maldonado <[email protected]>

* fix: deposit tests

Signed-off-by: Pablo Maldonado <[email protected]>

* fix: fill tests

Signed-off-by: Pablo Maldonado <[email protected]>

* refactor: rename and comments

Signed-off-by: Pablo Maldonado <[email protected]>

* fix: across plus

Signed-off-by: Pablo Maldonado <[email protected]>

* refactor: rename and organize function

Signed-off-by: Pablo Maldonado <[email protected]>

* feat: update deposit delegate seed

Signed-off-by: Pablo Maldonado <[email protected]>

* feat: use relay_hash from function arguments

Signed-off-by: Pablo Maldonado <[email protected]>

* fix: heap memory error

Signed-off-by: Pablo Maldonado <[email protected]>

* fix

Signed-off-by: Pablo Maldonado <[email protected]>

* refactor: cleanup

Signed-off-by: Pablo Maldonado <[email protected]>

* fix: deposit checks

Signed-off-by: Pablo Maldonado <[email protected]>

* fix: fill tests

Signed-off-by: Pablo Maldonado <[email protected]>

* fix: fill relay delagate

Signed-off-by: Pablo Maldonado <[email protected]>

* fix: fill

Signed-off-by: Pablo Maldonado <[email protected]>

* refactor: simplify

Signed-off-by: Pablo Maldonado <[email protected]>

* refactor: cleanup

Signed-off-by: Pablo Maldonado <[email protected]>

* refactor: clean fill test

Signed-off-by: Pablo Maldonado <[email protected]>

* test: update fill tests

Signed-off-by: Pablo Maldonado <[email protected]>

* refactor: comments

Signed-off-by: Pablo Maldonado <[email protected]>

* fix: scripts

Signed-off-by: Pablo Maldonado <[email protected]>

* refactor: make seed structs private

Signed-off-by: Pablo Maldonado <[email protected]>

* feat: add missing params to deposit hashes

Signed-off-by: Pablo Maldonado <[email protected]>

* refactor: simplify

Signed-off-by: Pablo Maldonado <[email protected]>

* refactor: delegate utils

Signed-off-by: Pablo Maldonado <[email protected]>

* refactor: anchor serialize

Signed-off-by: Pablo Maldonado <[email protected]>

* refactor: reuse helper deriveSeedHash

Signed-off-by: Pablo Maldonado <[email protected]>

* fix: move paused fills check in handler

Signed-off-by: Reinis Martinsons <[email protected]>

* feat: improvements

Signed-off-by: Pablo Maldonado <[email protected]>

* fix: remove program_id from transfer_from params

Signed-off-by: Reinis Martinsons <[email protected]>

---------

Signed-off-by: Pablo Maldonado <[email protected]>
Signed-off-by: Pablo Maldonado <[email protected]>
Signed-off-by: Reinis Martinsons <[email protected]>
Co-authored-by: Reinis Martinsons <[email protected]>
Signed-off-by: Reinis Martinsons <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants