false
false

Contract Address Details

0xd5235958c1F8a40641847A0E3BD51d04EFe9eC28

Contract Name
DestinationBridge
Creator
0xfe0c4d–5fd5d4 at 0xe1903b–0ca96f
Balance
0 MNT ( )
Tokens
Fetching tokens...
Transactions
15
Transfers
0
Gas Used
2,930,946
Last Balance Update
24387271
Contract is not verified. However, we found a verified contract with the same bytecode in Blockscout DB 0xcdc59b5b4e323a878b0d635d458de8c736c0cca8.
All metadata displayed below is from that contract. In order to verify current contract, click Verify & Publish button
Verify & Publish
Contract name:
DestinationBridge




Optimization enabled
true
Compiler version
v0.8.16+commit.07a7930e




Optimization runs
100
Verified at
2023-10-25T15:02:55.264477Z

contracts/bridge/DestinationBridge.sol

/**SPDX-License-Identifier: BUSL-1.1

      ▄▄█████████▄
   ╓██▀└ ,╓▄▄▄, '▀██▄
  ██▀ ▄██▀▀╙╙▀▀██▄ └██µ           ,,       ,,      ,     ,,,            ,,,
 ██ ,██¬ ▄████▄  ▀█▄ ╙█▄      ▄███▀▀███▄   ███▄    ██  ███▀▀▀███▄    ▄███▀▀███,
██  ██ ╒█▀'   ╙█▌ ╙█▌ ██     ▐██      ███  █████,  ██  ██▌    └██▌  ██▌     └██▌
██ ▐█▌ ██      ╟█  █▌ ╟█     ██▌      ▐██  ██ └███ ██  ██▌     ╟██ j██       ╟██
╟█  ██ ╙██    ▄█▀ ▐█▌ ██     ╙██      ██▌  ██   ╙████  ██▌    ▄██▀  ██▌     ,██▀
 ██ "██, ╙▀▀███████████⌐      ╙████████▀   ██     ╙██  ███████▀▀     ╙███████▀`
  ██▄ ╙▀██▄▄▄▄▄,,,                ¬─                                    '─¬
   ╙▀██▄ '╙╙╙▀▀▀▀▀▀▀▀
      ╙▀▀██████R⌐

 */
pragma solidity 0.8.16;

import "contracts/interfaces/IAxelarGateway.sol";
import "contracts/external/axelar/AxelarExecutable.sol";
import "contracts/interfaces/IRWALike.sol";
import "contracts/interfaces/IAllowlist.sol";
import "contracts/external/openzeppelin/contracts/access/Ownable.sol";
import "contracts/external/openzeppelin/contracts/security/Pausable.sol";
import "contracts/bridge/MintRateLimiter.sol";
import "contracts/external/openzeppelin/contracts/token/SafeERC20.sol";

contract DestinationBridge is
  AxelarExecutable,
  MintTimeBasedRateLimiter,
  Ownable,
  Pausable
{
  using SafeERC20 for IERC20;
  /// @notice Token contract bridged by this contract
  IRWALike public immutable TOKEN;

  /// @notice Pointer to AxelarGateway contract
  IAxelarGateway public immutable AXELAR_GATEWAY;

  /// @notice Pointer to USDY allowlist
  IAllowlist public immutable ALLOWLIST;

  // Mapping used to track approvers, approved msg src's and spent nonces
  mapping(address => bool) public approvers;
  mapping(string => bytes32) public chainToApprovedSender;
  mapping(bytes32 => mapping(uint256 => bool)) public isSpentNonce;

  /// @notice Versioning for payload, must match SourceBridge version
  bytes32 public constant VERSION = "1.0";

  /// @notice Mappings used to track transaction and thresholds
  mapping(bytes32 => TxnThreshold) public txnToThresholdSet;
  mapping(string => Threshold[]) public chainToThresholds;
  mapping(bytes32 => Transaction) public txnHashToTransaction;

  constructor(
    address _token,
    address _axelarGateway,
    address _allowlist,
    address _ondoApprover,
    address _owner,
    uint256 _mintLimit,
    uint256 _mintDuration
  )
    AxelarExecutable(_axelarGateway)
    MintTimeBasedRateLimiter(_mintDuration, _mintLimit)
  {
    TOKEN = IRWALike(_token);
    AXELAR_GATEWAY = IAxelarGateway(_axelarGateway);
    ALLOWLIST = IAllowlist(_allowlist);
    approvers[_ondoApprover] = true;
    _transferOwnership(_owner);
  }

  /*//////////////////////////////////////////////////////////////
                         Axelar Functions
  //////////////////////////////////////////////////////////////*/

  /**
   * @notice Internal overriden function that is executed when contract is called by Axelar Relayer
   *
   * @param srcChain The string of the source chain eg: arbitrum
   * @param srcAddr  The string of the address of the source contract
   * @param payload  The payload to pass cross chain
   */
  function _execute(
    string calldata srcChain,
    string calldata srcAddr,
    bytes calldata payload
  ) internal override whenNotPaused {
    (bytes32 version, , address srcSender, uint256 amt, uint256 nonce) = abi
      .decode(payload, (bytes32, uint256, address, uint256, uint256));

    if (version != VERSION) {
      revert InvalidVersion();
    }
    if (chainToApprovedSender[srcChain] == bytes32(0)) {
      revert ChainNotSupported();
    }
    if (chainToApprovedSender[srcChain] != keccak256(abi.encode(srcAddr))) {
      revert SourceNotSupported();
    }
    if (isSpentNonce[chainToApprovedSender[srcChain]][nonce]) {
      revert NonceSpent();
    }

    isSpentNonce[chainToApprovedSender[srcChain]][nonce] = true;

    bytes32 txnHash = keccak256(payload);
    txnHashToTransaction[txnHash] = Transaction(srcSender, amt);
    _attachThreshold(amt, txnHash, srcChain);
    _approve(txnHash);
    _mintIfThresholdMet(txnHash);
    emit MessageReceived(txnHash, srcChain, srcSender, amt, nonce);
  }

  /*//////////////////////////////////////////////////////////////
                        Internal Functions
  //////////////////////////////////////////////////////////////*/

  /**
   * @notice Internal function used to attach a specific threshold to a given
   *         `txnHash`.
   *
   * @param amount   The amount of the token being bridged
   * @param txnHash  The transaction hash to associate the threshold with
   * @param srcChain The chain corresponding to the chain that the token
   *                 being bridged originated from.
   */
  function _attachThreshold(
    uint256 amount,
    bytes32 txnHash,
    string memory srcChain
  ) internal {
    Threshold[] memory thresholds = chainToThresholds[srcChain];
    for (uint256 i = 0; i < thresholds.length; ++i) {
      Threshold memory t = thresholds[i];
      if (amount <= t.amount) {
        txnToThresholdSet[txnHash] = TxnThreshold(
          t.numberOfApprovalsNeeded,
          new address[](0)
        );
        break;
      }
    }
    if (txnToThresholdSet[txnHash].numberOfApprovalsNeeded == 0) {
      revert NoThresholdMatch();
    }
  }

  /**
   * @notice Internal function used to approve and conditionally mint for a
   *         given txn. Approval is conditional on this approver having not
   *         previously approved the txn
   *
   * @param txnHash The txnHash to approve and conditionally mint to
   */
  function _approve(bytes32 txnHash) internal {
    // Check that the approver has not already approved
    TxnThreshold storage t = txnToThresholdSet[txnHash];
    uint256 approversLength = t.approvers.length;
    if (approversLength > 0) {
      for (uint256 i = 0; i < approversLength; ++i) {
        if (t.approvers[i] == msg.sender) {
          revert AlreadyApproved();
        }
      }
    }
    t.approvers.push(msg.sender);
    emit TransactionApproved(
      txnHash,
      msg.sender,
      approversLength + 1,
      t.numberOfApprovalsNeeded
    );
  }

  /**
   * @notice Internal function to mint tokens for a user if the transaction has
   *         passed the threshold for number of approvers
   *
   * @param txnHash The hash of the payload we wish to mint
   */
  function _mintIfThresholdMet(bytes32 txnHash) internal {
    bool thresholdMet = _checkThresholdMet(txnHash);
    if (thresholdMet) {
      Transaction memory txn = txnHashToTransaction[txnHash];
      _checkAndUpdateInstantMintLimit(txn.amount);
      if (
        address(ALLOWLIST) != address(0) && !ALLOWLIST.isAllowed(txn.sender)
      ) {
        ALLOWLIST.setAccountStatus(
          txn.sender,
          ALLOWLIST.getValidTermIndexes()[0],
          true
        );
      }
      TOKEN.mint(txn.sender, txn.amount);
      // Clear the approval for this bridge payload
      delete txnHashToTransaction[txnHash];
      emit BridgeCompleted(txn.sender, txn.amount);
    }
  }

  /**
   * @notice Internal function used to check if the approval threshold has been
   *         met for a given transaction.
   *
   * @param txnHash The txnHash to check
   *
   * @dev If an approver has been removed, any previous approvals are still valid
   */
  function _checkThresholdMet(bytes32 txnHash) internal view returns (bool) {
    TxnThreshold storage t = txnToThresholdSet[txnHash];
    return t.approvers.length >= t.numberOfApprovalsNeeded;
  }

  /*//////////////////////////////////////////////////////////////
                        Protected Functions
  //////////////////////////////////////////////////////////////*/

  /**
   * @notice Protected Function used to approve messages passed to the
   *         Receiver contract. This function is able to be called by any
   *         approver that is added and associated with Ondo.
   *
   * @param txnHash The keccak256 hash of the payload
   */
  function approve(bytes32 txnHash) external {
    if (!approvers[msg.sender]) {
      revert NotApprover();
    }
    _approve(txnHash);
    _mintIfThresholdMet(txnHash);
  }

  /**
   * @notice Admin function to add an ondo Signer or Axelar Relayer
   *
   * @param approver  The address we would like to add
   */
  function addApprover(address approver) external onlyOwner {
    approvers[approver] = true;
    emit ApproverAdded(approver);
  }

  /**
   * @notice Admin function to remove an approver
   *
   * @param approver The address of the approver that we would like to remove
   */
  function removeApprover(address approver) external onlyOwner {
    delete approvers[approver];
    emit ApproverRemoved(approver);
  }

  /**
   * @notice Admin function that will allow bridge calls originating from a given address
   *         on a given chain.
   * @notice This will initialize a nested mapping in which spent nonces from this `srcAddress`
   *         are logged and prevented from being reused
   *
   * @param srcChain            The chain to support
   * @param srcContractAddress  The address of the Ondo Bridge on the source chain
   *
   * @dev srcContractAddress: Is case sensitive and must be the checksum address
   * of the srcBridge contract which is allowed to call into this contract.
   */
  function addChainSupport(
    string calldata srcChain,
    string calldata srcContractAddress
  ) external onlyOwner {
    chainToApprovedSender[srcChain] = keccak256(abi.encode(srcContractAddress));
    emit ChainIdSupported(srcChain, srcContractAddress);
  }

  /**
   * @notice Admin function that will remove support for previously supported chains
   *
   * @param srcChain The source chain whose support is being removed
   */
  function removeChainSupport(string calldata srcChain) external onlyOwner {
    delete chainToApprovedSender[srcChain];
    emit ChainSupportRemoved(srcChain);
  }

  /**
   * @notice Admin function used to clear and set thresholds corresponding to a chain
   *
   * @param srcChain       The chain to set the threshold for
   * @param amounts        The ordered array of values corresponding to
   *                       the amount for a given threshold
   * @param numOfApprovers The ordered array of the number of approvals needed
   *                       for a given threshold
   *
   * @dev This function will remove all previously set thresholds for a given chain
   *      and will thresholds corresponding to the params of this function. Passing
   *      in empty arrays will remove all thresholds for a given chain
   */
  function setThresholds(
    string calldata srcChain,
    uint256[] calldata amounts,
    uint256[] calldata numOfApprovers
  ) external onlyOwner {
    if (amounts.length != numOfApprovers.length) {
      revert ArrayLengthMismatch();
    }
    delete chainToThresholds[srcChain];
    for (uint256 i = 0; i < amounts.length; ++i) {
      if (numOfApprovers[i] == 0) {
        revert NumOfApproversCannotBeZero();
      }
      if (i == 0) {
        chainToThresholds[srcChain].push(
          Threshold(amounts[i], numOfApprovers[i])
        );
      } else {
        if (chainToThresholds[srcChain][i - 1].amount > amounts[i]) {
          revert ThresholdsNotInAscendingOrder();
        }
        chainToThresholds[srcChain].push(
          Threshold(amounts[i], numOfApprovers[i])
        );
      }
    }
    emit ThresholdSet(srcChain, amounts, numOfApprovers);
  }

  /**
   * @notice Admin function used to set the mint limit
   *
   * @param mintLimit The new mint limit
   */
  function setMintLimit(uint256 mintLimit) external onlyOwner {
    _setMintLimit(mintLimit);
  }

  /**
   * @notice Admin function used to set the mint duration
   *
   * @param mintDuration The new mint duration
   */
  function setMintLimitDuration(uint256 mintDuration) external onlyOwner {
    _setMintLimitDuration(mintDuration);
  }

  /**
   * @notice Admin function used to pause the contract
   *
   * @dev Only used for bridge functions
   */
  function pause() external onlyOwner {
    _pause();
  }

  /**
   * @notice Admin function used to unpause the contract
   *
   * @dev Only used for bridge functions
   */
  function unpause() external onlyOwner {
    _unpause();
  }

  /**
   * @notice Admin function used to rescue ERC20 Tokens sent to the contract
   *
   * @param _token The address of the token to rescue
   */
  function rescueTokens(address _token) external onlyOwner {
    uint256 balance = IERC20(_token).balanceOf(address(this));
    IERC20(_token).safeTransfer(owner(), balance);
  }

  /*//////////////////////////////////////////////////////////////
                       Helper Functions
  //////////////////////////////////////////////////////////////*/

  /**
   * @notice External view function used to get the number of approvers for a
   *         given txnHash
   *
   * @param txnHash The hash to get the number of approvers for
   */
  function getNumApproved(bytes32 txnHash) external view returns (uint256) {
    return txnToThresholdSet[txnHash].approvers.length;
  }

  /*//////////////////////////////////////////////////////////////
                      Structs, Events, Errors
  //////////////////////////////////////////////////////////////*/

  struct Threshold {
    uint256 amount;
    uint256 numberOfApprovalsNeeded;
  }

  struct TxnThreshold {
    uint256 numberOfApprovalsNeeded;
    address[] approvers;
  }

  struct Transaction {
    address sender;
    uint256 amount;
  }

  /**
   * @notice event emitted when an address is removed as an approver
   *
   * @param approver The address being removed
   */
  event ApproverRemoved(address approver);

  /**
   * @notice event emitted when an address is added as an approver
   *
   * @param approver  The address to add
   */
  event ApproverAdded(address approver);

  /**
   * @notice event emitted when a new contract is whitelisted as an approved
   *         message passer.
   *
   * @param srcChain        The chain for the approved address
   * @param approvedSource  The address corresponding to the source bridge contract
   */
  event ChainIdSupported(string indexed srcChain, string approvedSource);

  /**
   * @notice event emitted when a threshold has been set
   *
   * @param chain           The chain for which the threshold was set
   * @param amounts         The amount of tokens to reach this threshold
   * @param numOfApprovers  The number of approvals needed
   */
  event ThresholdSet(
    string indexed chain,
    uint256[] amounts,
    uint256[] numOfApprovers
  );

  /**
   * @notice event emitted when the user has been minted their tokens on the dst chain
   *
   * @param user    The recipient address of the newly minted tokens
   * @param amount  The amount of tokens that have been minted
   */
  event BridgeCompleted(address indexed user, uint256 amount);

  /**
   * @notice event emitted when this bridge contract receives a cross chain message
   *
   * @param txnHash   The hash of the payload that has been bridged
   * @param srcChain  The chain from which the message is originating
   * @param srcSender The address of the msg.sender on the source chain
   * @param amt       The amount of tokens being bridged
   * @param nonce     The nonce corresponding to the contract which originated the msg
   */
  event MessageReceived(
    bytes32 indexed txnHash,
    string indexed srcChain,
    address indexed srcSender,
    uint256 amt,
    uint256 nonce
  );

  /**
   * @notice event emitted when a transaction has been approved
   *
   * @param txnHash              The hash of the payload that has been approved
   * @param approver             The address of the approver
   * @param numApprovers         The number of approvers for this transaction
   * @param thresholdRequirement The number of approvals needed for this transaction
   */
  event TransactionApproved(
    bytes32 indexed txnHash,
    address approver,
    uint256 numApprovers,
    uint256 thresholdRequirement
  );

  /**
   * @notice event emitted when support for a chain is removed
   *
   * @param srcChain The chain whose support is being removed
   */
  event ChainSupportRemoved(string indexed srcChain);

  error NotApprover();
  error NoThresholdMatch();
  error ThresholdsNotInAscendingOrder();

  error ChainNotSupported();
  error SourceNotSupported();
  error NonceSpent();
  error AlreadyApproved();
  error InvalidVersion();
  error ArrayLengthMismatch();
  error NumOfApproversCannotBeZero();
}
              

contracts/bridge/MintRateLimiter.sol

/**SPDX-License-Identifier: BUSL-1.1

      ▄▄█████████▄
   ╓██▀└ ,╓▄▄▄, '▀██▄
  ██▀ ▄██▀▀╙╙▀▀██▄ └██µ           ,,       ,,      ,     ,,,            ,,,
 ██ ,██¬ ▄████▄  ▀█▄ ╙█▄      ▄███▀▀███▄   ███▄    ██  ███▀▀▀███▄    ▄███▀▀███,
██  ██ ╒█▀'   ╙█▌ ╙█▌ ██     ▐██      ███  █████,  ██  ██▌    └██▌  ██▌     └██▌
██ ▐█▌ ██      ╟█  █▌ ╟█     ██▌      ▐██  ██ └███ ██  ██▌     ╟██ j██       ╟██
╟█  ██ ╙██    ▄█▀ ▐█▌ ██     ╙██      ██▌  ██   ╙████  ██▌    ▄██▀  ██▌     ,██▀
 ██ "██, ╙▀▀███████████⌐      ╙████████▀   ██     ╙██  ███████▀▀     ╙███████▀`
  ██▄ ╙▀██▄▄▄▄▄,,,                ¬─                                    '─¬
   ╙▀██▄ '╙╙╙▀▀▀▀▀▀▀▀
      ╙▀▀██████R⌐

 */
pragma solidity 0.8.16;

/**
 * @title InstantMintTimeBasedRateLimiter
 *
 * @notice This abstract contract implements two rate limiters: one for minting
 *         and one for redeeming. Each limit is completely independent: mints
 *         and redemption don't offset each other. Each limit is associated
 *         with a duration, after which the tracked amount is reset. The
 *         amounts tracked are agnostic to a specific token; the usage is
 *         determined by the inheriting contracts.
 *
 * @dev Although this contract has all of its functions implemented, this
 *      contract is marked abstract to prevent an accidental deployment and to
 *      signify that we would never deploy this contract standalone.
 *
 */
abstract contract MintTimeBasedRateLimiter {
  // `currentMintAmount` resets after this interval (in seconds)
  uint256 public resetMintDuration;
  // timestamp when `currentMintAmount` was last reset
  uint256 public lastResetMintTime;

  // maximum amount that can be minted during a `resetMintDuration` window
  uint256 public mintLimit;
  // amount already minted during the current `resetMintDuration` window
  uint256 public currentMintAmount;

  /**
   * @notice In the constructor, we initialize the variables for the mint and
   *         redemption rate limiters.
   *
   * @param _mintResetDuration   `currentMintAmount` resets after this interval
   *                                    (in seconds)
   * @param _instantMintLimit           maximum amount that can be minted during a
   *                                    `resetMintDuration` window
   *
   * @dev If a duration is zero, the limit resets before each mint/redemption.
   * @dev If a limit is zero, the relevant check always fails.
   */
  constructor(uint256 _mintResetDuration, uint256 _instantMintLimit) {
    resetMintDuration = _mintResetDuration; // can be zero for per-block limit
    mintLimit = _instantMintLimit; // can be zero to disable minting

    lastResetMintTime = block.timestamp;
  }

  /**
   * @notice Checks the requested mint amount against the rate limiter (and
   *         updates the remaining amount)
   *
   * @param amount The requested mint amount
   *
   * @dev Reverts if the requested mint amount exceeds the current limit
   */
  function _checkAndUpdateInstantMintLimit(uint256 amount) internal {
    require(amount > 0, "RateLimit: mint amount can't be zero");

    if (block.timestamp >= lastResetMintTime + resetMintDuration) {
      // time has passed, reset
      currentMintAmount = 0;
      lastResetMintTime = block.timestamp;
    }
    require(
      amount <= mintLimit - currentMintAmount,
      "RateLimit: Mint exceeds rate limit"
    );

    currentMintAmount += amount;
  }

  /**
   * @notice Update the amount of token that can be minted during one duration
   *
   * @param _mintLimit The token amount
   *
   * @dev If a limit is zero, the relevant check always fails.
   */
  function _setMintLimit(uint256 _mintLimit) internal {
    mintLimit = _mintLimit;
    emit MintLimitSet(_mintLimit);
  }

  /**
   * @notice Update the duration for the mint rate limiter
   *
   * @param _mintResetDuration The duration in seconds
   *
   * @dev If a duration is zero, the limit resets before each mint/redemption
   */
  function _setMintLimitDuration(uint256 _mintResetDuration) internal {
    resetMintDuration = _mintResetDuration;
    emit MintLimitDurationSet(_mintResetDuration);
  }

  /**
   * @notice Event emitted when mint limit is set
   *
   * @param mintLimit How much of some token can be minted within
   *                  an interval of length `resetMintDuration`
   *
   * @dev See inheriting contract for representation
   */
  event MintLimitSet(uint256 mintLimit);

  /**
   * @notice Event emitted when mint limit duration is set
   *
   * @param instantMintLimitDuration The time window in which `mintLimit`
   *                          of some token can be minted
   *
   * @dev instantMintLimitDuration is specified in seconds
   */
  event MintLimitDurationSet(uint256 instantMintLimitDuration);
}
                

contracts/external/axelar/AxelarExecutable.sol

// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import {IAxelarGateway} from "../../interfaces/IAxelarGateway.sol";
import {IAxelarExecutable} from "../../interfaces/IAxelarExecutable.sol";

contract AxelarExecutable is IAxelarExecutable {
  IAxelarGateway public immutable gateway;

  constructor(address gateway_) {
    if (gateway_ == address(0)) revert InvalidAddress();

    gateway = IAxelarGateway(gateway_);
  }

  function execute(
    bytes32 commandId,
    string calldata sourceChain,
    string calldata sourceAddress,
    bytes calldata payload
  ) external {
    bytes32 payloadHash = keccak256(payload);

    if (
      !gateway.validateContractCall(
        commandId,
        sourceChain,
        sourceAddress,
        payloadHash
      )
    ) revert NotApprovedByGateway();

    _execute(sourceChain, sourceAddress, payload);
  }

  function executeWithToken(
    bytes32 commandId,
    string calldata sourceChain,
    string calldata sourceAddress,
    bytes calldata payload,
    string calldata tokenSymbol,
    uint256 amount
  ) external {
    bytes32 payloadHash = keccak256(payload);

    if (
      !gateway.validateContractCallAndMint(
        commandId,
        sourceChain,
        sourceAddress,
        payloadHash,
        tokenSymbol,
        amount
      )
    ) revert NotApprovedByGateway();

    _executeWithToken(sourceChain, sourceAddress, payload, tokenSymbol, amount);
  }

  function _execute(
    string calldata sourceChain,
    string calldata sourceAddress,
    bytes calldata payload
  ) internal virtual {}

  // false detection from slither
  // slither-disable-next-line dead-code
  function _executeWithToken(
    string calldata sourceChain,
    string calldata sourceAddress,
    bytes calldata payload,
    string calldata tokenSymbol,
    uint256 amount
  ) internal virtual {}
}
                

contracts/external/openzeppelin/contracts/access/Ownable.sol

// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (access/Ownable.sol)

pragma solidity ^0.8.0;

import "contracts/external/openzeppelin/contracts/utils/Context.sol";

/**
 * @dev Contract module which provides a basic access control mechanism, where
 * there is an account (an owner) that can be granted exclusive access to
 * specific functions.
 *
 * By default, the owner account will be the one that deploys the contract. This
 * can later be changed with {transferOwnership}.
 *
 * This module is used through inheritance. It will make available the modifier
 * `onlyOwner`, which can be applied to your functions to restrict their use to
 * the owner.
 */
abstract contract Ownable is Context {
  address private _owner;

  event OwnershipTransferred(
    address indexed previousOwner,
    address indexed newOwner
  );

  /**
   * @dev Initializes the contract setting the deployer as the initial owner.
   */
  constructor() {
    _transferOwnership(_msgSender());
  }

  /**
   * @dev Returns the address of the current owner.
   */
  function owner() public view virtual returns (address) {
    return _owner;
  }

  /**
   * @dev Throws if called by any account other than the owner.
   */
  modifier onlyOwner() {
    require(owner() == _msgSender(), "Ownable: caller is not the owner");
    _;
  }

  /**
   * @dev Leaves the contract without owner. It will not be possible to call
   * `onlyOwner` functions anymore. Can only be called by the current owner.
   *
   * NOTE: Renouncing ownership will leave the contract without an owner,
   * thereby removing any functionality that is only available to the owner.
   */
  function renounceOwnership() public virtual onlyOwner {
    _transferOwnership(address(0));
  }

  /**
   * @dev Transfers ownership of the contract to a new account (`newOwner`).
   * Can only be called by the current owner.
   */
  function transferOwnership(address newOwner) public virtual onlyOwner {
    require(newOwner != address(0), "Ownable: new owner is the zero address");
    _transferOwnership(newOwner);
  }

  /**
   * @dev Transfers ownership of the contract to a new account (`newOwner`).
   * Internal function without access restriction.
   */
  function _transferOwnership(address newOwner) internal virtual {
    address oldOwner = _owner;
    _owner = newOwner;
    emit OwnershipTransferred(oldOwner, newOwner);
  }
}
                

contracts/external/openzeppelin/contracts/security/Pausable.sol

// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (security/Pausable.sol)

pragma solidity ^0.8.0;

import "contracts/external/openzeppelin/contracts/utils/Context.sol";

/**
 * @dev Contract module which allows children to implement an emergency stop
 * mechanism that can be triggered by an authorized account.
 *
 * This module is used through inheritance. It will make available the
 * modifiers `whenNotPaused` and `whenPaused`, which can be applied to
 * the functions of your contract. Note that they will not be pausable by
 * simply including this module, only once the modifiers are put in place.
 */
abstract contract Pausable is Context {
  /**
   * @dev Emitted when the pause is triggered by `account`.
   */
  event Paused(address account);

  /**
   * @dev Emitted when the pause is lifted by `account`.
   */
  event Unpaused(address account);

  bool private _paused;

  /**
   * @dev Initializes the contract in unpaused state.
   */
  constructor() {
    _paused = false;
  }

  /**
   * @dev Returns true if the contract is paused, and false otherwise.
   */
  function paused() public view virtual returns (bool) {
    return _paused;
  }

  /**
   * @dev Modifier to make a function callable only when the contract is not paused.
   *
   * Requirements:
   *
   * - The contract must not be paused.
   */
  modifier whenNotPaused() {
    require(!paused(), "Pausable: paused");
    _;
  }

  /**
   * @dev Modifier to make a function callable only when the contract is paused.
   *
   * Requirements:
   *
   * - The contract must be paused.
   */
  modifier whenPaused() {
    require(paused(), "Pausable: not paused");
    _;
  }

  /**
   * @dev Triggers stopped state.
   *
   * Requirements:
   *
   * - The contract must not be paused.
   */
  function _pause() internal virtual whenNotPaused {
    _paused = true;
    emit Paused(_msgSender());
  }

  /**
   * @dev Returns to normal state.
   *
   * Requirements:
   *
   * - The contract must be paused.
   */
  function _unpause() internal virtual whenPaused {
    _paused = false;
    emit Unpaused(_msgSender());
  }
}
                

contracts/external/openzeppelin/contracts/token/IERC20.sol

// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/IERC20.sol)

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 `to`.
   *
   * Returns a boolean value indicating whether the operation succeeded.
   *
   * Emits a {Transfer} event.
   */
  function transfer(address to, 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 `from` to `to` 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 from,
    address to,
    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);
}
                

contracts/external/openzeppelin/contracts/token/SafeERC20.sol

// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC20/utils/SafeERC20.sol)

pragma solidity ^0.8.0;

import "contracts/external/openzeppelin/contracts/token/IERC20.sol";
import "contracts/external/openzeppelin/contracts/utils/Address.sol";

/**
 * @title SafeERC20
 * @dev Wrappers around ERC20 operations that throw on failure (when the token
 * contract returns false). Tokens that return no value (and instead revert or
 * throw on failure) are also supported, non-reverting calls are assumed to be
 * successful.
 * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,
 * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.
 */
library SafeERC20 {
  using Address for address;

  function safeTransfer(
    IERC20 token,
    address to,
    uint256 value
  ) internal {
    _callOptionalReturn(
      token,
      abi.encodeWithSelector(token.transfer.selector, to, value)
    );
  }

  function safeTransferFrom(
    IERC20 token,
    address from,
    address to,
    uint256 value
  ) internal {
    _callOptionalReturn(
      token,
      abi.encodeWithSelector(token.transferFrom.selector, from, to, value)
    );
  }

  /**
   * @dev Deprecated. This function has issues similar to the ones found in
   * {IERC20-approve}, and its usage is discouraged.
   *
   * Whenever possible, use {safeIncreaseAllowance} and
   * {safeDecreaseAllowance} instead.
   */
  function safeApprove(
    IERC20 token,
    address spender,
    uint256 value
  ) internal {
    // safeApprove should only be called when setting an initial allowance,
    // or when resetting it to zero. To increase and decrease it, use
    // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'
    require(
      (value == 0) || (token.allowance(address(this), spender) == 0),
      "SafeERC20: approve from non-zero to non-zero allowance"
    );
    _callOptionalReturn(
      token,
      abi.encodeWithSelector(token.approve.selector, spender, value)
    );
  }

  function safeIncreaseAllowance(
    IERC20 token,
    address spender,
    uint256 value
  ) internal {
    uint256 newAllowance = token.allowance(address(this), spender) + value;
    _callOptionalReturn(
      token,
      abi.encodeWithSelector(token.approve.selector, spender, newAllowance)
    );
  }

  function safeDecreaseAllowance(
    IERC20 token,
    address spender,
    uint256 value
  ) internal {
    unchecked {
      uint256 oldAllowance = token.allowance(address(this), spender);
      require(
        oldAllowance >= value,
        "SafeERC20: decreased allowance below zero"
      );
      uint256 newAllowance = oldAllowance - value;
      _callOptionalReturn(
        token,
        abi.encodeWithSelector(token.approve.selector, spender, newAllowance)
      );
    }
  }

  /**
   * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement
   * on the return value: the return value is optional (but if data is returned, it must not be false).
   * @param token The token targeted by the call.
   * @param data The call data (encoded using abi.encode or one of its variants).
   */
  function _callOptionalReturn(IERC20 token, bytes memory data) private {
    // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since
    // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that
    // the target address contains contract code and also asserts for success in the low-level call.

    bytes memory returndata =
      address(token).functionCall(data, "SafeERC20: low-level call failed");
    if (returndata.length > 0) {
      // Return data is optional
      require(
        abi.decode(returndata, (bool)),
        "SafeERC20: ERC20 operation did not succeed"
      );
    }
  }
}
                

contracts/external/openzeppelin/contracts/utils/Address.sol

// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)

pragma solidity ^0.8.1;

/**
 * @dev Collection of functions related to the address type
 */
library Address {
  /**
   * @dev Returns true if `account` is a contract.
   *
   * [IMPORTANT]
   * ====
   * It is unsafe to assume that an address for which this function returns
   * false is an externally-owned account (EOA) and not a contract.
   *
   * Among others, `isContract` will return false for the following
   * types of addresses:
   *
   *  - an externally-owned account
   *  - a contract in construction
   *  - an address where a contract will be created
   *  - an address where a contract lived, but was destroyed
   * ====
   *
   * [IMPORTANT]
   * ====
   * You shouldn't rely on `isContract` to protect against flash loan attacks!
   *
   * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets
   * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract
   * constructor.
   * ====
   */
  function isContract(address account) internal view returns (bool) {
    // This method relies on extcodesize/address.code.length, which returns 0
    // for contracts in construction, since the code is only stored at the end
    // of the constructor execution.

    return account.code.length > 0;
  }

  /**
   * @dev Replacement for Solidity's `transfer`: sends `amount` wei to
   * `recipient`, forwarding all available gas and reverting on errors.
   *
   * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost
   * of certain opcodes, possibly making contracts go over the 2300 gas limit
   * imposed by `transfer`, making them unable to receive funds via
   * `transfer`. {sendValue} removes this limitation.
   *
   * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].
   *
   * IMPORTANT: because control is transferred to `recipient`, care must be
   * taken to not create reentrancy vulnerabilities. Consider using
   * {ReentrancyGuard} or the
   * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].
   */
  function sendValue(address payable recipient, uint256 amount) internal {
    require(address(this).balance >= amount, "Address: insufficient balance");

    (bool success, ) = recipient.call{value: amount}("");
    require(
      success,
      "Address: unable to send value, recipient may have reverted"
    );
  }

  /**
   * @dev Performs a Solidity function call using a low level `call`. A
   * plain `call` is an unsafe replacement for a function call: use this
   * function instead.
   *
   * If `target` reverts with a revert reason, it is bubbled up by this
   * function (like regular Solidity function calls).
   *
   * Returns the raw returned data. To convert to the expected return value,
   * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].
   *
   * Requirements:
   *
   * - `target` must be a contract.
   * - calling `target` with `data` must not revert.
   *
   * _Available since v3.1._
   */
  function functionCall(address target, bytes memory data)
    internal
    returns (bytes memory)
  {
    return functionCall(target, data, "Address: low-level call failed");
  }

  /**
   * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with
   * `errorMessage` as a fallback revert reason when `target` reverts.
   *
   * _Available since v3.1._
   */
  function functionCall(
    address target,
    bytes memory data,
    string memory errorMessage
  ) internal returns (bytes memory) {
    return functionCallWithValue(target, data, 0, errorMessage);
  }

  /**
   * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
   * but also transferring `value` wei to `target`.
   *
   * Requirements:
   *
   * - the calling contract must have an ETH balance of at least `value`.
   * - the called Solidity function must be `payable`.
   *
   * _Available since v3.1._
   */
  function functionCallWithValue(
    address target,
    bytes memory data,
    uint256 value
  ) internal returns (bytes memory) {
    return
      functionCallWithValue(
        target,
        data,
        value,
        "Address: low-level call with value failed"
      );
  }

  /**
   * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but
   * with `errorMessage` as a fallback revert reason when `target` reverts.
   *
   * _Available since v3.1._
   */
  function functionCallWithValue(
    address target,
    bytes memory data,
    uint256 value,
    string memory errorMessage
  ) internal returns (bytes memory) {
    require(
      address(this).balance >= value,
      "Address: insufficient balance for call"
    );
    require(isContract(target), "Address: call to non-contract");

    (bool success, bytes memory returndata) = target.call{value: value}(data);
    return verifyCallResult(success, returndata, errorMessage);
  }

  /**
   * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
   * but performing a static call.
   *
   * _Available since v3.3._
   */
  function functionStaticCall(address target, bytes memory data)
    internal
    view
    returns (bytes memory)
  {
    return
      functionStaticCall(target, data, "Address: low-level static call failed");
  }

  /**
   * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
   * but performing a static call.
   *
   * _Available since v3.3._
   */
  function functionStaticCall(
    address target,
    bytes memory data,
    string memory errorMessage
  ) internal view returns (bytes memory) {
    require(isContract(target), "Address: static call to non-contract");

    (bool success, bytes memory returndata) = target.staticcall(data);
    return verifyCallResult(success, returndata, errorMessage);
  }

  /**
   * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
   * but performing a delegate call.
   *
   * _Available since v3.4._
   */
  function functionDelegateCall(address target, bytes memory data)
    internal
    returns (bytes memory)
  {
    return
      functionDelegateCall(
        target,
        data,
        "Address: low-level delegate call failed"
      );
  }

  /**
   * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
   * but performing a delegate call.
   *
   * _Available since v3.4._
   */
  function functionDelegateCall(
    address target,
    bytes memory data,
    string memory errorMessage
  ) internal returns (bytes memory) {
    require(isContract(target), "Address: delegate call to non-contract");

    (bool success, bytes memory returndata) = target.delegatecall(data);
    return verifyCallResult(success, returndata, errorMessage);
  }

  /**
   * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the
   * revert reason using the provided one.
   *
   * _Available since v4.3._
   */
  function verifyCallResult(
    bool success,
    bytes memory returndata,
    string memory errorMessage
  ) internal pure returns (bytes memory) {
    if (success) {
      return returndata;
    } else {
      // Look for revert reason and bubble it up if present
      if (returndata.length > 0) {
        // The easiest way to bubble the revert reason is using memory via assembly

        assembly {
          let returndata_size := mload(returndata)
          revert(add(32, returndata), returndata_size)
        }
      } else {
        revert(errorMessage);
      }
    }
  }
}
                

contracts/external/openzeppelin/contracts/utils/Context.sol

// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (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) {
    return msg.data;
  }
}
                

contracts/interfaces/IAllowlist.sol

/**SPDX-License-Identifier: BUSL-1.1

      ▄▄█████████▄
   ╓██▀└ ,╓▄▄▄, '▀██▄
  ██▀ ▄██▀▀╙╙▀▀██▄ └██µ           ,,       ,,      ,     ,,,            ,,,
 ██ ,██¬ ▄████▄  ▀█▄ ╙█▄      ▄███▀▀███▄   ███▄    ██  ███▀▀▀███▄    ▄███▀▀███,
██  ██ ╒█▀'   ╙█▌ ╙█▌ ██     ▐██      ███  █████,  ██  ██▌    └██▌  ██▌     └██▌
██ ▐█▌ ██      ╟█  █▌ ╟█     ██▌      ▐██  ██ └███ ██  ██▌     ╟██ j██       ╟██
╟█  ██ ╙██    ▄█▀ ▐█▌ ██     ╙██      ██▌  ██   ╙████  ██▌    ▄██▀  ██▌     ,██▀
 ██ "██, ╙▀▀███████████⌐      ╙████████▀   ██     ╙██  ███████▀▀     ╙███████▀`
  ██▄ ╙▀██▄▄▄▄▄,,,                ¬─                                    '─¬
   ╙▀██▄ '╙╙╙▀▀▀▀▀▀▀▀
      ╙▀▀██████R⌐

 */
pragma solidity 0.8.16;

interface IAllowlist {
  function addTerm(string calldata term) external;

  function setCurrentTermIndex(uint256 _currentTermIndex) external;

  function setValidTermIndexes(uint256[] calldata indexes) external;

  function isAllowed(address account) external view returns (bool);

  function getCurrentTerm() external view returns (string memory);

  function currentTermIndex() external view returns (uint256);

  function getValidTermIndexes() external view returns (uint256[] memory);

  function addAccountToAllowlist(
    uint256 _currentTermIndex,
    address account,
    uint8 v,
    bytes32 r,
    bytes32 s
  ) external;

  function addSelfToAllowlist(uint256 termIndex) external;

  function setAccountStatus(
    address account,
    uint256 termIndex,
    bool status
  ) external;

  /**
   * @notice Event emitted when a term is added
   *
   * @param hashedMessage The hash of the terms string that was added
   * @param termIndex     The index of the term that was added
   */
  event TermAdded(bytes32 hashedMessage, uint256 termIndex);

  /**
   * @notice Event emitted when the current term index is set
   *
   * @param oldIndex The old current term index
   * @param newIndex The new current term index
   */
  event CurrentTermIndexSet(uint256 oldIndex, uint256 newIndex);

  /**
   * @notice Event emitted when the valid term indexes are set
   *
   * @param oldIndexes The old valid term indexes
   * @param newIndexes The new valid term indexes
   */
  event ValidTermIndexesSet(uint256[] oldIndexes, uint256[] newIndexes);

  /**
   * @notice Event emitted when an accoun status is set by an admin
   *
   * @param account   The account whose status was set
   * @param termIndex The term index of the account whose status that was set
   * @param status    The new status of the account
   */
  event AccountStatusSetByAdmin(
    address indexed account,
    uint256 indexed termIndex,
    bool status
  );

  /**
   * @notice Event emitted when an account adds itself added to the allowlist
   *
   * @param account   The account that was added
   * @param termIndex The term index for which the account was added
   */
  event AccountAddedSelf(address indexed account, uint256 indexed termIndex);

  /**
   * @notice Event emitted when an account is added to the allowlist by a signature
   *
   * @param account   The account that was added
   * @param termIndex The term index for which the account was added
   * @param v         The v value of the signature
   * @param r         The r value of the signature
   * @param s         The s value of the signature
   */
  event AccountAddedFromSignature(
    address indexed account,
    uint256 indexed termIndex,
    uint8 v,
    bytes32 r,
    bytes32 s
  );

  /**
   * @notice Event emitted when an account status is set
   *
   * @param account   The account whose status was set
   * @param termIndex The term index of the account whose status was set
   * @param status    The new status of the account
   */
  event AccountStatusSet(
    address indexed account,
    uint256 indexed termIndex,
    bool status
  );

  /// ERRORS ///
  error InvalidTermIndex();
  error InvalidVSignature();
  error AlreadyVerified();
  error InvalidSigner();
}
                

contracts/interfaces/IAxelarExecutable.sol

// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import {IAxelarGateway} from "./IAxelarGateway.sol";

interface IAxelarExecutable {
  error InvalidAddress();
  error NotApprovedByGateway();

  function gateway() external view returns (IAxelarGateway);

  function execute(
    bytes32 commandId,
    string calldata sourceChain,
    string calldata sourceAddress,
    bytes calldata payload
  ) external;

  function executeWithToken(
    bytes32 commandId,
    string calldata sourceChain,
    string calldata sourceAddress,
    bytes calldata payload,
    string calldata tokenSymbol,
    uint256 amount
  ) external;
}
                

contracts/interfaces/IAxelarGateway.sol

// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

interface IAxelarGateway {
  function callContract(
    string calldata destinationChain,
    string calldata contractAddress,
    bytes calldata payload
  ) external;

  function validateContractCall(
    bytes32 commandId,
    string calldata sourceChain,
    string calldata sourceAddress,
    bytes32 payloadHash
  ) external returns (bool);

  function validateContractCallAndMint(
    bytes32 commandId,
    string calldata sourceChain,
    string calldata sourceAddress,
    bytes32 payloadHash,
    string calldata symbol,
    uint256 amount
  ) external returns (bool);
}
                

contracts/interfaces/IRWALike.sol

/**SPDX-License-Identifier: BUSL-1.1

      ▄▄█████████▄
   ╓██▀└ ,╓▄▄▄, '▀██▄
  ██▀ ▄██▀▀╙╙▀▀██▄ └██µ           ,,       ,,      ,     ,,,            ,,,
 ██ ,██¬ ▄████▄  ▀█▄ ╙█▄      ▄███▀▀███▄   ███▄    ██  ███▀▀▀███▄    ▄███▀▀███,
██  ██ ╒█▀'   ╙█▌ ╙█▌ ██     ▐██      ███  █████,  ██  ██▌    └██▌  ██▌     └██▌
██ ▐█▌ ██      ╟█  █▌ ╟█     ██▌      ▐██  ██ └███ ██  ██▌     ╟██ j██       ╟██
╟█  ██ ╙██    ▄█▀ ▐█▌ ██     ╙██      ██▌  ██   ╙████  ██▌    ▄██▀  ██▌     ,██▀
 ██ "██, ╙▀▀███████████⌐      ╙████████▀   ██     ╙██  ███████▀▀     ╙███████▀`
  ██▄ ╙▀██▄▄▄▄▄,,,                ¬─                                    '─¬
   ╙▀██▄ '╙╙╙▀▀▀▀▀▀▀▀
      ╙▀▀██████R⌐
 */
pragma solidity 0.8.16;

// This interface is not inherited directly by RWA, instead, it is a
// subset of functions provided by all RWA tokens that the RWA Hub
// Client uses.
import "contracts/external/openzeppelin/contracts/token/IERC20.sol";

interface IRWALike is IERC20 {
  function mint(address to, uint256 amount) external;

  function burn(uint256 amount) external;

  function burnFrom(address from, uint256 amount) external;
}
                

Compiler Settings

{"outputSelection":{"*":{"*":["abi","evm.bytecode","evm.deployedBytecode","evm.methodIdentifiers"]}},"optimizer":{"runs":100,"enabled":true},"metadata":{"useLiteralContent":true},"libraries":{}}
                    

Contract ABI

[{"type":"constructor","stateMutability":"nonpayable","inputs":[{"type":"address","name":"_token","internalType":"address"},{"type":"address","name":"_axelarGateway","internalType":"address"},{"type":"address","name":"_allowlist","internalType":"address"},{"type":"address","name":"_ondoApprover","internalType":"address"},{"type":"address","name":"_owner","internalType":"address"},{"type":"uint256","name":"_mintLimit","internalType":"uint256"},{"type":"uint256","name":"_mintDuration","internalType":"uint256"}]},{"type":"error","name":"AlreadyApproved","inputs":[]},{"type":"error","name":"ArrayLengthMismatch","inputs":[]},{"type":"error","name":"ChainNotSupported","inputs":[]},{"type":"error","name":"InvalidAddress","inputs":[]},{"type":"error","name":"InvalidVersion","inputs":[]},{"type":"error","name":"NoThresholdMatch","inputs":[]},{"type":"error","name":"NonceSpent","inputs":[]},{"type":"error","name":"NotApprovedByGateway","inputs":[]},{"type":"error","name":"NotApprover","inputs":[]},{"type":"error","name":"NumOfApproversCannotBeZero","inputs":[]},{"type":"error","name":"SourceNotSupported","inputs":[]},{"type":"error","name":"ThresholdsNotInAscendingOrder","inputs":[]},{"type":"event","name":"ApproverAdded","inputs":[{"type":"address","name":"approver","internalType":"address","indexed":false}],"anonymous":false},{"type":"event","name":"ApproverRemoved","inputs":[{"type":"address","name":"approver","internalType":"address","indexed":false}],"anonymous":false},{"type":"event","name":"BridgeCompleted","inputs":[{"type":"address","name":"user","internalType":"address","indexed":true},{"type":"uint256","name":"amount","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"ChainIdSupported","inputs":[{"type":"string","name":"srcChain","internalType":"string","indexed":true},{"type":"string","name":"approvedSource","internalType":"string","indexed":false}],"anonymous":false},{"type":"event","name":"ChainSupportRemoved","inputs":[{"type":"string","name":"srcChain","internalType":"string","indexed":true}],"anonymous":false},{"type":"event","name":"MessageReceived","inputs":[{"type":"bytes32","name":"txnHash","internalType":"bytes32","indexed":true},{"type":"string","name":"srcChain","internalType":"string","indexed":true},{"type":"address","name":"srcSender","internalType":"address","indexed":true},{"type":"uint256","name":"amt","internalType":"uint256","indexed":false},{"type":"uint256","name":"nonce","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"MintLimitDurationSet","inputs":[{"type":"uint256","name":"instantMintLimitDuration","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"MintLimitSet","inputs":[{"type":"uint256","name":"mintLimit","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"OwnershipTransferred","inputs":[{"type":"address","name":"previousOwner","internalType":"address","indexed":true},{"type":"address","name":"newOwner","internalType":"address","indexed":true}],"anonymous":false},{"type":"event","name":"Paused","inputs":[{"type":"address","name":"account","internalType":"address","indexed":false}],"anonymous":false},{"type":"event","name":"ThresholdSet","inputs":[{"type":"string","name":"chain","internalType":"string","indexed":true},{"type":"uint256[]","name":"amounts","internalType":"uint256[]","indexed":false},{"type":"uint256[]","name":"numOfApprovers","internalType":"uint256[]","indexed":false}],"anonymous":false},{"type":"event","name":"TransactionApproved","inputs":[{"type":"bytes32","name":"txnHash","internalType":"bytes32","indexed":true},{"type":"address","name":"approver","internalType":"address","indexed":false},{"type":"uint256","name":"numApprovers","internalType":"uint256","indexed":false},{"type":"uint256","name":"thresholdRequirement","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"Unpaused","inputs":[{"type":"address","name":"account","internalType":"address","indexed":false}],"anonymous":false},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"contract IAllowlist"}],"name":"ALLOWLIST","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"contract IAxelarGateway"}],"name":"AXELAR_GATEWAY","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"contract IRWALike"}],"name":"TOKEN","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"bytes32","name":"","internalType":"bytes32"}],"name":"VERSION","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"addApprover","inputs":[{"type":"address","name":"approver","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"addChainSupport","inputs":[{"type":"string","name":"srcChain","internalType":"string"},{"type":"string","name":"srcContractAddress","internalType":"string"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"approve","inputs":[{"type":"bytes32","name":"txnHash","internalType":"bytes32"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"approvers","inputs":[{"type":"address","name":"","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"bytes32","name":"","internalType":"bytes32"}],"name":"chainToApprovedSender","inputs":[{"type":"string","name":"","internalType":"string"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"amount","internalType":"uint256"},{"type":"uint256","name":"numberOfApprovalsNeeded","internalType":"uint256"}],"name":"chainToThresholds","inputs":[{"type":"string","name":"","internalType":"string"},{"type":"uint256","name":"","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"currentMintAmount","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"execute","inputs":[{"type":"bytes32","name":"commandId","internalType":"bytes32"},{"type":"string","name":"sourceChain","internalType":"string"},{"type":"string","name":"sourceAddress","internalType":"string"},{"type":"bytes","name":"payload","internalType":"bytes"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"executeWithToken","inputs":[{"type":"bytes32","name":"commandId","internalType":"bytes32"},{"type":"string","name":"sourceChain","internalType":"string"},{"type":"string","name":"sourceAddress","internalType":"string"},{"type":"bytes","name":"payload","internalType":"bytes"},{"type":"string","name":"tokenSymbol","internalType":"string"},{"type":"uint256","name":"amount","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"contract IAxelarGateway"}],"name":"gateway","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"getNumApproved","inputs":[{"type":"bytes32","name":"txnHash","internalType":"bytes32"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"isSpentNonce","inputs":[{"type":"bytes32","name":"","internalType":"bytes32"},{"type":"uint256","name":"","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"lastResetMintTime","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"mintLimit","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"owner","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"pause","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"paused","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"removeApprover","inputs":[{"type":"address","name":"approver","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"removeChainSupport","inputs":[{"type":"string","name":"srcChain","internalType":"string"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"renounceOwnership","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"rescueTokens","inputs":[{"type":"address","name":"_token","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"resetMintDuration","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setMintLimit","inputs":[{"type":"uint256","name":"mintLimit","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setMintLimitDuration","inputs":[{"type":"uint256","name":"mintDuration","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setThresholds","inputs":[{"type":"string","name":"srcChain","internalType":"string"},{"type":"uint256[]","name":"amounts","internalType":"uint256[]"},{"type":"uint256[]","name":"numOfApprovers","internalType":"uint256[]"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"transferOwnership","inputs":[{"type":"address","name":"newOwner","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"sender","internalType":"address"},{"type":"uint256","name":"amount","internalType":"uint256"}],"name":"txnHashToTransaction","inputs":[{"type":"bytes32","name":"","internalType":"bytes32"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"numberOfApprovalsNeeded","internalType":"uint256"}],"name":"txnToThresholdSet","inputs":[{"type":"bytes32","name":"","internalType":"bytes32"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"unpause","inputs":[]}]
                    

Contract Creation Code

0x6101006040523480156200001257600080fd5b50604051620029273803806200292783398101604081905262000035916200014d565b8082876001600160a01b038116620000605760405163e6c4247b60e01b815260040160405180910390fd5b6001600160a01b0316608052600091909155600255426001556200008433620000de565b6004805460ff60a01b191690556001600160a01b0380881660a05286811660c05285811660e05284166000908152600560205260409020805460ff19166001179055620000d183620000de565b50505050505050620001d0565b600480546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b80516001600160a01b03811681146200014857600080fd5b919050565b600080600080600080600060e0888a0312156200016957600080fd5b620001748862000130565b9650620001846020890162000130565b9550620001946040890162000130565b9450620001a46060890162000130565b9350620001b46080890162000130565b925060a0880151915060c0880151905092959891949750929550565b60805160a05160c05160e0516126ec6200023b600039600081816102990152818161159a015281816115e40152818161166201526116960152600061042a0152600081816103b101526117bb015260008181610224015281816108c901526109e501526126ec6000f3fe608060405234801561001057600080fd5b50600436106101ba5760003560e01c80637183c758116100fa578063a59b4b3a1161009d578063a59b4b3a14610425578063a826dff01461044c578063b2a6206414610455578063b646c1941461045e578063e42edf7d14610471578063e6c911b21461049c578063f19b4896146104bf578063f2fde38b146104d2578063ffa1ad74146104e557600080fd5b80637183c758146103a357806382bfefc8146103ac5780638456cb59146103d35780638da5cb5b146103db578063996517cf146103e35780639a2ac7c1146103ec5780639e6a1d7d146103ff578063a53a1adf1461041257600080fd5b80633f4ba83a116101625780633f4ba83a146102fc57806349160658146103045780635b2d1b71146103175780635c975abb146103455780636636a24b1461034d5780636cf4c88f146103755780636e51351d14610388578063715018a61461039b57600080fd5b8062ae3bf8146101bf57806302dd732b146101d45780630a144391146101e7578063116191b61461021f5780631a98b2e0146102535780631cb0ed00146102665780631f3a6f04146102945780633a1ce4af146102bb575b600080fd5b6101d26101cd366004611dfd565b6104f2565b005b6101d26101e2366004611ea6565b6105bc565b61020a6101f5366004611dfd565b60056020526000908152604090205460ff1681565b60405190151581526020015b60405180910390f35b6102467f000000000000000000000000000000000000000000000000000000000000000081565b6040516102169190611f3f565b6101d2610261366004611f53565b610898565b61020a61027436600461202c565b600760209081526000928352604080842090915290825290205460ff1681565b6102467f000000000000000000000000000000000000000000000000000000000000000081565b6102ee6102c936600461204e565b600a60205260009081526040902080546001909101546001600160a01b039091169082565b604051610216929190612067565b6101d261097b565b6101d2610312366004612080565b6109b4565b61033761032536600461204e565b60086020526000908152604090205481565b604051908152602001610216565b61020a610a9c565b61036061035b3660046121d8565b610aac565b60408051928352602083019190915201610216565b6101d2610383366004611dfd565b610af7565b6101d261039636600461221c565b610b81565b6101d2610c16565b61033760015481565b6102467f000000000000000000000000000000000000000000000000000000000000000081565b6101d2610c4f565b610246610c86565b61033760025481565b6101d26103fa36600461204e565b610c95565b6101d261040d36600461204e565b610cd0565b6101d261042036600461204e565b610d08565b6102467f000000000000000000000000000000000000000000000000000000000000000081565b61033760005481565b61033760035481565b6101d261046c366004611dfd565b610d4a565b61033761047f36600461225d565b805160208183018101805160068252928201919093012091525481565b6103376104aa36600461204e565b60009081526008602052604090206001015490565b6101d26104cd366004612299565b610dcc565b6101d26104e0366004611dfd565b610e9d565b610337620312e360ec1b81565b336104fb610c86565b6001600160a01b03161461052a5760405162461bcd60e51b815260040161052190612304565b60405180910390fd5b6040516370a0823160e01b81526000906001600160a01b038316906370a0823190610559903090600401611f3f565b602060405180830381865afa158015610576573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061059a9190612339565b90506105b86105a7610c86565b6001600160a01b0384169083610f3a565b5050565b336105c5610c86565b6001600160a01b0316146105eb5760405162461bcd60e51b815260040161052190612304565b82811461060b5760405163512509d360e11b815260040160405180910390fd5b6009868660405161061d929190612352565b908152602001604051809103902060006106379190611d32565b60005b8381101561083a5782828281811061065457610654612362565b9050602002013560000361067a57604051626b964760e21b815260040160405180910390fd5b806000036107155760098787604051610694929190612352565b908152602001604051809103902060405180604001604052808787858181106106bf576106bf612362565b9050602002013581526020018585858181106106dd576106dd612362565b60209081029290920135909252835460018181018655600095865294829020845160029092020190815592015191909201555061082a565b84848281811061072757610727612362565b9050602002013560098888604051610740929190612352565b90815260405190819003602001902061075a60018461238e565b8154811061076a5761076a612362565b906000526020600020906002020160000154111561079b576040516308097a7360e01b815260040160405180910390fd5b600987876040516107ad929190612352565b908152602001604051809103902060405180604001604052808787858181106107d8576107d8612362565b9050602002013581526020018585858181106107f6576107f6612362565b6020908102929092013590925283546001818101865560009586529482902084516002909202019081559201519190920155505b610833816123a7565b905061063a565b50858560405161084b929190612352565b60405180910390207f81bc784d38be2db247023a764d1a550ba3f86ae4f6d0b7b9480d1b86ce43399b8585858560405161088894939291906123f2565b60405180910390a2505050505050565b600085856040516108aa929190612352565b604051908190038120631876eed960e01b825291506001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001690631876eed99061090e908e908e908e908e908e9089908d908d908d90600401612442565b6020604051808303816000875af115801561092d573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061095191906124a1565b61096e57604051631403112d60e21b815260040160405180910390fd5b5050505050505050505050565b33610984610c86565b6001600160a01b0316146109aa5760405162461bcd60e51b815260040161052190612304565b6109b2610f95565b565b600082826040516109c6929190612352565b604051908190038120635f6970c360e01b825291506001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001690635f6970c390610a24908b908b908b908b908b9089906004016124c3565b6020604051808303816000875af1158015610a43573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a6791906124a1565b610a8457604051631403112d60e21b815260040160405180910390fd5b610a92878787878787611027565b5050505050505050565b600454600160a01b900460ff1690565b81516020818401810180516009825292820191850191909120919052805482908110610ad757600080fd5b600091825260209091206002909102018054600190910154909250905082565b33610b00610c86565b6001600160a01b031614610b265760405162461bcd60e51b815260040161052190612304565b6001600160a01b03811660009081526005602052604090819020805460ff19169055517fc6e35658c76ecdde40a54f31a91fb7c8615e9893cc0885584b27bb3433270d4690610b76908390611f3f565b60405180910390a150565b33610b8a610c86565b6001600160a01b031614610bb05760405162461bcd60e51b815260040161052190612304565b60068282604051610bc2929190612352565b90815260405190819003602001812060009055610be29083908390612352565b604051908190038120907f158a044d8042048b13e12437e2777a46dd46a6be69ebe30470c49532a17307c290600090a25050565b33610c1f610c86565b6001600160a01b031614610c455760405162461bcd60e51b815260040161052190612304565b6109b26000611312565b33610c58610c86565b6001600160a01b031614610c7e5760405162461bcd60e51b815260040161052190612304565b6109b2611364565b6004546001600160a01b031690565b33610c9e610c86565b6001600160a01b031614610cc45760405162461bcd60e51b815260040161052190612304565b610ccd816113c4565b50565b33610cd9610c86565b6001600160a01b031614610cff5760405162461bcd60e51b815260040161052190612304565b610ccd816113f9565b3360009081526005602052604090205460ff16610d3857604051630197e13360e61b815260040160405180910390fd5b610d418161142e565b610ccd81611540565b33610d53610c86565b6001600160a01b031614610d795760405162461bcd60e51b815260040161052190612304565b6001600160a01b03811660009081526005602052604090819020805460ff19166001179055517f835bddf1ceee4956e4329af9edf018523c1191238187a597453f6020bcadb04290610b76908390611f3f565b33610dd5610c86565b6001600160a01b031614610dfb5760405162461bcd60e51b815260040161052190612304565b8181604051602001610e0e929190612504565b6040516020818303038152906040528051906020012060068585604051610e36929190612352565b90815260405190819003602001812091909155610e569085908590612352565b60405180910390207f17369ff287d5e05e21f0210b36059644eca4e207e5481cf343c00ce99261ef278383604051610e8f929190612504565b60405180910390a250505050565b33610ea6610c86565b6001600160a01b031614610ecc5760405162461bcd60e51b815260040161052190612304565b6001600160a01b038116610f315760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610521565b610ccd81611312565b610f908363a9059cbb60e01b8484604051602401610f59929190612067565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152611883565b505050565b610f9d610a9c565b610fe05760405162461bcd60e51b815260206004820152601460248201527314185d5cd8589b194e881b9bdd081c185d5cd95960621b6044820152606401610521565b6004805460ff60a01b191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa335b60405161101d9190611f3f565b60405180910390a1565b61102f610a9c565b1561104c5760405162461bcd60e51b815260040161052190612518565b600080808061105d85870187612542565b945094509450509350620312e360ec1b841461108c5760405163a9146eeb60e01b815260040160405180910390fd5b6000801b60068b8b6040516110a2929190612352565b908152602001604051809103902054036110cf5760405163f21c9f0760e01b815260040160405180910390fd5b87876040516020016110e2929190612504565b6040516020818303038152906040528051906020012060068b8b60405161110a929190612352565b908152602001604051809103902054146111365760405162ff453f60e31b815260040160405180910390fd5b6007600060068c8c60405161114c929190612352565b9081526040805160209281900383019020548352828201939093529082016000908120848252909152205460ff16156111985760405163e323fd5d60e01b815260040160405180910390fd5b60016007600060068d8d6040516111b0929190612352565b9081526020016040518091039020548152602001908152602001600020600083815260200190815260200160002060006101000a81548160ff02191690831515021790555060008686604051611207929190612352565b6040805191829003822082820182526001600160a01b03878116845260208085018881526000848152600a8352859020955186546001600160a01b031916931692909217855590516001909401939093558151601f8e018490048402810184019092528c8252925061129791859184918f908f908190840183828082843760009201919091525061195592505050565b6112a08161142e565b6112a981611540565b836001600160a01b03168b8b6040516112c3929190612352565b60408051918290038220868352602083018690529184917ff87812c5aeb6f0b63030eea79acd80053021b86e2f2246280909466810ab4c54910160405180910390a45050505050505050505050565b600480546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b61136c610a9c565b156113895760405162461bcd60e51b815260040161052190612518565b6004805460ff60a01b1916600160a01b1790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a2586110103390565b60008190556040518181527f0d16c22f1a8d8050cb1f90d4fc81275e9a52eeb32d4cb9e6c10c87d0e80c5dda90602001610b76565b60028190556040518181527f28ebdbd10a26a82cec6aa90b2fecb2a9aca61629ad2e80d17de29c6a0018539890602001610b76565b6000818152600860205260409020600181015480156114b65760005b818110156114b457336001600160a01b031683600101828154811061147157611471612362565b6000918252602090912001546001600160a01b0316036114a45760405163080fc0bd60e11b815260040160405180910390fd5b6114ad816123a7565b905061144a565b505b600180830180548083018255600091825260209091200180546001600160a01b0319163390811790915584917fc688a9923ae84cc5cbace0353e8935fe766e29064d17d3fdd0c97b69bb493879919061151090859061258b565b8554604080516001600160a01b0390941684526020840192909252908201526060015b60405180910390a2505050565b60008181526008602052604090208054600190910154108015906105b8576000828152600a6020908152604091829020825180840190935280546001600160a01b031683526001015490820181905261159890611aaf565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03161580159061165b5750805160405163babcc53960e01b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169163babcc539916116189190600401611f3f565b602060405180830381865afa158015611635573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061165991906124a1565b155b1561179d577f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166302ffc76482600001517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663209b98336040518163ffffffff1660e01b8152600401600060405180830381865afa1580156116f2573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261171a919081019061259e565b60008151811061172c5761172c612362565b60209081029190910101516040516001600160e01b031960e085901b1681526001600160a01b039092166004830152602482015260016044820152606401600060405180830381600087803b15801561178457600080fd5b505af1158015611798573d6000803e3d6000fd5b505050505b805160208201516040516340c10f1960e01b81526001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016926340c10f19926117ee92600401612067565b600060405180830381600087803b15801561180857600080fd5b505af115801561181c573d6000803e3d6000fd5b5050506000848152600a6020908152604080832080546001600160a01b03191681556001019290925583518482015192519283526001600160a01b031692507f3160144ac9bee2b9ce381a81709c299ed8b6d1da1384c79c2777d3dea699f5349101611533565b60006118d8826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316611baf9092919063ffffffff16565b805190915015610f9057808060200190518101906118f691906124a1565b610f905760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152608401610521565b60006009826040516119679190612667565b9081526020016040518091039020805480602002602001604051908101604052809291908181526020016000905b828210156119db57838290600052602060002090600202016040518060400160405290816000820154815260200160018201548152505081526020019060010190611995565b50505050905060005b8151811015611a7a576000828281518110611a0157611a01612362565b6020026020010151905080600001518611611a6957604080518082018252602083810151825282516000808252818301855282840191825289815260088352939093208251815592518051929392611a5f9260018501920190611d53565b5090505050611a7a565b50611a73816123a7565b90506119e4565b506000838152600860205260408120549003611aa957604051637c191ff960e01b815260040160405180910390fd5b50505050565b60008111611b0b5760405162461bcd60e51b8152602060048201526024808201527f526174654c696d69743a206d696e7420616d6f756e742063616e2774206265206044820152637a65726f60e01b6064820152608401610521565b600054600154611b1b919061258b565b4210611b2b576000600355426001555b600354600254611b3b919061238e565b811115611b955760405162461bcd60e51b815260206004820152602260248201527f526174654c696d69743a204d696e7420657863656564732072617465206c696d6044820152611a5d60f21b6064820152608401610521565b8060036000828254611ba7919061258b565b909155505050565b6060611bbe8484600085611bc8565b90505b9392505050565b606082471015611c295760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b6064820152608401610521565b6001600160a01b0385163b611c805760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610521565b600080866001600160a01b03168587604051611c9c9190612667565b60006040518083038185875af1925050503d8060008114611cd9576040519150601f19603f3d011682016040523d82523d6000602084013e611cde565b606091505b5091509150611cee828286611cf9565b979650505050505050565b60608315611d08575081611bc1565b825115611d185782518084602001fd5b8160405162461bcd60e51b81526004016105219190612683565b5080546000825560020290600052602060002090810190610ccd9190611db8565b828054828255906000526020600020908101928215611da8579160200282015b82811115611da857825182546001600160a01b0319166001600160a01b03909116178255602090920191600190910190611d73565b50611db4929150611dd3565b5090565b5b80821115611db45760008082556001820155600201611db9565b5b80821115611db45760008155600101611dd4565b6001600160a01b0381168114610ccd57600080fd5b600060208284031215611e0f57600080fd5b8135611bc181611de8565b60008083601f840112611e2c57600080fd5b5081356001600160401b03811115611e4357600080fd5b602083019150836020828501011115611e5b57600080fd5b9250929050565b60008083601f840112611e7457600080fd5b5081356001600160401b03811115611e8b57600080fd5b6020830191508360208260051b8501011115611e5b57600080fd5b60008060008060008060608789031215611ebf57600080fd5b86356001600160401b0380821115611ed657600080fd5b611ee28a838b01611e1a565b90985096506020890135915080821115611efb57600080fd5b611f078a838b01611e62565b90965094506040890135915080821115611f2057600080fd5b50611f2d89828a01611e62565b979a9699509497509295939492505050565b6001600160a01b0391909116815260200190565b60008060008060008060008060008060c08b8d031215611f7257600080fd5b8a35995060208b01356001600160401b0380821115611f9057600080fd5b611f9c8e838f01611e1a565b909b50995060408d0135915080821115611fb557600080fd5b611fc18e838f01611e1a565b909950975060608d0135915080821115611fda57600080fd5b611fe68e838f01611e1a565b909750955060808d0135915080821115611fff57600080fd5b5061200c8d828e01611e1a565b9150809450508092505060a08b013590509295989b9194979a5092959850565b6000806040838503121561203f57600080fd5b50508035926020909101359150565b60006020828403121561206057600080fd5b5035919050565b6001600160a01b03929092168252602082015260400190565b60008060008060008060006080888a03121561209b57600080fd5b8735965060208801356001600160401b03808211156120b957600080fd5b6120c58b838c01611e1a565b909850965060408a01359150808211156120de57600080fd5b6120ea8b838c01611e1a565b909650945060608a013591508082111561210357600080fd5b506121108a828b01611e1a565b989b979a50959850939692959293505050565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f191681016001600160401b038111828210171561216157612161612123565b604052919050565b600082601f83011261217a57600080fd5b81356001600160401b0381111561219357612193612123565b6121a6601f8201601f1916602001612139565b8181528460208386010111156121bb57600080fd5b816020850160208301376000918101602001919091529392505050565b600080604083850312156121eb57600080fd5b82356001600160401b0381111561220157600080fd5b61220d85828601612169565b95602094909401359450505050565b6000806020838503121561222f57600080fd5b82356001600160401b0381111561224557600080fd5b61225185828601611e1a565b90969095509350505050565b60006020828403121561226f57600080fd5b81356001600160401b0381111561228557600080fd5b61229184828501612169565b949350505050565b600080600080604085870312156122af57600080fd5b84356001600160401b03808211156122c657600080fd5b6122d288838901611e1a565b909650945060208701359150808211156122eb57600080fd5b506122f887828801611e1a565b95989497509550505050565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b60006020828403121561234b57600080fd5b5051919050565b8183823760009101908152919050565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b818103818111156123a1576123a1612378565b92915050565b6000600182016123b9576123b9612378565b5060010190565b81835260006001600160fb1b038311156123d957600080fd5b8260051b80836020870137939093016020019392505050565b6040815260006124066040830186886123c0565b8281036020840152611cee8185876123c0565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b89815260c06020820152600061245c60c083018a8c612419565b828103604084015261246f81898b612419565b9050866060840152828103608084015261248a818688612419565b9150508260a08301529a9950505050505050505050565b6000602082840312156124b357600080fd5b81518015158114611bc157600080fd5b8681526080602082015260006124dd608083018789612419565b82810360408401526124f0818688612419565b915050826060830152979650505050505050565b602081526000611bbe602083018486612419565b60208082526010908201526f14185d5cd8589b194e881c185d5cd95960821b604082015260600190565b600080600080600060a0868803121561255a57600080fd5b8535945060208601359350604086013561257381611de8565b94979396509394606081013594506080013592915050565b808201808211156123a1576123a1612378565b600060208083850312156125b157600080fd5b82516001600160401b03808211156125c857600080fd5b818501915085601f8301126125dc57600080fd5b8151818111156125ee576125ee612123565b8060051b91506125ff848301612139565b818152918301840191848101908884111561261957600080fd5b938501935b838510156126375784518252938501939085019061261e565b98975050505050505050565b60005b8381101561265e578181015183820152602001612646565b50506000910152565b60008251612679818460208701612643565b9190910192915050565b60208152600082518060208401526126a2816040850160208701612643565b601f01601f1916919091016040019291505056fea264697066735822122062aa1f80d26f9456cf7d30ca520509b2dbe20f5cf8c50a56bc796653bfaea29a64736f6c634300081000330000000000000000000000005be26527e817998a7206475496fde1e68957c5a6000000000000000000000000e432150cce91c13a887f7d836923d5597add8e310000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c8a7870ffe41054612f7f3433e173d8b5bfca8e3000000000000000000000000c8a7870ffe41054612f7f3433e173d8b5bfca8e300000000000000000000000000000000000000000000152d02c7e14af68000000000000000000000000000000000000000000000000000000000000000015180

Deployed ByteCode

0x608060405234801561001057600080fd5b50600436106101ba5760003560e01c80637183c758116100fa578063a59b4b3a1161009d578063a59b4b3a14610425578063a826dff01461044c578063b2a6206414610455578063b646c1941461045e578063e42edf7d14610471578063e6c911b21461049c578063f19b4896146104bf578063f2fde38b146104d2578063ffa1ad74146104e557600080fd5b80637183c758146103a357806382bfefc8146103ac5780638456cb59146103d35780638da5cb5b146103db578063996517cf146103e35780639a2ac7c1146103ec5780639e6a1d7d146103ff578063a53a1adf1461041257600080fd5b80633f4ba83a116101625780633f4ba83a146102fc57806349160658146103045780635b2d1b71146103175780635c975abb146103455780636636a24b1461034d5780636cf4c88f146103755780636e51351d14610388578063715018a61461039b57600080fd5b8062ae3bf8146101bf57806302dd732b146101d45780630a144391146101e7578063116191b61461021f5780631a98b2e0146102535780631cb0ed00146102665780631f3a6f04146102945780633a1ce4af146102bb575b600080fd5b6101d26101cd366004611dfd565b6104f2565b005b6101d26101e2366004611ea6565b6105bc565b61020a6101f5366004611dfd565b60056020526000908152604090205460ff1681565b60405190151581526020015b60405180910390f35b6102467f000000000000000000000000e432150cce91c13a887f7d836923d5597add8e3181565b6040516102169190611f3f565b6101d2610261366004611f53565b610898565b61020a61027436600461202c565b600760209081526000928352604080842090915290825290205460ff1681565b6102467f000000000000000000000000000000000000000000000000000000000000000081565b6102ee6102c936600461204e565b600a60205260009081526040902080546001909101546001600160a01b039091169082565b604051610216929190612067565b6101d261097b565b6101d2610312366004612080565b6109b4565b61033761032536600461204e565b60086020526000908152604090205481565b604051908152602001610216565b61020a610a9c565b61036061035b3660046121d8565b610aac565b60408051928352602083019190915201610216565b6101d2610383366004611dfd565b610af7565b6101d261039636600461221c565b610b81565b6101d2610c16565b61033760015481565b6102467f0000000000000000000000005be26527e817998a7206475496fde1e68957c5a681565b6101d2610c4f565b610246610c86565b61033760025481565b6101d26103fa36600461204e565b610c95565b6101d261040d36600461204e565b610cd0565b6101d261042036600461204e565b610d08565b6102467f000000000000000000000000e432150cce91c13a887f7d836923d5597add8e3181565b61033760005481565b61033760035481565b6101d261046c366004611dfd565b610d4a565b61033761047f36600461225d565b805160208183018101805160068252928201919093012091525481565b6103376104aa36600461204e565b60009081526008602052604090206001015490565b6101d26104cd366004612299565b610dcc565b6101d26104e0366004611dfd565b610e9d565b610337620312e360ec1b81565b336104fb610c86565b6001600160a01b03161461052a5760405162461bcd60e51b815260040161052190612304565b60405180910390fd5b6040516370a0823160e01b81526000906001600160a01b038316906370a0823190610559903090600401611f3f565b602060405180830381865afa158015610576573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061059a9190612339565b90506105b86105a7610c86565b6001600160a01b0384169083610f3a565b5050565b336105c5610c86565b6001600160a01b0316146105eb5760405162461bcd60e51b815260040161052190612304565b82811461060b5760405163512509d360e11b815260040160405180910390fd5b6009868660405161061d929190612352565b908152602001604051809103902060006106379190611d32565b60005b8381101561083a5782828281811061065457610654612362565b9050602002013560000361067a57604051626b964760e21b815260040160405180910390fd5b806000036107155760098787604051610694929190612352565b908152602001604051809103902060405180604001604052808787858181106106bf576106bf612362565b9050602002013581526020018585858181106106dd576106dd612362565b60209081029290920135909252835460018181018655600095865294829020845160029092020190815592015191909201555061082a565b84848281811061072757610727612362565b9050602002013560098888604051610740929190612352565b90815260405190819003602001902061075a60018461238e565b8154811061076a5761076a612362565b906000526020600020906002020160000154111561079b576040516308097a7360e01b815260040160405180910390fd5b600987876040516107ad929190612352565b908152602001604051809103902060405180604001604052808787858181106107d8576107d8612362565b9050602002013581526020018585858181106107f6576107f6612362565b6020908102929092013590925283546001818101865560009586529482902084516002909202019081559201519190920155505b610833816123a7565b905061063a565b50858560405161084b929190612352565b60405180910390207f81bc784d38be2db247023a764d1a550ba3f86ae4f6d0b7b9480d1b86ce43399b8585858560405161088894939291906123f2565b60405180910390a2505050505050565b600085856040516108aa929190612352565b604051908190038120631876eed960e01b825291506001600160a01b037f000000000000000000000000e432150cce91c13a887f7d836923d5597add8e311690631876eed99061090e908e908e908e908e908e9089908d908d908d90600401612442565b6020604051808303816000875af115801561092d573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061095191906124a1565b61096e57604051631403112d60e21b815260040160405180910390fd5b5050505050505050505050565b33610984610c86565b6001600160a01b0316146109aa5760405162461bcd60e51b815260040161052190612304565b6109b2610f95565b565b600082826040516109c6929190612352565b604051908190038120635f6970c360e01b825291506001600160a01b037f000000000000000000000000e432150cce91c13a887f7d836923d5597add8e311690635f6970c390610a24908b908b908b908b908b9089906004016124c3565b6020604051808303816000875af1158015610a43573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a6791906124a1565b610a8457604051631403112d60e21b815260040160405180910390fd5b610a92878787878787611027565b5050505050505050565b600454600160a01b900460ff1690565b81516020818401810180516009825292820191850191909120919052805482908110610ad757600080fd5b600091825260209091206002909102018054600190910154909250905082565b33610b00610c86565b6001600160a01b031614610b265760405162461bcd60e51b815260040161052190612304565b6001600160a01b03811660009081526005602052604090819020805460ff19169055517fc6e35658c76ecdde40a54f31a91fb7c8615e9893cc0885584b27bb3433270d4690610b76908390611f3f565b60405180910390a150565b33610b8a610c86565b6001600160a01b031614610bb05760405162461bcd60e51b815260040161052190612304565b60068282604051610bc2929190612352565b90815260405190819003602001812060009055610be29083908390612352565b604051908190038120907f158a044d8042048b13e12437e2777a46dd46a6be69ebe30470c49532a17307c290600090a25050565b33610c1f610c86565b6001600160a01b031614610c455760405162461bcd60e51b815260040161052190612304565b6109b26000611312565b33610c58610c86565b6001600160a01b031614610c7e5760405162461bcd60e51b815260040161052190612304565b6109b2611364565b6004546001600160a01b031690565b33610c9e610c86565b6001600160a01b031614610cc45760405162461bcd60e51b815260040161052190612304565b610ccd816113c4565b50565b33610cd9610c86565b6001600160a01b031614610cff5760405162461bcd60e51b815260040161052190612304565b610ccd816113f9565b3360009081526005602052604090205460ff16610d3857604051630197e13360e61b815260040160405180910390fd5b610d418161142e565b610ccd81611540565b33610d53610c86565b6001600160a01b031614610d795760405162461bcd60e51b815260040161052190612304565b6001600160a01b03811660009081526005602052604090819020805460ff19166001179055517f835bddf1ceee4956e4329af9edf018523c1191238187a597453f6020bcadb04290610b76908390611f3f565b33610dd5610c86565b6001600160a01b031614610dfb5760405162461bcd60e51b815260040161052190612304565b8181604051602001610e0e929190612504565b6040516020818303038152906040528051906020012060068585604051610e36929190612352565b90815260405190819003602001812091909155610e569085908590612352565b60405180910390207f17369ff287d5e05e21f0210b36059644eca4e207e5481cf343c00ce99261ef278383604051610e8f929190612504565b60405180910390a250505050565b33610ea6610c86565b6001600160a01b031614610ecc5760405162461bcd60e51b815260040161052190612304565b6001600160a01b038116610f315760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610521565b610ccd81611312565b610f908363a9059cbb60e01b8484604051602401610f59929190612067565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152611883565b505050565b610f9d610a9c565b610fe05760405162461bcd60e51b815260206004820152601460248201527314185d5cd8589b194e881b9bdd081c185d5cd95960621b6044820152606401610521565b6004805460ff60a01b191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa335b60405161101d9190611f3f565b60405180910390a1565b61102f610a9c565b1561104c5760405162461bcd60e51b815260040161052190612518565b600080808061105d85870187612542565b945094509450509350620312e360ec1b841461108c5760405163a9146eeb60e01b815260040160405180910390fd5b6000801b60068b8b6040516110a2929190612352565b908152602001604051809103902054036110cf5760405163f21c9f0760e01b815260040160405180910390fd5b87876040516020016110e2929190612504565b6040516020818303038152906040528051906020012060068b8b60405161110a929190612352565b908152602001604051809103902054146111365760405162ff453f60e31b815260040160405180910390fd5b6007600060068c8c60405161114c929190612352565b9081526040805160209281900383019020548352828201939093529082016000908120848252909152205460ff16156111985760405163e323fd5d60e01b815260040160405180910390fd5b60016007600060068d8d6040516111b0929190612352565b9081526020016040518091039020548152602001908152602001600020600083815260200190815260200160002060006101000a81548160ff02191690831515021790555060008686604051611207929190612352565b6040805191829003822082820182526001600160a01b03878116845260208085018881526000848152600a8352859020955186546001600160a01b031916931692909217855590516001909401939093558151601f8e018490048402810184019092528c8252925061129791859184918f908f908190840183828082843760009201919091525061195592505050565b6112a08161142e565b6112a981611540565b836001600160a01b03168b8b6040516112c3929190612352565b60408051918290038220868352602083018690529184917ff87812c5aeb6f0b63030eea79acd80053021b86e2f2246280909466810ab4c54910160405180910390a45050505050505050505050565b600480546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b61136c610a9c565b156113895760405162461bcd60e51b815260040161052190612518565b6004805460ff60a01b1916600160a01b1790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a2586110103390565b60008190556040518181527f0d16c22f1a8d8050cb1f90d4fc81275e9a52eeb32d4cb9e6c10c87d0e80c5dda90602001610b76565b60028190556040518181527f28ebdbd10a26a82cec6aa90b2fecb2a9aca61629ad2e80d17de29c6a0018539890602001610b76565b6000818152600860205260409020600181015480156114b65760005b818110156114b457336001600160a01b031683600101828154811061147157611471612362565b6000918252602090912001546001600160a01b0316036114a45760405163080fc0bd60e11b815260040160405180910390fd5b6114ad816123a7565b905061144a565b505b600180830180548083018255600091825260209091200180546001600160a01b0319163390811790915584917fc688a9923ae84cc5cbace0353e8935fe766e29064d17d3fdd0c97b69bb493879919061151090859061258b565b8554604080516001600160a01b0390941684526020840192909252908201526060015b60405180910390a2505050565b60008181526008602052604090208054600190910154108015906105b8576000828152600a6020908152604091829020825180840190935280546001600160a01b031683526001015490820181905261159890611aaf565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03161580159061165b5750805160405163babcc53960e01b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169163babcc539916116189190600401611f3f565b602060405180830381865afa158015611635573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061165991906124a1565b155b1561179d577f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166302ffc76482600001517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663209b98336040518163ffffffff1660e01b8152600401600060405180830381865afa1580156116f2573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261171a919081019061259e565b60008151811061172c5761172c612362565b60209081029190910101516040516001600160e01b031960e085901b1681526001600160a01b039092166004830152602482015260016044820152606401600060405180830381600087803b15801561178457600080fd5b505af1158015611798573d6000803e3d6000fd5b505050505b805160208201516040516340c10f1960e01b81526001600160a01b037f0000000000000000000000005be26527e817998a7206475496fde1e68957c5a616926340c10f19926117ee92600401612067565b600060405180830381600087803b15801561180857600080fd5b505af115801561181c573d6000803e3d6000fd5b5050506000848152600a6020908152604080832080546001600160a01b03191681556001019290925583518482015192519283526001600160a01b031692507f3160144ac9bee2b9ce381a81709c299ed8b6d1da1384c79c2777d3dea699f5349101611533565b60006118d8826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316611baf9092919063ffffffff16565b805190915015610f9057808060200190518101906118f691906124a1565b610f905760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152608401610521565b60006009826040516119679190612667565b9081526020016040518091039020805480602002602001604051908101604052809291908181526020016000905b828210156119db57838290600052602060002090600202016040518060400160405290816000820154815260200160018201548152505081526020019060010190611995565b50505050905060005b8151811015611a7a576000828281518110611a0157611a01612362565b6020026020010151905080600001518611611a6957604080518082018252602083810151825282516000808252818301855282840191825289815260088352939093208251815592518051929392611a5f9260018501920190611d53565b5090505050611a7a565b50611a73816123a7565b90506119e4565b506000838152600860205260408120549003611aa957604051637c191ff960e01b815260040160405180910390fd5b50505050565b60008111611b0b5760405162461bcd60e51b8152602060048201526024808201527f526174654c696d69743a206d696e7420616d6f756e742063616e2774206265206044820152637a65726f60e01b6064820152608401610521565b600054600154611b1b919061258b565b4210611b2b576000600355426001555b600354600254611b3b919061238e565b811115611b955760405162461bcd60e51b815260206004820152602260248201527f526174654c696d69743a204d696e7420657863656564732072617465206c696d6044820152611a5d60f21b6064820152608401610521565b8060036000828254611ba7919061258b565b909155505050565b6060611bbe8484600085611bc8565b90505b9392505050565b606082471015611c295760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b6064820152608401610521565b6001600160a01b0385163b611c805760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610521565b600080866001600160a01b03168587604051611c9c9190612667565b60006040518083038185875af1925050503d8060008114611cd9576040519150601f19603f3d011682016040523d82523d6000602084013e611cde565b606091505b5091509150611cee828286611cf9565b979650505050505050565b60608315611d08575081611bc1565b825115611d185782518084602001fd5b8160405162461bcd60e51b81526004016105219190612683565b5080546000825560020290600052602060002090810190610ccd9190611db8565b828054828255906000526020600020908101928215611da8579160200282015b82811115611da857825182546001600160a01b0319166001600160a01b03909116178255602090920191600190910190611d73565b50611db4929150611dd3565b5090565b5b80821115611db45760008082556001820155600201611db9565b5b80821115611db45760008155600101611dd4565b6001600160a01b0381168114610ccd57600080fd5b600060208284031215611e0f57600080fd5b8135611bc181611de8565b60008083601f840112611e2c57600080fd5b5081356001600160401b03811115611e4357600080fd5b602083019150836020828501011115611e5b57600080fd5b9250929050565b60008083601f840112611e7457600080fd5b5081356001600160401b03811115611e8b57600080fd5b6020830191508360208260051b8501011115611e5b57600080fd5b60008060008060008060608789031215611ebf57600080fd5b86356001600160401b0380821115611ed657600080fd5b611ee28a838b01611e1a565b90985096506020890135915080821115611efb57600080fd5b611f078a838b01611e62565b90965094506040890135915080821115611f2057600080fd5b50611f2d89828a01611e62565b979a9699509497509295939492505050565b6001600160a01b0391909116815260200190565b60008060008060008060008060008060c08b8d031215611f7257600080fd5b8a35995060208b01356001600160401b0380821115611f9057600080fd5b611f9c8e838f01611e1a565b909b50995060408d0135915080821115611fb557600080fd5b611fc18e838f01611e1a565b909950975060608d0135915080821115611fda57600080fd5b611fe68e838f01611e1a565b909750955060808d0135915080821115611fff57600080fd5b5061200c8d828e01611e1a565b9150809450508092505060a08b013590509295989b9194979a5092959850565b6000806040838503121561203f57600080fd5b50508035926020909101359150565b60006020828403121561206057600080fd5b5035919050565b6001600160a01b03929092168252602082015260400190565b60008060008060008060006080888a03121561209b57600080fd5b8735965060208801356001600160401b03808211156120b957600080fd5b6120c58b838c01611e1a565b909850965060408a01359150808211156120de57600080fd5b6120ea8b838c01611e1a565b909650945060608a013591508082111561210357600080fd5b506121108a828b01611e1a565b989b979a50959850939692959293505050565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f191681016001600160401b038111828210171561216157612161612123565b604052919050565b600082601f83011261217a57600080fd5b81356001600160401b0381111561219357612193612123565b6121a6601f8201601f1916602001612139565b8181528460208386010111156121bb57600080fd5b816020850160208301376000918101602001919091529392505050565b600080604083850312156121eb57600080fd5b82356001600160401b0381111561220157600080fd5b61220d85828601612169565b95602094909401359450505050565b6000806020838503121561222f57600080fd5b82356001600160401b0381111561224557600080fd5b61225185828601611e1a565b90969095509350505050565b60006020828403121561226f57600080fd5b81356001600160401b0381111561228557600080fd5b61229184828501612169565b949350505050565b600080600080604085870312156122af57600080fd5b84356001600160401b03808211156122c657600080fd5b6122d288838901611e1a565b909650945060208701359150808211156122eb57600080fd5b506122f887828801611e1a565b95989497509550505050565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b60006020828403121561234b57600080fd5b5051919050565b8183823760009101908152919050565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b818103818111156123a1576123a1612378565b92915050565b6000600182016123b9576123b9612378565b5060010190565b81835260006001600160fb1b038311156123d957600080fd5b8260051b80836020870137939093016020019392505050565b6040815260006124066040830186886123c0565b8281036020840152611cee8185876123c0565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b89815260c06020820152600061245c60c083018a8c612419565b828103604084015261246f81898b612419565b9050866060840152828103608084015261248a818688612419565b9150508260a08301529a9950505050505050505050565b6000602082840312156124b357600080fd5b81518015158114611bc157600080fd5b8681526080602082015260006124dd608083018789612419565b82810360408401526124f0818688612419565b915050826060830152979650505050505050565b602081526000611bbe602083018486612419565b60208082526010908201526f14185d5cd8589b194e881c185d5cd95960821b604082015260600190565b600080600080600060a0868803121561255a57600080fd5b8535945060208601359350604086013561257381611de8565b94979396509394606081013594506080013592915050565b808201808211156123a1576123a1612378565b600060208083850312156125b157600080fd5b82516001600160401b03808211156125c857600080fd5b818501915085601f8301126125dc57600080fd5b8151818111156125ee576125ee612123565b8060051b91506125ff848301612139565b818152918301840191848101908884111561261957600080fd5b938501935b838510156126375784518252938501939085019061261e565b98975050505050505050565b60005b8381101561265e578181015183820152602001612646565b50506000910152565b60008251612679818460208701612643565b9190910192915050565b60208152600082518060208401526126a2816040850160208701612643565b601f01601f1916919091016040019291505056fea264697066735822122062aa1f80d26f9456cf7d30ca520509b2dbe20f5cf8c50a56bc796653bfaea29a64736f6c63430008100033
Loading...
Loading...