文件 1 的 9:FewWrappedToken.sol
pragma solidity =0.6.6;
import '@uniswap/lib/contracts/libraries/TransferHelper.sol';
import './interfaces/IFewWrappedToken.sol';
import './libraries/SafeMath.sol';
import './refs/ICoreRef.sol';
import './interfaces/IFewFactory.sol';
contract FewWrappedToken is IFewWrappedToken {
using SafeMath for uint;
string public override name;
string public override symbol;
uint8 public override decimals;
uint public override totalSupply;
mapping(address => uint) public override balanceOf;
mapping(address => mapping(address => uint)) public override allowance;
bytes32 public override DOMAIN_SEPARATOR;
bytes32 public override constant PERMIT_TYPEHASH = 0x6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9;
mapping(address => uint) public override nonces;
address public override factory;
address public override token;
modifier onlyMinter() {
require(ICoreRef(factory).core().isMinter(msg.sender), "CoreRef: Caller is not a minter");
_;
}
modifier onlyBurner() {
require(ICoreRef(factory).core().isBurner(msg.sender), "CoreRef: Caller is not a burner");
_;
}
modifier whenNotPaused() {
require(!IFewFactory(factory).paused(), "CoreRef: Caller is paused");
_;
}
event Mint(address indexed minter, uint256 amount, address indexed to);
event Burn(address indexed burner, uint256 amount, address indexed to);
event Wrap(address indexed sender, uint256 amount, address indexed to);
event Unwrap(address indexed sender, uint256 amount, address indexed to);
constructor() public {
uint chainId;
assembly {
chainId := chainid()
}
factory = msg.sender;
token = IFewFactory(msg.sender).parameter();
name = string(abi.encodePacked("Few Wrapped ", IERC20(token).name()));
symbol = string(abi.encodePacked("fw", IERC20(token).symbol()));
decimals = IERC20(token).decimals();
DOMAIN_SEPARATOR = keccak256(
abi.encode(
keccak256('EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)'),
keccak256(bytes(name)),
keccak256(bytes('1')),
chainId,
address(this)
)
);
}
function _mint(address to, uint value) internal {
totalSupply = totalSupply.add(value);
balanceOf[to] = balanceOf[to].add(value);
emit Transfer(address(0), to, value);
}
function _burn(address from, uint value) internal {
balanceOf[from] = balanceOf[from].sub(value);
totalSupply = totalSupply.sub(value);
emit Transfer(from, address(0), value);
}
function _approve(address owner, address spender, uint value) internal {
allowance[owner][spender] = value;
emit Approval(owner, spender, value);
}
function _transfer(address from, address to, uint value) private {
balanceOf[from] = balanceOf[from].sub(value);
balanceOf[to] = balanceOf[to].add(value);
emit Transfer(from, to, value);
}
function approve(address spender, uint value) external override returns (bool) {
_approve(msg.sender, spender, value);
return true;
}
function transfer(address to, uint value) external override returns (bool) {
_transfer(msg.sender, to, value);
return true;
}
function transferFrom(address from, address to, uint value) external override returns (bool) {
if (allowance[from][msg.sender] != uint(-1)) {
allowance[from][msg.sender] = allowance[from][msg.sender].sub(value);
}
_transfer(from, to, value);
return true;
}
function permit(address owner, address spender, uint value, uint deadline, uint8 v, bytes32 r, bytes32 s) external override {
require(deadline >= block.timestamp, 'Few: EXPIRED');
bytes32 digest = keccak256(
abi.encodePacked(
'\x19\x01',
DOMAIN_SEPARATOR,
keccak256(abi.encode(PERMIT_TYPEHASH, owner, spender, value, nonces[owner]++, deadline))
)
);
address recoveredAddress = ecrecover(digest, v, r, s);
require(recoveredAddress != address(0) && recoveredAddress == owner, 'Few: INVALID_SIGNATURE');
_approve(owner, spender, value);
}
function mint(address account, uint256 amount)
external
override
onlyMinter
whenNotPaused
{
_mint(account, amount);
emit Mint(msg.sender, amount, account);
}
function burn(uint256 amount) public override {
_burn(msg.sender, amount);
emit Burn(msg.sender, amount, msg.sender);
}
function burnFrom(address account, uint256 amount)
public
override
onlyBurner
whenNotPaused
{
_burn(account, amount);
emit Burn(msg.sender, amount, account);
}
function wrapTo(uint256 amount, address to) public override returns (uint256) {
require(amount > 0, "Few: can't wrap zero token");
TransferHelper.safeTransferFrom(token, msg.sender, address(this), amount);
_mint(to, amount);
emit Wrap(msg.sender, amount, to);
return amount;
}
function wrap(uint256 amount) external override returns (uint256) {
return wrapTo(amount, msg.sender);
}
function unwrapTo(uint256 amount, address to) public override returns (uint256) {
require(amount > 0, "Few: zero amount unwrap not allowed");
_burn(msg.sender, amount);
TransferHelper.safeTransfer(address(token), to, amount);
emit Unwrap(msg.sender, amount, to);
return amount;
}
function unwrap(uint256 amount) external override returns (uint256) {
return unwrapTo(amount, msg.sender);
}
}
文件 2 的 9:ICore.sol
pragma solidity >=0.5.0;
interface ICore {
function isBurner(address _address) external view returns (bool);
function isMinter(address _address) external view returns (bool);
function isGovernor(address _address) external view returns (bool);
function isGuardian(address _address) external view returns (bool);
}
文件 3 的 9:ICoreRef.sol
pragma solidity >=0.5.0;
import '../core/ICore.sol';
interface ICoreRef {
event CoreUpdate(address indexed _core);
function setCore(address coreAddress) external;
function pause() external;
function unpause() external;
function core() external view returns (ICore);
}
文件 4 的 9:IERC20.sol
pragma solidity >=0.5.0;
interface IERC20 {
event Approval(address indexed owner, address indexed spender, uint value);
event Transfer(address indexed from, address indexed to, uint value);
function name() external view returns (string memory);
function symbol() external view returns (string memory);
function decimals() external view returns (uint8);
function totalSupply() external view returns (uint);
function balanceOf(address owner) external view returns (uint);
function allowance(address owner, address spender) external view returns (uint);
function approve(address spender, uint value) external returns (bool);
function transfer(address to, uint value) external returns (bool);
function transferFrom(address from, address to, uint value) external returns (bool);
}
文件 5 的 9:IFewERC20.sol
pragma solidity >=0.5.0;
import './IERC20.sol';
interface IFewERC20 is IERC20 {
function DOMAIN_SEPARATOR() external view returns (bytes32);
function PERMIT_TYPEHASH() external pure returns (bytes32);
function nonces(address owner) external view returns (uint);
function permit(address owner, address spender, uint value, uint deadline, uint8 v, bytes32 r, bytes32 s) external;
}
文件 6 的 9:IFewFactory.sol
pragma solidity >=0.5.0;
interface IFewFactory {
event WrappedTokenCreated(address indexed originalToken, address wrappedToken, uint);
function getWrappedToken(address originalToken) external view returns (address wrappedToken);
function allWrappedTokens(uint) external view returns (address wrappedToken);
function parameter() external view returns (address);
function allWrappedTokensLength() external view returns (uint);
function paused() external view returns (bool);
function createToken(address originalToken) external returns (address wrappedToken);
}
文件 7 的 9:IFewWrappedToken.sol
pragma solidity >=0.5.0;
import '../interfaces/IFewERC20.sol';
interface IFewWrappedToken is IFewERC20 {
event Mint(address indexed minter, uint256 amount, address indexed to);
event Burn(address indexed burner, uint256 amount, address indexed to);
event Wrap(address indexed sender, uint256 amount, address indexed to);
event Unwrap(address indexed sender, uint256 amount, address indexed to);
function factory() external view returns (address);
function token() external view returns (address);
function mint(address account, uint256 amount) external;
function burn(uint256 amount) external;
function burnFrom(address account, uint256 amount) external;
function wrapTo(uint256 amount, address to) external returns (uint256);
function wrap(uint256 amount) external returns (uint256);
function unwrapTo(uint256 amount, address to) external returns (uint256);
function unwrap(uint256 amount) external returns (uint256);
}
文件 8 的 9:SafeMath.sol
pragma solidity =0.6.6;
library SafeMath {
function add(uint x, uint y) internal pure returns (uint z) {
require((z = x + y) >= x, 'ds-math-add-overflow');
}
function sub(uint x, uint y) internal pure returns (uint z) {
require((z = x - y) <= x, 'ds-math-sub-underflow');
}
function mul(uint x, uint y) internal pure returns (uint z) {
require(y == 0 || (z = x * y) / y == x, 'ds-math-mul-overflow');
}
}
文件 9 的 9:TransferHelper.sol
pragma solidity >=0.6.0;
library TransferHelper {
function safeApprove(
address token,
address to,
uint256 value
) internal {
(bool success, bytes memory data) = token.call(abi.encodeWithSelector(0x095ea7b3, to, value));
require(
success && (data.length == 0 || abi.decode(data, (bool))),
'TransferHelper::safeApprove: approve failed'
);
}
function safeTransfer(
address token,
address to,
uint256 value
) internal {
(bool success, bytes memory data) = token.call(abi.encodeWithSelector(0xa9059cbb, to, value));
require(
success && (data.length == 0 || abi.decode(data, (bool))),
'TransferHelper::safeTransfer: transfer failed'
);
}
function safeTransferFrom(
address token,
address from,
address to,
uint256 value
) internal {
(bool success, bytes memory data) = token.call(abi.encodeWithSelector(0x23b872dd, from, to, value));
require(
success && (data.length == 0 || abi.decode(data, (bool))),
'TransferHelper::transferFrom: transferFrom failed'
);
}
function safeTransferETH(address to, uint256 value) internal {
(bool success, ) = to.call{value: value}(new bytes(0));
require(success, 'TransferHelper::safeTransferETH: ETH transfer failed');
}
}
{
"compilationTarget": {
"contracts/FewWrappedToken.sol": "FewWrappedToken"
},
"evmVersion": "istanbul",
"libraries": {},
"metadata": {
"bytecodeHash": "ipfs"
},
"optimizer": {
"enabled": true,
"runs": 999999
},
"remappings": []
}
[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"burner","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":true,"internalType":"address","name":"to","type":"address"}],"name":"Burn","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"minter","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":true,"internalType":"address","name":"to","type":"address"}],"name":"Mint","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":true,"internalType":"address","name":"to","type":"address"}],"name":"Unwrap","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":true,"internalType":"address","name":"to","type":"address"}],"name":"Wrap","type":"event"},{"inputs":[],"name":"DOMAIN_SEPARATOR","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PERMIT_TYPEHASH","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"burn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"burnFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"factory","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"mint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"nonces","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"permit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"token","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"unwrap","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"address","name":"to","type":"address"}],"name":"unwrapTo","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"wrap","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"address","name":"to","type":"address"}],"name":"wrapTo","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"}]