ETH Price: $1,983.04 (-4.49%)

Transaction Decoder

Block:
24452957 at Feb-14-2026 05:32:35 AM +UTC
Transaction Fee:
0.000008996794932763 ETH $0.02
Gas Used:
176,681 Gas / 0.050921123 Gwei

Emitted Events:

553 Uni.Transfer( from=[Receiver] 0x51c72848c68a965f66fa7a88855f9f7784502a7f, to=0xC56371fBB4e3AE85E4c0778608C38d8aDb3a5FfF, amount=105800838054103367680 )
554 Uni.Transfer( from=0xC56371fBB4e3AE85E4c0778608C38d8aDb3a5FfF, to=FewWrappedToken, amount=105800838054103367680 )
555 FewWrappedToken.Transfer( from=0x0000000000000000000000000000000000000000, to=SwapV2Pair, value=105800838054103367680 )
556 FewWrappedToken.Wrap( sender=0xC56371fBB4e3AE85E4c0778608C38d8aDb3a5FfF, amount=105800838054103367680, to=SwapV2Pair )
557 FewWrappedToken.Transfer( from=SwapV2Pair, to=0xC56371fBB4e3AE85E4c0778608C38d8aDb3a5FfF, value=523416 )
558 SwapV2Pair.Sync( reserve0=5979149314, reserve1=1205076575790263949154894 )
559 SwapV2Pair.Swap( sender=0xC56371fBB4e3AE85E4c0778608C38d8aDb3a5FfF, amount0In=0, amount1In=105800838054103367680, amount0Out=523416, amount1Out=0, to=0xC56371fBB4e3AE85E4c0778608C38d8aDb3a5FfF )
560 FewWrappedToken.Transfer( from=0xC56371fBB4e3AE85E4c0778608C38d8aDb3a5FfF, to=0x0000000000000000000000000000000000000000, value=523416 )
561 WBTC.Transfer( from=FewWrappedToken, to=[Receiver] 0x51c72848c68a965f66fa7a88855f9f7784502a7f, value=523416 )
562 FewWrappedToken.Unwrap( sender=0xC56371fBB4e3AE85E4c0778608C38d8aDb3a5FfF, amount=523416, to=[Receiver] 0x51c72848c68a965f66fa7a88855f9f7784502a7f )

Account State Difference:

  Address   Before After State Difference Code
0x1f9840a8...C4201F984
0x2078f336...3274E1b23
0x2260FAC5...93bc2C599
(Titan Builder)
16.640321702797218393 Eth16.640324518301338707 Eth0.000002815504120314
0x51C72848...784502a7F 148.317031296434979492 Eth148.317028480930859178 Eth0.000002815504120314
0x5eB81De9...1f0d189ed
1.095893784766404545 Eth
Nonce: 24126
1.095884787971471782 Eth
Nonce: 24127
0.000008996794932763
0xE8E1F503...b8a52090a
0xf1Fe1725...DAaBE5c4a

Execution Trace

MEV Bot: 0x51C…a7F.a1c20303( )
  • Uni.transfer( dst=0xC56371fBB4e3AE85E4c0778608C38d8aDb3a5FfF, rawAmount=105800838054103367680 ) => ( True )
  • 0xc56371fbb4e3ae85e4c0778608c38d8adb3a5fff.022c0d9f( )
    • FewWrappedToken.STATICCALL( )
    • Uni.balanceOf( account=0xC56371fBB4e3AE85E4c0778608C38d8aDb3a5FfF ) => ( 105800838054103367680 )
    • FewWrappedToken.wrapTo( amount=105800838054103367680, to=0xf1Fe1725B9F529343659cbf0D990905DAaBE5c4a ) => ( 105800838054103367680 )
      • Uni.transferFrom( src=0xC56371fBB4e3AE85E4c0778608C38d8aDb3a5FfF, dst=0xE8E1F50392Bd61D0F8F48E8E7aF51D3b8a52090a, rawAmount=105800838054103367680 ) => ( True )
      • SwapV2Pair.swap( amount0Out=523416, amount1Out=0, to=0xC56371fBB4e3AE85E4c0778608C38d8aDb3a5FfF, data=0x )
        • FewWrappedToken.transfer( to=0xC56371fBB4e3AE85E4c0778608C38d8aDb3a5FfF, value=523416 ) => ( True )
        • FewWrappedToken.balanceOf( 0xf1Fe1725B9F529343659cbf0D990905DAaBE5c4a ) => ( 5979149314 )
        • FewWrappedToken.balanceOf( 0xf1Fe1725B9F529343659cbf0D990905DAaBE5c4a ) => ( 1205076575790263949154894 )
        • FewWrappedToken.unwrapTo( amount=523416, to=0x51C72848c68a965f66FA7a88855F9f7784502a7F ) => ( 523416 )
          • WBTC.transfer( _to=0x51C72848c68a965f66FA7a88855F9f7784502a7F, _value=523416 ) => ( True )
          • ETH 0.000002815504120314 Titan Builder.CALL( )
            File 1 of 5: Uni
            /**
             *Submitted for verification at Etherscan.io on 2020-09-15
            */
            
            pragma solidity ^0.5.16;
            pragma experimental ABIEncoderV2;
            
            // From https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/math/Math.sol
            // Subject to the MIT license.
            
            /**
             * @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 addition of two unsigned integers, reverting with custom message on overflow.
                 *
                 * Counterpart to Solidity's `+` operator.
                 *
                 * Requirements:
                 * - Addition cannot overflow.
                 */
                function add(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
                    uint256 c = a + b;
                    require(c >= a, errorMessage);
            
                    return c;
                }
            
                /**
                 * @dev Returns the subtraction of two unsigned integers, reverting on underflow (when the result is negative).
                 *
                 * Counterpart to Solidity's `-` operator.
                 *
                 * Requirements:
                 * - Subtraction cannot underflow.
                 */
                function sub(uint256 a, uint256 b) internal pure returns (uint256) {
                    return sub(a, b, "SafeMath: subtraction underflow");
                }
            
                /**
                 * @dev Returns the subtraction of two unsigned integers, reverting with custom message on underflow (when the result is negative).
                 *
                 * Counterpart to Solidity's `-` operator.
                 *
                 * Requirements:
                 * - Subtraction cannot underflow.
                 */
                function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
                    require(b <= a, errorMessage);
                    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: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522
                    if (a == 0) {
                        return 0;
                    }
            
                    uint256 c = a * b;
                    require(c / a == b, "SafeMath: multiplication overflow");
            
                    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, string memory errorMessage) 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: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522
                    if (a == 0) {
                        return 0;
                    }
            
                    uint256 c = a * b;
                    require(c / a == b, errorMessage);
            
                    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) {
                    return div(a, b, "SafeMath: division by zero");
                }
            
                /**
                 * @dev Returns the integer division of two unsigned integers.
                 * Reverts with custom message 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, string memory errorMessage) internal pure returns (uint256) {
                    // Solidity only automatically asserts when dividing by 0
                    require(b > 0, errorMessage);
                    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) {
                    return mod(a, b, "SafeMath: modulo by zero");
                }
            
                /**
                 * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
                 * Reverts with custom message 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, string memory errorMessage) internal pure returns (uint256) {
                    require(b != 0, errorMessage);
                    return a % b;
                }
            }
            
            contract Uni {
                /// @notice EIP-20 token name for this token
                string public constant name = "Uniswap";
            
                /// @notice EIP-20 token symbol for this token
                string public constant symbol = "UNI";
            
                /// @notice EIP-20 token decimals for this token
                uint8 public constant decimals = 18;
            
                /// @notice Total number of tokens in circulation
                uint public totalSupply = 1_000_000_000e18; // 1 billion Uni
            
                /// @notice Address which may mint new tokens
                address public minter;
            
                /// @notice The timestamp after which minting may occur
                uint public mintingAllowedAfter;
            
                /// @notice Minimum time between mints
                uint32 public constant minimumTimeBetweenMints = 1 days * 365;
            
                /// @notice Cap on the percentage of totalSupply that can be minted at each mint
                uint8 public constant mintCap = 2;
            
                /// @notice Allowance amounts on behalf of others
                mapping (address => mapping (address => uint96)) internal allowances;
            
                /// @notice Official record of token balances for each account
                mapping (address => uint96) internal balances;
            
                /// @notice A record of each accounts delegate
                mapping (address => address) public delegates;
            
                /// @notice A checkpoint for marking number of votes from a given block
                struct Checkpoint {
                    uint32 fromBlock;
                    uint96 votes;
                }
            
                /// @notice A record of votes checkpoints for each account, by index
                mapping (address => mapping (uint32 => Checkpoint)) public checkpoints;
            
                /// @notice The number of checkpoints for each account
                mapping (address => uint32) public numCheckpoints;
            
                /// @notice The EIP-712 typehash for the contract's domain
                bytes32 public constant DOMAIN_TYPEHASH = keccak256("EIP712Domain(string name,uint256 chainId,address verifyingContract)");
            
                /// @notice The EIP-712 typehash for the delegation struct used by the contract
                bytes32 public constant DELEGATION_TYPEHASH = keccak256("Delegation(address delegatee,uint256 nonce,uint256 expiry)");
            
                /// @notice The EIP-712 typehash for the permit struct used by the contract
                bytes32 public constant PERMIT_TYPEHASH = keccak256("Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)");
            
                /// @notice A record of states for signing / validating signatures
                mapping (address => uint) public nonces;
            
                /// @notice An event thats emitted when the minter address is changed
                event MinterChanged(address minter, address newMinter);
            
                /// @notice An event thats emitted when an account changes its delegate
                event DelegateChanged(address indexed delegator, address indexed fromDelegate, address indexed toDelegate);
            
                /// @notice An event thats emitted when a delegate account's vote balance changes
                event DelegateVotesChanged(address indexed delegate, uint previousBalance, uint newBalance);
            
                /// @notice The standard EIP-20 transfer event
                event Transfer(address indexed from, address indexed to, uint256 amount);
            
                /// @notice The standard EIP-20 approval event
                event Approval(address indexed owner, address indexed spender, uint256 amount);
            
                /**
                 * @notice Construct a new Uni token
                 * @param account The initial account to grant all the tokens
                 * @param minter_ The account with minting ability
                 * @param mintingAllowedAfter_ The timestamp after which minting may occur
                 */
                constructor(address account, address minter_, uint mintingAllowedAfter_) public {
                    require(mintingAllowedAfter_ >= block.timestamp, "Uni::constructor: minting can only begin after deployment");
            
                    balances[account] = uint96(totalSupply);
                    emit Transfer(address(0), account, totalSupply);
                    minter = minter_;
                    emit MinterChanged(address(0), minter);
                    mintingAllowedAfter = mintingAllowedAfter_;
                }
            
                /**
                 * @notice Change the minter address
                 * @param minter_ The address of the new minter
                 */
                function setMinter(address minter_) external {
                    require(msg.sender == minter, "Uni::setMinter: only the minter can change the minter address");
                    emit MinterChanged(minter, minter_);
                    minter = minter_;
                }
            
                /**
                 * @notice Mint new tokens
                 * @param dst The address of the destination account
                 * @param rawAmount The number of tokens to be minted
                 */
                function mint(address dst, uint rawAmount) external {
                    require(msg.sender == minter, "Uni::mint: only the minter can mint");
                    require(block.timestamp >= mintingAllowedAfter, "Uni::mint: minting not allowed yet");
                    require(dst != address(0), "Uni::mint: cannot transfer to the zero address");
            
                    // record the mint
                    mintingAllowedAfter = SafeMath.add(block.timestamp, minimumTimeBetweenMints);
            
                    // mint the amount
                    uint96 amount = safe96(rawAmount, "Uni::mint: amount exceeds 96 bits");
                    require(amount <= SafeMath.div(SafeMath.mul(totalSupply, mintCap), 100), "Uni::mint: exceeded mint cap");
                    totalSupply = safe96(SafeMath.add(totalSupply, amount), "Uni::mint: totalSupply exceeds 96 bits");
            
                    // transfer the amount to the recipient
                    balances[dst] = add96(balances[dst], amount, "Uni::mint: transfer amount overflows");
                    emit Transfer(address(0), dst, amount);
            
                    // move delegates
                    _moveDelegates(address(0), delegates[dst], amount);
                }
            
                /**
                 * @notice Get the number of tokens `spender` is approved to spend on behalf of `account`
                 * @param account The address of the account holding the funds
                 * @param spender The address of the account spending the funds
                 * @return The number of tokens approved
                 */
                function allowance(address account, address spender) external view returns (uint) {
                    return allowances[account][spender];
                }
            
                /**
                 * @notice Approve `spender` to transfer up to `amount` from `src`
                 * @dev This will overwrite the approval amount for `spender`
                 *  and is subject to issues noted [here](https://eips.ethereum.org/EIPS/eip-20#approve)
                 * @param spender The address of the account which may transfer tokens
                 * @param rawAmount The number of tokens that are approved (2^256-1 means infinite)
                 * @return Whether or not the approval succeeded
                 */
                function approve(address spender, uint rawAmount) external returns (bool) {
                    uint96 amount;
                    if (rawAmount == uint(-1)) {
                        amount = uint96(-1);
                    } else {
                        amount = safe96(rawAmount, "Uni::approve: amount exceeds 96 bits");
                    }
            
                    allowances[msg.sender][spender] = amount;
            
                    emit Approval(msg.sender, spender, amount);
                    return true;
                }
            
                /**
                 * @notice Triggers an approval from owner to spends
                 * @param owner The address to approve from
                 * @param spender The address to be approved
                 * @param rawAmount The number of tokens that are approved (2^256-1 means infinite)
                 * @param deadline The time at which to expire the signature
                 * @param v The recovery byte of the signature
                 * @param r Half of the ECDSA signature pair
                 * @param s Half of the ECDSA signature pair
                 */
                function permit(address owner, address spender, uint rawAmount, uint deadline, uint8 v, bytes32 r, bytes32 s) external {
                    uint96 amount;
                    if (rawAmount == uint(-1)) {
                        amount = uint96(-1);
                    } else {
                        amount = safe96(rawAmount, "Uni::permit: amount exceeds 96 bits");
                    }
            
                    bytes32 domainSeparator = keccak256(abi.encode(DOMAIN_TYPEHASH, keccak256(bytes(name)), getChainId(), address(this)));
                    bytes32 structHash = keccak256(abi.encode(PERMIT_TYPEHASH, owner, spender, rawAmount, nonces[owner]++, deadline));
                    bytes32 digest = keccak256(abi.encodePacked("\x19\x01", domainSeparator, structHash));
                    address signatory = ecrecover(digest, v, r, s);
                    require(signatory != address(0), "Uni::permit: invalid signature");
                    require(signatory == owner, "Uni::permit: unauthorized");
                    require(now <= deadline, "Uni::permit: signature expired");
            
                    allowances[owner][spender] = amount;
            
                    emit Approval(owner, spender, amount);
                }
            
                /**
                 * @notice Get the number of tokens held by the `account`
                 * @param account The address of the account to get the balance of
                 * @return The number of tokens held
                 */
                function balanceOf(address account) external view returns (uint) {
                    return balances[account];
                }
            
                /**
                 * @notice Transfer `amount` tokens from `msg.sender` to `dst`
                 * @param dst The address of the destination account
                 * @param rawAmount The number of tokens to transfer
                 * @return Whether or not the transfer succeeded
                 */
                function transfer(address dst, uint rawAmount) external returns (bool) {
                    uint96 amount = safe96(rawAmount, "Uni::transfer: amount exceeds 96 bits");
                    _transferTokens(msg.sender, dst, amount);
                    return true;
                }
            
                /**
                 * @notice Transfer `amount` tokens from `src` to `dst`
                 * @param src The address of the source account
                 * @param dst The address of the destination account
                 * @param rawAmount The number of tokens to transfer
                 * @return Whether or not the transfer succeeded
                 */
                function transferFrom(address src, address dst, uint rawAmount) external returns (bool) {
                    address spender = msg.sender;
                    uint96 spenderAllowance = allowances[src][spender];
                    uint96 amount = safe96(rawAmount, "Uni::approve: amount exceeds 96 bits");
            
                    if (spender != src && spenderAllowance != uint96(-1)) {
                        uint96 newAllowance = sub96(spenderAllowance, amount, "Uni::transferFrom: transfer amount exceeds spender allowance");
                        allowances[src][spender] = newAllowance;
            
                        emit Approval(src, spender, newAllowance);
                    }
            
                    _transferTokens(src, dst, amount);
                    return true;
                }
            
                /**
                 * @notice Delegate votes from `msg.sender` to `delegatee`
                 * @param delegatee The address to delegate votes to
                 */
                function delegate(address delegatee) public {
                    return _delegate(msg.sender, delegatee);
                }
            
                /**
                 * @notice Delegates votes from signatory to `delegatee`
                 * @param delegatee The address to delegate votes to
                 * @param nonce The contract state required to match the signature
                 * @param expiry The time at which to expire the signature
                 * @param v The recovery byte of the signature
                 * @param r Half of the ECDSA signature pair
                 * @param s Half of the ECDSA signature pair
                 */
                function delegateBySig(address delegatee, uint nonce, uint expiry, uint8 v, bytes32 r, bytes32 s) public {
                    bytes32 domainSeparator = keccak256(abi.encode(DOMAIN_TYPEHASH, keccak256(bytes(name)), getChainId(), address(this)));
                    bytes32 structHash = keccak256(abi.encode(DELEGATION_TYPEHASH, delegatee, nonce, expiry));
                    bytes32 digest = keccak256(abi.encodePacked("\x19\x01", domainSeparator, structHash));
                    address signatory = ecrecover(digest, v, r, s);
                    require(signatory != address(0), "Uni::delegateBySig: invalid signature");
                    require(nonce == nonces[signatory]++, "Uni::delegateBySig: invalid nonce");
                    require(now <= expiry, "Uni::delegateBySig: signature expired");
                    return _delegate(signatory, delegatee);
                }
            
                /**
                 * @notice Gets the current votes balance for `account`
                 * @param account The address to get votes balance
                 * @return The number of current votes for `account`
                 */
                function getCurrentVotes(address account) external view returns (uint96) {
                    uint32 nCheckpoints = numCheckpoints[account];
                    return nCheckpoints > 0 ? checkpoints[account][nCheckpoints - 1].votes : 0;
                }
            
                /**
                 * @notice Determine the prior number of votes for an account as of a block number
                 * @dev Block number must be a finalized block or else this function will revert to prevent misinformation.
                 * @param account The address of the account to check
                 * @param blockNumber The block number to get the vote balance at
                 * @return The number of votes the account had as of the given block
                 */
                function getPriorVotes(address account, uint blockNumber) public view returns (uint96) {
                    require(blockNumber < block.number, "Uni::getPriorVotes: not yet determined");
            
                    uint32 nCheckpoints = numCheckpoints[account];
                    if (nCheckpoints == 0) {
                        return 0;
                    }
            
                    // First check most recent balance
                    if (checkpoints[account][nCheckpoints - 1].fromBlock <= blockNumber) {
                        return checkpoints[account][nCheckpoints - 1].votes;
                    }
            
                    // Next check implicit zero balance
                    if (checkpoints[account][0].fromBlock > blockNumber) {
                        return 0;
                    }
            
                    uint32 lower = 0;
                    uint32 upper = nCheckpoints - 1;
                    while (upper > lower) {
                        uint32 center = upper - (upper - lower) / 2; // ceil, avoiding overflow
                        Checkpoint memory cp = checkpoints[account][center];
                        if (cp.fromBlock == blockNumber) {
                            return cp.votes;
                        } else if (cp.fromBlock < blockNumber) {
                            lower = center;
                        } else {
                            upper = center - 1;
                        }
                    }
                    return checkpoints[account][lower].votes;
                }
            
                function _delegate(address delegator, address delegatee) internal {
                    address currentDelegate = delegates[delegator];
                    uint96 delegatorBalance = balances[delegator];
                    delegates[delegator] = delegatee;
            
                    emit DelegateChanged(delegator, currentDelegate, delegatee);
            
                    _moveDelegates(currentDelegate, delegatee, delegatorBalance);
                }
            
                function _transferTokens(address src, address dst, uint96 amount) internal {
                    require(src != address(0), "Uni::_transferTokens: cannot transfer from the zero address");
                    require(dst != address(0), "Uni::_transferTokens: cannot transfer to the zero address");
            
                    balances[src] = sub96(balances[src], amount, "Uni::_transferTokens: transfer amount exceeds balance");
                    balances[dst] = add96(balances[dst], amount, "Uni::_transferTokens: transfer amount overflows");
                    emit Transfer(src, dst, amount);
            
                    _moveDelegates(delegates[src], delegates[dst], amount);
                }
            
                function _moveDelegates(address srcRep, address dstRep, uint96 amount) internal {
                    if (srcRep != dstRep && amount > 0) {
                        if (srcRep != address(0)) {
                            uint32 srcRepNum = numCheckpoints[srcRep];
                            uint96 srcRepOld = srcRepNum > 0 ? checkpoints[srcRep][srcRepNum - 1].votes : 0;
                            uint96 srcRepNew = sub96(srcRepOld, amount, "Uni::_moveVotes: vote amount underflows");
                            _writeCheckpoint(srcRep, srcRepNum, srcRepOld, srcRepNew);
                        }
            
                        if (dstRep != address(0)) {
                            uint32 dstRepNum = numCheckpoints[dstRep];
                            uint96 dstRepOld = dstRepNum > 0 ? checkpoints[dstRep][dstRepNum - 1].votes : 0;
                            uint96 dstRepNew = add96(dstRepOld, amount, "Uni::_moveVotes: vote amount overflows");
                            _writeCheckpoint(dstRep, dstRepNum, dstRepOld, dstRepNew);
                        }
                    }
                }
            
                function _writeCheckpoint(address delegatee, uint32 nCheckpoints, uint96 oldVotes, uint96 newVotes) internal {
                  uint32 blockNumber = safe32(block.number, "Uni::_writeCheckpoint: block number exceeds 32 bits");
            
                  if (nCheckpoints > 0 && checkpoints[delegatee][nCheckpoints - 1].fromBlock == blockNumber) {
                      checkpoints[delegatee][nCheckpoints - 1].votes = newVotes;
                  } else {
                      checkpoints[delegatee][nCheckpoints] = Checkpoint(blockNumber, newVotes);
                      numCheckpoints[delegatee] = nCheckpoints + 1;
                  }
            
                  emit DelegateVotesChanged(delegatee, oldVotes, newVotes);
                }
            
                function safe32(uint n, string memory errorMessage) internal pure returns (uint32) {
                    require(n < 2**32, errorMessage);
                    return uint32(n);
                }
            
                function safe96(uint n, string memory errorMessage) internal pure returns (uint96) {
                    require(n < 2**96, errorMessage);
                    return uint96(n);
                }
            
                function add96(uint96 a, uint96 b, string memory errorMessage) internal pure returns (uint96) {
                    uint96 c = a + b;
                    require(c >= a, errorMessage);
                    return c;
                }
            
                function sub96(uint96 a, uint96 b, string memory errorMessage) internal pure returns (uint96) {
                    require(b <= a, errorMessage);
                    return a - b;
                }
            
                function getChainId() internal pure returns (uint) {
                    uint256 chainId;
                    assembly { chainId := chainid() }
                    return chainId;
                }
            }

            File 2 of 5: FewWrappedToken
            // SPDX-License-Identifier: GPL-3.0-or-later
            pragma solidity >=0.6.0;
            // helper methods for interacting with ERC20 tokens and sending ETH that do not consistently return true/false
            library TransferHelper {
                function safeApprove(
                    address token,
                    address to,
                    uint256 value
                ) internal {
                    // bytes4(keccak256(bytes('approve(address,uint256)')));
                    (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 {
                    // bytes4(keccak256(bytes('transfer(address,uint256)')));
                    (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 {
                    // bytes4(keccak256(bytes('transferFrom(address,address,uint256)')));
                    (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');
                }
            }
            // SPDX-License-Identifier: GPL-2.0-or-later
            pragma solidity >=0.5.0;
            interface ICore {
                // ----------- Getters -----------
                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);
            }
            // SPDX-License-Identifier: BUSL-1.1
            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';
            /// @title Few Wrapped Token
            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;
                // keccak256("Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)");
                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);
                /// @notice Few wrapped token constructor
                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);
                }
                /// @notice mint Few wrapped tokens
                /// @param account the account to mint to
                /// @param amount the amount to mint
                function mint(address account, uint256 amount)
                    external
                    override
                    onlyMinter
                    whenNotPaused
                {
                    _mint(account, amount);
                    emit Mint(msg.sender, amount, account);
                }
                /// @notice burn Few wrapped tokens from caller
                /// @param amount the amount to burn
                function burn(uint256 amount) public override {
                    _burn(msg.sender, amount);
                    emit Burn(msg.sender, amount, msg.sender);
                }
                /// @notice burn Few wrapped tokens from specified account
                /// @param account the account to burn from
                /// @param amount the amount to burn
                function burnFrom(address account, uint256 amount)
                    public
                    override
                    onlyBurner
                    whenNotPaused
                {
                    _burn(account, amount);
                    emit Burn(msg.sender, amount, account);
                }
                /// @notice exchanges token to Few wrapped token
                /// @param amount the amount to wrap
                /// @param to wrapped token reciver address
                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);
                }
                /// @notice exchange Few wrapped token to token
                /// @param amount the amount to unwrap
                /// @param to token receiver address
                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);
                }
            }
            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);
            }
            // SPDX-License-Identifier: GPL-2.0-or-later
            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;
            }
            // SPDX-License-Identifier: GPL-2.0-or-later
            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);
            }
            // SPDX-License-Identifier: GPL-2.0-or-later
            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);
            }
            pragma solidity =0.6.6;
            // a library for performing overflow-safe math, courtesy of DappHub (https://github.com/dapphub/ds-math)
            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');
                }
            }
            // SPDX-License-Identifier: GPL-2.0-or-later
            pragma solidity >=0.5.0;
            import '../core/ICore.sol';
            /// @title CoreRef interface
            interface ICoreRef {
                event CoreUpdate(address indexed _core);
                function setCore(address coreAddress) external;
                function pause() external;
                function unpause() external;
                function core() external view returns (ICore);
            }
            

            File 3 of 5: SwapV2Pair
            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);
            }
            pragma solidity >=0.5.0;
            interface ISwapV2Callee {
                function swapV2Call(address sender, uint amount0, uint amount1, bytes calldata data) external;
            }
            pragma solidity >=0.5.0;
            interface ISwapV2ERC20 {
                event Approval(address indexed owner, address indexed spender, uint value);
                event Transfer(address indexed from, address indexed to, uint value);
                function name() external pure returns (string memory);
                function symbol() external pure returns (string memory);
                function decimals() external pure 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);
                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;
            }
            pragma solidity >=0.5.0;
            interface ISwapV2Factory {
                event PairCreated(address indexed token0, address indexed token1, address pair, uint);
                function feeTo() external view returns (address);
                function feeToSetter() external view returns (address);
                function getPair(address tokenA, address tokenB) external view returns (address pair);
                function allPairs(uint) external view returns (address pair);
                function allPairsLength() external view returns (uint);
                function createPair(address tokenA, address tokenB) external returns (address pair);
                function setFeeTo(address) external;
                function setFeeToSetter(address) external;
            }
            pragma solidity >=0.5.0;
            interface ISwapV2Pair {
                event Approval(address indexed owner, address indexed spender, uint value);
                event Transfer(address indexed from, address indexed to, uint value);
                function name() external pure returns (string memory);
                function symbol() external pure returns (string memory);
                function decimals() external pure 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);
                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;
                event Mint(address indexed sender, uint amount0, uint amount1);
                event Burn(address indexed sender, uint amount0, uint amount1, address indexed to);
                event Swap(
                    address indexed sender,
                    uint amount0In,
                    uint amount1In,
                    uint amount0Out,
                    uint amount1Out,
                    address indexed to
                );
                event Sync(uint112 reserve0, uint112 reserve1);
                function MINIMUM_LIQUIDITY() external pure returns (uint);
                function factory() external view returns (address);
                function token0() external view returns (address);
                function token1() external view returns (address);
                function getReserves() external view returns (uint112 reserve0, uint112 reserve1, uint32 blockTimestampLast);
                function price0CumulativeLast() external view returns (uint);
                function price1CumulativeLast() external view returns (uint);
                function kLast() external view returns (uint);
                function mint(address to) external returns (uint liquidity);
                function burn(address to) external returns (uint amount0, uint amount1);
                function swap(uint amount0Out, uint amount1Out, address to, bytes calldata data) external;
                function skim(address to) external;
                function sync() external;
                function initialize(address, address) external;
            }
            pragma solidity =0.5.16;
            // a library for performing various math operations
            library Math {
                function min(uint x, uint y) internal pure returns (uint z) {
                    z = x < y ? x : y;
                }
                // babylonian method (https://en.wikipedia.org/wiki/Methods_of_computing_square_roots#Babylonian_method)
                function sqrt(uint y) internal pure returns (uint z) {
                    if (y > 3) {
                        z = y;
                        uint x = y / 2 + 1;
                        while (x < z) {
                            z = x;
                            x = (y / x + x) / 2;
                        }
                    } else if (y != 0) {
                        z = 1;
                    }
                }
            }
            pragma solidity =0.5.16;
            // a library for performing overflow-safe math, courtesy of DappHub (https://github.com/dapphub/ds-math)
            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');
                }
            }
            pragma solidity =0.5.16;
            // a library for handling binary fixed point numbers (https://en.wikipedia.org/wiki/Q_(number_format))
            // range: [0, 2**112 - 1]
            // resolution: 1 / 2**112
            library UQ112x112 {
                uint224 constant Q112 = 2**112;
                // encode a uint112 as a UQ112x112
                function encode(uint112 y) internal pure returns (uint224 z) {
                    z = uint224(y) * Q112; // never overflows
                }
                // divide a UQ112x112 by a uint112, returning a UQ112x112
                function uqdiv(uint224 x, uint112 y) internal pure returns (uint224 z) {
                    z = x / uint224(y);
                }
            }
            pragma solidity =0.5.16;
            import './interfaces/ISwapV2ERC20.sol';
            import './libraries/SafeMath.sol';
            contract SwapV2ERC20 is ISwapV2ERC20 {
                using SafeMath for uint;
                string public constant name = 'Ring V2';
                string public constant symbol = 'RING-V2';
                uint8 public constant decimals = 18;
                uint  public totalSupply;
                mapping(address => uint) public balanceOf;
                mapping(address => mapping(address => uint)) public allowance;
                bytes32 public DOMAIN_SEPARATOR;
                // keccak256("Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)");
                bytes32 public constant PERMIT_TYPEHASH = 0x6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9;
                mapping(address => uint) public nonces;
                event Approval(address indexed owner, address indexed spender, uint value);
                event Transfer(address indexed from, address indexed to, uint value);
                constructor() public {
                    uint chainId;
                    assembly {
                        chainId := chainid
                    }
                    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) private {
                    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 returns (bool) {
                    _approve(msg.sender, spender, value);
                    return true;
                }
                function transfer(address to, uint value) external returns (bool) {
                    _transfer(msg.sender, to, value);
                    return true;
                }
                function transferFrom(address from, address to, uint value) external 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 {
                    require(deadline >= block.timestamp, 'SwapV2: 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, 'SwapV2: INVALID_SIGNATURE');
                    _approve(owner, spender, value);
                }
            }
            pragma solidity =0.5.16;
            import './interfaces/ISwapV2Pair.sol';
            import './SwapV2ERC20.sol';
            import './libraries/Math.sol';
            import './libraries/UQ112x112.sol';
            import './interfaces/IERC20.sol';
            import './interfaces/ISwapV2Factory.sol';
            import './interfaces/ISwapV2Callee.sol';
            contract SwapV2Pair is ISwapV2Pair, SwapV2ERC20 {
                using SafeMath  for uint;
                using UQ112x112 for uint224;
                uint public constant MINIMUM_LIQUIDITY = 10**3;
                bytes4 private constant SELECTOR = bytes4(keccak256(bytes('transfer(address,uint256)')));
                address public factory;
                address public token0;
                address public token1;
                uint112 private reserve0;           // uses single storage slot, accessible via getReserves
                uint112 private reserve1;           // uses single storage slot, accessible via getReserves
                uint32  private blockTimestampLast; // uses single storage slot, accessible via getReserves
                uint public price0CumulativeLast;
                uint public price1CumulativeLast;
                uint public kLast; // reserve0 * reserve1, as of immediately after the most recent liquidity event
                uint private unlocked = 1;
                modifier lock() {
                    require(unlocked == 1, 'SwapV2: LOCKED');
                    unlocked = 0;
                    _;
                    unlocked = 1;
                }
                function getReserves() public view returns (uint112 _reserve0, uint112 _reserve1, uint32 _blockTimestampLast) {
                    _reserve0 = reserve0;
                    _reserve1 = reserve1;
                    _blockTimestampLast = blockTimestampLast;
                }
                function _safeTransfer(address token, address to, uint value) private {
                    (bool success, bytes memory data) = token.call(abi.encodeWithSelector(SELECTOR, to, value));
                    require(success && (data.length == 0 || abi.decode(data, (bool))), 'SwapV2: TRANSFER_FAILED');
                }
                event Mint(address indexed sender, uint amount0, uint amount1);
                event Burn(address indexed sender, uint amount0, uint amount1, address indexed to);
                event Swap(
                    address indexed sender,
                    uint amount0In,
                    uint amount1In,
                    uint amount0Out,
                    uint amount1Out,
                    address indexed to
                );
                event Sync(uint112 reserve0, uint112 reserve1);
                constructor() public {
                    factory = msg.sender;
                }
                // called once by the factory at time of deployment
                function initialize(address _token0, address _token1) external {
                    require(msg.sender == factory, 'SwapV2: FORBIDDEN'); // sufficient check
                    token0 = _token0;
                    token1 = _token1;
                }
                // update reserves and, on the first call per block, price accumulators
                function _update(uint balance0, uint balance1, uint112 _reserve0, uint112 _reserve1) private {
                    require(balance0 <= uint112(-1) && balance1 <= uint112(-1), 'SwapV2: OVERFLOW');
                    uint32 blockTimestamp = uint32(block.timestamp % 2**32);
                    uint32 timeElapsed = blockTimestamp - blockTimestampLast; // overflow is desired
                    if (timeElapsed > 0 && _reserve0 != 0 && _reserve1 != 0) {
                        // * never overflows, and + overflow is desired
                        price0CumulativeLast += uint(UQ112x112.encode(_reserve1).uqdiv(_reserve0)) * timeElapsed;
                        price1CumulativeLast += uint(UQ112x112.encode(_reserve0).uqdiv(_reserve1)) * timeElapsed;
                    }
                    reserve0 = uint112(balance0);
                    reserve1 = uint112(balance1);
                    blockTimestampLast = blockTimestamp;
                    emit Sync(reserve0, reserve1);
                }
                // if fee is on, mint liquidity equivalent to 1/6th of the growth in sqrt(k)
                function _mintFee(uint112 _reserve0, uint112 _reserve1) private returns (bool feeOn) {
                    address feeTo = ISwapV2Factory(factory).feeTo();
                    feeOn = feeTo != address(0);
                    uint _kLast = kLast; // gas savings
                    if (feeOn) {
                        if (_kLast != 0) {
                            uint rootK = Math.sqrt(uint(_reserve0).mul(_reserve1));
                            uint rootKLast = Math.sqrt(_kLast);
                            if (rootK > rootKLast) {
                                uint numerator = totalSupply.mul(rootK.sub(rootKLast));
                                uint denominator = rootK.mul(5).add(rootKLast);
                                uint liquidity = numerator / denominator;
                                if (liquidity > 0) _mint(feeTo, liquidity);
                            }
                        }
                    } else if (_kLast != 0) {
                        kLast = 0;
                    }
                }
                // this low-level function should be called from a contract which performs important safety checks
                function mint(address to) external lock returns (uint liquidity) {
                    (uint112 _reserve0, uint112 _reserve1,) = getReserves(); // gas savings
                    uint balance0 = IERC20(token0).balanceOf(address(this));
                    uint balance1 = IERC20(token1).balanceOf(address(this));
                    uint amount0 = balance0.sub(_reserve0);
                    uint amount1 = balance1.sub(_reserve1);
                    bool feeOn = _mintFee(_reserve0, _reserve1);
                    uint _totalSupply = totalSupply; // gas savings, must be defined here since totalSupply can update in _mintFee
                    if (_totalSupply == 0) {
                        liquidity = Math.sqrt(amount0.mul(amount1)).sub(MINIMUM_LIQUIDITY);
                       _mint(address(0), MINIMUM_LIQUIDITY); // permanently lock the first MINIMUM_LIQUIDITY tokens
                    } else {
                        liquidity = Math.min(amount0.mul(_totalSupply) / _reserve0, amount1.mul(_totalSupply) / _reserve1);
                    }
                    require(liquidity > 0, 'SwapV2: INSUFFICIENT_LIQUIDITY_MINTED');
                    _mint(to, liquidity);
                    _update(balance0, balance1, _reserve0, _reserve1);
                    if (feeOn) kLast = uint(reserve0).mul(reserve1); // reserve0 and reserve1 are up-to-date
                    emit Mint(msg.sender, amount0, amount1);
                }
                // this low-level function should be called from a contract which performs important safety checks
                function burn(address to) external lock returns (uint amount0, uint amount1) {
                    (uint112 _reserve0, uint112 _reserve1,) = getReserves(); // gas savings
                    address _token0 = token0;                                // gas savings
                    address _token1 = token1;                                // gas savings
                    uint balance0 = IERC20(_token0).balanceOf(address(this));
                    uint balance1 = IERC20(_token1).balanceOf(address(this));
                    uint liquidity = balanceOf[address(this)];
                    bool feeOn = _mintFee(_reserve0, _reserve1);
                    uint _totalSupply = totalSupply; // gas savings, must be defined here since totalSupply can update in _mintFee
                    amount0 = liquidity.mul(balance0) / _totalSupply; // using balances ensures pro-rata distribution
                    amount1 = liquidity.mul(balance1) / _totalSupply; // using balances ensures pro-rata distribution
                    require(amount0 > 0 && amount1 > 0, 'SwapV2: INSUFFICIENT_LIQUIDITY_BURNED');
                    _burn(address(this), liquidity);
                    _safeTransfer(_token0, to, amount0);
                    _safeTransfer(_token1, to, amount1);
                    balance0 = IERC20(_token0).balanceOf(address(this));
                    balance1 = IERC20(_token1).balanceOf(address(this));
                    _update(balance0, balance1, _reserve0, _reserve1);
                    if (feeOn) kLast = uint(reserve0).mul(reserve1); // reserve0 and reserve1 are up-to-date
                    emit Burn(msg.sender, amount0, amount1, to);
                }
                // this low-level function should be called from a contract which performs important safety checks
                function swap(uint amount0Out, uint amount1Out, address to, bytes calldata data) external lock {
                    require(amount0Out > 0 || amount1Out > 0, 'SwapV2: INSUFFICIENT_OUTPUT_AMOUNT');
                    (uint112 _reserve0, uint112 _reserve1,) = getReserves(); // gas savings
                    require(amount0Out < _reserve0 && amount1Out < _reserve1, 'SwapV2: INSUFFICIENT_LIQUIDITY');
                    uint balance0;
                    uint balance1;
                    { // scope for _token{0,1}, avoids stack too deep errors
                    address _token0 = token0;
                    address _token1 = token1;
                    require(to != _token0 && to != _token1, 'SwapV2: INVALID_TO');
                    if (amount0Out > 0) _safeTransfer(_token0, to, amount0Out); // optimistically transfer tokens
                    if (amount1Out > 0) _safeTransfer(_token1, to, amount1Out); // optimistically transfer tokens
                    if (data.length > 0) ISwapV2Callee(to).swapV2Call(msg.sender, amount0Out, amount1Out, data);
                    balance0 = IERC20(_token0).balanceOf(address(this));
                    balance1 = IERC20(_token1).balanceOf(address(this));
                    }
                    uint amount0In = balance0 > _reserve0 - amount0Out ? balance0 - (_reserve0 - amount0Out) : 0;
                    uint amount1In = balance1 > _reserve1 - amount1Out ? balance1 - (_reserve1 - amount1Out) : 0;
                    require(amount0In > 0 || amount1In > 0, 'SwapV2: INSUFFICIENT_INPUT_AMOUNT');
                    { // scope for reserve{0,1}Adjusted, avoids stack too deep errors
                    uint balance0Adjusted = balance0.mul(1000).sub(amount0In.mul(3));
                    uint balance1Adjusted = balance1.mul(1000).sub(amount1In.mul(3));
                    require(balance0Adjusted.mul(balance1Adjusted) >= uint(_reserve0).mul(_reserve1).mul(1000**2), 'SwapV2: K');
                    }
                    _update(balance0, balance1, _reserve0, _reserve1);
                    emit Swap(msg.sender, amount0In, amount1In, amount0Out, amount1Out, to);
                }
                // force balances to match reserves
                function skim(address to) external lock {
                    address _token0 = token0; // gas savings
                    address _token1 = token1; // gas savings
                    _safeTransfer(_token0, to, IERC20(_token0).balanceOf(address(this)).sub(reserve0));
                    _safeTransfer(_token1, to, IERC20(_token1).balanceOf(address(this)).sub(reserve1));
                }
                // force reserves to match balances
                function sync() external lock {
                    _update(IERC20(token0).balanceOf(address(this)), IERC20(token1).balanceOf(address(this)), reserve0, reserve1);
                }
            }
            

            File 4 of 5: FewWrappedToken
            // SPDX-License-Identifier: GPL-3.0-or-later
            pragma solidity >=0.6.0;
            // helper methods for interacting with ERC20 tokens and sending ETH that do not consistently return true/false
            library TransferHelper {
                function safeApprove(
                    address token,
                    address to,
                    uint256 value
                ) internal {
                    // bytes4(keccak256(bytes('approve(address,uint256)')));
                    (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 {
                    // bytes4(keccak256(bytes('transfer(address,uint256)')));
                    (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 {
                    // bytes4(keccak256(bytes('transferFrom(address,address,uint256)')));
                    (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');
                }
            }
            // SPDX-License-Identifier: GPL-2.0-or-later
            pragma solidity >=0.5.0;
            interface ICore {
                // ----------- Getters -----------
                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);
            }
            // SPDX-License-Identifier: BUSL-1.1
            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';
            /// @title Few Wrapped Token
            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;
                // keccak256("Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)");
                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);
                /// @notice Few wrapped token constructor
                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);
                }
                /// @notice mint Few wrapped tokens
                /// @param account the account to mint to
                /// @param amount the amount to mint
                function mint(address account, uint256 amount)
                    external
                    override
                    onlyMinter
                    whenNotPaused
                {
                    _mint(account, amount);
                    emit Mint(msg.sender, amount, account);
                }
                /// @notice burn Few wrapped tokens from caller
                /// @param amount the amount to burn
                function burn(uint256 amount) public override {
                    _burn(msg.sender, amount);
                    emit Burn(msg.sender, amount, msg.sender);
                }
                /// @notice burn Few wrapped tokens from specified account
                /// @param account the account to burn from
                /// @param amount the amount to burn
                function burnFrom(address account, uint256 amount)
                    public
                    override
                    onlyBurner
                    whenNotPaused
                {
                    _burn(account, amount);
                    emit Burn(msg.sender, amount, account);
                }
                /// @notice exchanges token to Few wrapped token
                /// @param amount the amount to wrap
                /// @param to wrapped token reciver address
                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);
                }
                /// @notice exchange Few wrapped token to token
                /// @param amount the amount to unwrap
                /// @param to token receiver address
                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);
                }
            }
            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);
            }
            // SPDX-License-Identifier: GPL-2.0-or-later
            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;
            }
            // SPDX-License-Identifier: GPL-2.0-or-later
            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);
            }
            // SPDX-License-Identifier: GPL-2.0-or-later
            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);
            }
            pragma solidity =0.6.6;
            // a library for performing overflow-safe math, courtesy of DappHub (https://github.com/dapphub/ds-math)
            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');
                }
            }
            // SPDX-License-Identifier: GPL-2.0-or-later
            pragma solidity >=0.5.0;
            import '../core/ICore.sol';
            /// @title CoreRef interface
            interface ICoreRef {
                event CoreUpdate(address indexed _core);
                function setCore(address coreAddress) external;
                function pause() external;
                function unpause() external;
                function core() external view returns (ICore);
            }
            

            File 5 of 5: WBTC
            pragma solidity 0.4.24;
            
            // File: openzeppelin-solidity/contracts/token/ERC20/ERC20Basic.sol
            
            /**
             * @title ERC20Basic
             * @dev Simpler version of ERC20 interface
             * See https://github.com/ethereum/EIPs/issues/179
             */
            contract ERC20Basic {
              function totalSupply() public view returns (uint256);
              function balanceOf(address _who) public view returns (uint256);
              function transfer(address _to, uint256 _value) public returns (bool);
              event Transfer(address indexed from, address indexed to, uint256 value);
            }
            
            // File: openzeppelin-solidity/contracts/math/SafeMath.sol
            
            /**
             * @title SafeMath
             * @dev Math operations with safety checks that throw on error
             */
            library SafeMath {
            
              /**
              * @dev Multiplies two numbers, throws on overflow.
              */
              function mul(uint256 _a, uint256 _b) internal pure returns (uint256 c) {
                // Gas optimization: this is cheaper than asserting 'a' not being zero, but the
                // benefit is lost if 'b' is also tested.
                // See: https://github.com/OpenZeppelin/openzeppelin-solidity/pull/522
                if (_a == 0) {
                  return 0;
                }
            
                c = _a * _b;
                assert(c / _a == _b);
                return c;
              }
            
              /**
              * @dev Integer division of two numbers, truncating the quotient.
              */
              function div(uint256 _a, uint256 _b) internal pure returns (uint256) {
                // assert(_b > 0); // Solidity automatically throws when dividing by 0
                // uint256 c = _a / _b;
                // assert(_a == _b * c + _a % _b); // There is no case in which this doesn't hold
                return _a / _b;
              }
            
              /**
              * @dev Subtracts two numbers, throws on overflow (i.e. if subtrahend is greater than minuend).
              */
              function sub(uint256 _a, uint256 _b) internal pure returns (uint256) {
                assert(_b <= _a);
                return _a - _b;
              }
            
              /**
              * @dev Adds two numbers, throws on overflow.
              */
              function add(uint256 _a, uint256 _b) internal pure returns (uint256 c) {
                c = _a + _b;
                assert(c >= _a);
                return c;
              }
            }
            
            // File: openzeppelin-solidity/contracts/token/ERC20/BasicToken.sol
            
            /**
             * @title Basic token
             * @dev Basic version of StandardToken, with no allowances.
             */
            contract BasicToken is ERC20Basic {
              using SafeMath for uint256;
            
              mapping(address => uint256) internal balances;
            
              uint256 internal totalSupply_;
            
              /**
              * @dev Total number of tokens in existence
              */
              function totalSupply() public view returns (uint256) {
                return totalSupply_;
              }
            
              /**
              * @dev Transfer token for a specified address
              * @param _to The address to transfer to.
              * @param _value The amount to be transferred.
              */
              function transfer(address _to, uint256 _value) public returns (bool) {
                require(_value <= balances[msg.sender]);
                require(_to != address(0));
            
                balances[msg.sender] = balances[msg.sender].sub(_value);
                balances[_to] = balances[_to].add(_value);
                emit Transfer(msg.sender, _to, _value);
                return true;
              }
            
              /**
              * @dev Gets the balance of the specified address.
              * @param _owner The address to query the the balance of.
              * @return An uint256 representing the amount owned by the passed address.
              */
              function balanceOf(address _owner) public view returns (uint256) {
                return balances[_owner];
              }
            
            }
            
            // File: openzeppelin-solidity/contracts/token/ERC20/ERC20.sol
            
            /**
             * @title ERC20 interface
             * @dev see https://github.com/ethereum/EIPs/issues/20
             */
            contract ERC20 is ERC20Basic {
              function allowance(address _owner, address _spender)
                public view returns (uint256);
            
              function transferFrom(address _from, address _to, uint256 _value)
                public returns (bool);
            
              function approve(address _spender, uint256 _value) public returns (bool);
              event Approval(
                address indexed owner,
                address indexed spender,
                uint256 value
              );
            }
            
            // File: openzeppelin-solidity/contracts/token/ERC20/StandardToken.sol
            
            /**
             * @title Standard ERC20 token
             *
             * @dev Implementation of the basic standard token.
             * https://github.com/ethereum/EIPs/issues/20
             * Based on code by FirstBlood: https://github.com/Firstbloodio/token/blob/master/smart_contract/FirstBloodToken.sol
             */
            contract StandardToken is ERC20, BasicToken {
            
              mapping (address => mapping (address => uint256)) internal allowed;
            
            
              /**
               * @dev Transfer tokens from one address to another
               * @param _from address The address which you want to send tokens from
               * @param _to address The address which you want to transfer to
               * @param _value uint256 the amount of tokens to be transferred
               */
              function transferFrom(
                address _from,
                address _to,
                uint256 _value
              )
                public
                returns (bool)
              {
                require(_value <= balances[_from]);
                require(_value <= allowed[_from][msg.sender]);
                require(_to != address(0));
            
                balances[_from] = balances[_from].sub(_value);
                balances[_to] = balances[_to].add(_value);
                allowed[_from][msg.sender] = allowed[_from][msg.sender].sub(_value);
                emit Transfer(_from, _to, _value);
                return true;
              }
            
              /**
               * @dev Approve the passed address to spend the specified amount of tokens on behalf of msg.sender.
               * 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:
               * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
               * @param _spender The address which will spend the funds.
               * @param _value The amount of tokens to be spent.
               */
              function approve(address _spender, uint256 _value) public returns (bool) {
                allowed[msg.sender][_spender] = _value;
                emit Approval(msg.sender, _spender, _value);
                return true;
              }
            
              /**
               * @dev Function to check the amount of tokens that an owner allowed to a spender.
               * @param _owner address The address which owns the funds.
               * @param _spender address The address which will spend the funds.
               * @return A uint256 specifying the amount of tokens still available for the spender.
               */
              function allowance(
                address _owner,
                address _spender
               )
                public
                view
                returns (uint256)
              {
                return allowed[_owner][_spender];
              }
            
              /**
               * @dev Increase the amount of tokens that an owner allowed to a spender.
               * approve should be called when allowed[_spender] == 0. To increment
               * allowed value is better to use this function to avoid 2 calls (and wait until
               * the first transaction is mined)
               * From MonolithDAO Token.sol
               * @param _spender The address which will spend the funds.
               * @param _addedValue The amount of tokens to increase the allowance by.
               */
              function increaseApproval(
                address _spender,
                uint256 _addedValue
              )
                public
                returns (bool)
              {
                allowed[msg.sender][_spender] = (
                  allowed[msg.sender][_spender].add(_addedValue));
                emit Approval(msg.sender, _spender, allowed[msg.sender][_spender]);
                return true;
              }
            
              /**
               * @dev Decrease the amount of tokens that an owner allowed to a spender.
               * approve should be called when allowed[_spender] == 0. To decrement
               * allowed value is better to use this function to avoid 2 calls (and wait until
               * the first transaction is mined)
               * From MonolithDAO Token.sol
               * @param _spender The address which will spend the funds.
               * @param _subtractedValue The amount of tokens to decrease the allowance by.
               */
              function decreaseApproval(
                address _spender,
                uint256 _subtractedValue
              )
                public
                returns (bool)
              {
                uint256 oldValue = allowed[msg.sender][_spender];
                if (_subtractedValue >= oldValue) {
                  allowed[msg.sender][_spender] = 0;
                } else {
                  allowed[msg.sender][_spender] = oldValue.sub(_subtractedValue);
                }
                emit Approval(msg.sender, _spender, allowed[msg.sender][_spender]);
                return true;
              }
            
            }
            
            // File: openzeppelin-solidity/contracts/token/ERC20/DetailedERC20.sol
            
            /**
             * @title DetailedERC20 token
             * @dev The decimals are only for visualization purposes.
             * All the operations are done using the smallest and indivisible token unit,
             * just as on Ethereum all the operations are done in wei.
             */
            contract DetailedERC20 is ERC20 {
              string public name;
              string public symbol;
              uint8 public decimals;
            
              constructor(string _name, string _symbol, uint8 _decimals) public {
                name = _name;
                symbol = _symbol;
                decimals = _decimals;
              }
            }
            
            // File: openzeppelin-solidity/contracts/ownership/Ownable.sol
            
            /**
             * @title Ownable
             * @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 OwnershipRenounced(address indexed previousOwner);
              event OwnershipTransferred(
                address indexed previousOwner,
                address indexed newOwner
              );
            
            
              /**
               * @dev The Ownable constructor sets the original `owner` of the contract to the sender
               * account.
               */
              constructor() public {
                owner = msg.sender;
              }
            
              /**
               * @dev Throws if called by any account other than the owner.
               */
              modifier onlyOwner() {
                require(msg.sender == owner);
                _;
              }
            
              /**
               * @dev Allows the current owner to relinquish control of the contract.
               * @notice Renouncing to ownership will leave the contract without an owner.
               * It will not be possible to call the functions with the `onlyOwner`
               * modifier anymore.
               */
              function renounceOwnership() public onlyOwner {
                emit OwnershipRenounced(owner);
                owner = address(0);
              }
            
              /**
               * @dev Allows the current owner to transfer control of the contract to a newOwner.
               * @param _newOwner The address to transfer ownership to.
               */
              function transferOwnership(address _newOwner) public onlyOwner {
                _transferOwnership(_newOwner);
              }
            
              /**
               * @dev Transfers control of the contract to a newOwner.
               * @param _newOwner The address to transfer ownership to.
               */
              function _transferOwnership(address _newOwner) internal {
                require(_newOwner != address(0));
                emit OwnershipTransferred(owner, _newOwner);
                owner = _newOwner;
              }
            }
            
            // File: openzeppelin-solidity/contracts/token/ERC20/MintableToken.sol
            
            /**
             * @title Mintable token
             * @dev Simple ERC20 Token example, with mintable token creation
             * Based on code by TokenMarketNet: https://github.com/TokenMarketNet/ico/blob/master/contracts/MintableToken.sol
             */
            contract MintableToken is StandardToken, Ownable {
              event Mint(address indexed to, uint256 amount);
              event MintFinished();
            
              bool public mintingFinished = false;
            
            
              modifier canMint() {
                require(!mintingFinished);
                _;
              }
            
              modifier hasMintPermission() {
                require(msg.sender == owner);
                _;
              }
            
              /**
               * @dev Function to mint tokens
               * @param _to The address that will receive the minted tokens.
               * @param _amount The amount of tokens to mint.
               * @return A boolean that indicates if the operation was successful.
               */
              function mint(
                address _to,
                uint256 _amount
              )
                public
                hasMintPermission
                canMint
                returns (bool)
              {
                totalSupply_ = totalSupply_.add(_amount);
                balances[_to] = balances[_to].add(_amount);
                emit Mint(_to, _amount);
                emit Transfer(address(0), _to, _amount);
                return true;
              }
            
              /**
               * @dev Function to stop minting new tokens.
               * @return True if the operation was successful.
               */
              function finishMinting() public onlyOwner canMint returns (bool) {
                mintingFinished = true;
                emit MintFinished();
                return true;
              }
            }
            
            // File: openzeppelin-solidity/contracts/token/ERC20/BurnableToken.sol
            
            /**
             * @title Burnable Token
             * @dev Token that can be irreversibly burned (destroyed).
             */
            contract BurnableToken is BasicToken {
            
              event Burn(address indexed burner, uint256 value);
            
              /**
               * @dev Burns a specific amount of tokens.
               * @param _value The amount of token to be burned.
               */
              function burn(uint256 _value) public {
                _burn(msg.sender, _value);
              }
            
              function _burn(address _who, uint256 _value) internal {
                require(_value <= balances[_who]);
                // no need to require value <= totalSupply, since that would imply the
                // sender's balance is greater than the totalSupply, which *should* be an assertion failure
            
                balances[_who] = balances[_who].sub(_value);
                totalSupply_ = totalSupply_.sub(_value);
                emit Burn(_who, _value);
                emit Transfer(_who, address(0), _value);
              }
            }
            
            // File: openzeppelin-solidity/contracts/lifecycle/Pausable.sol
            
            /**
             * @title Pausable
             * @dev Base contract which allows children to implement an emergency stop mechanism.
             */
            contract Pausable is Ownable {
              event Pause();
              event Unpause();
            
              bool public paused = false;
            
            
              /**
               * @dev Modifier to make a function callable only when the contract is not paused.
               */
              modifier whenNotPaused() {
                require(!paused);
                _;
              }
            
              /**
               * @dev Modifier to make a function callable only when the contract is paused.
               */
              modifier whenPaused() {
                require(paused);
                _;
              }
            
              /**
               * @dev called by the owner to pause, triggers stopped state
               */
              function pause() public onlyOwner whenNotPaused {
                paused = true;
                emit Pause();
              }
            
              /**
               * @dev called by the owner to unpause, returns to normal state
               */
              function unpause() public onlyOwner whenPaused {
                paused = false;
                emit Unpause();
              }
            }
            
            // File: openzeppelin-solidity/contracts/token/ERC20/PausableToken.sol
            
            /**
             * @title Pausable token
             * @dev StandardToken modified with pausable transfers.
             **/
            contract PausableToken is StandardToken, 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 increaseApproval(
                address _spender,
                uint _addedValue
              )
                public
                whenNotPaused
                returns (bool success)
              {
                return super.increaseApproval(_spender, _addedValue);
              }
            
              function decreaseApproval(
                address _spender,
                uint _subtractedValue
              )
                public
                whenNotPaused
                returns (bool success)
              {
                return super.decreaseApproval(_spender, _subtractedValue);
              }
            }
            
            // File: openzeppelin-solidity/contracts/ownership/Claimable.sol
            
            /**
             * @title Claimable
             * @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);
                _;
              }
            
              /**
               * @dev Allows the current owner to set the pendingOwner address.
               * @param newOwner The address to transfer ownership to.
               */
              function transferOwnership(address newOwner) public onlyOwner {
                pendingOwner = newOwner;
              }
            
              /**
               * @dev Allows the pendingOwner address to finalize the transfer.
               */
              function claimOwnership() public onlyPendingOwner {
                emit OwnershipTransferred(owner, pendingOwner);
                owner = pendingOwner;
                pendingOwner = address(0);
              }
            }
            
            // File: openzeppelin-solidity/contracts/token/ERC20/SafeERC20.sol
            
            /**
             * @title SafeERC20
             * @dev Wrappers around ERC20 operations that throw on failure.
             * 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 {
              function safeTransfer(
                ERC20Basic _token,
                address _to,
                uint256 _value
              )
                internal
              {
                require(_token.transfer(_to, _value));
              }
            
              function safeTransferFrom(
                ERC20 _token,
                address _from,
                address _to,
                uint256 _value
              )
                internal
              {
                require(_token.transferFrom(_from, _to, _value));
              }
            
              function safeApprove(
                ERC20 _token,
                address _spender,
                uint256 _value
              )
                internal
              {
                require(_token.approve(_spender, _value));
              }
            }
            
            // File: openzeppelin-solidity/contracts/ownership/CanReclaimToken.sol
            
            /**
             * @title Contracts that should be able to recover tokens
             * @author SylTi
             * @dev This allow a contract to recover any ERC20 token received in a contract by transferring the balance to the contract owner.
             * This will prevent any accidental loss of tokens.
             */
            contract CanReclaimToken is Ownable {
              using SafeERC20 for ERC20Basic;
            
              /**
               * @dev Reclaim all ERC20Basic compatible tokens
               * @param _token ERC20Basic The address of the token contract
               */
              function reclaimToken(ERC20Basic _token) external onlyOwner {
                uint256 balance = _token.balanceOf(this);
                _token.safeTransfer(owner, balance);
              }
            
            }
            
            // File: contracts/utils/OwnableContract.sol
            
            // empty block is used as this contract just inherits others.
            contract OwnableContract is CanReclaimToken, Claimable { } /* solhint-disable-line no-empty-blocks */
            
            // File: contracts/token/WBTC.sol
            
            contract WBTC is StandardToken, DetailedERC20("Wrapped BTC", "WBTC", 8),
                MintableToken, BurnableToken, PausableToken, OwnableContract {
            
                function burn(uint value) public onlyOwner {
                    super.burn(value);
                }
            
                function finishMinting() public onlyOwner returns (bool) {
                    return false;
                }
            
                function renounceOwnership() public onlyOwner {
                    revert("renouncing ownership is blocked");
                }
            }