diff --git a/target_chains/ton/contracts/README.md b/target_chains/ton/contracts/README.md index 6105cd2a1..3abc459cb 100644 --- a/target_chains/ton/contracts/README.md +++ b/target_chains/ton/contracts/README.md @@ -30,3 +30,21 @@ 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. +- 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. diff --git a/target_chains/ton/contracts/contracts/Main.fc b/target_chains/ton/contracts/contracts/Main.fc index 9fd78289b..faf534be7 100644 --- a/target_chains/ton/contracts/contracts/Main.fc +++ b/target_chains/ton/contracts/contracts/Main.fc @@ -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`. diff --git a/target_chains/ton/contracts/contracts/Pyth.fc b/target_chains/ton/contracts/contracts/Pyth.fc index 58cea18c7..adecbb0e9 100644 --- a/target_chains/ton/contracts/contracts/Pyth.fc +++ b/target_chains/ton/contracts/contracts/Pyth.fc @@ -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)