MainchainGatewayManager
About
Stats
Public Functions
20
Event Types
6
Code Size
29,629 bytes
Library Use
Uses AddressUtils for address.
Uses SafeMath for uint256.
Uses ECVerify for bytes32.
Events (6) keyboard_arrow_up
State Variables (7) keyboard_arrow_up
Functions
changeAdmin keyboard_arrow_up
Modifiers help
onlyAdmin checks for the following:
Source Code
function changeAdmin(address _newAdmin) external onlyAdmin {
require(_newAdmin != address(0));
emit AdminChanged(admin, _newAdmin);
admin = _newAdmin;
}
removeAdmin keyboard_arrow_up
pause keyboard_arrow_up
unpause keyboard_arrow_up
updateRegistry keyboard_arrow_up
Modifiers help
onlyAdmin checks for the following:
Source Code
function updateRegistry(address _registry) external onlyAdmin {
registry = Registry(_registry);
}
constructor keyboard_arrow_up
depositEth keyboard_arrow_up
depositERC20 keyboard_arrow_up
Requirements help
Source Code
function depositERC20(address _token, uint256 _amount)
external
whenNotPaused
returns (uint256)
{
return depositERC20For(msg.sender, _token, _amount);
}
depositERC721 keyboard_arrow_up
Requirements help
Source Code
function depositERC721(address _token, uint256 _tokenId)
external
whenNotPaused
returns (uint256)
{
return depositERC721For(msg.sender, _token, _tokenId);
}
depositEthFor keyboard_arrow_up
Requirements help
Source Code
function depositEthFor(address _owner)
public
payable
whenNotPaused
returns (uint256)
{
address _weth = registry.getContract(registry.WETH_TOKEN());
WETH(_weth).deposit.value(msg.value)();
return _createDepositEntry(_owner, _weth, 20, msg.value);
}
depositERC20For keyboard_arrow_up
Requirements help
Source Code
function depositERC20For(
address _user,
address _token,
uint256 _amount
) public whenNotPaused returns (uint256) {
require(
IERC20(_token).transferFrom(msg.sender, address(this), _amount),
"MainchainGatewayManager: ERC-20 token transfer failed"
);
return _createDepositEntry(_user, _token, 20, _amount);
}
depositERC721For keyboard_arrow_up
Requirements help
Source Code
function depositERC721For(
address _user,
address _token,
uint256 _tokenId
) public whenNotPaused returns (uint256) {
IERC721(_token).transferFrom(msg.sender, address(this), _tokenId);
return _createDepositEntry(_user, _token, 721, _tokenId);
}
depositBulkFor keyboard_arrow_up
Requirements help
Source Code
function depositBulkFor(
address _user,
address[] memory _tokens,
uint256[] memory _tokenNumbers
) public whenNotPaused {
require(_tokens.length == _tokenNumbers.length);
for (uint256 _i = 0; _i < _tokens.length; _i++) {
address _token = _tokens[_i];
uint256 _tokenNumber = _tokenNumbers[_i];
(, , uint32 _standard) = registry.getMappedToken(_token, true);
if (_standard == 20) {
depositERC20For(_user, _token, _tokenNumber);
} else if (_standard == 721) {
depositERC721For(_user, _token, _tokenNumber);
} else {
revert("Token is not mapped or token type not supported");
}
}
}
withdrawToken keyboard_arrow_up
Parameters help
Source Code
function withdrawToken(
uint256 _withdrawalId,
address _token,
uint256 _amount,
bytes memory _signatures
) public whenNotPaused {
withdrawTokenFor(_withdrawalId, msg.sender, _token, _amount, _signatures);
}
withdrawTokenFor keyboard_arrow_up
Parameters help
Source Code
function withdrawTokenFor(
uint256 _withdrawalId,
address _user,
address _token,
uint256 _amount,
bytes memory _signatures
) public whenNotPaused {
(, , uint32 _tokenType) = registry.getMappedToken(_token, true);
if (_tokenType == 20) {
withdrawERC20For(_withdrawalId, _user, _token, _amount, _signatures);
} else if (_tokenType == 721) {
withdrawERC721For(_withdrawalId, _user, _token, _amount, _signatures);
}
}
withdrawERC20 keyboard_arrow_up
withdrawERC20For keyboard_arrow_up
Parameters help
Modifiers help
whenNotPaused checks for the following:
onlyMappedToken checks for the following:
Requirements help
null
Source Code
function withdrawERC20For(
uint256 _withdrawalId,
address _user,
address _token,
uint256 _amount,
bytes memory _signatures
) public whenNotPaused onlyMappedToken(_token, 20) {
bytes32 _hash = keccak256(
abi.encodePacked("withdrawERC20", _withdrawalId, _user, _token, _amount)
);
require(verifySignatures(_hash, _signatures));
if (_token == registry.getContract(registry.WETH_TOKEN())) {
_withdrawETHFor(_user, _amount);
} else {
uint256 _gatewayBalance = IERC20(_token).balanceOf(address(this));
if (_gatewayBalance < _amount) {
require(
IERC20Mintable(_token).mint(
address(this),
_amount.sub(_gatewayBalance)
),
"MainchainGatewayManager: Minting ERC20 token to gateway failed"
);
}
require(IERC20(_token).transfer(_user, _amount), "Transfer failed");
}
_insertWithdrawalEntry(_withdrawalId, _user, _token, _amount);
}
withdrawERC721 keyboard_arrow_up
withdrawERC721For keyboard_arrow_up
Parameters help
Modifiers help
whenNotPaused checks for the following:
onlyMappedToken checks for the following:
Requirements help
null
Source Code
function withdrawERC721For(
uint256 _withdrawalId,
address _user,
address _token,
uint256 _tokenId,
bytes memory _signatures
) public whenNotPaused onlyMappedToken(_token, 721) {
bytes32 _hash = keccak256(
abi.encodePacked("withdrawERC721", _withdrawalId, _user, _token, _tokenId)
);
require(verifySignatures(_hash, _signatures));
if (!_tryERC721TransferFrom(_token, address(this), _user, _tokenId)) {
require(
IERC721Mintable(_token).mint(_user, _tokenId),
"MainchainGatewayManager: Minting ERC721 token to gateway failed"
);
}
_insertWithdrawalEntry(_withdrawalId, _user, _token, _tokenId);
}
verifySignatures keyboard_arrow_up
Source Code
function verifySignatures(bytes32 _hash, bytes memory _signatures)
public
view
returns (bool)
{
uint256 _signatureCount = _signatures.length.div(66);
Validator _validator = Validator(registry.getContract(registry.VALIDATOR()));
uint256 _validatorCount = 0;
address _lastSigner = address(0);
for (uint256 i = 0; i < _signatureCount; i++) {
address _signer = _hash.recover(_signatures, i.mul(66));
if (_validator.isValidator(_signer)) {
_validatorCount++;
}
// Prevent duplication of signatures
require(_signer > _lastSigner);
_lastSigner = _signer;
}
return _validator.checkThreshold(_validatorCount);
}
Internal Functions
Internal functions are parts of the contract that can't be used directly, but instead are used by the public functions listed above.
internal MainchainGatewayManager._createDepositEntry keyboard_arrow_up
Parameters help
Modifiers help
onlyMappedToken checks for the following:
Requirements help
Source Code
function _createDepositEntry(
address _owner,
address _token,
uint32 _standard,
uint256 _number
) internal onlyMappedToken(_token, _standard) returns (uint256 _depositId) {
(, address _sidechainToken, uint32 _tokenStandard) = registry.getMappedToken(
_token,
true
);
require(_standard == _tokenStandard);
DepositEntry memory _entry = DepositEntry(
_owner,
_token,
_sidechainToken,
_standard,
_number
);
deposits.push(_entry);
_depositId = depositCount++;
emit TokenDeposited(
_depositId,
_owner,
_token,
_sidechainToken,
_standard,
_number
);
}
internal MainchainGatewayManager._insertWithdrawalEntry keyboard_arrow_up
Parameters help
Modifiers help
onlyNewWithdrawal checks for the following:
Source Code
function _insertWithdrawalEntry(
uint256 _withdrawalId,
address _owner,
address _token,
uint256 _number
) internal onlyNewWithdrawal(_withdrawalId) {
WithdrawalEntry memory _entry = WithdrawalEntry(_owner, _token, _number);
withdrawals[_withdrawalId] = _entry;
emit TokenWithdrew(_withdrawalId, _owner, _token, _number);
}
internal MainchainGatewayManager._withdrawETHFor keyboard_arrow_up
Source Code
function _withdrawETHFor(address _user, uint256 _amount) internal {
address _weth = registry.getContract(registry.WETH_TOKEN());
WETH(_weth).withdraw(_amount);
_user.toPayable().transfer(_amount);
}
internal MainchainGatewayManager._tryERC721TransferFrom keyboard_arrow_up
Parameters help
Source Code
function _tryERC721TransferFrom(
address _token,
address _from,
address _to,
uint256 _tokenId
) internal returns (bool) {
(bool success, ) = _token.call(
abi.encodeWithSelector(
IERC721(_token).transferFrom.selector,
_from,
_to,
_tokenId
)
);
return success;
}