/

SMART CONTRACT on

c
0xc7198437980c041c805A1EDcbA50c1Ce5db95118
USDT.e Token

USDT.e Token Contract

Last Transaction

0x0601e53f4881b1c88ddb43b39305c02c8a60edfe6859c6d53a8edddede6e15ae
From
0xa943A14Dda16a964346cBe9aA5253F7Ed8c46598
To
USDT.e Token
a few seconds
Wed, 27 Oct 2021 16:01:12 GMT
0.00AVAX

AVAX balance

0

6 Tokens 16,511.41USD Total value

Amount Estimated value
USDT.e Token 11,900.792877 USDT.e 11,944.77USD
USDC.e Token 4,063.511003 USDC.e 4,081.66USD
Wrapped AVAX 5 WAVAX 311.15USD
LINK.e Token 5 LINK.e 148.69USD
DAI.e Token 25 DAI.e 25.14USD
XAVA Token 0 XAVA 0.00USD

Contract Properties

Language
Solidity
Compiler Version
v0.8.0+commit.c7dfd78e
Source Code
Available and Matching

Compiler settings

{
  "optimizer": {
    "enabled": false,
    "runs": 200
  },
  "outputSelection": {
    "BridgeToken.sol": {
      "BridgeToken": [
        "*"
      ]
    }
  }
}

ABI

[
  {
    "inputs": [],
    "stateMutability": "nonpayable",
    "type": "constructor"
  },
  {
    "anonymous": false,
    "inputs": [
      {
        "indexed": false,
        "internalType": "uint256",
        "name": "chainId",
        "type": "uint256"
      }
    ],
    "name": "AddSupportedChainId",
    "type": "event"
  },
  {
    "anonymous": false,
    "inputs": [
      {
        "indexed": false,
        "internalType": "address",
        "name": "contractAddress",
        "type": "address"
      },
      {
        "indexed": false,
        "internalType": "uint256",
        "name": "supplyIncrement",
        "type": "uint256"
      }
    ],
    "name": "AddSwapToken",
    "type": "event"
  },
  {
    "anonymous": false,
    "inputs": [
      {
        "indexed": true,
        "internalType": "address",
        "name": "owner",
        "type": "address"
      },
      {
        "indexed": true,
        "internalType": "address",
        "name": "spender",
        "type": "address"
      },
      {
        "indexed": false,
        "internalType": "uint256",
        "name": "value",
        "type": "uint256"
      }
    ],
    "name": "Approval",
    "type": "event"
  },
  {
    "anonymous": false,
    "inputs": [
      {
        "indexed": false,
        "internalType": "address",
        "name": "newBridgeRoleAddress",
        "type": "address"
      }
    ],
    "name": "MigrateBridgeRole",
    "type": "event"
  },
  {
    "anonymous": false,
    "inputs": [
      {
        "indexed": false,
        "internalType": "address",
        "name": "to",
        "type": "address"
      },
      {
        "indexed": false,
        "internalType": "uint256",
        "name": "amount",
        "type": "uint256"
      },
      {
        "indexed": false,
        "internalType": "address",
        "name": "feeAddress",
        "type": "address"
      },
      {
        "indexed": false,
        "internalType": "uint256",
        "name": "feeAmount",
        "type": "uint256"
      },
      {
        "indexed": false,
        "internalType": "bytes32",
        "name": "originTxId",
        "type": "bytes32"
      }
    ],
    "name": "Mint",
    "type": "event"
  },
  {
    "anonymous": false,
    "inputs": [
      {
        "indexed": false,
        "internalType": "address",
        "name": "contractAddress",
        "type": "address"
      },
      {
        "indexed": false,
        "internalType": "uint256",
        "name": "supplyDecrement",
        "type": "uint256"
      }
    ],
    "name": "RemoveSwapToken",
    "type": "event"
  },
  {
    "anonymous": false,
    "inputs": [
      {
        "indexed": false,
        "internalType": "address",
        "name": "token",
        "type": "address"
      },
      {
        "indexed": false,
        "internalType": "uint256",
        "name": "amount",
        "type": "uint256"
      }
    ],
    "name": "Swap",
    "type": "event"
  },
  {
    "anonymous": false,
    "inputs": [
      {
        "indexed": true,
        "internalType": "address",
        "name": "from",
        "type": "address"
      },
      {
        "indexed": true,
        "internalType": "address",
        "name": "to",
        "type": "address"
      },
      {
        "indexed": false,
        "internalType": "uint256",
        "name": "value",
        "type": "uint256"
      }
    ],
    "name": "Transfer",
    "type": "event"
  },
  {
    "anonymous": false,
    "inputs": [
      {
        "indexed": false,
        "internalType": "uint256",
        "name": "amount",
        "type": "uint256"
      },
      {
        "indexed": false,
        "internalType": "uint256",
        "name": "chainId",
        "type": "uint256"
      }
    ],
    "name": "Unwrap",
    "type": "event"
  },
  {
    "inputs": [
      {
        "internalType": "uint256",
        "name": "chainId",
        "type": "uint256"
      }
    ],
    "name": "addSupportedChainId",
    "outputs": [],
    "stateMutability": "nonpayable",
    "type": "function"
  },
  {
    "inputs": [
      {
        "internalType": "address",
        "name": "contractAddress",
        "type": "address"
      },
      {
        "internalType": "uint256",
        "name": "supplyIncrement",
        "type": "uint256"
      }
    ],
    "name": "addSwapToken",
    "outputs": [],
    "stateMutability": "nonpayable",
    "type": "function"
  },
  {
    "inputs": [
      {
        "internalType": "address",
        "name": "owner",
        "type": "address"
      },
      {
        "internalType": "address",
        "name": "spender",
        "type": "address"
      }
    ],
    "name": "allowance",
    "outputs": [
      {
        "internalType": "uint256",
        "name": "",
        "type": "uint256"
      }
    ],
    "stateMutability": "view",
    "type": "function"
  },
  {
    "inputs": [
      {
        "internalType": "address",
        "name": "spender",
        "type": "address"
      },
      {
        "internalType": "uint256",
        "name": "amount",
        "type": "uint256"
      }
    ],
    "name": "approve",
    "outputs": [
      {
        "internalType": "bool",
        "name": "",
        "type": "bool"
      }
    ],
    "stateMutability": "nonpayable",
    "type": "function"
  },
  {
    "inputs": [
      {
        "internalType": "address",
        "name": "account",
        "type": "address"
      }
    ],
    "name": "balanceOf",
    "outputs": [
      {
        "internalType": "uint256",
        "name": "",
        "type": "uint256"
      }
    ],
    "stateMutability": "view",
    "type": "function"
  },
  {
    "inputs": [
      {
        "internalType": "uint256",
        "name": "amount",
        "type": "uint256"
      }
    ],
    "name": "burn",
    "outputs": [],
    "stateMutability": "nonpayable",
    "type": "function"
  },
  {
    "inputs": [
      {
        "internalType": "address",
        "name": "account",
        "type": "address"
      },
      {
        "internalType": "uint256",
        "name": "amount",
        "type": "uint256"
      }
    ],
    "name": "burnFrom",
    "outputs": [],
    "stateMutability": "nonpayable",
    "type": "function"
  },
  {
    "inputs": [
      {
        "internalType": "uint256",
        "name": "",
        "type": "uint256"
      }
    ],
    "name": "chainIds",
    "outputs": [
      {
        "internalType": "bool",
        "name": "",
        "type": "bool"
      }
    ],
    "stateMutability": "view",
    "type": "function"
  },
  {
    "inputs": [],
    "name": "decimals",
    "outputs": [
      {
        "internalType": "uint8",
        "name": "",
        "type": "uint8"
      }
    ],
    "stateMutability": "view",
    "type": "function"
  },
  {
    "inputs": [
      {
        "internalType": "address",
        "name": "spender",
        "type": "address"
      },
      {
        "internalType": "uint256",
        "name": "subtractedValue",
        "type": "uint256"
      }
    ],
    "name": "decreaseAllowance",
    "outputs": [
      {
        "internalType": "bool",
        "name": "",
        "type": "bool"
      }
    ],
    "stateMutability": "nonpayable",
    "type": "function"
  },
  {
    "inputs": [
      {
        "internalType": "address",
        "name": "spender",
        "type": "address"
      },
      {
        "internalType": "uint256",
        "name": "addedValue",
        "type": "uint256"
      }
    ],
    "name": "increaseAllowance",
    "outputs": [
      {
        "internalType": "bool",
        "name": "",
        "type": "bool"
      }
    ],
    "stateMutability": "nonpayable",
    "type": "function"
  },
  {
    "inputs": [
      {
        "internalType": "address",
        "name": "newBridgeRoleAddress",
        "type": "address"
      }
    ],
    "name": "migrateBridgeRole",
    "outputs": [],
    "stateMutability": "nonpayable",
    "type": "function"
  },
  {
    "inputs": [
      {
        "internalType": "address",
        "name": "to",
        "type": "address"
      },
      {
        "internalType": "uint256",
        "name": "amount",
        "type": "uint256"
      },
      {
        "internalType": "address",
        "name": "feeAddress",
        "type": "address"
      },
      {
        "internalType": "uint256",
        "name": "feeAmount",
        "type": "uint256"
      },
      {
        "internalType": "bytes32",
        "name": "originTxId",
        "type": "bytes32"
      }
    ],
    "name": "mint",
    "outputs": [],
    "stateMutability": "nonpayable",
    "type": "function"
  },
  {
    "inputs": [],
    "name": "name",
    "outputs": [
      {
        "internalType": "string",
        "name": "",
        "type": "string"
      }
    ],
    "stateMutability": "view",
    "type": "function"
  },
  {
    "inputs": [
      {
        "internalType": "address",
        "name": "contractAddress",
        "type": "address"
      },
      {
        "internalType": "uint256",
        "name": "supplyDecrement",
        "type": "uint256"
      }
    ],
    "name": "removeSwapToken",
    "outputs": [],
    "stateMutability": "nonpayable",
    "type": "function"
  },
  {
    "inputs": [
      {
        "internalType": "address",
        "name": "token",
        "type": "address"
      },
      {
        "internalType": "uint256",
        "name": "amount",
        "type": "uint256"
      }
    ],
    "name": "swap",
    "outputs": [],
    "stateMutability": "nonpayable",
    "type": "function"
  },
  {
    "inputs": [
      {
        "internalType": "address",
        "name": "token",
        "type": "address"
      }
    ],
    "name": "swapSupply",
    "outputs": [
      {
        "internalType": "uint256",
        "name": "",
        "type": "uint256"
      }
    ],
    "stateMutability": "view",
    "type": "function"
  },
  {
    "inputs": [],
    "name": "symbol",
    "outputs": [
      {
        "internalType": "string",
        "name": "",
        "type": "string"
      }
    ],
    "stateMutability": "view",
    "type": "function"
  },
  {
    "inputs": [],
    "name": "totalSupply",
    "outputs": [
      {
        "internalType": "uint256",
        "name": "",
        "type": "uint256"
      }
    ],
    "stateMutability": "view",
    "type": "function"
  },
  {
    "inputs": [
      {
        "internalType": "address",
        "name": "recipient",
        "type": "address"
      },
      {
        "internalType": "uint256",
        "name": "amount",
        "type": "uint256"
      }
    ],
    "name": "transfer",
    "outputs": [
      {
        "internalType": "bool",
        "name": "",
        "type": "bool"
      }
    ],
    "stateMutability": "nonpayable",
    "type": "function"
  },
  {
    "inputs": [
      {
        "internalType": "address",
        "name": "sender",
        "type": "address"
      },
      {
        "internalType": "address",
        "name": "recipient",
        "type": "address"
      },
      {
        "internalType": "uint256",
        "name": "amount",
        "type": "uint256"
      }
    ],
    "name": "transferFrom",
    "outputs": [
      {
        "internalType": "bool",
        "name": "",
        "type": "bool"
      }
    ],
    "stateMutability": "nonpayable",
    "type": "function"
  },
  {
    "inputs": [
      {
        "internalType": "uint256",
        "name": "amount",
        "type": "uint256"
      },
      {
        "internalType": "uint256",
        "name": "chainId",
        "type": "uint256"
      }
    ],
    "name": "unwrap",
    "outputs": [],
    "stateMutability": "nonpayable",
    "type": "function"
  }
]

Contract Source Code

BridgeToken.sol

BridgeToken.sol

// File: @openzeppelin/contracts/token/ERC20/IERC20.sol

// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

/**
 * @dev Interface of the ERC20 standard as defined in the EIP.
 */
interface IERC20 {
    /**
     * @dev Returns the amount of tokens in existence.
     */
    function totalSupply() external view returns (uint256);

    /**
     * @dev Returns the amount of tokens owned by `account`.
     */
    function balanceOf(address account) external view returns (uint256);

    /**
     * @dev Moves `amount` tokens from the caller's account to `recipient`.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transfer(address recipient, uint256 amount) external returns (bool);

    /**
     * @dev Returns the remaining number of tokens that `spender` will be
     * allowed to spend on behalf of `owner` through {transferFrom}. This is
     * zero by default.
     *
     * This value changes when {approve} or {transferFrom} are called.
     */
    function allowance(address owner, address spender) external view returns (uint256);

    /**
     * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * IMPORTANT: 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
     *
     * Emits an {Approval} event.
     */
    function approve(address spender, uint256 amount) external returns (bool);

    /**
     * @dev Moves `amount` tokens from `sender` to `recipient` using the
     * allowance mechanism. `amount` is then deducted from the caller's
     * allowance.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);

    /**
     * @dev Emitted when `value` tokens are moved from one account (`from`) to
     * another (`to`).
     *
     * Note that `value` may be zero.
     */
    event Transfer(address indexed from, address indexed to, uint256 value);

    /**
     * @dev Emitted when the allowance of a `spender` for an `owner` is set by
     * a call to {approve}. `value` is the new allowance.
     */
    event Approval(address indexed owner, address indexed spender, uint256 value);
}

// File: @openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol


pragma solidity ^0.8.0;


/**
 * @dev Interface for the optional metadata functions from the ERC20 standard.
 *
 * _Available since v4.1._
 */
interface IERC20Metadata is IERC20 {
    /**
     * @dev Returns the name of the token.
     */
    function name() external view returns (string memory);

    /**
     * @dev Returns the symbol of the token.
     */
    function symbol() external view returns (string memory);

    /**
     * @dev Returns the decimals places of the token.
     */
    function decimals() external view returns (uint8);
}

// File: @openzeppelin/contracts/utils/Context.sol

pragma solidity ^0.8.0;

/*
 * @dev Provides information about the current execution context, including the
 * sender of the transaction and its data. While these are generally available
 * via msg.sender and msg.data, they should not be accessed in such a direct
 * manner, since when dealing with meta-transactions the account sending and
 * paying for execution may not be the actual sender (as far as an application
 * is concerned).
 *
 * This contract is only required for intermediate, library-like contracts.
 */
abstract contract Context {
    function _msgSender() internal view virtual returns (address) {
        return msg.sender;
    }

    function _msgData() internal view virtual returns (bytes calldata) {
        this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691
        return msg.data;
    }
}

// File: @openzeppelin/contracts/token/ERC20/ERC20.sol


pragma solidity ^0.8.0;




/**
 * @dev Implementation of the {IERC20} interface.
 *
 * This implementation is agnostic to the way tokens are created. This means
 * that a supply mechanism has to be added in a derived contract using {_mint}.
 * For a generic mechanism see {ERC20PresetMinterPauser}.
 *
 * TIP: For a detailed writeup see our guide
 * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How
 * to implement supply mechanisms].
 *
 * We have followed general OpenZeppelin guidelines: functions revert instead
 * of returning `false` on failure. This behavior is nonetheless conventional
 * and does not conflict with the expectations of ERC20 applications.
 *
 * Additionally, an {Approval} event is emitted on calls to {transferFrom}.
 * This allows applications to reconstruct the allowance for all accounts just
 * by listening to said events. Other implementations of the EIP may not emit
 * these events, as it isn't required by the specification.
 *
 * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}
 * functions have been added to mitigate the well-known issues around setting
 * allowances. See {IERC20-approve}.
 */
contract ERC20 is Context, IERC20, IERC20Metadata {
    mapping (address => uint256) private _balances;

    mapping (address => mapping (address => uint256)) private _allowances;

    uint256 private _totalSupply;

    string private _name;
    string private _symbol;

    /**
     * @dev Sets the values for {name} and {symbol}.
     *
     * The defaut value of {decimals} is 18. To select a different value for
     * {decimals} you should overload it.
     *
     * All two of these values are immutable: they can only be set once during
     * construction.
     */
    constructor (string memory name_, string memory symbol_) {
        _name = name_;
        _symbol = symbol_;
    }

    /**
     * @dev Returns the name of the token.
     */
    function name() public view virtual override returns (string memory) {
        return _name;
    }

    /**
     * @dev Returns the symbol of the token, usually a shorter version of the
     * name.
     */
    function symbol() public view virtual override returns (string memory) {
        return _symbol;
    }

    /**
     * @dev Returns the number of decimals used to get its user representation.
     * For example, if `decimals` equals `2`, a balance of `505` tokens should
     * be displayed to a user as `5,05` (`505 / 10 ** 2`).
     *
     * Tokens usually opt for a value of 18, imitating the relationship between
     * Ether and Wei. This is the value {ERC20} uses, unless this function is
     * overridden;
     *
     * NOTE: This information is only used for _display_ purposes: it in
     * no way affects any of the arithmetic of the contract, including
     * {IERC20-balanceOf} and {IERC20-transfer}.
     */
    function decimals() public view virtual override returns (uint8) {
        return 18;
    }

    /**
     * @dev See {IERC20-totalSupply}.
     */
    function totalSupply() public view virtual override returns (uint256) {
        return _totalSupply;
    }

    /**
     * @dev See {IERC20-balanceOf}.
     */
    function balanceOf(address account) public view virtual override returns (uint256) {
        return _balances[account];
    }

    /**
     * @dev See {IERC20-transfer}.
     *
     * Requirements:
     *
     * - `recipient` cannot be the zero address.
     * - the caller must have a balance of at least `amount`.
     */
    function transfer(address recipient, uint256 amount) public virtual override returns (bool) {
        _transfer(_msgSender(), recipient, amount);
        return true;
    }

    /**
     * @dev See {IERC20-allowance}.
     */
    function allowance(address owner, address spender) public view virtual override returns (uint256) {
        return _allowances[owner][spender];
    }

    /**
     * @dev See {IERC20-approve}.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     */
    function approve(address spender, uint256 amount) public virtual override returns (bool) {
        _approve(_msgSender(), spender, amount);
        return true;
    }

    /**
     * @dev See {IERC20-transferFrom}.
     *
     * Emits an {Approval} event indicating the updated allowance. This is not
     * required by the EIP. See the note at the beginning of {ERC20}.
     *
     * Requirements:
     *
     * - `sender` and `recipient` cannot be the zero address.
     * - `sender` must have a balance of at least `amount`.
     * - the caller must have allowance for ``sender``'s tokens of at least
     * `amount`.
     */
    function transferFrom(address sender, address recipient, uint256 amount) public virtual override returns (bool) {
        _transfer(sender, recipient, amount);

        uint256 currentAllowance = _allowances[sender][_msgSender()];
        require(currentAllowance >= amount, "ERC20: transfer amount exceeds allowance");
        _approve(sender, _msgSender(), currentAllowance - amount);

        return true;
    }

    /**
     * @dev Atomically increases the allowance granted to `spender` by the caller.
     *
     * This is an alternative to {approve} that can be used as a mitigation for
     * problems described in {IERC20-approve}.
     *
     * Emits an {Approval} event indicating the updated allowance.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     */
    function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {
        _approve(_msgSender(), spender, _allowances[_msgSender()][spender] + addedValue);
        return true;
    }

    /**
     * @dev Atomically decreases the allowance granted to `spender` by the caller.
     *
     * This is an alternative to {approve} that can be used as a mitigation for
     * problems described in {IERC20-approve}.
     *
     * Emits an {Approval} event indicating the updated allowance.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     * - `spender` must have allowance for the caller of at least
     * `subtractedValue`.
     */
    function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {
        uint256 currentAllowance = _allowances[_msgSender()][spender];
        require(currentAllowance >= subtractedValue, "ERC20: decreased allowance below zero");
        _approve(_msgSender(), spender, currentAllowance - subtractedValue);

        return true;
    }

    /**
     * @dev Moves tokens `amount` from `sender` to `recipient`.
     *
     * This is internal function is equivalent to {transfer}, and can be used to
     * e.g. implement automatic token fees, slashing mechanisms, etc.
     *
     * Emits a {Transfer} event.
     *
     * Requirements:
     *
     * - `sender` cannot be the zero address.
     * - `recipient` cannot be the zero address.
     * - `sender` must have a balance of at least `amount`.
     */
    function _transfer(address sender, address recipient, uint256 amount) internal virtual {
        require(sender != address(0), "ERC20: transfer from the zero address");
        require(recipient != address(0), "ERC20: transfer to the zero address");

        _beforeTokenTransfer(sender, recipient, amount);

        uint256 senderBalance = _balances[sender];
        require(senderBalance >= amount, "ERC20: transfer amount exceeds balance");
        _balances[sender] = senderBalance - amount;
        _balances[recipient] += amount;

        emit Transfer(sender, recipient, amount);
    }

    /** @dev Creates `amount` tokens and assigns them to `account`, increasing
     * the total supply.
     *
     * Emits a {Transfer} event with `from` set to the zero address.
     *
     * Requirements:
     *
     * - `to` cannot be the zero address.
     */
    function _mint(address account, uint256 amount) internal virtual {
        require(account != address(0), "ERC20: mint to the zero address");

        _beforeTokenTransfer(address(0), account, amount);

        _totalSupply += amount;
        _balances[account] += amount;
        emit Transfer(address(0), account, amount);
    }

    /**
     * @dev Destroys `amount` tokens from `account`, reducing the
     * total supply.
     *
     * Emits a {Transfer} event with `to` set to the zero address.
     *
     * Requirements:
     *
     * - `account` cannot be the zero address.
     * - `account` must have at least `amount` tokens.
     */
    function _burn(address account, uint256 amount) internal virtual {
        require(account != address(0), "ERC20: burn from the zero address");

        _beforeTokenTransfer(account, address(0), amount);

        uint256 accountBalance = _balances[account];
        require(accountBalance >= amount, "ERC20: burn amount exceeds balance");
        _balances[account] = accountBalance - amount;
        _totalSupply -= amount;

        emit Transfer(account, address(0), amount);
    }

    /**
     * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.
     *
     * This internal function is equivalent to `approve`, and can be used to
     * e.g. set automatic allowances for certain subsystems, etc.
     *
     * Emits an {Approval} event.
     *
     * Requirements:
     *
     * - `owner` cannot be the zero address.
     * - `spender` cannot be the zero address.
     */
    function _approve(address owner, address spender, uint256 amount) internal virtual {
        require(owner != address(0), "ERC20: approve from the zero address");
        require(spender != address(0), "ERC20: approve to the zero address");

        _allowances[owner][spender] = amount;
        emit Approval(owner, spender, amount);
    }

    /**
     * @dev Hook that is called before any transfer of tokens. This includes
     * minting and burning.
     *
     * Calling conditions:
     *
     * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens
     * will be to transferred to `to`.
     * - when `from` is zero, `amount` tokens will be minted for `to`.
     * - when `to` is zero, `amount` of ``from``'s tokens will be burned.
     * - `from` and `to` are never both zero.
     *
     * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
     */
    function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual { }
}

// File: @openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol

pragma solidity ^0.8.0;



/**
 * @dev Extension of {ERC20} that allows token holders to destroy both their own
 * tokens and those that they have an allowance for, in a way that can be
 * recognized off-chain (via event analysis).
 */
abstract contract ERC20Burnable is Context, ERC20 {
    /**
     * @dev Destroys `amount` tokens from the caller.
     *
     * See {ERC20-_burn}.
     */
    function burn(uint256 amount) public virtual {
        _burn(_msgSender(), amount);
    }

    /**
     * @dev Destroys `amount` tokens from `account`, deducting from the caller's
     * allowance.
     *
     * See {ERC20-_burn} and {ERC20-allowance}.
     *
     * Requirements:
     *
     * - the caller must have allowance for ``accounts``'s tokens of at least
     * `amount`.
     */
    function burnFrom(address account, uint256 amount) public virtual {
        uint256 currentAllowance = allowance(account, _msgSender());
        require(currentAllowance >= amount, "ERC20: burn amount exceeds allowance");
        _approve(account, _msgSender(), currentAllowance - amount);
        _burn(account, amount);
    }
}

// File: contracts/Roles.sol

pragma solidity ^0.8.0;

library Roles {
    struct Role {
        mapping(address => bool) bearer;
    }

    /**
     * @dev Give an account access to this role.
     */
    function add(Role storage role, address account) internal {
        require(!has(role, account), "Roles: account already has role");
        role.bearer[account] = true;
    }

    /**
     * @dev Remove an account's access to this role.
     */
    function remove(Role storage role, address account) internal {
        require(has(role, account), "Roles: account does not have role");
        role.bearer[account] = false;
    }

    /**
     * @dev Check if an account has this role.
     * @return bool
     */
    function has(Role storage role, address account)
        internal
        view
        returns (bool)
    {
        require(account != address(0), "Roles: account is the zero address");
        return role.bearer[account];
    }
}

// File: contracts/Wrapped1INCH.sol

pragma solidity ^0.8.0;



contract BridgeToken is ERC20Burnable {
    using Roles for Roles.Role;

    Roles.Role private bridgeRoles;

    string private constant TOKEN_NAME = "Tether USD";
    string private constant TOKEN_SYMBOL = "USDT.e";
    uint8 private constant TOKEN_DECIMALS = 6;

    struct SwapToken {
        address tokenContract;
        uint256 supply;
    }
    mapping(address => SwapToken) swapTokens;

    mapping(uint256 => bool) public chainIds;

    event Mint(
        address to,
        uint256 amount,
        address feeAddress,
        uint256 feeAmount,
        bytes32 originTxId
    );
    event Unwrap(uint256 amount, uint256 chainId);
    event AddSupportedChainId(uint256 chainId);
    event MigrateBridgeRole(address newBridgeRoleAddress);
    event AddSwapToken(address contractAddress, uint256 supplyIncrement);
    event RemoveSwapToken(address contractAddress, uint256 supplyDecrement);
    event Swap(address token, uint256 amount);

    constructor() ERC20(TOKEN_NAME, TOKEN_SYMBOL) {
        bridgeRoles.add(msg.sender);
        chainIds[0] = true;
    }

    function decimals() public view virtual override returns (uint8) {
        return TOKEN_DECIMALS;
    }

    /**
     * @dev Mint function used by bridge. Optional FeeAddress and FeeAmount parameters used to mint small percentage of transfered assets directly to bridge.
     * @param to Address to mint funds to.
     * @param amount Amount of funds to mint.
     * @param feeAddress Address to mint bridge fees to.
     * @param feeAmount Amount to mint as bridge fees.
     * @param feeAmount Amount to mint as bridge fees.
     * @param originTxId Transaction ID from external network that triggered this minting.
     */
    function mint(
        address to,
        uint256 amount,
        address feeAddress,
        uint256 feeAmount,
        bytes32 originTxId
    ) public {
        require(bridgeRoles.has(msg.sender), "Unauthorized.");
        _mint(to, amount);
        if (feeAmount > 0) {
            _mint(feeAddress, feeAmount);
        }
        emit Mint(to, amount, feeAddress, feeAmount, originTxId);
    }

    /**
     * @dev Add new chainId to list of supported Ids.
     * @param chainId ChainId to add.
     */
    function addSupportedChainId(uint256 chainId) public {
        require(bridgeRoles.has(msg.sender), "Unauthorized.");

        // Check that the chain ID is not the chain this contract is deployed on.
        uint256 currentChainId;
        assembly {
            currentChainId := chainid()
        }
        require(chainId != currentChainId, "Cannot add current chain ID.");

        // Already supported, no-op.
        if (chainIds[chainId] == true) {
            return;
        }

        chainIds[chainId] = true;
        emit AddSupportedChainId(chainId);
    }

    /**
     * @dev Burns assets and signals bridge to migrate funds to the same address on the provided chainId.
     * @param amount Amount of asset to unwrap.
     * @param chainId ChainId to unwrap or migrate funds to. Only used for multi-network bridge deployment.
     *                Zero by default for bridge deployment with only 2 networks.
     */
    function unwrap(uint256 amount, uint256 chainId) public {
        require(tx.origin == msg.sender, "Contract calls not supported.");
        require(chainIds[chainId] == true, "Chain ID not supported.");
        _burn(msg.sender, amount);
        emit Unwrap(amount, chainId);
    }

    /**
     * @dev Provide Bridge Role (Admin Role) to new address.
     * @param newBridgeRoleAddress New bridge role address.
     */
    function migrateBridgeRole(address newBridgeRoleAddress) public {
        require(bridgeRoles.has(msg.sender), "Unauthorized.");
        bridgeRoles.remove(msg.sender);
        bridgeRoles.add(newBridgeRoleAddress);
        emit MigrateBridgeRole(newBridgeRoleAddress);
    }

    /**
     * @dev Add Token to accept swaps from or increase supply of existing swap token.
     * @param contractAddress Token Address to allow swaps.
     * @param supplyIncrement Amount of assets allowed to be swapped (or incremental increase in amount).
     */
    function addSwapToken(address contractAddress, uint256 supplyIncrement)
        public
    {
        require(bridgeRoles.has(msg.sender), "Unauthorized.");
        require(isContract(contractAddress), "Address is not contract.");

        // If the swap token is not already supported, add it with the total supply of supplyIncrement.
        // Otherwise, increment the current supply.
        if (swapTokens[contractAddress].tokenContract == address(0)) {
            swapTokens[contractAddress] = SwapToken({
                tokenContract: contractAddress,
                supply: supplyIncrement
            });
        } else {
            swapTokens[contractAddress].supply =
                swapTokens[contractAddress].supply +
                supplyIncrement;
        }
        emit AddSwapToken(contractAddress, supplyIncrement);
    }

    /**
     * @dev Remove amount of swaps allowed from existing swap token.
     * @param contractAddress Token Address to remove swap amount.
     * @param supplyDecrement Amount to remove from the swap supply.
     */
    function removeSwapToken(address contractAddress, uint256 supplyDecrement)
        public
    {
        require(bridgeRoles.has(msg.sender), "Unauthorized");
        require(isContract(contractAddress), "Address is not contract.");
        require(
            swapTokens[contractAddress].tokenContract != address(0),
            "Swap token not supported"
        );

        // If the decrement is less than the current supply, decrement it from the current supply.
        // Otherwise, if the decrement is greater than or equal to the current supply, delete the mapping value.
        if (swapTokens[contractAddress].supply > supplyDecrement) {
            swapTokens[contractAddress].supply =
                swapTokens[contractAddress].supply -
                supplyDecrement;
        } else {
            delete swapTokens[contractAddress];
        }
        emit RemoveSwapToken(contractAddress, supplyDecrement);
    }

    /**
     * @dev Fetch the remaining amount allowed for a swap token.
     * @param token Address of swap token.
     * @return amount of swaps remaining.
     */
    function swapSupply(address token) public view returns (uint256) {
        return swapTokens[token].supply;
    }

    /**
     * @dev Perform Swap.
     * @param token Address of token to be swapped.
     * @param amount Amount of token to be swapped.
     */
    function swap(address token, uint256 amount) public {
        require(isContract(token), "Token is not a contract.");
        require(
            swapTokens[token].tokenContract != address(0),
            "Swap token is not a contract."
        );
        require(
            amount <= swapTokens[token].supply,
            "Swap amount is more than supply."
        );

        // Update the allowed swap amount.
        swapTokens[token].supply = swapTokens[token].supply - amount;

        // Burn the old token.
        ERC20Burnable swapToken = ERC20Burnable(
            swapTokens[token].tokenContract
        );
        swapToken.burnFrom(msg.sender, amount);

        // Mint the new token.
        _mint(msg.sender, amount);

        emit Swap(token, amount);
    }

    /**
     * @dev Check if provided address is a contract.
     * @param addr Address to check.
     * @return hasCode
     */
    function isContract(address addr) private view returns (bool hasCode) {
        uint256 length;
        assembly {
            length := extcodesize(addr)
        }
        return length > 0;
    }
}

Contract Bytecode

Bytecode

60806040523480156200001157600080fd5b506040518060400160405280600a81526020017f54657468657220555344000000000000000000000000000000000000000000008152506040518060400160405280600681526020017f555344542e6500000000000000000000000000000000000000000000000000008152508160039080519060200190620000969291906200027d565b508060049080519060200190620000af9291906200027d565b505050620000cd336005620000ff60201b620017251790919060201c565b60016007600080815260200190815260200160002060006101000a81548160ff02191690831515021790555062000491565b620001118282620001b260201b60201c565b1562000154576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016200014b90620003d7565b60405180910390fd5b60018260000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055505050565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16141562000226576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016200021d90620003f9565b60405180910390fd5b8260000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b8280546200028b906200042c565b90600052602060002090601f016020900481019282620002af5760008555620002fb565b82601f10620002ca57805160ff1916838001178555620002fb565b82800160010185558215620002fb579182015b82811115620002fa578251825591602001919060010190620002dd565b5b5090506200030a91906200030e565b5090565b5b80821115620003295760008160009055506001016200030f565b5090565b60006200033c601f836200041b565b91507f526f6c65733a206163636f756e7420616c72656164792068617320726f6c65006000830152602082019050919050565b60006200037e6022836200041b565b91507f526f6c65733a206163636f756e7420697320746865207a65726f20616464726560008301527f73730000000000000000000000000000000000000000000000000000000000006020830152604082019050919050565b60006020820190508181036000830152620003f2816200032d565b9050919050565b6000602082019050818103600083015262000414816200036f565b9050919050565b600082825260208201905092915050565b600060028204905060018216806200044557607f821691505b602082108114156200045c576200045b62000462565b5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b6131ac80620004a16000396000f3fe608060405234801561001057600080fd5b50600436106101425760003560e01c80636e286671116100b8578063a457c2d71161007c578063a457c2d714610373578063a9059cbb146103a3578063ab32dbb7146103d3578063d004f0f714610403578063dd62ed3e1461041f578063eff038301461044f57610142565b80636e286671146102d157806370a08231146102ed57806379cc67901461031d5780637c38b4571461033957806395d89b411461035557610142565b8063313ce5671161010a578063313ce56714610213578063395093511461023157806342966c68146102615780635d9898d31461027d57806366de3b361461029957806367fc19bb146102b557610142565b806306fdde0314610147578063095ea7b31461016557806318160ddd1461019557806321d93090146101b357806323b872dd146101e3575b600080fd5b61014f61046b565b60405161015c9190612bd7565b60405180910390f35b61017f600480360381019061017a91906121c1565b6104fd565b60405161018c9190612bbc565b60405180910390f35b61019d61051b565b6040516101aa9190612ef9565b60405180910390f35b6101cd60048036038101906101c89190612274565b610525565b6040516101da9190612bbc565b60405180910390f35b6101fd60048036038101906101f89190612172565b610545565b60405161020a9190612bbc565b60405180910390f35b61021b610646565b6040516102289190612f3d565b60405180910390f35b61024b600480360381019061024691906121c1565b61064f565b6040516102589190612bbc565b60405180910390f35b61027b60048036038101906102769190612274565b6106fb565b005b6102976004803603810190610292919061210d565b61070f565b005b6102b360048036038101906102ae9190612274565b6107c4565b005b6102cf60048036038101906102ca91906121fd565b6108fa565b005b6102eb60048036038101906102e6919061229d565b6109b1565b005b6103076004803603810190610302919061210d565b610acd565b6040516103149190612ef9565b60405180910390f35b610337600480360381019061033291906121c1565b610b15565b005b610353600480360381019061034e91906121c1565b610b99565b005b61035d610e98565b60405161036a9190612bd7565b60405180910390f35b61038d600480360381019061038891906121c1565b610f2a565b60405161039a9190612bbc565b60405180910390f35b6103bd60048036038101906103b891906121c1565b61101e565b6040516103ca9190612bbc565b60405180910390f35b6103ed60048036038101906103e8919061210d565b61103c565b6040516103fa9190612ef9565b60405180910390f35b61041d600480360381019061041891906121c1565b611088565b005b61043960048036038101906104349190612136565b6113d7565b6040516104469190612ef9565b60405180910390f35b610469600480360381019061046491906121c1565b61145e565b005b60606003805461047a90613090565b80601f01602080910402602001604051908101604052809291908181526020018280546104a690613090565b80156104f35780601f106104c8576101008083540402835291602001916104f3565b820191906000526020600020905b8154815290600101906020018083116104d657829003601f168201915b5050505050905090565b600061051161050a6117cd565b84846117d5565b6001905092915050565b6000600254905090565b60076020528060005260406000206000915054906101000a900460ff1681565b60006105528484846119a0565b6000600160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600061059d6117cd565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205490508281101561061d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161061490612d59565b60405180910390fd5b61063a856106296117cd565b85846106359190612fca565b6117d5565b60019150509392505050565b60006006905090565b60006106f161065c6117cd565b84846001600061066a6117cd565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546106ec9190612f74565b6117d5565b6001905092915050565b61070c6107066117cd565b82611c1f565b50565b610723336005611df390919063ffffffff16565b610762576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161075990612d39565b60405180910390fd5b610776336005611ebb90919063ffffffff16565b61078a81600561172590919063ffffffff16565b7f871b00a4e20f8436702d0174eb87d84d7cd1dd5c34d4bb1b4e75438b3398d512816040516107b99190612b25565b60405180910390a150565b6107d8336005611df390919063ffffffff16565b610817576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161080e90612d39565b60405180910390fd5b60004690508082141561085f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161085690612e59565b60405180910390fd5b600115156007600084815260200190815260200160002060009054906101000a900460ff161515141561089257506108f7565b60016007600084815260200190815260200160002060006101000a81548160ff0219169083151502179055507f677e2d9a4ed9201aa86725fef875137fc53876e6b68036b974404762682bd122826040516108ed9190612ef9565b60405180910390a1505b50565b61090e336005611df390919063ffffffff16565b61094d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161094490612d39565b60405180910390fd5b6109578585611f62565b600082111561096b5761096a8383611f62565b5b7f918d77674bb88eaf75afb307c9723ea6037706de68d6fc07dd0c6cba423a525085858585856040516109a2959493929190612b69565b60405180910390a15050505050565b3373ffffffffffffffffffffffffffffffffffffffff163273ffffffffffffffffffffffffffffffffffffffff1614610a1f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a1690612c19565b60405180910390fd5b600115156007600083815260200190815260200160002060009054906101000a900460ff16151514610a86576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a7d90612cf9565b60405180910390fd5b610a903383611c1f565b7f37a06799a3500428a773d00284aa706101f5ad94dae9ec37e1c3773aa54c33048282604051610ac1929190612f14565b60405180910390a15050565b60008060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b6000610b2883610b236117cd565b6113d7565b905081811015610b6d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b6490612db9565b60405180910390fd5b610b8a83610b796117cd565b8484610b859190612fca565b6117d5565b610b948383611c1f565b505050565b610bad336005611df390919063ffffffff16565b610bec576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610be390612c79565b60405180910390fd5b610bf5826120b6565b610c34576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c2b90612d79565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff16600660008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161415610d06576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610cfd90612dd9565b60405180910390fd5b80600660008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600101541115610de95780600660008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060010154610d9e9190612fca565b600660008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060010181905550610e5b565b600660008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600080820160006101000a81549073ffffffffffffffffffffffffffffffffffffffff0219169055600182016000905550505b7fd3b4025ff115b79bf2ec5a73c9c784ba8aa9f8f6ba9186b255895c1a9f9042a38282604051610e8c929190612b40565b60405180910390a15050565b606060048054610ea790613090565b80601f0160208091040260200160405190810160405280929190818152602001828054610ed390613090565b8015610f205780601f10610ef557610100808354040283529160200191610f20565b820191906000526020600020905b815481529060010190602001808311610f0357829003601f168201915b5050505050905090565b60008060016000610f396117cd565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905082811015610ff6576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610fed90612eb9565b60405180910390fd5b6110136110016117cd565b85858461100e9190612fca565b6117d5565b600191505092915050565b600061103261102b6117cd565b84846119a0565b6001905092915050565b6000600660008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600101549050919050565b611091826120b6565b6110d0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016110c790612e99565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff16600660008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614156111a2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161119990612e79565b60405180910390fd5b600660008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060010154811115611227576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161121e90612cd9565b60405180910390fd5b80600660008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600101546112759190612fca565b600660008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600101819055506000600660008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690508073ffffffffffffffffffffffffffffffffffffffff166379cc679033846040518363ffffffff1660e01b815260040161135d929190612b40565b600060405180830381600087803b15801561137757600080fd5b505af115801561138b573d6000803e3d6000fd5b505050506113993383611f62565b7f562c219552544ec4c9d7a8eb850f80ea152973e315372bf4999fe7c953ea004f83836040516113ca929190612b40565b60405180910390a1505050565b6000600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905092915050565b611472336005611df390919063ffffffff16565b6114b1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016114a890612d39565b60405180910390fd5b6114ba826120b6565b6114f9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016114f090612d79565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff16600660008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614156116535760405180604001604052808373ffffffffffffffffffffffffffffffffffffffff16815260200182815250600660008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008201518160000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550602082015181600101559050506116e8565b80600660008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600101546116a19190612f74565b600660008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600101819055505b7f3e4fdfb0f47da284fe8b5b3a7e5d10b211e323c9a0c144c421ae1d211873f8538282604051611719929190612b40565b60405180910390a15050565b61172f8282611df3565b1561176f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161176690612c39565b60405180910390fd5b60018260000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055505050565b600033905090565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415611845576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161183c90612e39565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614156118b5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016118ac90612c99565b60405180910390fd5b80600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925836040516119939190612ef9565b60405180910390a3505050565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415611a10576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611a0790612e19565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415611a80576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611a7790612bf9565b60405180910390fd5b611a8b8383836120c9565b60008060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905081811015611b11576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611b0890612cb9565b60405180910390fd5b8181611b1d9190612fca565b6000808673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550816000808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254611bad9190612f74565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051611c119190612ef9565b60405180910390a350505050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415611c8f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611c8690612df9565b60405180910390fd5b611c9b826000836120c9565b60008060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905081811015611d21576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611d1890612c59565b60405180910390fd5b8181611d2d9190612fca565b6000808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508160026000828254611d819190612fca565b92505081905550600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051611de69190612ef9565b60405180910390a3505050565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415611e64576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611e5b90612d99565b60405180910390fd5b8260000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b611ec58282611df3565b611f04576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611efb90612d19565b60405180910390fd5b60008260000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055505050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415611fd2576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611fc990612ed9565b60405180910390fd5b611fde600083836120c9565b8060026000828254611ff09190612f74565b92505081905550806000808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546120459190612f74565b925050819055508173ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040516120aa9190612ef9565b60405180910390a35050565b600080823b905060008111915050919050565b505050565b6000813590506120dd81613131565b92915050565b6000813590506120f281613148565b92915050565b6000813590506121078161315f565b92915050565b60006020828403121561211f57600080fd5b600061212d848285016120ce565b91505092915050565b6000806040838503121561214957600080fd5b6000612157858286016120ce565b9250506020612168858286016120ce565b9150509250929050565b60008060006060848603121561218757600080fd5b6000612195868287016120ce565b93505060206121a6868287016120ce565b92505060406121b7868287016120f8565b9150509250925092565b600080604083850312156121d457600080fd5b60006121e2858286016120ce565b92505060206121f3858286016120f8565b9150509250929050565b600080600080600060a0868803121561221557600080fd5b6000612223888289016120ce565b9550506020612234888289016120f8565b9450506040612245888289016120ce565b9350506060612256888289016120f8565b9250506080612267888289016120e3565b9150509295509295909350565b60006020828403121561228657600080fd5b6000612294848285016120f8565b91505092915050565b600080604083850312156122b057600080fd5b60006122be858286016120f8565b92505060206122cf858286016120f8565b9150509250929050565b6122e281612ffe565b82525050565b6122f181613010565b82525050565b6123008161301c565b82525050565b600061231182612f58565b61231b8185612f63565b935061232b81856020860161305d565b61233481613120565b840191505092915050565b600061234c602383612f63565b91507f45524332303a207472616e7366657220746f20746865207a65726f206164647260008301527f65737300000000000000000000000000000000000000000000000000000000006020830152604082019050919050565b60006123b2601d83612f63565b91507f436f6e74726163742063616c6c73206e6f7420737570706f727465642e0000006000830152602082019050919050565b60006123f2601f83612f63565b91507f526f6c65733a206163636f756e7420616c72656164792068617320726f6c65006000830152602082019050919050565b6000612432602283612f63565b91507f45524332303a206275726e20616d6f756e7420657863656564732062616c616e60008301527f63650000000000000000000000000000000000000000000000000000000000006020830152604082019050919050565b6000612498600c83612f63565b91507f556e617574686f72697a656400000000000000000000000000000000000000006000830152602082019050919050565b60006124d8602283612f63565b91507f45524332303a20617070726f766520746f20746865207a65726f20616464726560008301527f73730000000000000000000000000000000000000000000000000000000000006020830152604082019050919050565b600061253e602683612f63565b91507f45524332303a207472616e7366657220616d6f756e742065786365656473206260008301527f616c616e636500000000000000000000000000000000000000000000000000006020830152604082019050919050565b60006125a4602083612f63565b91507f5377617020616d6f756e74206973206d6f7265207468616e20737570706c792e6000830152602082019050919050565b60006125e4601783612f63565b91507f436861696e204944206e6f7420737570706f727465642e0000000000000000006000830152602082019050919050565b6000612624602183612f63565b91507f526f6c65733a206163636f756e7420646f6573206e6f74206861766520726f6c60008301527f65000000000000000000000000000000000000000000000000000000000000006020830152604082019050919050565b600061268a600d83612f63565b91507f556e617574686f72697a65642e000000000000000000000000000000000000006000830152602082019050919050565b60006126ca602883612f63565b91507f45524332303a207472616e7366657220616d6f756e742065786365656473206160008301527f6c6c6f77616e63650000000000000000000000000000000000000000000000006020830152604082019050919050565b6000612730601883612f63565b91507f41646472657373206973206e6f7420636f6e74726163742e00000000000000006000830152602082019050919050565b6000612770602283612f63565b91507f526f6c65733a206163636f756e7420697320746865207a65726f20616464726560008301527f73730000000000000000000000000000000000000000000000000000000000006020830152604082019050919050565b60006127d6602483612f63565b91507f45524332303a206275726e20616d6f756e74206578636565647320616c6c6f7760008301527f616e6365000000000000000000000000000000000000000000000000000000006020830152604082019050919050565b600061283c601883612f63565b91507f5377617020746f6b656e206e6f7420737570706f7274656400000000000000006000830152602082019050919050565b600061287c602183612f63565b91507f45524332303a206275726e2066726f6d20746865207a65726f2061646472657360008301527f73000000000000000000000000000000000000000000000000000000000000006020830152604082019050919050565b60006128e2602583612f63565b91507f45524332303a207472616e736665722066726f6d20746865207a65726f20616460008301527f64726573730000000000000000000000000000000000000000000000000000006020830152604082019050919050565b6000612948602483612f63565b91507f45524332303a20617070726f76652066726f6d20746865207a65726f2061646460008301527f72657373000000000000000000000000000000000000000000000000000000006020830152604082019050919050565b60006129ae601c83612f63565b91507f43616e6e6f74206164642063757272656e7420636861696e2049442e000000006000830152602082019050919050565b60006129ee601d83612f63565b91507f5377617020746f6b656e206973206e6f74206120636f6e74726163742e0000006000830152602082019050919050565b6000612a2e601883612f63565b91507f546f6b656e206973206e6f74206120636f6e74726163742e00000000000000006000830152602082019050919050565b6000612a6e602583612f63565b91507f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f7760008301527f207a65726f0000000000000000000000000000000000000000000000000000006020830152604082019050919050565b6000612ad4601f83612f63565b91507f45524332303a206d696e7420746f20746865207a65726f2061646472657373006000830152602082019050919050565b612b1081613046565b82525050565b612b1f81613050565b82525050565b6000602082019050612b3a60008301846122d9565b92915050565b6000604082019050612b5560008301856122d9565b612b626020830184612b07565b9392505050565b600060a082019050612b7e60008301886122d9565b612b8b6020830187612b07565b612b9860408301866122d9565b612ba56060830185612b07565b612bb260808301846122f7565b9695505050505050565b6000602082019050612bd160008301846122e8565b92915050565b60006020820190508181036000830152612bf18184612306565b905092915050565b60006020820190508181036000830152612c128161233f565b9050919050565b60006020820190508181036000830152612c32816123a5565b9050919050565b60006020820190508181036000830152612c52816123e5565b9050919050565b60006020820190508181036000830152612c7281612425565b9050919050565b60006020820190508181036000830152612c928161248b565b9050919050565b60006020820190508181036000830152612cb2816124cb565b9050919050565b60006020820190508181036000830152612cd281612531565b9050919050565b60006020820190508181036000830152612cf281612597565b9050919050565b60006020820190508181036000830152612d12816125d7565b9050919050565b60006020820190508181036000830152612d3281612617565b9050919050565b60006020820190508181036000830152612d528161267d565b9050919050565b60006020820190508181036000830152612d72816126bd565b9050919050565b60006020820190508181036000830152612d9281612723565b9050919050565b60006020820190508181036000830152612db281612763565b9050919050565b60006020820190508181036000830152612dd2816127c9565b9050919050565b60006020820190508181036000830152612df28161282f565b9050919050565b60006020820190508181036000830152612e128161286f565b9050919050565b60006020820190508181036000830152612e32816128d5565b9050919050565b60006020820190508181036000830152612e528161293b565b9050919050565b60006020820190508181036000830152612e72816129a1565b9050919050565b60006020820190508181036000830152612e92816129e1565b9050919050565b60006020820190508181036000830152612eb281612a21565b9050919050565b60006020820190508181036000830152612ed281612a61565b9050919050565b60006020820190508181036000830152612ef281612ac7565b9050919050565b6000602082019050612f0e6000830184612b07565b92915050565b6000604082019050612f296000830185612b07565b612f366020830184612b07565b9392505050565b6000602082019050612f526000830184612b16565b92915050565b600081519050919050565b600082825260208201905092915050565b6000612f7f82613046565b9150612f8a83613046565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff03821115612fbf57612fbe6130c2565b5b828201905092915050565b6000612fd582613046565b9150612fe083613046565b925082821015612ff357612ff26130c2565b5b828203905092915050565b600061300982613026565b9050919050565b60008115159050919050565b6000819050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b600060ff82169050919050565b60005b8381101561307b578082015181840152602081019050613060565b8381111561308a576000848401525b50505050565b600060028204905060018216806130a857607f821691505b602082108114156130bc576130bb6130f1565b5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b6000601f19601f8301169050919050565b61313a81612ffe565b811461314557600080fd5b50565b6131518161301c565b811461315c57600080fd5b50565b61316881613046565b811461317357600080fd5b5056fe