Blockwell

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

AdminChanged Event

Parameters help
_oldAdmin
address help
_newAdmin
address help

AdminRemoved Event

Parameters help
_oldAdmin
address help

Paused Event

Parameters help

TokenDeposited Event

Parameters help
_depositId
uint256 help
_owner
address help
_tokenAddress
address help
_sidechainAddress
address help
_standard
uint32 help
_tokenNumber
uint256 help

TokenWithdrew Event

Parameters help
_withdrawId
uint256 help
_owner
address help
_tokenAddress
address help
_tokenNumber
uint256 help

Unpaused Event

Parameters help

registry Variable

address help

depositCount Variable

uint256 help

admin Variable

address help

paused Variable

bool help

deposits Variable

DepositEntry[] help
Internal Variable

withdrawals Variable

mapping(uint256 => WithdrawalEntry) help
Internal Variable

_proxyTo Variable

address help
Internal Variable

Functions Expand All Collapse All

changeAdmin keyboard_arrow_up

Parameters help

Name Type
_newAdmin
address help

Properties

Visibility help public
Mutability help transaction

Requirements help

Source Code
function changeAdmin(address _newAdmin) external onlyAdmin {
  require(_newAdmin != address(0));
  emit AdminChanged(admin, _newAdmin);
  admin = _newAdmin;
}

removeAdmin keyboard_arrow_up

Parameters help

This function has no parameters.

Properties

Visibility help public
Mutability help transaction
Source Code
function removeAdmin() external onlyAdmin {
  emit AdminRemoved(admin);
  admin = address(0);
}

pause keyboard_arrow_up

Parameters help

This function has no parameters.

Properties

Visibility help public
Mutability help transaction
Source Code
function pause() public onlyAdmin whenNotPaused {
  paused = true;
  emit Paused();
}

unpause keyboard_arrow_up

Parameters help

This function has no parameters.

Properties

Visibility help public
Mutability help transaction
Source Code
function unpause() public onlyAdmin whenPaused {
  paused = false;
  emit Unpaused();
}

updateRegistry keyboard_arrow_up

Parameters help

Name Type
_registry
address help

Properties

Visibility help public
Mutability help transaction
Source Code
function updateRegistry(address _registry) external onlyAdmin {
  registry = Registry(_registry);
}

constructor keyboard_arrow_up

Parameters help

This function has no parameters.

Properties

Visibility help public
Mutability help payable
Source Code
function() external payable {}

depositEth keyboard_arrow_up

Parameters help

This function has no parameters.

Properties

Visibility help public
Mutability help payable

Modifiers help

Requirements help

Source Code
function depositEth() external payable whenNotPaused returns (uint256) {
  return depositEthFor(msg.sender);
}

depositERC20 keyboard_arrow_up

Parameters help

Name Type
_token
address help
_amount
uint256 help

Properties

Visibility help public
Mutability help transaction

Modifiers help

Requirements help

Source Code
function depositERC20(address _token, uint256 _amount)
  external
  whenNotPaused
  returns (uint256)
{
  return depositERC20For(msg.sender, _token, _amount);
}

depositERC721 keyboard_arrow_up

Parameters help

Name Type
_token
address help
_tokenId
uint256 help

Properties

Visibility help public
Mutability help transaction

Modifiers help

Requirements help

Source Code
function depositERC721(address _token, uint256 _tokenId)
  external
  whenNotPaused
  returns (uint256)
{
  return depositERC721For(msg.sender, _token, _tokenId);
}

depositEthFor keyboard_arrow_up

Parameters help

Name Type
_owner
address help

Properties

Visibility help public
Mutability help payable

Modifiers help

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

Parameters help

Name Type
_user
address help
_token
address help
_amount
uint256 help

Properties

Visibility help public
Mutability help transaction

Modifiers help

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

Parameters help

Name Type
_user
address help
_token
address help
_tokenId
uint256 help

Properties

Visibility help public
Mutability help transaction

Modifiers help

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

Parameters help

Name Type
_user
address help
_tokens
address[] help
_tokenNumbers
uint256[] help

Properties

Visibility help public
Mutability help transaction

Modifiers 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

Name Type
_withdrawalId
uint256 help
_token
address help
_amount
uint256 help
_signatures
bytes help

Properties

Visibility help public
Mutability help transaction

Modifiers 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

Name Type
_withdrawalId
uint256 help
_user
address help
_token
address help
_amount
uint256 help
_signatures
bytes help

Properties

Visibility help public
Mutability help transaction

Modifiers 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

Parameters help

Name Type
_withdrawalId
uint256 help
_token
address help
_amount
uint256 help
_signatures
bytes help

Properties

Visibility help public
Mutability help transaction

Modifiers help

Requirements help

null
Source Code
function withdrawERC20(
  uint256 _withdrawalId,
  address _token,
  uint256 _amount,
  bytes memory _signatures
) public whenNotPaused {
  withdrawERC20For(_withdrawalId, msg.sender, _token, _amount, _signatures);
}

withdrawERC20For keyboard_arrow_up

Parameters help

Name Type
_withdrawalId
uint256 help
_user
address help
_token
address help
_amount
uint256 help
_signatures
bytes help

Properties

Visibility help public
Mutability help transaction

Modifiers help

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

Parameters help

Name Type
_withdrawalId
uint256 help
_token
address help
_tokenId
uint256 help
_signatures
bytes help

Properties

Visibility help public
Mutability help transaction

Modifiers help

Requirements help

null
Source Code
function withdrawERC721(
  uint256 _withdrawalId,
  address _token,
  uint256 _tokenId,
  bytes memory _signatures
) public whenNotPaused {
  withdrawERC721For(_withdrawalId, msg.sender, _token, _tokenId, _signatures);
}

withdrawERC721For keyboard_arrow_up

Parameters help

Name Type
_withdrawalId
uint256 help
_user
address help
_token
address help
_tokenId
uint256 help
_signatures
bytes help

Properties

Visibility help public
Mutability help transaction

Modifiers help

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

Parameters help

Name Type
_hash
bytes32 help
_signatures
bytes help

Properties

Visibility help public
Mutability help view
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 Expand All Collapse All

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

Name Type
_owner
address help
_token
address help
_standard
uint32 help
_number
uint256 help

Properties

Visibility help internal
Mutability help transaction

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

Name Type
_withdrawalId
uint256 help
_owner
address help
_token
address help
_number
uint256 help

Properties

Visibility help internal
Mutability help transaction

Modifiers help

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

Parameters help

Name Type
_user
address help
_amount
uint256 help

Properties

Visibility help internal
Mutability help transaction
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

Name Type
_token
address help
_from
address help
_to
address help
_tokenId
uint256 help

Properties

Visibility help internal
Mutability help transaction
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;
}

internal HasAdmin.constructor keyboard_arrow_up

Parameters help

This function has no parameters.

Properties

Visibility help internal
Mutability help transaction
Source Code
constructor() internal {
  admin = msg.sender;
  emit AdminChanged(address(0), admin);
}

internal HasAdmin.constructor keyboard_arrow_up

Parameters help

This function has no parameters.

Properties

Visibility help internal
Mutability help transaction
Source Code
constructor() internal {
  admin = msg.sender;
  emit AdminChanged(address(0), admin);
}