Skip to content
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

add comments and ignore bounced messages #2151

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions target_chains/ton/contracts/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,3 +30,21 @@ CHAIN_ID=<CHAIN-ID> npx blueprint run --custom https://testnet.toncenter.com/api
### Add a new contract

`npx blueprint create ContractName` or `yarn blueprint create ContractName`

## Important Note on Message Handling

When using the Pyth price feed in the recommended flow (User/App -> Pyth -> Protocol), be aware that:

### Security Warning ⚠️

**CRITICAL**: Integrators MUST validate the sender address in their receive function to ensure messages are coming from the Pyth Oracle contract. Failure to do so could allow attackers to:

- Send invalid price responses
- Impersonate users via the sender_address and custom_payload fields
- Potentially drain the protocol

### Message Bouncing Behavior

- If the target protocol bounces the message (e.g., due to invalid custom payload or other errors), the forwarded TON will remain in the Pyth contract and will not be automatically refunded to the original sender.
Copy link
Collaborator

Choose a reason for hiding this comment

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

can't we bounce back?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

to handle bounced messages and return funds to the original sender, we need to:

  • store the sender's address when receiving the initial request
  • add a bounce handling function that checks for bounced messages and refunds the original sender

its not as straightforward but if you think its worth it then we can consider implementing this

Copy link
Collaborator

@ali-bahjati ali-bahjati Nov 29, 2024

Choose a reason for hiding this comment

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

oof it seems pretty complicated. let's skip it.

- This could be significant when dealing with large amounts of TON (e.g., in DeFi operations).
- Integrators should implement proper error handling and refund mechanisms in their applications.
5 changes: 4 additions & 1 deletion target_chains/ton/contracts/contracts/Main.fc
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,10 @@

;; Get sender address from message
slice cs = in_msg_full.begin_parse();
cs~skip_bits(4); ;; skip flags
int flags = cs~load_uint(4);
if (flags & 1) { ;; ignore all bounced messages
return ();
}
slice sender_address = cs~load_msg_addr(); ;; load sender address

;; * The remainder of the message body is specific for each supported value of `op`.
Expand Down
9 changes: 9 additions & 0 deletions target_chains/ton/contracts/contracts/Pyth.fc
Original file line number Diff line number Diff line change
Expand Up @@ -349,6 +349,15 @@ cell create_price_feed_cell_chain(tuple price_feeds) {
int total_fees = compute_fee + update_fee;
int excess = msg_value - total_fees;

;; SECURITY: Integrators MUST validate that messages are from this Pyth contract
;; in their receive function. Otherwise, attackers could:
;; 1. Send invalid price responses
;; 2. Impersonate users via sender_address and custom_payload fields
;; 3. Potentially drain the protocol
;;
;; Note: This message is bounceable. If the target contract rejects the message,
;; the excess TON will remain in this contract and won't be automatically refunded to the
;; original sender. Integrators should handle failed requests and refunds in their implementation.
send_raw_message(begin_cell()
.store_uint(0x18, 6)
.store_slice(target_address)
Expand Down
Loading