diff --git a/contracts/src/Assets.sol b/contracts/src/Assets.sol index b8f4db66ed..a0fc3ff98b 100644 --- a/contracts/src/Assets.sol +++ b/contracts/src/Assets.sol @@ -11,7 +11,7 @@ import {AssetsStorage, TokenInfo} from "./storage/AssetsStorage.sol"; import {CoreStorage} from "./storage/CoreStorage.sol"; import {SubstrateTypes} from "./SubstrateTypes.sol"; -import {ParaID, MultiAddress, Ticket, Costs} from "./Types.sol"; +import {ChannelID, ParaID, MultiAddress, Ticket, Costs} from "./Types.sol"; import {Address} from "./utils/Address.sol"; import {AgentExecutor} from "./AgentExecutor.sol"; import {Agent} from "./Agent.sol"; @@ -280,7 +280,13 @@ library Assets { } // @dev Mint foreign token from Polkadot - function mintForeignToken(bytes32 foreignTokenID, address recipient, uint256 amount) external { + function mintForeignToken(ChannelID channelID, bytes32 foreignTokenID, address recipient, uint256 amount) + external + { + AssetsStorage.Layout storage $ = AssetsStorage.layout(); + if (channelID != $.assetHubParaID.into()) { + revert TokenMintFailed(); + } address token = _ensureTokenAddressOf(foreignTokenID); Token(token).mint(recipient, amount); } diff --git a/contracts/src/Gateway.sol b/contracts/src/Gateway.sol index 685627fe34..96befc183f 100644 --- a/contracts/src/Gateway.sol +++ b/contracts/src/Gateway.sol @@ -227,7 +227,7 @@ contract Gateway is IGateway, IInitializable, IUpgradable { success = false; } } else if (message.command == Command.MintForeignToken) { - try Gateway(this).mintForeignToken{gas: maxDispatchGas}(message.params) {} + try Gateway(this).mintForeignToken{gas: maxDispatchGas}(message.channelID, message.params) {} catch { success = false; } @@ -411,9 +411,9 @@ contract Gateway is IGateway, IInitializable, IUpgradable { } // @dev Mint foreign token from polkadot - function mintForeignToken(bytes calldata data) external onlySelf { + function mintForeignToken(ChannelID channelID, bytes calldata data) external onlySelf { MintForeignTokenParams memory params = abi.decode(data, (MintForeignTokenParams)); - Assets.mintForeignToken(params.foreignTokenID, params.recipient, params.amount); + Assets.mintForeignToken(channelID, params.foreignTokenID, params.recipient, params.amount); } // @dev Transfer Ethereum native token back from polkadot diff --git a/contracts/test/Gateway.t.sol b/contracts/test/Gateway.t.sol index e17c7df1a9..4c766733b6 100644 --- a/contracts/test/Gateway.t.sol +++ b/contracts/test/Gateway.t.sol @@ -62,11 +62,11 @@ contract GatewayTest is Test { event Transfer(address indexed from, address indexed to, uint256 value); ParaID public bridgeHubParaID = ParaID.wrap(1013); - bytes32 public bridgeHubAgentID = 0x03170a2e7597b7b7e3d84c05391d139a62b157e78786d8c082f29dcf4c111314; + bytes32 public bridgeHubAgentID = 0xbc0eb42478cf1d8f1542c986e5e6a513f926c4552d7b7ab6084b97e192c622fa; address public bridgeHubAgent; ParaID public assetHubParaID = ParaID.wrap(1000); - bytes32 public assetHubAgentID = 0x81c5ab2571199e3188135178f3c2c8e2d268be1313d029b30f534fa579b69b79; + bytes32 public assetHubAgentID = 0xc173fac324158e77fb5840738a1a541f633cbec8884c6a601c567d2b376a0539; address public assetHubAgent; address public relayer; @@ -901,7 +901,7 @@ contract GatewayTest is Test { vm.expectEmit(true, true, false, false); emit Transfer(address(0), account1, 1000); - MockGateway(address(gateway)).mintForeignTokenPublic(abi.encode(params)); + MockGateway(address(gateway)).mintForeignTokenPublic(assetHubParaID.into(), abi.encode(params)); address dotToken = MockGateway(address(gateway)).tokenAddressOf(dotTokenID); @@ -916,7 +916,16 @@ contract GatewayTest is Test { vm.expectRevert(Assets.TokenNotRegistered.selector); - MockGateway(address(gateway)).mintForeignTokenPublic(abi.encode(params)); + MockGateway(address(gateway)).mintForeignTokenPublic(assetHubParaID.into(), abi.encode(params)); + } + + function testMintFromParachainOtherThanAssetHubWillFail() public { + MintForeignTokenParams memory params = + MintForeignTokenParams({foreignTokenID: bytes32(uint256(1)), recipient: account1, amount: 1000}); + + vm.expectRevert(Assets.TokenMintFailed.selector); + + MockGateway(address(gateway)).mintForeignTokenPublic(bridgeHubParaID.into(), abi.encode(params)); } function testSendRelayTokenToAssetHubWithAddress32() public { diff --git a/contracts/test/mocks/MockGateway.sol b/contracts/test/mocks/MockGateway.sol index 4356bb9876..441961e0ca 100644 --- a/contracts/test/mocks/MockGateway.sol +++ b/contracts/test/mocks/MockGateway.sol @@ -2,7 +2,7 @@ pragma solidity 0.8.25; import {Gateway} from "../../src/Gateway.sol"; -import {ParaID, OperatingMode} from "../../src/Types.sol"; +import {ChannelID, ParaID, OperatingMode} from "../../src/Types.sol"; import {CoreStorage} from "../../src/storage/CoreStorage.sol"; import {Verification} from "../../src/Verification.sol"; import {IInitializable} from "../../src/interfaces/IInitializable.sol"; @@ -81,8 +81,8 @@ contract MockGateway is Gateway { this.registerForeignToken(params); } - function mintForeignTokenPublic(bytes calldata params) external { - this.mintForeignToken(params); + function mintForeignTokenPublic(ChannelID channelID, bytes calldata params) external { + this.mintForeignToken(channelID, params); } function transferNativeTokenPublic(bytes calldata params) external {