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:
-
controlling how users access SKALE Chain FUEL (sFUEL) to perform transactions.
-
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
Contracts | Functions | Description |
---|---|---|
DepositBoxERC20 DepositBoxERC721 DepositBoxERC1155 |
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 |
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
Contracts | Functions | Description |
---|---|---|
ProxyAdmin |
Allows owner to upgrade contracts. |
|
MessageProxyForSchain |
grantRole |
Allows owner to grant |
addConnectedChain removeConnectedChain |
Allows owner or |
|
registerExtraContract removeExtraContract |
Allows owner or |
|
setNewGasLimit |
Allows owner or |
|
TokenManagerEth |
setEthErc20Address |
Allows owner to set a new address for ETHERC20 (wrapped ETH) on SKALE. |
TokenManagerERC20 TokenManagerERC721 TokenManagerERC1155 |
grantRole |
Allows owner to grant |
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 |
|
addERC20TokenByOwner addERC721TokenByOwner addERC1155TokenByOwner |
Allows owner or |
|
TokenManagerLinker |
registerTokenManager removeTokenManager |
Allows owner or |
connectSchain disconnectSchain |
Allows owner or |
|
CommunityLocker |
setTimeLimitPerMessage |
Allows owner or |
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:
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:
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
-
Deploy the ERC20/ERC721/ERC1155 token contract on the SKALE chain.
-
Add the token to TokenManagerERC20/TokenManagerERC721/TokenManager1155 on the SKALE chain.
-
Grant the token’s minter role to TokenManagerERC20/TokenManagerERC721/TokenManager1155 on the SKALE chain.
-
Add the token to DepositBoxERC20/DepositBoxERC721/DepositBox1155 on Mainnet.
Adding tokens to TokenManager
Adding ERC20
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
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:
Adding tokens to DepositBox
addERC20TokenByOwner , addERC721TokenByOwner , addERC1155TokenByOwner on the DepositBox takes 2 arguments: schainName and erc20Mainnet/erc721Mainnet/erc1155Mainnet address.
|
Adding ERC20
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.
|
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)