Can't answer authoritatively on the 1st or 3rd, but maybe answers to the 2nd question may help illuminate.
- The answer is no, but let's list out all of the instructions that allow a user to provide an arbitrary XCM blob as a parameter and sends it onward to another destination:
InitiateTeleport
InitiateReserveWithdraw
DepositReserveAsset
ExportMessage // XCMv3 instruction
For the top 3, every time the XCM blob is sent to the intended destination, a ClearOrigin
instruction is inserted right before executing the XCM blob, making it impossible for the XCM blob to run any privileged operations. Take for instance, the WithdrawAsset
instruction and look at how it is executed:
WithdrawAsset(assets) => {
// Take `assets` from the origin account (on-chain) and place in holding.
let origin = self.origin_ref().ok_or(XcmError::BadOrigin)?.clone();
for asset in assets.into_inner().into_iter() {
Config::AssetTransactor::withdraw_asset(&asset, &origin, Some(&self.context))?;
self.subsume_asset(asset)?;
}
Ok(())
},
Right on the first line, we see that it's trying to get a reference to the local origin register. Since the origin register has been cleared out via ClearOrigin
, this line will fail and we won't be able to send and execute such an instruction via InitiateTeleport
, InititateReserveWithdraw
or DepositReserveAsset
.
In addition, the two instructions InitiateTeleport
and DepositReserveAsset
requires the destination to whitelist the sender as a safe teleporter/reserve, adding another layer of security against arbitrary XCM executions.
For ExportMessage
, there is a validation function that is called during the execution of it, which is controlled by the message exporter, so the responsibility of ensuring that nothing weird gets sent via the bridge is up to the bridge itself.