IMA Access Control

Introduction

The SKALE Chain owner has special permissions to configure SKALE Chain access control. The owner may choose a "permission-by-owner" policy, selectively restricting access to only certain users and/or tokens, or may choose a permissionless policy, enabling any user and/or tokens. This access control includes several features:

SKALE Chain FUEL
  • controlling how users access SKALE Chain FUEL (sFUEL) to perform transactions.

IMA token exchange
  • controlling which tokens transfer between Mainnet and SKALE Chains.

This document describes how SKALE Chain owners can set permissions for the IMA Bridge. There are two general categories:

  • Owner permissions for IMA Mainnet

  • Owner permissions for IMA SKALE Chain

There are several IMA SKALE Chain roles that can be granted by the owner, these include:

  • CHAIN_CONNECTOR_ROLE

  • EXTRA_CONTRACT_REGISTRAR_ROLE

  • CONSTANT_SETTER_ROLE (MessageProxy)

  • CONSTANT_SETTER_ROLE (CommunityLocker)

  • REGISTRAR_ROLE

  • AUTOMATIC_DEPLOY_ROLE

  • TOKEN_REGISTRAR_ROLE

Owner IMA Mainnet Permissions

Table 1. Owner IMA Mainnet Permissions
Contracts Functions Description

DepositBoxERC20 DepositBoxERC721 DepositBoxERC1155

enableWhitelist disableWhitelist

Enable/disable whitelist (default: enabled). Whitelist allows only specific tokens to be used with the IMA Bridge.

addERC20TokenByOwner addERC721TokenByOwner addERC1155TokenByOwner

Allows owner to manually map tokens to the bridge.

DepositBoxEth DepositBoxERC20 DepositBoxERC721 DepositBoxERC1155

getFunds

If the kill operation is executed, allows owner to return tokens to end-users.

MessageProxyForMainnet

registerExtraContract removeExtraContract

Allows owner to add/remove extra contracts to/from the IMA Bridge.

Linker

allowInterchainConnections

Allows owner to connect other chains (that they own) to the IMA bridge.

kill

Allows owner and contract deployer to kill the SKALE Chain IMA Bridge and allow owner to execute getFunds(). Both roles must call this function to execute. Reserved only for extraordinary situations.

IMA SKALE Chain Permissions

Table 2. IMA SKALE Chain Permissions
Contracts Functions Description

ProxyAdmin

Allows owner to upgrade contracts.

MessageProxyForSchain

grantRole

Allows owner to grant CHAIN_CONNECTOR_ROLE, EXTRA_CONTRACT_REGISTRAR_ROLE, REGISTRAR_ROLE, AUTOMATIC_DEPLOY_ROLE, TOKEN_REGISTRAR_ROLE and CONSTANT_SETTER_ROLE.

addConnectedChain removeConnectedChain

Allows owner or CHAIN_CONNECTOR_ROLE to add/remove a chain.

registerExtraContract removeExtraContract

Allows owner or EXTRA_CONTRACT_REGISTRAR_ROLE to add/remove an extra SKALE Chain contract to/from the IMA Bridge.

setNewGasLimit

Allows owner or CONSTANT_SETTER_ROLE to set a new gas limit for MessageProxy outgoing messages.

TokenManagerEth

setEthErc20Address

Allows owner to set a new address for ETHERC20 (wrapped ETH) on SKALE.

TokenManagerERC20 TokenManagerERC721 TokenManagerERC1155

grantRole

Allows owner to grant AUTOMATIC_DEPLOY_ROLE, and TOKEN_REGISTRAR_ROLE.

addTokenManager removeTokenManager

Allows owner to add/remove other TokenManagers to the IMA Bridge.

changeDepositBoxAddress

Allows owner to set a new DepositBox address.

enableAutomaticDeploy disableAutomaticDeploy

Allows owner or AUTOMATIC_DEPLOY_ROLE to enable/disable automatic deployment (default: disabled).

addERC20TokenByOwner addERC721TokenByOwner addERC1155TokenByOwner

Allows owner or TOKEN_REGISTRAR_ROLE to manually map tokens to the SKALE Chain side of the IMA Bridge.

TokenManagerLinker

registerTokenManager removeTokenManager

Allows owner or REGISTRAR_ROLE to add/remove TokenManager contracts.

connectSchain disconnectSchain

Allows owner or REGISTRAR_ROLE to connect/disconnect SKALE Chains.

CommunityLocker

setTimeLimitPerMessage

Allows owner or CONSTANT_SETTER_ROLE to set a new rate limit for exit messages. (default: 5 minutes per SKALE Chain exit message).

Enable or Disable the Whitelist

The token whitelist allows the SKALE chain owner to allow token exchange through IMA and a SKALE chain. For example, a decentralized exchange may prefer to disable the whitelist to allow any token transfer. A dApp using only one token may enable the whitelist to allow only a single token exchange.

To disable the whitelist, the owner executes disableWhitelist in DepositBoxERC20/721/1155 contracts, and pass in the schainName as the only argument. For example:

  • Python

deposit_box_erc20 = self._get_contract_on_mainnet('deposit_box_erc20')
disable = deposit_box_erc20.encodeABI(fn_name="disableWhitelist", args=[schainName])

signed_txn = self.web3_mainnet.eth.account.signTransaction(dict(
        nonce=self.web3_mainnet.eth.getTransactionCount(sender_address),
        gasPrice=self.web3_mainnet.eth.gasPrice,
        gas=200000,
        to=deposit_box_erc20.address,
        value=0,
        data = disable
    ),
    from_key)

self.web3_mainnet.eth.sendRawTransaction(signed_txn.rawTransaction)

To re-enable the whitelist:

  • Python

deposit_box_erc20 = self._get_contract_on_mainnet('deposit_box_erc20')
enable = deposit_box_erc20.encodeABI(fn_name="enableWhitelist", args=[schainName])

signed_txn = self.web3_mainnet.eth.account.signTransaction(dict(
        nonce=self.web3_mainnet.eth.getTransactionCount(sender_address),
        gasPrice=self.web3_mainnet.eth.gasPrice,
        gas=200000,
        to=deposit_box_erc20.address,
        value=0,
        data = enable
    ),
    from_key)

self.web3_mainnet.eth.sendRawTransaction(signed_txn.rawTransaction)

Adding tokens with Enabled Whitelist

If the whitelist is enabled, the SKALE chain owner must authorize each token for the schain.

You can use addERC20TokenByOwner, addERC721TokenByOwner, and addERC1155TokenByOwner functions available in DepositBoxERC20, DepositBoxERC721, DepositBox1155, and TokenManagerERC20, TokenManagerERC721, TokenManagerERC1155 contracts on both Mainnet and each SKALE chain.

The recommended process is

  1. Deploy the ERC20/ERC721/ERC1155 token contract on the SKALE chain.

  2. Add the token to TokenManagerERC20/TokenManagerERC721/TokenManager1155 on the SKALE chain.

  3. Grant the token’s minter role to TokenManagerERC20/TokenManagerERC721/TokenManager1155 on the SKALE chain.

  4. Add the token to DepositBoxERC20/DepositBoxERC721/DepositBox1155 on Mainnet.

Adding tokens to TokenManager

Adding ERC20

  • Python

token_manager_erc20 = self._get_contract_on_schain('token_manager_erc20')
addERC20Schain = token_manager_erc20.encodeABI(fn_name="addERC20TokenByOwner", args=[erc20MainnetAddress, erc20SchainAddress])

signed_txn = self.web3_schain.eth.account.signTransaction(dict(
        nonce=self.web3_schain.eth.getTransactionCount(sender_address),
        gasPrice=self.web3_schain.eth.gasPrice,
        gas=200000,
        to=token_manager_erc20.address,
        value=0,
        data = addERC20Schain
    ),
    from_key)

self.web3_schain.eth.sendRawTransaction(signed_txn.rawTransaction)

Adding ERC721

  • Python

token_manager_erc721 = self._get_contract_on_schain('token_manager_erc721')
addERC721Schain = token_manager_erc721.encodeABI(fn_name="addERC721TokenByOwner", args=[erc721MainnetAddress, erc721SchainAddress])

signed_txn = self.web3_schain.eth.account.signTransaction(dict(
        nonce=self.web3_schain.eth.getTransactionCount(sender_address),
        gasPrice=self.web3_schain.eth.gasPrice,
        gas=200000,
        to=token_manager_erc721.address,
        value=0,
        data = addERC721Schain
    ),
    from_key)

self.web3_schain.eth.sendRawTransaction(signed_txn.rawTransaction)

Assign Schain TokenManager as Minter and Burner role

You need to assign TokenManagerERC20/TokenManagerERC721/TokenManagerERC1155 as the minter and burner for the deployed token on the schain. For AccessControl supported ERC20/ERC721/ERC1155, you can use apply the following pseudocode:

  • Python

newERC20 = deployERC20(deployer)
minterRoleERC20 = newERC20.MINTER_ROLE()
newERC20.grantRole(minterRoleERC20, token_manager_erc20.address)

Adding tokens to DepositBox

addERC20TokenByOwner, addERC721TokenByOwner, addERC1155TokenByOwner on the DepositBox takes 2 arguments: schainName and erc20Mainnet/erc721Mainnet/erc1155Mainnet address.

Adding ERC20

  • Python

deposit_box_erc20 = self._get_contract_on_mainnet('deposit_box_erc20')
addERC20Mainnet = deposit_box_erc20.encodeABI(fn_name="addERC20TokenByOwner", args=[schainName, erc20MainnetAddress])

signed_txn = self.web3_mainnet.eth.account.signTransaction(dict(
        nonce=self.web3_mainnet.eth.getTransactionCount(sender_address),
        gasPrice=self.web3_mainnet.eth.gasPrice,
        gas=200000,
        to=deposit_box_erc20.address,
        value=0,
        data = addERC20Mainnet
    ),
    from_key)

self.web3_mainnet.eth.sendRawTransaction(signed_txn.rawTransaction)

Adding ERC721

addERC721TokenByOwner on the DepositBox takes 2 arguments: schainName and erc721Mainnet address.
  • Python

deposit_box_erc721 = self._get_contract_on_mainnet('deposit_box_erc721')
addERC721Mainnet = deposit_box_erc721.encodeABI(fn_name="addERC721TokenByOwner", args=[schainName, erc721MainnetAddress])

signed_txn = self.web3_mainnet.eth.account.signTransaction(dict(
        nonce=self.web3_mainnet.eth.getTransactionCount(sender_address),
        gasPrice=self.web3_mainnet.eth.gasPrice,
        gas=200000,
        to=deposit_box_erc721.address,
        value=0,
        data = addERC20Mainnet
    ),
    from_key)

self.web3_mainnet.eth.sendRawTransaction(signed_txn.rawTransaction)

Automatic deployment

Automatic deployment is disabled by default and requires that the SKALE Chain owner deploys the token contract on the schain.

If enabled, then tokens are automatically deployed on the schain by the TokenFactory contract after a token is received through DepositBox on mainnet.