/** Submitted for verification at Etherscan.io on 2019-08-18 / // File: openzeppelin-solidity/contracts/math/SafeMath.sol pragma solidity ^0.5.0; / * @dev Wrappers over Solidity's arithmetic operations with added overflow * checks. * * Arithmetic operations in Solidity wrap on overflow. This can easily result * in bugs, because programmers usually assume that an overflow raises an * error, which is the standard behavior in high level programming languages. * SafeMath
restores this intuition by reverting the transaction when 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. / library SafeMath { /* * @dev Returns the addition of two unsigned integers, reverting on * overflow. * * Counterpart to Solidity's +
operator. * * Requirements: * - Addition cannot overflow. / function add(uint256 a, uint256 b) internal pure returns (uint256) { uint256 c = a + b; require(c >= a, "SafeMath: addition overflow"); return c; } /* * @dev Returns the subtraction of two unsigned integers, reverting on * overflow (when the result is negative). * * Counterpart to Solidity's -
operator. * * Requirements: * - Subtraction cannot overflow. / function sub(uint256 a, uint256 b) internal pure returns (uint256) { require(b <= a, "SafeMath: subtraction overflow"); uint256 c = a - b; return c; } /* * @dev Returns the multiplication of two unsigned integers, reverting on * overflow. * * Counterpart to Solidity's *
operator. * * Requirements: * - Multiplication cannot overflow. / function mul(uint256 a, uint256 b) internal pure returns (uint256) { // Gas optimization: this is cheaper than requiring 'a' not being zero, but the // benefit is lost if 'b' is also tested. // See: OpenZeppelin/openzeppelin-contracts#522 if (a == 0) { return 0; } uint256 c = a * b; require(c / a == b, "SafeMath: multiplication overflow"); return c; } /* * @dev Returns the integer division of two unsigned integers. Reverts on * division by zero. The result is rounded towards zero. * * Counterpart to Solidity's /
operator. Note: this function uses a * revert
opcode (which leaves remaining gas untouched) while Solidity * uses an invalid opcode to revert (consuming all remaining gas). * * Requirements: * - The divisor cannot be zero. / function div(uint256 a, uint256 b) internal pure returns (uint256) { // Solidity only automatically asserts when dividing by 0 require(b > 0, "SafeMath: division by zero"); uint256 c = a / b; // assert(a == b * c + a % b); // There is no case in which this doesn't hold return c; } /* * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * Reverts when dividing by zero. * * Counterpart to Solidity's %
operator. This function uses a revert
* opcode (which leaves remaining gas untouched) while Solidity uses an * invalid opcode to revert (consuming all remaining gas). * * Requirements: * - The divisor cannot be zero. / function mod(uint256 a, uint256 b) internal pure returns (uint256) { require(b != 0, "SafeMath: modulo by zero"); return a % b; } } // File: openzeppelin-solidity/contracts/token/ERC20/IERC20.sol pragma solidity ^0.5.0; /* * @dev Interface of the ERC20 standard as defined in the EIP. Does not include * the optional functions; to access them see ERC20Detailed
. / interface IERC20 { /* * @dev Returns the amount of tokens in existence. / function totalSupply() external view returns (uint256); /* * @dev Returns the amount of tokens owned by account
. / function balanceOf(address account) external view returns (uint256); /* * @dev Moves amount
tokens from the caller's account to recipient
. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a Transfer
event. / function transfer(address recipient, uint256 amount) external returns (bool); /* * @dev Returns the remaining number of tokens that spender
will be * allowed to spend on behalf of owner
through transferFrom
. This is * zero by default. * * This value changes when approve
or transferFrom
are called. / function allowance(address owner, address spender) external view returns (uint256); /* * @dev Sets amount
as the allowance of spender
over the caller's tokens. * * Returns a boolean value indicating whether the operation succeeded. * * > Beware that changing an allowance with this method brings the risk * that someone may use both the old and the new allowance by unfortunate * transaction ordering. One possible solution to mitigate this race * condition is to first reduce the spender's allowance to 0 and set the * desired value afterwards: * ethereum/EIPs#20 (comment) * * Emits an Approval
event. / function approve(address spender, uint256 amount) external returns (bool); /* * @dev Moves amount
tokens from sender
to recipient
using the * allowance mechanism. amount
is then deducted from the caller's * allowance. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a Transfer
event. / function transferFrom(address sender, address recipient, uint256 amount) external returns (bool); /* * @dev Emitted when value
tokens are moved from one account (from
) to * another (to
). * * Note that value
may be zero. / event Transfer(address indexed from, address indexed to, uint256 value); /* * @dev Emitted when the allowance of a spender
for an owner
is set by * a call to approve
. value
is the new allowance. / event Approval(address indexed owner, address indexed spender, uint256 value); } // File: openzeppelin-solidity/contracts/token/ERC20/ERC20Detailed.sol pragma solidity ^0.5.0; /* * @dev Optional functions from the ERC20 standard. / contract ERC20Detailed is IERC20 { string private _name; string private _symbol; uint8 private _decimals; /* * @dev Sets the values for name
, symbol
, and decimals
. All three of * these values are immutable: they can only be set once during * construction. / constructor (string memory name, string memory symbol, uint8 decimals) public { _name = name; _symbol = symbol; _decimals = decimals; } /* * @dev Returns the name of the token. / function name() public view returns (string memory) { return _name; } /* * @dev Returns the symbol of the token, usually a shorter version of the * name. / function symbol() public view returns (string memory) { return _symbol; } /* * @dev Returns the number of decimals used to get its user representation. * For example, if decimals
equals 2
, a balance of 505
tokens should * be displayed to a user as 5,05
(505 / 10 ** 2
). * * Tokens usually opt for a value of 18, imitating the relationship between * Ether and Wei. * * > Note that this information is only used for display purposes: it in * no way affects any of the arithmetic of the contract, including * IERC20.balanceOf
and IERC20.transfer
. / function decimals() public view returns (uint8) { return _decimals; } } // File: openzeppelin-solidity/contracts/token/ERC20/ERC20.sol pragma solidity ^0.5.0; /* * @dev Implementation of the IERC20
interface. * * This implementation is agnostic to the way tokens are created. This means * that a supply mechanism has to be added in a derived contract using _mint
. * For a generic mechanism see ERC20Mintable
. * * For a detailed writeup see our guide How to implement supply * mechanisms. * * We have followed general OpenZeppelin guidelines: functions revert instead * of returning false
on failure. This behavior is nonetheless conventional * and does not conflict with the expectations of ERC20 applications. * * Additionally, an Approval
event is emitted on calls to transferFrom
. * This allows applications to reconstruct the allowance for all accounts just * by listening to said events. Other implementations of the EIP may not emit * these events, as it isn't required by the specification. * * Finally, the non-standard decreaseAllowance
and increaseAllowance
* functions have been added to mitigate the well-known issues around setting * allowances. See IERC20.approve
. / contract ERC20 is IERC20 { using SafeMath for uint256; mapping (address => uint256) private _balances; mapping (address => mapping (address => uint256)) private _allowances; uint256 private _totalSupply; /* * @dev See IERC20.totalSupply
. / function totalSupply() public view returns (uint256) { return _totalSupply; } /* * @dev See IERC20.balanceOf
. / function balanceOf(address account) public view returns (uint256) { return _balances[account]; } /* * @dev See IERC20.transfer
. * * Requirements: * * - recipient
cannot be the zero address. * - the caller must have a balance of at least amount
. / function transfer(address recipient, uint256 amount) public returns (bool) { _transfer(msg.sender, recipient, amount); return true; } /* * @dev See IERC20.allowance
. / function allowance(address owner, address spender) public view returns (uint256) { return _allowances[owner][spender]; } /* * @dev See IERC20.approve
. * * Requirements: * * - spender
cannot be the zero address. / function approve(address spender, uint256 value) public returns (bool) { _approve(msg.sender, spender, value); return true; } /* * @dev See IERC20.transferFrom
. * * Emits an Approval
event indicating the updated allowance. This is not * required by the EIP. See the note at the beginning of ERC20
; * * Requirements: * - sender
and recipient
cannot be the zero address. * - sender
must have a balance of at least value
. * - the caller must have allowance for sender
's tokens of at least * amount
. / function transferFrom(address sender, address recipient, uint256 amount) public returns (bool) { _transfer(sender, recipient, amount); _approve(sender, msg.sender, _allowances[sender][msg.sender].sub(amount)); return true; } /* * @dev Atomically increases the allowance granted to spender
by the caller. * * This is an alternative to approve
that can be used as a mitigation for * problems described in IERC20.approve
. * * Emits an Approval
event indicating the updated allowance. * * Requirements: * * - spender
cannot be the zero address. / function increaseAllowance(address spender, uint256 addedValue) public returns (bool) { _approve(msg.sender, spender, _allowances[msg.sender][spender].add(addedValue)); return true; } /* * @dev Atomically decreases the allowance granted to spender
by the caller. * * This is an alternative to approve
that can be used as a mitigation for * problems described in IERC20.approve
. * * Emits an Approval
event indicating the updated allowance. * * Requirements: * * - spender
cannot be the zero address. * - spender
must have allowance for the caller of at least * subtractedValue
. / function decreaseAllowance(address spender, uint256 subtractedValue) public returns (bool) { _approve(msg.sender, spender, _allowances[msg.sender][spender].sub(subtractedValue)); return true; } /* * @dev Moves tokens amount
from sender
to recipient
. * * This is internal function is equivalent to transfer
, and can be used to * e.g. implement automatic token fees, slashing mechanisms, etc. * * Emits a Transfer
event. * * Requirements: * * - sender
cannot be the zero address. * - recipient
cannot be the zero address. * - sender
must have a balance of at least amount
. / function _transfer(address sender, address recipient, uint256 amount) internal { require(sender != address(0), "ERC20: transfer from the zero address"); require(recipient != address(0), "ERC20: transfer to the zero address"); _balances[sender] = _balances[sender].sub(amount); _balances[recipient] = _balances[recipient].add(amount); emit Transfer(sender, recipient, amount); } /* @dev Creates amount
tokens and assigns them to account
, increasing * the total supply. * * Emits a Transfer
event with from
set to the zero address. * * Requirements * * - to
cannot be the zero address. / function _mint(address account, uint256 amount) internal { require(account != address(0), "ERC20: mint to the zero address"); _totalSupply = _totalSupply.add(amount); _balances[account] = _balances[account].add(amount); emit Transfer(address(0), account, amount); } /* * @dev Destoys amount
tokens from account
, reducing the * total supply. * * Emits a Transfer
event with to
set to the zero address. * * Requirements * * - account
cannot be the zero address. * - account
must have at least amount
tokens. / function _burn(address account, uint256 value) internal { require(account != address(0), "ERC20: burn from the zero address"); _totalSupply = _totalSupply.sub(value); _balances[account] = _balances[account].sub(value); emit Transfer(account, address(0), value); } /* * @dev Sets amount
as the allowance of spender
over the owner
s tokens. * * This is internal function is equivalent to approve
, and can be used to * e.g. set automatic allowances for certain subsystems, etc. * * Emits an Approval
event. * * Requirements: * * - owner
cannot be the zero address. * - spender
cannot be the zero address. / function _approve(address owner, address spender, uint256 value) internal { require(owner != address(0), "ERC20: approve from the zero address"); require(spender != address(0), "ERC20: approve to the zero address"); _allowances[owner][spender] = value; emit Approval(owner, spender, value); } /* * @dev Destoys amount
tokens from account
.amount
is then deducted * from the caller's allowance. * * See _burn
and _approve
. / function _burnFrom(address account, uint256 amount) internal { _burn(account, amount); _approve(account, msg.sender, _allowances[account][msg.sender].sub(amount)); } } // File: openzeppelin-solidity/contracts/access/Roles.sol pragma solidity ^0.5.0; /* * @title Roles * @dev Library for managing addresses assigned to a Role. / library Roles { struct Role { mapping (address => bool) bearer; } /* * @dev Give an account access to this role. / function add(Role storage role, address account) internal { require(!has(role, account), "Roles: account already has role"); role.bearer[account] = true; } /* * @dev Remove an account's access to this role. / function remove(Role storage role, address account) internal { require(has(role, account), "Roles: account does not have role"); role.bearer[account] = false; } /* * @dev Check if an account has this role. * @return bool / function has(Role storage role, address account) internal view returns (bool) { require(account != address(0), "Roles: account is the zero address"); return role.bearer[account]; } } // File: openzeppelin-solidity/contracts/access/roles/PauserRole.sol pragma solidity ^0.5.0; contract PauserRole { using Roles for Roles.Role; event PauserAdded(address indexed account); event PauserRemoved(address indexed account); Roles.Role private _pausers; constructor () internal { _addPauser(msg.sender); } modifier onlyPauser() { require(isPauser(msg.sender), "PauserRole: caller does not have the Pauser role"); _; } function isPauser(address account) public view returns (bool) { return _pausers.has(account); } function addPauser(address account) public onlyPauser { _addPauser(account); } function renouncePauser() public { _removePauser(msg.sender); } function _addPauser(address account) internal { _pausers.add(account); emit PauserAdded(account); } function _removePauser(address account) internal { _pausers.remove(account); emit PauserRemoved(account); } } // File: openzeppelin-solidity/contracts/lifecycle/Pausable.sol pragma solidity ^0.5.0; /* * @dev Contract module which allows children to implement an emergency stop * mechanism that can be triggered by an authorized account. * * This module is used through inheritance. It will make available the * modifiers whenNotPaused
and whenPaused
, which can be applied to * the functions of your contract. Note that they will not be pausable by * simply including this module, only once the modifiers are put in place. / contract Pausable is PauserRole { /* * @dev Emitted when the pause is triggered by a pauser (account
). / event Paused(address account); /* * @dev Emitted when the pause is lifted by a pauser (account
). / event Unpaused(address account); bool private _paused; /* * @dev Initializes the contract in unpaused state. Assigns the Pauser role * to the deployer. / constructor () internal { _paused = false; } /* * @dev Returns true if the contract is paused, and false otherwise. / function paused() public view returns (bool) { return _paused; } /* * @dev Modifier to make a function callable only when the contract is not paused. / modifier whenNotPaused() { require(!_paused, "Pausable: paused"); _; } /* * @dev Modifier to make a function callable only when the contract is paused. / modifier whenPaused() { require(_paused, "Pausable: not paused"); _; } /* * @dev Called by a pauser to pause, triggers stopped state. / function pause() public onlyPauser whenNotPaused { _paused = true; emit Paused(msg.sender); } /* * @dev Called by a pauser to unpause, returns to normal state. / function unpause() public onlyPauser whenPaused { _paused = false; emit Unpaused(msg.sender); } } // File: openzeppelin-solidity/contracts/token/ERC20/ERC20Pausable.sol pragma solidity ^0.5.0; /* * @title Pausable token * @dev ERC20 modified with pausable transfers. / contract ERC20Pausable is ERC20, Pausable { function transfer(address to, uint256 value) public whenNotPaused returns (bool) { return super.transfer(to, value); } function transferFrom(address from, address to, uint256 value) public whenNotPaused returns (bool) { return super.transferFrom(from, to, value); } function approve(address spender, uint256 value) public whenNotPaused returns (bool) { return super.approve(spender, value); } function increaseAllowance(address spender, uint addedValue) public whenNotPaused returns (bool) { return super.increaseAllowance(spender, addedValue); } function decreaseAllowance(address spender, uint subtractedValue) public whenNotPaused returns (bool) { return super.decreaseAllowance(spender, subtractedValue); } } // File: openzeppelin-solidity/contracts/access/roles/MinterRole.sol pragma solidity ^0.5.0; contract MinterRole { using Roles for Roles.Role; event MinterAdded(address indexed account); event MinterRemoved(address indexed account); Roles.Role private _minters; constructor () internal { _addMinter(msg.sender); } modifier onlyMinter() { require(isMinter(msg.sender), "MinterRole: caller does not have the Minter role"); _; } function isMinter(address account) public view returns (bool) { return _minters.has(account); } function addMinter(address account) public onlyMinter { _addMinter(account); } function renounceMinter() public { _removeMinter(msg.sender); } function _addMinter(address account) internal { _minters.add(account); emit MinterAdded(account); } function _removeMinter(address account) internal { _minters.remove(account); emit MinterRemoved(account); } } // File: openzeppelin-solidity/contracts/token/ERC20/ERC20Mintable.sol pragma solidity ^0.5.0; /* * @dev Extension of ERC20
that adds a set of accounts with the MinterRole
, * which have permission to mint (create) new tokens as they see fit. * * At construction, the deployer of the contract is the only minter. / contract ERC20Mintable is ERC20, MinterRole { /* * @dev See ERC20._mint
. * * Requirements: * * - the caller must have the MinterRole
. / function mint(address account, uint256 amount) public onlyMinter returns (bool) { _mint(account, amount); return true; } } // File: openzeppelin-solidity/contracts/ownership/Ownable.sol pragma solidity ^0.5.0; /* * @dev Contract module which provides a basic access control mechanism, where * there is an account (an owner) that can be granted exclusive access to * specific functions. * * This module is used through inheritance. It will make available the modifier * onlyOwner
, which can be aplied to your functions to restrict their use to * the owner. / contract Ownable { address private _owner; event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /* * @dev Initializes the contract setting the deployer as the initial owner. / constructor () internal { _owner = msg.sender; emit OwnershipTransferred(address(0), _owner); } /* * @dev Returns the address of the current owner. / function owner() public view returns (address) { return _owner; } /* * @dev Throws if called by any account other than the owner. / modifier onlyOwner() { require(isOwner(), "Ownable: caller is not the owner"); _; } /* * @dev Returns true if the caller is the current owner. / function isOwner() public view returns (bool) { return msg.sender == _owner; } /* * @dev Leaves the contract without owner. It will not be possible to call * onlyOwner
functions anymore. Can only be called by the current owner. * * > Note: Renouncing ownership will leave the contract without an owner, * thereby removing any functionality that is only available to the owner. / function renounceOwnership() public onlyOwner { emit OwnershipTransferred(_owner, address(0)); _owner = address(0); } /* * @dev Transfers ownership of the contract to a new account (newOwner
). * Can only be called by the current owner. / function transferOwnership(address newOwner) public onlyOwner { _transferOwnership(newOwner); } /* * @dev Transfers ownership of the contract to a new account (newOwner
). / function _transferOwnership(address newOwner) internal { require(newOwner != address(0), "Ownable: new owner is the zero address"); emit OwnershipTransferred(_owner, newOwner); _owner = newOwner; } } // File: contracts/whitelist/IWhitelist.sol pragma solidity ^0.5.0; // Interface to be implemented by the Whitelist contract. contract IWhitelist { function isWhitelisted(address account) public view returns (bool); } // File: contracts/token/BurnerRole.sol pragma solidity ^0.5.0; contract BurnerRole { using Roles for Roles.Role; event BurnerAdded(address indexed account); event BurnerRemoved(address indexed account); Roles.Role private _burners; constructor () internal { _addBurner(msg.sender); } modifier onlyBurner() { require(isBurner(msg.sender)); _; } function isBurner(address account) public view returns (bool) { return _burners.has(account); } function addBurner(address account) public onlyBurner { _addBurner(account); } function renounceBurner() public { _removeBurner(msg.sender); } function _addBurner(address account) internal { _burners.add(account); emit BurnerAdded(account); } function _removeBurner(address account) internal { _burners.remove(account); emit BurnerRemoved(account); } } // File: contracts/token/ERC20Burnable.sol pragma solidity ^0.5.0; // Only allow accounts with the burner role to burn tokens. contract ERC20Burnable is ERC20, BurnerRole { function burn(uint256 value) public onlyBurner() { _burn(msg.sender, value); } function burnFrom(address from, uint256 value) public onlyBurner() { _burnFrom(from, value); } } // File: contracts/token/ERC20Whitelistable.sol pragma solidity ^0.5.0; // Disallow transfers of the token to or from blacklisted accounts. contract ERC20Whitelistable is ERC20Mintable, ERC20Burnable, Ownable { event WhitelistChanged(IWhitelist indexed account); IWhitelist public whitelist; function setWhitelist(IWhitelist _whitelist) public onlyOwner { whitelist = _whitelist; emit WhitelistChanged(_whitelist); } modifier onlyWhitelisted(address account) { require(isWhitelisted(account)); _; } modifier notWhitelisted(address account) { require(!isWhitelisted(account)); _; } // Returns true if the account is allowed to send and receive tokens. function isWhitelisted(address account) public view returns (bool) { return whitelist.isWhitelisted(account); } function transfer(address to, uint256 value) public onlyWhitelisted(msg.sender) onlyWhitelisted(to) returns (bool) { return super.transfer(to, value); } function transferFrom(address from, address to, uint256 value) public onlyWhitelisted(from) onlyWhitelisted(to) returns (bool) { return super.transferFrom(from, to, value); } function mint(address to, uint256 value) public onlyWhitelisted(to) returns (bool) { return super.mint(to, value); } // Destroy the tokens held by a blacklisted account. function burnBlacklisted(address from, uint256 value) public onlyBurner() notWhitelisted(from) { _burn(from, value); } } // File: contracts/utils/CanReclaimEther.sol pragma solidity ^0.5.0; // Ether should not be sent to this contract. If any ether is accidentally sent to this // contract, allow the contract owner to recover it. // Copied from https://github.com/OpenZeppelin/openzeppelin-solidity/blob/2441fd7d17bffa1944f6f539b2cddd6d19997a31/contracts/ownership/HasNoEther.sol contract CanReclaimEther is Ownable { function reclaimEther() external onlyOwner { msg.sender.transfer(address(this).balance); } } // File: openzeppelin-solidity/contracts/utils/Address.sol pragma solidity ^0.5.0; /* * @dev Collection of functions related to the address type, / library Address { /* * @dev Returns true if account
is a contract. * * This test is non-exhaustive, and there may be false-negatives: during the * execution of a contract's constructor, its address will be reported as * not containing a contract. * * > It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. / function isContract(address account) internal view returns (bool) { // This method relies in extcodesize, which returns 0 for contracts in // construction, since the code is only stored at the end of the // constructor execution. uint256 size; // solhint-disable-next-line no-inline-assembly assembly { size := extcodesize(account) } return size > 0; } } // File: openzeppelin-solidity/contracts/token/ERC20/SafeERC20.sol pragma solidity ^0.5.0; /* * @title SafeERC20 * @dev Wrappers around ERC20 operations that throw on failure (when the token * contract returns false). Tokens that return no value (and instead revert or * throw on failure) are also supported, non-reverting calls are assumed to be * successful. * To use this library you can add a using SafeERC20 for ERC20;
statement to your contract, * which allows you to call the safe operations as token.safeTransfer(...)
, etc. / library SafeERC20 { using SafeMath for uint256; using Address for address; function safeTransfer(IERC20 token, address to, uint256 value) internal { callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value)); } function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal { callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value)); } function safeApprove(IERC20 token, address spender, uint256 value) internal { // safeApprove should only be called when setting an initial allowance, // or when resetting it to zero. To increase and decrease it, use // 'safeIncreaseAllowance' and 'safeDecreaseAllowance' // solhint-disable-next-line max-line-length require((value == 0) || (token.allowance(address(this), spender) == 0), "SafeERC20: approve from non-zero to non-zero allowance" ); callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value)); } function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal { uint256 newAllowance = token.allowance(address(this), spender).add(value); callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); } function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal { uint256 newAllowance = token.allowance(address(this), spender).sub(value); callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); } /* * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement * on the return value: the return value is optional (but if data is returned, it must not be false). * @param token The token targeted by the call. * @param data The call data (encoded using abi.encode or one of its variants). */ function callOptionalReturn(IERC20 token, bytes memory data) private { // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since // we're implementing it ourselves. // A Solidity high level call has three parts: // 1. The target address is checked to verify it contains contract code // 2. The call itself is made, and success asserted // 3. The return value is decoded, which in turn checks the size of the returned data. // solhint-disable-next-line max-line-length require(address(token).isContract(), "SafeERC20: call to non-contract"); // solhint-disable-next-line avoid-low-level-calls (bool success, bytes memory returndata) = address(token).call(data); require(success, "SafeERC20: low-level call failed"); if (returndata.length > 0) { // Return data is optional // solhint-disable-next-line max-line-length require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed"); } } } // File: contracts/utils/CanReclaimToken.sol pragma solidity ^0.5.0; // Tokens should not be sent to this contract. If any tokens are accidentally sent to // this contract, allow the contract owner to recover them. // Copied from https://github.com/OpenZeppelin/openzeppelin-solidity/blob/6c4c8989b399510a66d8b98ad75a0979482436d2/contracts/ownership/CanReclaimToken.sol contract CanReclaimToken is Ownable { using SafeERC20 for IERC20; function reclaimToken(IERC20 token) external onlyOwner { uint256 balance = token.balanceOf(address(this)); token.safeTransfer(owner(), balance); } } // File: contracts/token/LeveragedToken.sol pragma solidity ^0.5.0; contract LeveragedToken is ERC20Detailed, ERC20Pausable, ERC20Mintable, ERC20Burnable, ERC20Whitelistable, CanReclaimEther, CanReclaimToken { string public underlying; int8 public leverage; constructor(string memory name, string memory symbol, string memory _underlying, int8 _leverage) ERC20Detailed(name, symbol, 18) public { underlying = _underlying; leverage = _leverage; } }
-
Notifications
You must be signed in to change notification settings - Fork 4
/** *Submitted for verification at Etherscan.io on 2019-08-18 */ // File: openzeppelin-solidity/contracts/math/SafeMath.sol pragma solidity ^0.5.0; /** * @dev Wrappers over Solidity's arithmetic operations with added overflow * checks. * * Arithmetic operations in Solidity wrap on overflow. This can easily result * in bugs, because programmers u…
BitCashCF/ERC20
Folders and files
Name | Name | Last commit message | Last commit date | |
---|---|---|---|---|
Repository files navigation
About
/** *Submitted for verification at Etherscan.io on 2019-08-18 */ // File: openzeppelin-solidity/contracts/math/SafeMath.sol pragma solidity ^0.5.0; /** * @dev Wrappers over Solidity's arithmetic operations with added overflow * checks. * * Arithmetic operations in Solidity wrap on overflow. This can easily result * in bugs, because programmers u…
Resources
Stars
Watchers
Forks
Releases
No releases published
Packages 0
No packages published