false
false

Contract Address Details

0xcDc59B5b4e323a878B0D635d458DE8c736c0cca8

Contract Name
DestinationBridge
Creator
0xb232d7–436128 at 0x7542b7–93fe83
Balance
0 MNT ( )
Tokens
Fetching tokens...
Transactions
0
Transfers
0
Gas Used
Fetching gas used...
Last Balance Update
57651775
Warning! Contract bytecode has been changed and doesn't match the verified one. Therefore, interaction with this smart contract may be risky.
Contract name:
DestinationBridge




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




Optimization runs
100
EVM Version
default




Verified at
2023-10-25T15:02:55.264477Z

Constructor Arguments

0x0000000000000000000000005be26527e817998a7206475496fde1e68957c5a6000000000000000000000000e432150cce91c13a887f7d836923d5597add8e310000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c8a7870ffe41054612f7f3433e173d8b5bfca8e3000000000000000000000000c8a7870ffe41054612f7f3433e173d8b5bfca8e300000000000000000000000000000000000000000000152d02c7e14af68000000000000000000000000000000000000000000000000000000000000000015180

Arg [0] (address) : 0x5be26527e817998a7206475496fde1e68957c5a6
Arg [1] (address) : 0xe432150cce91c13a887f7d836923d5597add8e31
Arg [2] (address) : 0x0000000000000000000000000000000000000000
Arg [3] (address) : 0xc8a7870ffe41054612f7f3433e173d8b5bfca8e3
Arg [4] (address) : 0xc8a7870ffe41054612f7f3433e173d8b5bfca8e3
Arg [5] (uint256) : 100000000000000000000000
Arg [6] (uint256) : 86400

                    

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...