From 012896ee9a87f0dad478646531b1b2ec83525172 Mon Sep 17 00:00:00 2001 From: Brendan Graetz Date: Tue, 6 Jan 2026 15:58:14 +0800 Subject: [PATCH 1/9] docs: minor - syntax cleanup of MTS page Signed-off-by: Brendan Graetz --- .../developers-evm/multivm-token-standard.mdx | 64 +++++++++++++------ 1 file changed, 43 insertions(+), 21 deletions(-) diff --git a/.gitbook/developers-evm/multivm-token-standard.mdx b/.gitbook/developers-evm/multivm-token-standard.mdx index 38359cb2..68c6e509 100644 --- a/.gitbook/developers-evm/multivm-token-standard.mdx +++ b/.gitbook/developers-evm/multivm-token-standard.mdx @@ -1,11 +1,15 @@ --- -description: Understanding token representation in Injective's multi-VM architecture title: MultiVM Token Standard +description: Understanding token representation in Injective's multi-VM architecture --- ## What is MultiVM Token Standard (MTS)? -MTS (MultiVM Token Standard) ensures that every token on Injective—whether deployed using Cosmos modules or via the Ethereum Virtual Machine (EVM)—has one canonical balance and identity. This unified approach prevents fragmentation and eliminates the need for bridging or wrapping tokens, thereby enabling seamless interoperability and unified liquidity for decentralized finance (DeFi) and dApp interactions. +MTS (MultiVM Token Standard) ensures that every token on Injective - +whether deployed using Cosmos modules or via the Ethereum Virtual Machine (EVM) — +has one canonical balance and identity. +This unified approach prevents fragmentation and eliminates the need for bridging or wrapping tokens, +thereby enabling seamless interoperability and unified liquidity for decentralized finance (DeFi) and dApp interactions. ## Why is MTS Important? @@ -27,7 +31,7 @@ The system comprises two main components:

Single Token Representation Architecture

-### **Creating an** MTS**-Compliant Token** +### Creating an** MTS-Compliant Token 1. [**Using Our Prebuilt Templates**](https://github.com/InjectiveLabs/solidity-contracts/tree/master/src): * Start with the provided Solidity templates, such as `BankERC20.sol`, `MintBurnBankERC20.sol`, or `FixedSupplyBankERC20.sol`. @@ -35,38 +39,56 @@ The system comprises two main components: * Deploy your MTS token contract on the Injective EVM network. * The contract automatically interacts with the Bank Precompile to update the canonical state. -### **Interoperability and Cross-Chain Integration** +### Interoperability and Cross-Chain Integration -#### **Native Interoperability** +#### Native Interoperability* Injective’s EVM is integrated directly into the Cosmos-based chain. -* EVM smart contracts, when using MTS, perform operations that reflect immediately on native modules (such as the exchange, staking, and governance modules). -* [JSON-RPC endpoints](/developers-evm/network-information/) provided within the Injective binary are compatible with Ethereum, ensuring smooth developer integration. +* EVM smart contracts, when using MTS, perform operations that reflect immediately + on native modules (such as the exchange, staking, and governance modules). +* [JSON-RPC endpoints](/developers-evm/network-information/) + provided within the Injective binary are compatible with Ethereum, + ensuring smooth developer integration. -#### **Cross-Chain Operations** +#### Cross-Chain Operations -* **IBC Compatibility:** Existing native tokens (e.g., those created via a [Token Factory](/developers-native/injective/tokenfactory/) or pegged via Peggy) are accessible from the EVM once an MTS pairing is established. -* **Bridging Alternatives:** While many blockchains require separate bridge operations (lock, mint, unlock), MTS avoids these steps by natively synchronizing states. +* **IBC Compatibility:** Existing native tokens + (e.g., those created via a + [Token Factory](/developers-native/injective/tokenfactory/) or pegged via Peggy) + are accessible from the EVM once an MTS pairing is established. +* **Bridging Alternatives:** While many blockchains require separate bridge operations (lock, mint, unlock), + MTS avoids these steps by natively synchronizing states. -#### **Allowances & Extended ERC20 Functions** +#### Allowances & Extended ERC20 Functions -* MTS contracts maintain standard ERC20 functionalities such as allowances (approve/transferFrom). -* Note that while the allowance mechanism is maintained within the EVM contract for convenience, the ultimate balance is managed by the bank module, preserving integrity. +* MTS contracts maintain standard ERC20 functionalities such as allowances + (approve/transferFrom). +* Note that while the allowance mechanism is maintained within the EVM contract for convenience, + the ultimate balance is managed by the bank module, preserving integrity. -### **Performance, Gas, and Security Considerations** +### Performance, Gas, and Security Considerations -#### **Gas Costs and Efficiency** +#### Gas Costs and Efficiency -* Gas fees are paid in INJ. While MTS operations via the EVM introduce an abstraction layer that may slightly increase gas usage compared to native transactions, the overall cost remains lower than comparable operations on Ethereum. +* Gas fees are paid in INJ. + While MTS operations via the EVM introduce an abstraction layer that may slightly increase gas usage compared to native transactions, + the overall cost remains lower than comparable operations on Ethereum. * The gas model is designed to reflect a balance between EVM-style opcode costs and native module interactions. -#### **Security** +#### Security -* The [bank module](/developers-native/core/), as the single source of truth, underpins MTS’s security by ensuring that token balances are consistent and verifiable. -* The use of [precompiles](/developers-evm/precompiles/) prevents common pitfalls like state desynchronization, ensuring that all operations—no matter where initiated—update the same canonical ledger. -* Advanced security guidelines and best practices for smart contract development are provided in our security section and external resources. +* The [bank module](/developers-native/core/), as the single source of truth, + underpins MTS’s security by ensuring that token balances are consistent and verifiable. +* The use of [precompiles](/developers-evm/precompiles/) prevents common pitfalls + like state desynchronization, ensuring that all operations - + no matter where initiated—update the same canonical ledger. +* Advanced security guidelines and best practices for smart contract development + are provided in our security section and external resources. **ℹ️ Note:** -To prevent denom spam, deploying an ERC20 contract via the ERC20 module is a **payable operation** and requires a deployment fee of **1 INJ**. Make sure your ERC20 contract deployment transaction includes this amount, or the operation will be rejected. +To prevent denom spam, deploying an ERC20 contract via the ERC20 module +is a **payable operation** and requires a deployment fee of **1 INJ**. +Make sure your ERC20 contract deployment transaction includes this amount, +or the operation will be rejected. From 7c7c3f64362f3e0649550bb4974139bbaf66708f Mon Sep 17 00:00:00 2001 From: Brendan Graetz Date: Tue, 6 Jan 2026 16:04:45 +0800 Subject: [PATCH 2/9] docs: add permissioned MTS page (blank) Signed-off-by: Brendan Graetz --- .../permissioned-multivm-token.mdx | 17 +++++++++++++++++ .gitbook/docs.json | 4 ++++ 2 files changed, 21 insertions(+) create mode 100644 .gitbook/developers-evm/permissioned-multivm-token.mdx diff --git a/.gitbook/developers-evm/permissioned-multivm-token.mdx b/.gitbook/developers-evm/permissioned-multivm-token.mdx new file mode 100644 index 00000000..4e976c27 --- /dev/null +++ b/.gitbook/developers-evm/permissioned-multivm-token.mdx @@ -0,0 +1,17 @@ +--- +title: Permissioned MTS Tokens +description: Leverage Injective's permissions module in MultiVM Token Standard (MTS) tokens +--- + +## Injective's Permissions Module + +TODO + +## Why Uses Permissions on MTS Tokens? + +TODO + +## Implementation + +TODO + diff --git a/.gitbook/docs.json b/.gitbook/docs.json index a3eb99ec..620329d1 100644 --- a/.gitbook/docs.json +++ b/.gitbook/docs.json @@ -1434,6 +1434,10 @@ "source": "/developers/evm-developers/technical-information/multivm-token-standard", "destination": "/developers-evm/multivm-token-standard" }, + { + "source": "/developers/evm-developers/technical-information/permissioned-multivm-token", + "destination": "/developers-evm/permissioned-multivm-token" + }, { "source": "/developers/evm-developers/technical-information/precompiles", "destination": "/developers-evm/precompiles" From c192f378ffd09850eb359366da74cbb84d6f0f5b Mon Sep 17 00:00:00 2001 From: Brendan Graetz Date: Tue, 6 Jan 2026 16:28:54 +0800 Subject: [PATCH 3/9] docs: add docs for permissioned MTS tokens Signed-off-by: Brendan Graetz --- .../permissioned-multivm-token.mdx | 69 ++++++++++++++++++- 1 file changed, 66 insertions(+), 3 deletions(-) diff --git a/.gitbook/developers-evm/permissioned-multivm-token.mdx b/.gitbook/developers-evm/permissioned-multivm-token.mdx index 4e976c27..9e494be0 100644 --- a/.gitbook/developers-evm/permissioned-multivm-token.mdx +++ b/.gitbook/developers-evm/permissioned-multivm-token.mdx @@ -5,13 +5,76 @@ description: Leverage Injective's permissions module in MultiVM Token Standard ( ## Injective's Permissions Module -TODO +The [`permissions` module](https://docs.injective.network/developers-native/injective/permissions) +is native to Injective, and allows custom management (e.g. roles) for Denoms. +This capability is extended to MultiVM Token Standard (MTS) tokens, +where you can implement those custom management rules within your EVM smart contract code. ## Why Uses Permissions on MTS Tokens? -TODO +If you are tokenizing real world assets (RWAs) using MTS on Injective, +and that underlying asset inherently requires permissions, +that is a great use case for tapping into Injective's `permissions` module. + +The EVM smart contract of your MTS token simply needs to implement +an additional Solidity interface to leverage the power of the `permissions` module. ## Implementation -TODO +In your smart contract, import `IPermissionsHook` from `PermissionsHook.sol` and extend it. + +```solidity +interface IPermissionsHook +``` + +This will involve implementing the `isTransferRestricted` function, +with the following signature: + +```solidity +function isTransferRestricted( + address from, + address to, + Cosmos.Coin calldata amount +) +``` + +You may find the full file on Github: +[`PermissionsHook.sol`](https://github.com/InjectiveLabs/solidity-contracts/blob/master/src/PermissionsHook.sol) + +## Example + +Create a smart contract that extends `PermissionsHook`: + +```solidity +import { Cosmos } from "../src/CosmosTypes.sol"; +import { PermissionsHook } from "../src/PermissionsHook.sol"; +contract RestrictedAddressTransferHook is PermissionsHook { + /* + ... + */ +} +``` + +Add a custom implementation of the `isTransferRestricted` function. +For example, this function will allow all transfers, +exepct for ones involving a specific address: + +```solidity + function isTransferRestricted( + address from, + address to, + Cosmos.Coin calldata amount + ) external pure override returns (bool) { + address restrictedAddress = '0x...'; + if (from == restrictedAddress || to == restrictedAddress) { + // this particular address is not allowed to transfer + return true; + } + + // All other transfers are allowed + return false; + } +``` +You may find a more detailed example of this on Github: +[`PermissionsHookExamples.sol`](https://github.com/InjectiveLabs/solidity-contracts/blob/master/examples/PermissionsHookExamples.sol) From 19c66c1b2236e843fd90f951eb25f42e735ed64b Mon Sep 17 00:00:00 2001 From: Brendan Graetz Date: Tue, 6 Jan 2026 17:00:33 +0800 Subject: [PATCH 4/9] fix: nav menu error Signed-off-by: Brendan Graetz --- .gitbook/docs.json | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/.gitbook/docs.json b/.gitbook/docs.json index 620329d1..c37aeac3 100644 --- a/.gitbook/docs.json +++ b/.gitbook/docs.json @@ -272,6 +272,7 @@ }, "developers-evm/evm-equivalence", "developers-evm/multivm-token-standard", + "developers-evm/permissioned-multivm-token", "developers-evm/wrapped-inj", "developers-evm/precompiles", "developers-evm/bank-precompile", @@ -1434,10 +1435,6 @@ "source": "/developers/evm-developers/technical-information/multivm-token-standard", "destination": "/developers-evm/multivm-token-standard" }, - { - "source": "/developers/evm-developers/technical-information/permissioned-multivm-token", - "destination": "/developers-evm/permissioned-multivm-token" - }, { "source": "/developers/evm-developers/technical-information/precompiles", "destination": "/developers-evm/precompiles" From aec3883b57a955cc86818e1fbc125577a0383705 Mon Sep 17 00:00:00 2001 From: Brendan Graetz Date: Tue, 6 Jan 2026 17:14:36 +0800 Subject: [PATCH 5/9] docs: instructions on registering a hook Signed-off-by: Brendan Graetz --- .../permissioned-multivm-token.mdx | 71 ++++++++++++++++++- 1 file changed, 69 insertions(+), 2 deletions(-) diff --git a/.gitbook/developers-evm/permissioned-multivm-token.mdx b/.gitbook/developers-evm/permissioned-multivm-token.mdx index 9e494be0..791f57eb 100644 --- a/.gitbook/developers-evm/permissioned-multivm-token.mdx +++ b/.gitbook/developers-evm/permissioned-multivm-token.mdx @@ -19,7 +19,7 @@ that is a great use case for tapping into Injective's `permissions` module. The EVM smart contract of your MTS token simply needs to implement an additional Solidity interface to leverage the power of the `permissions` module. -## Implementation +## Smart Contract Implementation In your smart contract, import `IPermissionsHook` from `PermissionsHook.sol` and extend it. @@ -41,7 +41,7 @@ function isTransferRestricted( You may find the full file on Github: [`PermissionsHook.sol`](https://github.com/InjectiveLabs/solidity-contracts/blob/master/src/PermissionsHook.sol) -## Example +### Smart Contract Example Create a smart contract that extends `PermissionsHook`: @@ -78,3 +78,70 @@ exepct for ones involving a specific address: You may find a more detailed example of this on Github: [`PermissionsHookExamples.sol`](https://github.com/InjectiveLabs/solidity-contracts/blob/master/examples/PermissionsHookExamples.sol) + +## Registering Hook + +In order to register the hook for the permissions, +you will need the following: + +- Control of the same account that deployed the MTS token. +- The deployed address of the MTS token +- The deployed address of the Permissions Hook +- The address of the account which should have an *admin* role on the MTS token. + +With the above, you can create +[a JSON file similar to this one](https://github.com/InjectiveLabs/stablecoin-evm/blob/fiattoken-inj/scripts/demo/namespace.json). + +Then run `injectived` for the registration, +using the same account that deployed the MTS token. + +```shell +injectived tx permissions create-namespace ... +``` + + +Note that the MTS token and the Permissions Hook can have the same address. +That is an architectrual decision that is up to you. + + +### Registering Hook Example + +Create a file named `register-hooks.json`, with the following content: + +```jsonc +{ + "denom": "erc20:0x...", // <-- EVM address of the MTS token + "evm_hook": "0x...", // <-- EVM address of the permissions hook + "role_permissions": [ + { + "name": "EVERYONE", + "role_id": 0, + "permissions": 10 + }, + { + "name": "admin", + "role_id": 1, + "permissions": 2013265920 + } + ], + "actor_roles": [ + { + "actor": "inj...", // <-- Injective address of the admin account + "roles": ["admin"] + } + ] +} +``` + +Be sure to replace the value of the +`denom`, `evm_hook`, and `actor_roles[].actor` fields with the appropriate values. +Delete all comments as well, so that the file is valid JSON. + +Then run the following command: + +```shell +injectived tx permissions create-namespace register-hooks.json [flags] +``` + +For additional details on this step, refer to +[How to Launch Permissioned Assets](https://docs.injective.network/developers-native/injective/permissions/04_launch_permissioned_asset). From 62f3c2d67767b4afeee3a91271f77b2f53eb4776 Mon Sep 17 00:00:00 2001 From: Brendan Graetz Date: Tue, 6 Jan 2026 17:17:28 +0800 Subject: [PATCH 6/9] docs: minor - fix typos Signed-off-by: Brendan Graetz --- .gitbook/developers-evm/multivm-token-standard.mdx | 2 +- .gitbook/developers-evm/permissioned-multivm-token.mdx | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.gitbook/developers-evm/multivm-token-standard.mdx b/.gitbook/developers-evm/multivm-token-standard.mdx index 68c6e509..cb9ba02b 100644 --- a/.gitbook/developers-evm/multivm-token-standard.mdx +++ b/.gitbook/developers-evm/multivm-token-standard.mdx @@ -31,7 +31,7 @@ The system comprises two main components:

Single Token Representation Architecture

-### Creating an** MTS-Compliant Token +### Creating an MTS-Compliant Token 1. [**Using Our Prebuilt Templates**](https://github.com/InjectiveLabs/solidity-contracts/tree/master/src): * Start with the provided Solidity templates, such as `BankERC20.sol`, `MintBurnBankERC20.sol`, or `FixedSupplyBankERC20.sol`. diff --git a/.gitbook/developers-evm/permissioned-multivm-token.mdx b/.gitbook/developers-evm/permissioned-multivm-token.mdx index 791f57eb..6bb1bc47 100644 --- a/.gitbook/developers-evm/permissioned-multivm-token.mdx +++ b/.gitbook/developers-evm/permissioned-multivm-token.mdx @@ -10,9 +10,9 @@ is native to Injective, and allows custom management (e.g. roles) for Denoms. This capability is extended to MultiVM Token Standard (MTS) tokens, where you can implement those custom management rules within your EVM smart contract code. -## Why Uses Permissions on MTS Tokens? +## Why Use Permissions on MTS Tokens? -If you are tokenizing real world assets (RWAs) using MTS on Injective, +If you are tokenizing real-world assets (RWAs) using MTS on Injective, and that underlying asset inherently requires permissions, that is a great use case for tapping into Injective's `permissions` module. @@ -57,7 +57,7 @@ contract RestrictedAddressTransferHook is PermissionsHook { Add a custom implementation of the `isTransferRestricted` function. For example, this function will allow all transfers, -exepct for ones involving a specific address: +except for ones involving a specific address: ```solidity function isTransferRestricted( @@ -65,7 +65,7 @@ exepct for ones involving a specific address: address to, Cosmos.Coin calldata amount ) external pure override returns (bool) { - address restrictedAddress = '0x...'; + address restrictedAddress = "0x..."; if (from == restrictedAddress || to == restrictedAddress) { // this particular address is not allowed to transfer return true; From 6b4f5b07fe0d28cd0604259b01950b593f430e56 Mon Sep 17 00:00:00 2001 From: Brendan Graetz Date: Tue, 6 Jan 2026 17:28:21 +0800 Subject: [PATCH 7/9] docs: add reference impl for stablecoins: Signed-off-by: Brendan Graetz --- .../permissioned-multivm-token.mdx | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/.gitbook/developers-evm/permissioned-multivm-token.mdx b/.gitbook/developers-evm/permissioned-multivm-token.mdx index 6bb1bc47..87369e03 100644 --- a/.gitbook/developers-evm/permissioned-multivm-token.mdx +++ b/.gitbook/developers-evm/permissioned-multivm-token.mdx @@ -145,3 +145,28 @@ injectived tx permissions create-namespace register-hooks.json [flags] For additional details on this step, refer to [How to Launch Permissioned Assets](https://docs.injective.network/developers-native/injective/permissions/04_launch_permissioned_asset). + +## Reference Implementation + +A more complete example theat demonstrates the use of permissioned MTS tokens +for a stable coin is also available. + +This example involves a permissions hook which prevents transfers +when the token is paused, and also maintains a blacklist of addresses. + +```solidity +function isTransferRestricted( + address _from, + address _to, + Cosmos.Coin calldata /* _amount */ +) external view returns (bool) { + if (fiatToken.paused()) { + return true; + } else if (fiatToken.isBlacklisted(_from) || fiatToken.isBlacklisted(_to)) { + return true; + } + + return false; +} +``` +See [`PermissionsHook_Inj.sol`](https://github.com/InjectiveLabs/stablecoin-evm/blob/fiattoken-inj/contracts/v2/PermissionsHook_Inj.sol). From b6a0c01b429df65428afea4a9daa89d8ebb83082 Mon Sep 17 00:00:00 2001 From: Brendan Graetz Date: Tue, 6 Jan 2026 17:57:58 +0800 Subject: [PATCH 8/9] docs: minor - fix typos Signed-off-by: Brendan Graetz --- .gitbook/developers-evm/permissioned-multivm-token.mdx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.gitbook/developers-evm/permissioned-multivm-token.mdx b/.gitbook/developers-evm/permissioned-multivm-token.mdx index 87369e03..5f62b9ed 100644 --- a/.gitbook/developers-evm/permissioned-multivm-token.mdx +++ b/.gitbook/developers-evm/permissioned-multivm-token.mdx @@ -81,7 +81,7 @@ You may find a more detailed example of this on Github: ## Registering Hook -In order to register the hook for the permissions, +To register the hook for the permissions, you will need the following: - Control of the same account that deployed the MTS token. @@ -101,7 +101,7 @@ injectived tx permissions create-namespace ... Note that the MTS token and the Permissions Hook can have the same address. -That is an architectrual decision that is up to you. +That is an architectural decision that is up to you. ### Registering Hook Example @@ -148,7 +148,7 @@ For additional details on this step, refer to ## Reference Implementation -A more complete example theat demonstrates the use of permissioned MTS tokens +A more complete example that demonstrates the use of permissioned MTS tokens for a stable coin is also available. This example involves a permissions hook which prevents transfers From a7881f2a655821e6c040f17f2dbf990fbaeea7c3 Mon Sep 17 00:00:00 2001 From: Brendan Graetz Date: Tue, 6 Jan 2026 22:11:38 +0800 Subject: [PATCH 9/9] docs: updates basd on feedback from @kakysha Signed-off-by: Brendan Graetz --- .../permissioned-multivm-token.mdx | 20 ++++++++----------- 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/.gitbook/developers-evm/permissioned-multivm-token.mdx b/.gitbook/developers-evm/permissioned-multivm-token.mdx index 5f62b9ed..fdbcbd9e 100644 --- a/.gitbook/developers-evm/permissioned-multivm-token.mdx +++ b/.gitbook/developers-evm/permissioned-multivm-token.mdx @@ -87,7 +87,6 @@ you will need the following: - Control of the same account that deployed the MTS token. - The deployed address of the MTS token - The deployed address of the Permissions Hook -- The address of the account which should have an *admin* role on the MTS token. With the above, you can create [a JSON file similar to this one](https://github.com/InjectiveLabs/stablecoin-evm/blob/fiattoken-inj/scripts/demo/namespace.json). @@ -117,25 +116,19 @@ Create a file named `register-hooks.json`, with the following content: "name": "EVERYONE", "role_id": 0, "permissions": 10 - }, - { - "name": "admin", - "role_id": 1, - "permissions": 2013265920 } ], "actor_roles": [ - { - "actor": "inj...", // <-- Injective address of the admin account - "roles": ["admin"] - } ] } ``` Be sure to replace the value of the -`denom`, `evm_hook`, and `actor_roles[].actor` fields with the appropriate values. +`denom` and `evm_hook` fields with the appropriate values. + + Delete all comments as well, so that the file is valid JSON. + Then run the following command: @@ -143,7 +136,9 @@ Then run the following command: injectived tx permissions create-namespace register-hooks.json [flags] ``` -For additional details on this step, refer to +Note that this is merely one specific way to define permissions hooks on an MTS token. +There are multiple variations. +For additional details on this step, including other variations, refer to [How to Launch Permissioned Assets](https://docs.injective.network/developers-native/injective/permissions/04_launch_permissioned_asset). ## Reference Implementation @@ -169,4 +164,5 @@ function isTransferRestricted( return false; } ``` + See [`PermissionsHook_Inj.sol`](https://github.com/InjectiveLabs/stablecoin-evm/blob/fiattoken-inj/contracts/v2/PermissionsHook_Inj.sol).