IMA Access Control

Introduction

The SKALE Chain owner has special permissions to configure SKALE Chain access control. The owner may choose a permissive policy, 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 ETH
  • controlling how users access SKALE Chain ETH 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 IMA token exchange.

IMA permissions include:

  • Enable/disable IMA token whitelist on mainnet (default: enabled)

  • Enable/disable automatic deployment on SKALE Chain (default: disabled)

  • AddERC20TokenByOwner on mainnet and on SKALE Chain

  • AddERC721TokenByOwner on mainnet and on SKALE Chain

  • AddERC1155TokenByOwner on mainnet and on SKALE Chain

The general architecture is that:

  • Enable/disable permissions are set using DepositBox and TokenManager contracts on Ethereum and on a SKALE Chain.

  • Mapping (AddERC20TokenByOwner, AddERC721TokenByOwner, AddERC1155TokenByOwner) are set using the respective DepositBoxERC20, DepositBoxERC721, DepositBoxERC1155.

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.