/* Copyright 2020 DODO ZOO. SPDX-License-Identifier: Apache-2.0 */ pragma solidity 0.6.9; import {SafeMath} from "./SafeMath.sol"; import {IERC20} from "../intf/IERC20.sol"; import {SafeERC20} from "./SafeERC20.sol"; library UniversalERC20 { using SafeMath for uint256; using SafeERC20 for IERC20; IERC20 private constant ZERO_ADDRESS = IERC20(0x0000000000000000000000000000000000000000); IERC20 private constant ETH_ADDRESS = IERC20(0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE); function universalTransfer(IERC20 token, address to, uint256 amount) internal { universalTransfer(token, to, amount, false); } function universalTransfer(IERC20 token, address to, uint256 amount, bool mayFail) internal returns(bool) { if (amount == 0) { return true; } if (token == ZERO_ADDRESS || token == ETH_ADDRESS) { if (mayFail) { return address(uint160(to)).send(amount); } else { address(uint160(to)).transfer(amount); return true; } } else { token.safeTransfer(to, amount); return true; } } function universalApprove(IERC20 token, address to, uint256 amount) internal { if (token != ZERO_ADDRESS && token != ETH_ADDRESS) { token.safeApprove(to, amount); } } function universalTransferFrom(IERC20 token, address from, address to, uint256 amount) internal { if (amount == 0) { return; } if (token == ZERO_ADDRESS || token == ETH_ADDRESS) { require(from == msg.sender && msg.value >= amount, "msg.value is zero"); if (to != address(this)) { address(uint160(to)).transfer(amount); } if (msg.value > amount) { msg.sender.transfer(msg.value.sub(amount)); } } else { token.safeTransferFrom(from, to, amount); } } function universalBalanceOf(IERC20 token, address who) internal view returns (uint256) { if (token == ZERO_ADDRESS || token == ETH_ADDRESS) { return who.balance; } else { return token.balanceOf(who); } } }