// SPDX-License-Identifier: Apache-2.0
// Copyright 2017 Loopring Technology Limited.
pragma solidity ^0.7.0;
/// @title Ownable
/// @author Brecht Devos - <brecht@loopring.org>
/// @dev The Ownable contract has an owner address, and provides basic
/// authorization control functions, this simplifies the implementation of
/// "user permissions".
contract Ownable
{
address public owner;
event OwnershipTransferred(
address indexed previousOwner,
address indexed newOwner
);
/// @dev The Ownable constructor sets the original `owner` of the contract
/// to the sender.
constructor()
{
owner = msg.sender;
}
/// @dev Throws if called by any account other than the owner.
modifier onlyOwner()
{
require(msg.sender == owner, "UNAUTHORIZED");
_;
}
/// @dev Allows the current owner to transfer control of the contract to a
/// new owner.
/// @param newOwner The address to transfer ownership to.
function transferOwnership(
address newOwner
)
public
virtual
onlyOwner
{
require(newOwner != address(0), "ZERO_ADDRESS");
emit OwnershipTransferred(owner, newOwner);
owner = newOwner;
}
function renounceOwnership()
public
onlyOwner
{
emit OwnershipTransferred(owner, address(0));
owner = address(0);
}
}
// Copyright 2017 Loopring Technology Limited.
/// @title Utility Functions for uint
/// @author Daniel Wang - <daniel@loopring.org>
library MathUint
{
using MathUint for uint;
function mul(
uint a,
uint b
)
internal
pure
returns (uint c)
{
c = a * b;
require(a == 0 || c / a == b, "MUL_OVERFLOW");
}
function sub(
uint a,
uint b
)
internal
pure
returns (uint)
{
require(b <= a, "SUB_UNDERFLOW");
return a - b;
}
function add(
uint a,
uint b
)
internal
pure
returns (uint c)
{
c = a + b;
require(c >= a, "ADD_OVERFLOW");
}
function add64(
uint64 a,
uint64 b
)
internal
pure
returns (uint64 c)
{
c = a + b;
require(c >= a, "ADD_OVERFLOW");
}
}
// Copyright 2017 Loopring Technology Limited.
/// @title ERC20 Token Interface
/// @dev see https://github.com/ethereum/EIPs/issues/20
/// @author Daniel Wang - <daniel@loopring.org>
abstract contract ERC20
{
function totalSupply()
public
virtual
view
returns (uint);
function balanceOf(
address who
)
public
virtual
view
returns (uint);
function allowance(
address owner,
address spender
)
public
virtual
view
returns (uint);
function transfer(
address to,
uint value
)
public
virtual
returns (bool);
function transferFrom(
address from,
address to,
uint value
)
public
virtual
returns (bool);
function approve(
address spender,
uint value
)
public
virtual
returns (bool);
}
// Copyright 2017 Loopring Technology Limited.
// Copyright 2017 Loopring Technology Limited.
/// @title Utility Functions for addresses
/// @author Daniel Wang - <daniel@loopring.org>
/// @author Brecht Devos - <brecht@loopring.org>
library AddressUtil
{
using AddressUtil for *;
function isContract(
address addr
)
internal
view
returns (bool)
{
// According to EIP-1052, 0x0 is the value returned for not-yet created accounts
// and 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470 is returned
// for accounts without code, i.e. `keccak256('')`
bytes32 codehash;
// solhint-disable-next-line no-inline-assembly
assembly { codehash := extcodehash(addr) }
return (codehash != 0x0 &&
codehash != 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470);
}
function toPayable(
address addr
)
internal
pure
returns (address payable)
{
return payable(addr);
}
// Works like address.send but with a customizable gas limit
// Make sure your code is safe for reentrancy when using this function!
function sendETH(
address to,
uint amount,
uint gasLimit
)
internal
returns (bool success)
{
if (amount == 0) {
return true;
}
address payable recipient = to.toPayable();
/* solium-disable-next-line */
(success, ) = recipient.call{value: amount, gas: gasLimit}("");
}
// Works like address.transfer but with a customizable gas limit
// Make sure your code is safe for reentrancy when using this function!
function sendETHAndVerify(
address to,
uint amount,
uint gasLimit
)
internal
returns (bool success)
{
success = to.sendETH(amount, gasLimit);
require(success, "TRANSFER_FAILURE");
}
// Works like call but is slightly more efficient when data
// needs to be copied from memory to do the call.
function fastCall(
address to,
uint gasLimit,
uint value,
bytes memory data
)
internal
returns (bool success, bytes memory returnData)
{
if (to != address(0)) {
assembly {
// Do the call
success := call(gasLimit, to, value, add(data, 32), mload(data), 0, 0)
// Copy the return data
let size := returndatasize()
returnData := mload(0x40)
mstore(returnData, size)
returndatacopy(add(returnData, 32), 0, size)
// Update free memory pointer
mstore(0x40, add(returnData, add(32, size)))
}
}
}
// Like fastCall, but throws when the call is unsuccessful.
function fastCallAndVerify(
address to,
uint gasLimit,
uint value,
bytes memory data
)
internal
returns (bytes memory returnData)
{
bool success;
(success, returnData) = fastCall(to, gasLimit, value, data);
if (!success) {
assembly {
revert(add(returnData, 32), mload(returnData))
}
}
}
}
// Copyright 2017 Loopring Technology Limited.
/// @title Claimable
/// @author Brecht Devos - <brecht@loopring.org>
/// @dev Extension for the Ownable contract, where the ownership needs
/// to be claimed. This allows the new owner to accept the transfer.
contract Claimable is Ownable
{
address public pendingOwner;
/// @dev Modifier throws if called by any account other than the pendingOwner.
modifier onlyPendingOwner() {
require(msg.sender == pendingOwner, "UNAUTHORIZED");
_;
}
/// @dev Allows the current owner to set the pendingOwner address.
/// @param newOwner The address to transfer ownership to.
function transferOwnership(
address newOwner
)
public
override
onlyOwner
{
require(newOwner != address(0) && newOwner != owner, "INVALID_ADDRESS");
pendingOwner = newOwner;
}
/// @dev Allows the pendingOwner address to finalize the transfer.
function claimOwnership()
public
onlyPendingOwner
{
emit OwnershipTransferred(owner, pendingOwner);
owner = pendingOwner;
pendingOwner = address(0);
}
}
// Copyright 2017 Loopring Technology Limited.
/// @title ERC20 safe transfer
/// @dev see https://github.com/sec-bit/badERC20Fix
/// @author Brecht Devos - <brecht@loopring.org>
library ERC20SafeTransfer
{
function safeTransferAndVerify(
address token,
address to,
uint value
)
internal
{
safeTransferWithGasLimitAndVerify(
token,
to,
value,
gasleft()
);
}
function safeTransfer(
address token,
address to,
uint value
)
internal
returns (bool)
{
return safeTransferWithGasLimit(
token,
to,
value,
gasleft()
);
}
function safeTransferWithGasLimitAndVerify(
address token,
address to,
uint value,
uint gasLimit
)
internal
{
require(
safeTransferWithGasLimit(token, to, value, gasLimit),
"TRANSFER_FAILURE"
);
}
function safeTransferWithGasLimit(
address token,
address to,
uint value,
uint gasLimit
)
internal
returns (bool)
{
// A transfer is successful when 'call' is successful and depending on the token:
// - No value is returned: we assume a revert when the transfer failed (i.e. 'call' returns false)
// - A single boolean is returned: this boolean needs to be true (non-zero)
// bytes4(keccak256("transfer(address,uint256)")) = 0xa9059cbb
bytes memory callData = abi.encodeWithSelector(
bytes4(0xa9059cbb),
to,
value
);
(bool success, ) = token.call{gas: gasLimit}(callData);
return checkReturnValue(success);
}
function safeTransferFromAndVerify(
address token,
address from,
address to,
uint value
)
internal
{
safeTransferFromWithGasLimitAndVerify(
token,
from,
to,
value,
gasleft()
);
}
function safeTransferFrom(
address token,
address from,
address to,
uint value
)
internal
returns (bool)
{
return safeTransferFromWithGasLimit(
token,
from,
to,
value,
gasleft()
);
}
function safeTransferFromWithGasLimitAndVerify(
address token,
address from,
address to,
uint value,
uint gasLimit
)
internal
{
bool result = safeTransferFromWithGasLimit(
token,
from,
to,
value,
gasLimit
);
require(result, "TRANSFER_FAILURE");
}
function safeTransferFromWithGasLimit(
address token,
address from,
address to,
uint value,
uint gasLimit
)
internal
returns (bool)
{
// A transferFrom is successful when 'call' is successful and depending on the token:
// - No value is returned: we assume a revert when the transfer failed (i.e. 'call' returns false)
// - A single boolean is returned: this boolean needs to be true (non-zero)
// bytes4(keccak256("transferFrom(address,address,uint256)")) = 0x23b872dd
bytes memory callData = abi.encodeWithSelector(
bytes4(0x23b872dd),
from,
to,
value
);
(bool success, ) = token.call{gas: gasLimit}(callData);
return checkReturnValue(success);
}
function checkReturnValue(
bool success
)
internal
pure
returns (bool)
{
// A transfer/transferFrom is successful when 'call' is successful and depending on the token:
// - No value is returned: we assume a revert when the transfer failed (i.e. 'call' returns false)
// - A single boolean is returned: this boolean needs to be true (non-zero)
if (success) {
assembly {
switch returndatasize()
// Non-standard ERC20: nothing is returned so if 'call' was successful we assume the transfer succeeded
case 0 {
success := 1
}
// Standard ERC20: a single boolean value is returned which needs to be true
case 32 {
returndatacopy(0, 0, 32)
success := mload(0)
}
// None of the above: not successful
default {
success := 0
}
}
}
return success;
}
}
// Taken from https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/SafeCast.sol
/**
* @dev Wrappers over Solidity's uintXX/intXX casting operators with added overflow
* checks.
*
* Downcasting from uint256/int256 in Solidity does not revert on overflow. This can
* easily result in undesired exploitation or bugs, since developers usually
* assume that overflows raise errors. `SafeCast` restores this intuition by
* reverting the transaction when such an operation overflows.
*
* Using this library instead of the unchecked operations eliminates an entire
* class of bugs, so it's recommended to use it always.
*
* Can be combined with {SafeMath} and {SignedSafeMath} to extend it to smaller types, by performing
* all math on `uint256` and `int256` and then downcasting.
*/
library SafeCast {
/**
* @dev Returns the downcasted uint128 from uint256, reverting on
* overflow (when the input is greater than largest uint128).
*
* Counterpart to Solidity's `uint128` operator.
*
* Requirements:
*
* - input must fit into 128 bits
*/
function toUint128(uint256 value) internal pure returns (uint128) {
require(value < 2**128, "SafeCast: value doesn\'t fit in 128 bits");
return uint128(value);
}
/**
* @dev Returns the downcasted uint96 from uint256, reverting on
* overflow (when the input is greater than largest uint96).
*
* Counterpart to Solidity's `uint96` operator.
*
* Requirements:
*
* - input must fit into 96 bits
*/
function toUint96(uint256 value) internal pure returns (uint96) {
require(value < 2**96, "SafeCast: value doesn\'t fit in 96 bits");
return uint96(value);
}
/**
* @dev Returns the downcasted uint64 from uint256, reverting on
* overflow (when the input is greater than largest uint64).
*
* Counterpart to Solidity's `uint64` operator.
*
* Requirements:
*
* - input must fit into 64 bits
*/
function toUint64(uint256 value) internal pure returns (uint64) {
require(value < 2**64, "SafeCast: value doesn\'t fit in 64 bits");
return uint64(value);
}
/**
* @dev Returns the downcasted uint32 from uint256, reverting on
* overflow (when the input is greater than largest uint32).
*
* Counterpart to Solidity's `uint32` operator.
*
* Requirements:
*
* - input must fit into 32 bits
*/
function toUint32(uint256 value) internal pure returns (uint32) {
require(value < 2**32, "SafeCast: value doesn\'t fit in 32 bits");
return uint32(value);
}
/**
* @dev Returns the downcasted uint40 from uint256, reverting on
* overflow (when the input is greater than largest uint40).
*
* Counterpart to Solidity's `uint32` operator.
*
* Requirements:
*
* - input must fit into 40 bits
*/
function toUint40(uint256 value) internal pure returns (uint40) {
require(value < 2**40, "SafeCast: value doesn\'t fit in 40 bits");
return uint40(value);
}
/**
* @dev Returns the downcasted uint16 from uint256, reverting on
* overflow (when the input is greater than largest uint16).
*
* Counterpart to Solidity's `uint16` operator.
*
* Requirements:
*
* - input must fit into 16 bits
*/
function toUint16(uint256 value) internal pure returns (uint16) {
require(value < 2**16, "SafeCast: value doesn\'t fit in 16 bits");
return uint16(value);
}
/**
* @dev Returns the downcasted uint8 from uint256, reverting on
* overflow (when the input is greater than largest uint8).
*
* Counterpart to Solidity's `uint8` operator.
*
* Requirements:
*
* - input must fit into 8 bits.
*/
function toUint8(uint256 value) internal pure returns (uint8) {
require(value < 2**8, "SafeCast: value doesn\'t fit in 8 bits");
return uint8(value);
}
/**
* @dev Converts a signed int256 into an unsigned uint256.
*
* Requirements:
*
* - input must be greater than or equal to 0.
*/
function toUint256(int256 value) internal pure returns (uint256) {
require(value >= 0, "SafeCast: value must be positive");
return uint256(value);
}
/**
* @dev Returns the downcasted int128 from int256, reverting on
* overflow (when the input is less than smallest int128 or
* greater than largest int128).
*
* Counterpart to Solidity's `int128` operator.
*
* Requirements:
*
* - input must fit into 128 bits
*
* _Available since v3.1._
*/
function toInt128(int256 value) internal pure returns (int128) {
require(value >= -2**127 && value < 2**127, "SafeCast: value doesn\'t fit in 128 bits");
return int128(value);
}
/**
* @dev Returns the downcasted int64 from int256, reverting on
* overflow (when the input is less than smallest int64 or
* greater than largest int64).
*
* Counterpart to Solidity's `int64` operator.
*
* Requirements:
*
* - input must fit into 64 bits
*
* _Available since v3.1._
*/
function toInt64(int256 value) internal pure returns (int64) {
require(value >= -2**63 && value < 2**63, "SafeCast: value doesn\'t fit in 64 bits");
return int64(value);
}
/**
* @dev Returns the downcasted int32 from int256, reverting on
* overflow (when the input is less than smallest int32 or
* greater than largest int32).
*
* Counterpart to Solidity's `int32` operator.
*
* Requirements:
*
* - input must fit into 32 bits
*
* _Available since v3.1._
*/
function toInt32(int256 value) internal pure returns (int32) {
require(value >= -2**31 && value < 2**31, "SafeCast: value doesn\'t fit in 32 bits");
return int32(value);
}
/**
* @dev Returns the downcasted int16 from int256, reverting on
* overflow (when the input is less than smallest int16 or
* greater than largest int16).
*
* Counterpart to Solidity's `int16` operator.
*
* Requirements:
*
* - input must fit into 16 bits
*
* _Available since v3.1._
*/
function toInt16(int256 value) internal pure returns (int16) {
require(value >= -2**15 && value < 2**15, "SafeCast: value doesn\'t fit in 16 bits");
return int16(value);
}
/**
* @dev Returns the downcasted int8 from int256, reverting on
* overflow (when the input is less than smallest int8 or
* greater than largest int8).
*
* Counterpart to Solidity's `int8` operator.
*
* Requirements:
*
* - input must fit into 8 bits.
*
* _Available since v3.1._
*/
function toInt8(int256 value) internal pure returns (int8) {
require(value >= -2**7 && value < 2**7, "SafeCast: value doesn\'t fit in 8 bits");
return int8(value);
}
/**
* @dev Converts an unsigned uint256 into a signed int256.
*
* Requirements:
*
* - input must be less than or equal to maxInt256.
*/
function toInt256(uint256 value) internal pure returns (int256) {
require(value < 2**255, "SafeCast: value doesn't fit in an int256");
return int256(value);
}
}
// Copyright 2017 Loopring Technology Limited.
/// @title IDepositContract.
/// @dev Contract storing and transferring funds for an exchange.
///
/// ERC1155 tokens can be supported by registering pseudo token addresses calculated
/// as `address(keccak256(real_token_address, token_params))`. Then the custom
/// deposit contract can look up the real token address and paramsters with the
/// pseudo token address before doing the transfers.
/// @author Brecht Devos - <brecht@loopring.org>
interface IDepositContract
{
/// @dev Returns if a token is suppoprted by this contract.
function isTokenSupported(address token)
external
view
returns (bool);
/// @dev Transfers tokens from a user to the exchange. This function will
/// be called when a user deposits funds to the exchange.
/// In a simple implementation the funds are simply stored inside the
/// deposit contract directly. More advanced implementations may store the funds
/// in some DeFi application to earn interest, so this function could directly
/// call the necessary functions to store the funds there.
///
/// This function needs to throw when an error occurred!
///
/// This function can only be called by the exchange.
///
/// @param from The address of the account that sends the tokens.
/// @param token The address of the token to transfer (`0x0` for ETH).
/// @param amount The amount of tokens to transfer.
/// @param extraData Opaque data that can be used by the contract to handle the deposit
/// @return amountReceived The amount to deposit to the user's account in the Merkle tree
function deposit(
address from,
address token,
uint96 amount,
bytes calldata extraData
)
external
payable
returns (uint96 amountReceived);
/// @dev Transfers tokens from the exchange to a user. This function will
/// be called when a withdrawal is done for a user on the exchange.
/// In the simplest implementation the funds are simply stored inside the
/// deposit contract directly so this simply transfers the requested tokens back
/// to the user. More advanced implementations may store the funds
/// in some DeFi application to earn interest so the function would
/// need to get those tokens back from the DeFi application first before they
/// can be transferred to the user.
///
/// This function needs to throw when an error occurred!
///
/// This function can only be called by the exchange.
///
/// @param from The address from which 'amount' tokens are transferred.
/// @param to The address to which 'amount' tokens are transferred.
/// @param token The address of the token to transfer (`0x0` for ETH).
/// @param amount The amount of tokens transferred.
/// @param extraData Opaque data that can be used by the contract to handle the withdrawal
function withdraw(
address from,
address to,
address token,
uint amount,
bytes calldata extraData
)
external
payable;
/// @dev Transfers tokens (ETH not supported) for a user using the allowance set
/// for the exchange. This way the approval can be used for all functionality (and
/// extended functionality) of the exchange.
/// Should NOT be used to deposit/withdraw user funds, `deposit`/`withdraw`
/// should be used for that as they will contain specialised logic for those operations.
/// This function can be called by the exchange to transfer onchain funds of users
/// necessary for Agent functionality.
///
/// This function needs to throw when an error occurred!
///
/// This function can only be called by the exchange.
///
/// @param from The address of the account that sends the tokens.
/// @param to The address to which 'amount' tokens are transferred.
/// @param token The address of the token to transfer (ETH is and cannot be suppported).
/// @param amount The amount of tokens transferred.
function transfer(
address from,
address to,
address token,
uint amount
)
external
payable;
/// @dev Checks if the given address is used for depositing ETH or not.
/// Is used while depositing to send the correct ETH amount to the deposit contract.
///
/// Note that 0x0 is always registered for deposting ETH when the exchange is created!
/// This function allows additional addresses to be used for depositing ETH, the deposit
/// contract can implement different behaviour based on the address value.
///
/// @param addr The address to check
/// @return True if the address is used for depositing ETH, else false.
function isETH(address addr)
external
view
returns (bool);
}
/// @title DefaultDepositContract
/// @dev Default implementation of IDepositContract that just stores
/// all funds without doing anything with them.
///
/// Should be able to work with proxy contracts so the contract
/// can be updated easily (but with great caution and transparency!)
/// when necessary.
///
/// @author Brecht Devos - <brecht@loopring.org>
contract DefaultDepositContract is IDepositContract, Claimable
{
using AddressUtil for address;
using ERC20SafeTransfer for address;
using MathUint for uint;
using SafeCast for uint;
address public exchange;
mapping (address => bool) needCheckBalance;
modifier onlyExchange()
{
require(msg.sender == exchange, "UNAUTHORIZED");
_;
}
modifier ifNotZero(uint amount)
{
if (amount == 0) return;
else _;
}
event CheckBalance(
address indexed token,
bool checkBalance
);
function initialize(
address _exchange
)
external
{
require(
exchange == address(0) && _exchange != address(0),
"INVALID_EXCHANGE"
);
owner = msg.sender;
exchange = _exchange;
}
function setCheckBalance(
address token,
bool checkBalance
)
external
onlyOwner
{
require(needCheckBalance[token] != checkBalance, "INVALID_VALUE");
needCheckBalance[token] = checkBalance;
emit CheckBalance(token, checkBalance);
}
function isTokenSupported(address /*token*/)
external
override
pure
returns (bool)
{
return true;
}
function deposit(
address from,
address token,
uint96 amount,
bytes calldata /*extraData*/
)
external
override
payable
onlyExchange
ifNotZero(amount)
returns (uint96 amountReceived)
{
uint ethToReturn = 0;
if (isETHInternal(token)) {
require(msg.value >= amount, "INVALID_ETH_DEPOSIT");
amountReceived = amount;
ethToReturn = msg.value - amount;
} else {
bool checkBalance = needCheckBalance[token];
uint balanceBefore = checkBalance ? ERC20(token).balanceOf(address(this)) : 0;
token.safeTransferFromAndVerify(from, address(this), uint(amount));
uint balanceAfter = checkBalance ? ERC20(token).balanceOf(address(this)) : amount;
uint diff = balanceAfter.sub(balanceBefore);
amountReceived = diff.toUint96();
ethToReturn = msg.value;
}
if (ethToReturn > 0) {
from.sendETHAndVerify(ethToReturn, gasleft());
}
}
function withdraw(
address /*from*/,
address to,
address token,
uint amount,
bytes calldata /*extraData*/
)
external
override
payable
onlyExchange
ifNotZero(amount)
{
if (isETHInternal(token)) {
to.sendETHAndVerify(amount, gasleft());
} else {
if (!token.safeTransfer(to, amount)){
uint amountPaid = ERC20(token).balanceOf(address(this));
require(amountPaid < amount, "UNEXPECTED");
token.safeTransferAndVerify(to, amountPaid);
}
}
}
function transfer(
address from,
address to,
address token,
uint amount
)
external
override
payable
onlyExchange
ifNotZero(amount)
{
token.safeTransferFromAndVerify(from, to, amount);
}
function isETH(address addr)
external
override
pure
returns (bool)
{
return isETHInternal(addr);
}
// -- Internal --
function isETHInternal(address addr)
internal
pure
returns (bool)
{
return addr == address(0);
}
}
{
"compilationTarget": {
"DefaultDepositContract.sol": "DefaultDepositContract"
},
"evmVersion": "istanbul",
"libraries": {},
"metadata": {
"bytecodeHash": "ipfs"
},
"optimizer": {
"enabled": true,
"runs": 999999
},
"remappings": []
}
[{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"token","type":"address"},{"indexed":false,"internalType":"bool","name":"checkBalance","type":"bool"}],"name":"CheckBalance","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"inputs":[],"name":"claimOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"token","type":"address"},{"internalType":"uint96","name":"amount","type":"uint96"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"deposit","outputs":[{"internalType":"uint96","name":"amountReceived","type":"uint96"}],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"exchange","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_exchange","type":"address"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"addr","type":"address"}],"name":"isETH","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"isTokenSupported","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pendingOwner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"bool","name":"checkBalance","type":"bool"}],"name":"setCheckBalance","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transfer","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"withdraw","outputs":[],"stateMutability":"payable","type":"function"}]