{"record":{"id":"82519da307760ae5","repo":"datahaven-xyz/datahaven","slug":"transfersdisabled","errorCode":"TransfersDisabled","errorMessage":"TransfersDisabled","messagePattern":"TransfersDisabled","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"operator/pallets/datahaven-native-transfer/src/lib.rs","lineNumber":180,"sourceCode":"        /// Locks the tokens in the vault and sends a message through Snowbridge\n        /// to mint the equivalent tokens on Ethereum.\n        ///\n        /// Parameters:\n        /// - `origin`: The account initiating the transfer\n        /// - `recipient`: The Ethereum address to receive the tokens\n        /// - `amount`: The amount of tokens to transfer\n        /// - `fee`: The fee to incentivize relayers (in native tokens)\n        #[pallet::call_index(0)]\n        #[pallet::weight(T::WeightInfo::transfer_to_ethereum())]\n        pub fn transfer_to_ethereum(\n            origin: OriginFor<T>,\n            recipient: H160,\n            amount: BalanceOf<T>,\n            fee: BalanceOf<T>,\n        ) -> DispatchResult {\n            let who = ensure_signed(origin)?;\n\n            ensure!(!Paused::<T>::get(), Error::<T>::TransfersDisabled);\n\n            // Get the token ID - fails if not registered\n            let token_id = T::NativeTokenId::get().ok_or(Error::<T>::TokenNotRegistered)?;\n\n            ensure!(amount > Zero::zero(), Error::<T>::InvalidAmount);\n            ensure!(fee > Zero::zero(), Error::<T>::ZeroFee);\n            ensure!(\n                recipient != H160::zero(),\n                Error::<T>::InvalidEthereumAddress\n            );\n\n            // Transfer fee to recipient\n            T::Currency::transfer(&who, &T::FeeRecipient::get(), fee, Preservation::Preserve)?;\n\n            // Lock tokens in the sovereign account\n            Self::lock_tokens(&who, amount)?;\n\n            // Build and send the message","sourceCodeStart":162,"sourceCodeEnd":198,"githubUrl":"https://github.com/datahaven-xyz/datahaven/blob/edcb13dbbcd3c29489eaa2480a6f60ee4cb1f3ec/operator/pallets/datahaven-native-transfer/src/lib.rs#L162-L198","documentation":"The datahaven-native-transfer pallet rejects transfer_to_ethereum calls while the pallet is paused. Paused::<T> is a global kill-switch; when set, all outbound transfers to Ethereum are disabled to allow maintenance or incident response. The extrinsic fails with the TransfersDisabled dispatch error before any funds move.","triggerScenarios":"Submitting transfer_to_ethereum (extrinsic at lib.rs:180 region) while Paused::<T>::get() is true — i.e., after the pause admin/manager has called the pallet's pause operation.","commonSituations":"DApps or users attempting outbound bridge transfers during an active security pause or scheduled maintenance window; integrations not checking pause state before building transactions.","solutions":["Have the pallet admin invoke the unpause extrinsic (with appropriate governance/manager origin) once transfers are safe to resume.","Before submitting, query Paused::<T> storage and surface a user-friendly 'bridge paused' state instead of letting the tx fail.","Retry the transfer after the pause is lifted; funds were never debited."],"exampleFix":"// before: submit blindly\napi.tx.datahavenNativeTransfer.transferToEthereum(recipient, amount, fee).signAndSend(account);\n// after\nconst paused = await api.query.datahavenNativeTransfer.paused();\nif (paused.isTrue) throw new Error('Bridge transfers are paused');\nawait api.tx.datahavenNativeTransfer.transferToEthereum(recipient, amount, fee).signAndSend(account);","handlingStrategy":"validation","validationCode":"// check pause state before submitting\nconst paused = await api.query.datahavenNativeTransfer.paused();\nif (paused.isTrue) throw new Error('Bridge transfers are currently paused');","typeGuard":null,"tryCatchPattern":"try {\n  await api.tx.datahavenNativeTransfer.transferToEthereum(recipient, amount, fee).signAndSend(account);\n} catch (e) {\n  if (String(e).includes('TransfersDisabled')) notifyUser('Bridge paused; try again later');\n  else throw e;\n}","preventionTips":["Subscribe to the paused storage item and disable transfer UI when set.","Surface maintenance windows in the app before accepting user inputs.","Never assume funds were debited when this error returns."],"tags":["bridge","paused","substrate","dispatch-error"],"backgroundTag":"feature-not-enabled","analyzedSha":"edcb13dbbcd3c29489eaa2480a6f60ee4cb1f3ec","analyzedAt":"2026-09-13T19:19:32.206Z","contentChangedAt":"2026-09-13T19:19:32.206Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}