Contract 0x6098b3bcEce6E76a387e1d0689Fbd38Af0dC293f

Contract Overview

Balance:
0 BTT
Txn Hash Method
Block
From
To
Value [Txn Fee]
0xce379ea4a69d13a1779053f2e0e8443e76b20cdff4e59a9aaeebb995c3dbe02dSpecial Swap149671702022-11-25 15:01:2273 days 3 hrs ago0xf9f36dc75eafc38f5e6525fadba2939fcbc666e0 IN  0x6098b3bcece6e76a387e1d0689fbd38af0dc293f0 BTT32.7654
0x19b9b9a783f77bc3868e32e8274644f63372ac5bb3f140401b06f8fc58c059f1Regular Swap149671062022-11-25 14:59:1073 days 3 hrs ago0xf9f36dc75eafc38f5e6525fadba2939fcbc666e0 IN  0x6098b3bcece6e76a387e1d0689fbd38af0dc293f0 BTT41.3979
0x3e5200f501a8de1961651caf02e18a218d8a534de89165a16c2a2997e9378fbaSet X Rate149664852022-11-25 14:37:4873 days 3 hrs ago0x31003c2d5685c7d28d7174c3255307eb9a0f3015 IN  0x6098b3bcece6e76a387e1d0689fbd38af0dc293f0 BTT37.4298
0xb8ac79f358c6a44b8b0d24830f20b1739035b3c3d3878d9b7ec6bf6c5471835cSet X Rate149664762022-11-25 14:37:3073 days 3 hrs ago0x31003c2d5685c7d28d7174c3255307eb9a0f3015 IN  0x6098b3bcece6e76a387e1d0689fbd38af0dc293f0 BTT35.9781
0x26ad23845e4f2426bcaafaacc8a7f32944c873dba718ebadd086d27c408488c1Set Schedule149664712022-11-25 14:37:2073 days 3 hrs ago0x31003c2d5685c7d28d7174c3255307eb9a0f3015 IN  0x6098b3bcece6e76a387e1d0689fbd38af0dc293f0 BTT20.8296
0x1c6d7ee83b36d3dc5ce483c0df57a09c8625be1df150b4ffecccf859e0f62640Set Schedule149663592022-11-25 14:33:2873 days 3 hrs ago0x31003c2d5685c7d28d7174c3255307eb9a0f3015 IN  0x6098b3bcece6e76a387e1d0689fbd38af0dc293f0 BTT8.8509
0xe29ca2f938606006996dc14ba75fb753fdc7467fe61546b3c7c71395c965f9200x60806040149662392022-11-25 14:29:2073 days 3 hrs ago0x31003c2d5685c7d28d7174c3255307eb9a0f3015 IN  Create: Periphery20 BTT627.7566
[ Download CSV Export 
Latest 12 internal transactions
Parent Txn Hash Block From To Value
0xce379ea4a69d13a1779053f2e0e8443e76b20cdff4e59a9aaeebb995c3dbe02d149671702022-11-25 15:01:2273 days 3 hrs ago 0x6098b3bcece6e76a387e1d0689fbd38af0dc293f 0x1b72c80342ec893c04d3d4a9421a70067c51118c0 BTT
0xce379ea4a69d13a1779053f2e0e8443e76b20cdff4e59a9aaeebb995c3dbe02d149671702022-11-25 15:01:2273 days 3 hrs ago 0x6098b3bcece6e76a387e1d0689fbd38af0dc293f 0x533e331098ce304c8620270dc460ef57051c61470 BTT
0xce379ea4a69d13a1779053f2e0e8443e76b20cdff4e59a9aaeebb995c3dbe02d149671702022-11-25 15:01:2273 days 3 hrs ago 0x6098b3bcece6e76a387e1d0689fbd38af0dc293f 0x667979e3c4a5f5628674e3f06fdbdde4d8057faf0 BTT
0xce379ea4a69d13a1779053f2e0e8443e76b20cdff4e59a9aaeebb995c3dbe02d149671702022-11-25 15:01:2273 days 3 hrs ago 0x6098b3bcece6e76a387e1d0689fbd38af0dc293f 0x533e331098ce304c8620270dc460ef57051c61470 BTT
0xce379ea4a69d13a1779053f2e0e8443e76b20cdff4e59a9aaeebb995c3dbe02d149671702022-11-25 15:01:2273 days 3 hrs ago 0x6098b3bcece6e76a387e1d0689fbd38af0dc293f 0xdf80f659b832399f6b01f1bc5b420ff1f5ab43840 BTT
0xce379ea4a69d13a1779053f2e0e8443e76b20cdff4e59a9aaeebb995c3dbe02d149671702022-11-25 15:01:2273 days 3 hrs ago 0x6098b3bcece6e76a387e1d0689fbd38af0dc293f 0x6950319dd4a19b505d792ea8c3bd7af191affea80 BTT
0x19b9b9a783f77bc3868e32e8274644f63372ac5bb3f140401b06f8fc58c059f1149671062022-11-25 14:59:1073 days 3 hrs ago 0x6098b3bcece6e76a387e1d0689fbd38af0dc293f 0x1b72c80342ec893c04d3d4a9421a70067c51118c0 BTT
0x19b9b9a783f77bc3868e32e8274644f63372ac5bb3f140401b06f8fc58c059f1149671062022-11-25 14:59:1073 days 3 hrs ago 0x6098b3bcece6e76a387e1d0689fbd38af0dc293f 0x533e331098ce304c8620270dc460ef57051c61470 BTT
0x19b9b9a783f77bc3868e32e8274644f63372ac5bb3f140401b06f8fc58c059f1149671062022-11-25 14:59:1073 days 3 hrs ago 0x6098b3bcece6e76a387e1d0689fbd38af0dc293f 0x667979e3c4a5f5628674e3f06fdbdde4d8057faf0 BTT
0x19b9b9a783f77bc3868e32e8274644f63372ac5bb3f140401b06f8fc58c059f1149671062022-11-25 14:59:1073 days 3 hrs ago 0x6098b3bcece6e76a387e1d0689fbd38af0dc293f 0x533e331098ce304c8620270dc460ef57051c61470 BTT
0x19b9b9a783f77bc3868e32e8274644f63372ac5bb3f140401b06f8fc58c059f1149671062022-11-25 14:59:1073 days 3 hrs ago 0x6098b3bcece6e76a387e1d0689fbd38af0dc293f 0xdf80f659b832399f6b01f1bc5b420ff1f5ab43840 BTT
0x19b9b9a783f77bc3868e32e8274644f63372ac5bb3f140401b06f8fc58c059f1149671062022-11-25 14:59:1073 days 3 hrs ago 0x6098b3bcece6e76a387e1d0689fbd38af0dc293f 0x6950319dd4a19b505d792ea8c3bd7af191affea80 BTT
[ Download CSV Export 
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
Periphery2

Compiler Version
v0.8.9+commit.e5eed63a

Optimization Enabled:
No with 200 runs

Other Settings:
default evmVersion

Contract Source Code (Solidity Standard Json-Input format)

File 1 of 10 : Ownable.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol)

pragma solidity ^0.8.0;

import "../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 Throws if called by any account other than the owner.
     */
    modifier onlyOwner() {
        _checkOwner();
        _;
    }

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

    /**
     * @dev Throws if the sender is not the owner.
     */
    function _checkOwner() internal view virtual {
        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);
    }
}

File 2 of 10 : IERC20.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)

pragma solidity ^0.8.0;

/**
 * @dev Interface of the ERC20 standard as defined in the EIP.
 */
interface IERC20 {
    /**
     * @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);

    /**
     * @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);
}

File 3 of 10 : IERC721Enumerable.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC721/extensions/IERC721Enumerable.sol)

pragma solidity ^0.8.0;

import "../IERC721.sol";

/**
 * @title ERC-721 Non-Fungible Token Standard, optional enumeration extension
 * @dev See https://eips.ethereum.org/EIPS/eip-721
 */
interface IERC721Enumerable is IERC721 {
    /**
     * @dev Returns the total amount of tokens stored by the contract.
     */
    function totalSupply() external view returns (uint256);

    /**
     * @dev Returns a token ID owned by `owner` at a given `index` of its token list.
     * Use along with {balanceOf} to enumerate all of ``owner``'s tokens.
     */
    function tokenOfOwnerByIndex(address owner, uint256 index) external view returns (uint256);

    /**
     * @dev Returns a token ID at a given `index` of all the tokens stored by the contract.
     * Use along with {totalSupply} to enumerate all tokens.
     */
    function tokenByIndex(uint256 index) external view returns (uint256);
}

File 4 of 10 : IERC721.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.8.0) (token/ERC721/IERC721.sol)

pragma solidity ^0.8.0;

import "../../utils/introspection/IERC165.sol";

/**
 * @dev Required interface of an ERC721 compliant contract.
 */
interface IERC721 is IERC165 {
    /**
     * @dev Emitted when `tokenId` token is transferred from `from` to `to`.
     */
    event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);

    /**
     * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.
     */
    event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);

    /**
     * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.
     */
    event ApprovalForAll(address indexed owner, address indexed operator, bool approved);

    /**
     * @dev Returns the number of tokens in ``owner``'s account.
     */
    function balanceOf(address owner) external view returns (uint256 balance);

    /**
     * @dev Returns the owner of the `tokenId` token.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     */
    function ownerOf(uint256 tokenId) external view returns (address owner);

    /**
     * @dev Safely transfers `tokenId` token from `from` to `to`.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `tokenId` token must exist and be owned by `from`.
     * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.
     * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
     *
     * Emits a {Transfer} event.
     */
    function safeTransferFrom(
        address from,
        address to,
        uint256 tokenId,
        bytes calldata data
    ) external;

    /**
     * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients
     * are aware of the ERC721 protocol to prevent tokens from being forever locked.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `tokenId` token must exist and be owned by `from`.
     * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}.
     * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
     *
     * Emits a {Transfer} event.
     */
    function safeTransferFrom(
        address from,
        address to,
        uint256 tokenId
    ) external;

    /**
     * @dev Transfers `tokenId` token from `from` to `to`.
     *
     * WARNING: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC721
     * or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must
     * understand this adds an external call which potentially creates a reentrancy vulnerability.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `tokenId` token must be owned by `from`.
     * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.
     *
     * Emits a {Transfer} event.
     */
    function transferFrom(
        address from,
        address to,
        uint256 tokenId
    ) external;

    /**
     * @dev Gives permission to `to` to transfer `tokenId` token to another account.
     * The approval is cleared when the token is transferred.
     *
     * Only a single account can be approved at a time, so approving the zero address clears previous approvals.
     *
     * Requirements:
     *
     * - The caller must own the token or be an approved operator.
     * - `tokenId` must exist.
     *
     * Emits an {Approval} event.
     */
    function approve(address to, uint256 tokenId) external;

    /**
     * @dev Approve or remove `operator` as an operator for the caller.
     * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.
     *
     * Requirements:
     *
     * - The `operator` cannot be the caller.
     *
     * Emits an {ApprovalForAll} event.
     */
    function setApprovalForAll(address operator, bool _approved) external;

    /**
     * @dev Returns the account approved for `tokenId` token.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     */
    function getApproved(uint256 tokenId) external view returns (address operator);

    /**
     * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.
     *
     * See {setApprovalForAll}
     */
    function isApprovedForAll(address owner, address operator) external view returns (bool);
}

File 5 of 10 : 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;
    }
}

File 6 of 10 : IERC165.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)

pragma solidity ^0.8.0;

/**
 * @dev Interface of the ERC165 standard, as defined in the
 * https://eips.ethereum.org/EIPS/eip-165[EIP].
 *
 * Implementers can declare support of contract interfaces, which can then be
 * queried by others ({ERC165Checker}).
 *
 * For an implementation, see {ERC165}.
 */
interface IERC165 {
    /**
     * @dev Returns true if this contract implements the interface defined by
     * `interfaceId`. See the corresponding
     * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]
     * to learn more about how these ids are created.
     *
     * This function call must use less than 30 000 gas.
     */
    function supportsInterface(bytes4 interfaceId) external view returns (bool);
}

File 7 of 10 : ILoyalty.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import "@openzeppelin/contracts/token/ERC20/IERC20.sol";

/**
   	@title ILoyalty contract
   	@dev Provide an interface that other contracts can integrate with Loyalty contract
*/
interface ILoyalty is IERC20 {
    /**
       	@notice Update loyalty points of `_account`
       	@dev  Caller must be Operator
        @param _account         Account address will be updated loyalty points
        @param _amount          Amount of points will be updated
        @param _isAdded         Boolean flag (Add = True, Deduct = False)
    */
    function updatePoint(address _account, uint256 _amount, bool _isAdded) external;
}

File 8 of 10 : IMembership.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import "@openzeppelin/contracts/token/ERC721/extensions/IERC721Enumerable.sol";

/**
   	@title IMembership contract
   	@dev Provide interfaces that other contracts can integrate with Membership contract
*/
interface IMembership is IERC721Enumerable {

    /**
       	@notice Add new membership
       	@dev  Caller must be Operator
        @param _account          Account address to be added
        @param _memberId         Assigning member id
    */
    function addMembership(address _account, uint256 _memberId) external;

    /**
       	@notice Cancel current membership
       	@dev  Caller must be Operator
        @param _memberId         Assigning member id
    */
    function cancelMembership(uint256 _memberId) external;

    /**
       	@notice Upgrade `_account` to next tier
       	@dev  Caller must be Operator
        @param _account          Account address to be added
        @param _memberId         Current member id
        @param _nextTier         Upcoming tier will be upgraded

        Note: Checking requiring points, as qualification, could either be done off-chain or on-chain 
    */
    function upgrade(address _account, uint256 _memberId, uint256 _nextTier) external;

    /**
       	@notice Get current `maxTier` of this membership type
       	@dev  Caller can be ANY
    */
    function maxTier() external view returns (uint256);

    /**
       	@notice Get requiring loyalty points per tier
       	@dev  Caller can be ANY
        @param _tierNo       Tier number
    */
    function requirement(uint256 _tierNo) external view returns (uint256);

    /**
       	@notice Get current tier of `_account` with `_memberId`
       	@dev  Caller can be ANY
        @param _account         Account address to query a current tier
        @param _memberId        Member id of `_account`
    */
    function tier(address _account, uint256 _memberId) external view returns (uint256);

    /**
       	@notice Find next tier of `_account` with `_memberId`
       	@dev  Caller can be ANY
        @param _account         Account address to check
        @param _memberId        Member id of `_account`
        @param _balance         Current loyalty point of `_account`

        Note: This function is used by Periphery contract to find next tier
        when `msg.sender` requests to upgrade his/her tier
    */
    function nextTier(address _account, uint256 _memberId, uint256 _balance) external view returns (uint256);
}

File 9 of 10 : IPeriphery.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

/**
   	@title IPeriphery contract
   	@dev Provide interfaces that other contracts can integrate with Periphery contract
*/
interface IPeriphery {

    struct Redeem {
        address membership;
        uint256 memberId;
        uint256 point;
        address voucher;
        uint256 value;
        uint128 nonce;
        uint128 expiry;
    }

    struct Buy {
        address beneficiary;
        address membership;
        uint256 memberId;
        address paymentToken;
        uint256 point;
        uint256 totalPayment;
        uint128 nonce;
        uint128 expiry;
    }

    struct TopUp {
        address beneficiary;
        address membership;
        uint256 memberId;
        address voucher;
        uint256 value;
        address paymentToken;
        uint256 totalPayment;
        uint128 nonce;
        uint128 expiry;
    }

    /**
       	@notice Return corresponding `_loyalty` contract to `_membership` contract
       	@dev  Caller can be ANY
    */
    function getLoyalty(address _membership) external view returns (address);

    /**
       	@notice Checking whether `_membership` contract is disabled
       	@dev  Caller can be ANY
    */
    function disabled(address _membership) external view returns (bool);

    /**
       	@notice Redeem loyalty points to voucher's value
       	@dev  Caller can be ANY
        @param _invoice             Redeem invoice struct
        - membership (address)          Address of Membership contract
        - memberId (uint256)            Member id of `msg.sender`
        - point (uint256)               Amount of point to redeem
        - voucher (address)             Address of Voucher contract to receive a value
        - value (uint256)               Additional value to receive after redemption
        - nonce (uint128)               Current counter of `msg.sender`
        - expiry (uint128)              Expiring time of authorizing signature   
        @param _signature           Authorizing signature provided by Verifier
    */
    function redeem(
        Redeem calldata _invoice,
        bytes calldata _signature
    ) external;

    /**
       	@notice Purchase/Topup voucher's value
       	@dev  Caller can be ANY
        @param _invoice             Topup invoice struct
        - beneficiary (address)         Address of Beneficiary that receives a voucher's value
        - membership (address)          Address of Membership contract
        - memberId (uint256)            Beneficiary's member id
        - voucher (address)             Address of Voucher contract to receive a value
        - value (uint256)               Additional value to receive after topup request
        - paymentToken (address)        Address of payment token (0x00 for Native coin)
        - totalPayment (uint256)        Total payment amount
        - nonce (uint128)               Current counter of `msg.sender`
        - expiry (uint128)              Expiring time of authorizing signature   
        @param _signature           Authorizing signature provided by Verifier
    */
    function topup(
        TopUp calldata _invoice,
        bytes calldata _signature
    ) external payable;

    /**
       	@notice Buy loyaly points
       	@dev  Caller can be ANY
        @param _invoice             Buy invoice struct
        - beneficiary (address)         Address of Beneficiary that receives additional loyalty points
        - membership (address)          Address of Membership contract
        - memberId (uint256)            Beneficiary's member id
        - paymentToken (address)        Address of payment token (0x00 for Native coin)
        - point (uint256)               Additional value to receive after buy request
        - totalPayment (uint256)        Total payment amount
        - nonce (uint128)               Current counter of `msg.sender`
        - expiry (uint128)              Expiring time of authorizing signature   
        @param _signature           Authorizing signature provided by Verifier
    */
    function buy(
        Buy calldata _invoice,
        bytes calldata _signature
    ) external payable;
}

File 10 of 10 : Periphery2.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import "@openzeppelin/contracts/access/Ownable.sol";
import "./interfaces/IMembership.sol";
import "./interfaces/IPeriphery.sol";
import "./interfaces/ILoyalty.sol";

/**
   	@title Periphery2 contract (Optional)
   	@dev This contract provide additional feature and external interface (beside Periphery) on top of Membership, Loyalty and Voucher contracts
    - Register/Unregister exchange pair of Loyalty types
    - Add a method of swapping two Loyalty types (Regular)
    - Add a method of swapping two Loyalty types (Special Event)

    Note: This contract is optional to provide a swappable feature among Loyalty types
*/
contract Periphery2 is Ownable {

    struct XRate {
        uint256 bValue;             //  base value
        uint256 qValue;             //  quote value
    }

    struct Schedule {
        uint256 start;
        uint256 end;
    }

    //  Address of Periphery contract
    IPeriphery public periphery;

    //  Regular exchange rate for a pair of two Loyalty types 
    //  (address (base) => address (quote) => exchange_rate)
    mapping(address => mapping(address => XRate)) private _globalRates;

    //  Exclusive exchange rate for a pair of two Loyalty types during one special event
    //  (event_id => address (base) => address (quote) => exchange_rate)
    mapping(uint256 => mapping(address => mapping(address => XRate))) private _specialRates;

    //  Event schedule (event_id => starting and ending time)
    mapping(uint256 => Schedule) private _schedules;

    event Swap(
        uint256 eventId,
        address indexed caller,
        address indexed bMembership,
        address indexed qMembership,
        uint256 bAmount,
        uint256 qAmount
    );

    constructor(IPeriphery _periphery) Ownable() {
        periphery = _periphery;
    }

    /**
       	@notice Return global exchange rate of two loyalty types
       	@dev  Caller can be ANY
        @param _bMembership             Address of base Membership contract
        @param _qMembership             Address of quote Membership contract
    */
    function globalRate(address _bMembership, address _qMembership) public view returns (XRate memory) {
        return _globalRates[_bMembership][_qMembership];
    }

    /**
       	@notice Return special exchange rate of two loyalty types during `_eventId`
       	@dev  Caller can be ANY
        @param _eventId                 Event id
        @param _bMembership             Address of base Membership contract
        @param _qMembership             Address of quote Membership contract
    */
    function specialRate(uint256 _eventId, address _bMembership, address _qMembership) public view returns (XRate memory) {
        require(schedule(_eventId).start != 0, "EventId not exists");
        return _specialRates[_eventId][_bMembership][_qMembership];
    }

    /**
       	@notice Return schedule of `_eventId`
       	@dev  Caller can be ANY
        @param _eventId                 Event id
    */
    function schedule(uint256 _eventId) public view returns (Schedule memory) {
        return _schedules[_eventId];
    }

    /**
       	@notice Set schedule of `_eventId`
       	@dev  Caller must be Owner
        @param _eventId                 Event id
        @param _start                   Starting time (unix timestamp)
        @param _end                     Ending time (unix timestamp)
    */
    function setSchedule(uint256 _eventId, uint256 _start, uint256 _end) external onlyOwner {
        uint256 _currentTime = block.timestamp;
        require(schedule(_eventId).start == 0, "EventId exists");
        require(_start >= _currentTime && _start < _end, "Invalid schedule");

        _schedules[_eventId].start = _start;
        _schedules[_eventId].end = _end;
    }

    /**
       	@notice Adjust ending time of `_eventId`
       	@dev  Caller must be Owner
        @param _eventId                 Event id
        @param _end                     New ending time (unix timestamp)
    */
    function adjust(uint256 _eventId, uint256 _end) external onlyOwner {
        uint256 _currentTime = block.timestamp;
        Schedule memory schedule_ = _schedules[_eventId];
        require(schedule_.start != 0 && _currentTime < schedule_.end, "Invalid request");

        _schedules[_eventId].end = _end;
    }

    /**
       	@notice Set exchange rate of multiple pairs
       	@dev  Caller must be Owner
        @param _eventId                 Event id
        @param _baseMemberships         A list of base Membership contracts
        @param _quoteMemberships        A list of quote Membership contracts
        @param _baseValues              A list of input amounts
        @param _quoteValues             A list of output amounts

        Note:
        - Using this method to unregister exchanging pairs (by setting exchange_rate to 0)
        - Global and special settings must be separated
        - Event's schedule must be set before setting special exchange rates
        - Just passing one direction of conversion rate, other direction is reversed accordingly
        Example:
            + _bMemberships = [Type A, Type B]
            + _qMemberships = [Type C, Type D]
            + _baseValues = [1, 2]
            + _quoteValues = [5, 15]
    */
    function setXRate(
        uint256 _eventId,
        address[] calldata _baseMemberships,
        address[] calldata _quoteMemberships,
        uint256[] calldata _baseValues,
        uint256[] calldata _quoteValues
    ) external onlyOwner {
        uint256 _len = _baseMemberships.length;
        require(
            _baseValues.length == _len &&
            _quoteMemberships.length == _len &&
            _quoteValues.length == _len,
            "Invalid length"
        );

        _eventId == 0 ? _setGlobalRate(_len, _baseMemberships, _quoteMemberships, _baseValues, _quoteValues) : _setSpecialRate(_len, _eventId, _baseMemberships, _quoteMemberships, _baseValues, _quoteValues);
    }

    /**
       	@notice Swap of two types of loyalty points (Regular)
       	@dev  Caller can be ANY
        @param _bMembership             Address of base Membership contract
        @param _bMemberId               Base membership id of `msg.sender`
        @param _qMembership             Address of quote Membership contract
        @param _qMemberId               Quote membership id of `msg.sender`
        @param _bAmount                 Swapping amount of points
    */
    function regularSwap(address _bMembership, uint256 _bMemberId, address _qMembership, uint256 _qMemberId, uint256 _bAmount) external {
        _swap(0, _bMembership, _bMemberId, _qMembership, _qMemberId, _bAmount);
    }

    /**
       	@notice Swap two types of loyalty points during `_eventId`
       	@dev  Caller can be ANY
        @param _eventId                 Event id
        @param _bMembership             Address of base Membership contract
        @param _bMemberId               Base membership id of `msg.sender`
        @param _qMembership             Address of quote Membership contract
        @param _qMemberId               Quote membership id of `msg.sender`
        @param _bAmount                 Swapping amount of points
    */
    function specialSwap(uint256 _eventId, address _bMembership, uint256 _bMemberId, address _qMembership, uint256 _qMemberId, uint256 _bAmount) external {
        uint256 _currentTime = block.timestamp;
        Schedule memory schedule_ = schedule(_eventId);
        require(
            schedule_.start <= _currentTime && _currentTime <= schedule_.end,
            "Event not yet started or already ended"
        );
        _swap(_eventId, _bMembership, _bMemberId, _qMembership, _qMemberId, _bAmount);
    }

    function _swap(uint256 _eventId, address _bMembership, uint256 _bMemberId, address _qMembership, uint256 _qMemberId, uint256 _bAmount) private {
        address _caller = msg.sender;
        require(
            IMembership(_bMembership).ownerOf(_bMemberId) == _caller &&
            IMembership(_qMembership).ownerOf(_qMemberId) == _caller,
            "Memberships not recorded"
        );

        XRate memory _xrate;
        if (_eventId != 0)
            _xrate = specialRate(_eventId, _bMembership, _qMembership);
        else
            _xrate = globalRate(_bMembership, _qMembership); 
        require(
            _xrate.bValue != 0 && _xrate.qValue != 0, "Unsupport swapping the pair"
        );
        uint256 _qAmount = _bAmount * _xrate.qValue / _xrate.bValue;

        IPeriphery _periphery = periphery;
        ILoyalty(_periphery.getLoyalty(_bMembership)).updatePoint(_caller, _bAmount, false);
        ILoyalty(_periphery.getLoyalty(_qMembership)).updatePoint(_caller, _qAmount, true);

        emit Swap(_eventId, _caller, _bMembership, _qMembership, _bAmount, _qAmount);
    }

    function _setGlobalRate(
        uint256 _len,
        address[] calldata _baseMemberships,
        address[] calldata _quoteMemberships,
        uint256[] calldata _baseValues,
        uint256[] calldata _quoteValues
    ) private {
        address _bMembership;
        address _qMembership;
        for (uint256 i; i < 2 * _len; i++) {
            if (i < _len) {
                _bMembership = _baseMemberships[i];
                _qMembership = _quoteMemberships[i];
                _globalRates[_bMembership][_qMembership].bValue = _baseValues[i];
                _globalRates[_bMembership][_qMembership].qValue = _quoteValues[i];
            }
            else {
                _bMembership = _baseMemberships[i - _len];
                _qMembership = _quoteMemberships[i - _len];
                _globalRates[_qMembership][_bMembership].bValue = _quoteValues[i - _len];
                _globalRates[_qMembership][_bMembership].qValue = _baseValues[i - _len];
            }
        }
    }

    function _setSpecialRate(
        uint256 _len,
        uint256 _eventId,
        address[] calldata _baseMemberships,
        address[] calldata _quoteMemberships,
        uint256[] calldata _baseValues,
        uint256[] calldata _quoteValues
    ) private {
        {
            uint256 _currentTime = block.timestamp;
            Schedule memory schedule_ = _schedules[_eventId];
            require(
                schedule_.start != 0 && schedule_.start <= _currentTime && _currentTime <= schedule_.end,
                "Invalid request"
            );
        }

        address _bMembership;
        address _qMembership;
        for (uint256 i; i < 2 * _len; i++) {
            if (i < _len) {
                _bMembership = _baseMemberships[i];
                _qMembership = _quoteMemberships[i];
                _specialRates[_eventId][_bMembership][_qMembership].bValue = _baseValues[i];
                _specialRates[_eventId][_bMembership][_qMembership].qValue = _quoteValues[i];
            }
            else {
                _bMembership = _baseMemberships[i - _len];
                _qMembership = _quoteMemberships[i - _len];
                _specialRates[_eventId][_qMembership][_bMembership].bValue = _quoteValues[i - _len];
                _specialRates[_eventId][_qMembership][_bMembership].qValue = _baseValues[i - _len];
            }
        }
    }
}

Settings
{
  "optimizer": {
    "enabled": false,
    "runs": 200
  },
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "devdoc",
        "userdoc",
        "metadata",
        "abi"
      ]
    }
  },
  "metadata": {
    "useLiteralContent": true
  },
  "libraries": {}
}

Contract ABI

[{"inputs":[{"internalType":"contract IPeriphery","name":"_periphery","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"eventId","type":"uint256"},{"indexed":true,"internalType":"address","name":"caller","type":"address"},{"indexed":true,"internalType":"address","name":"bMembership","type":"address"},{"indexed":true,"internalType":"address","name":"qMembership","type":"address"},{"indexed":false,"internalType":"uint256","name":"bAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"qAmount","type":"uint256"}],"name":"Swap","type":"event"},{"inputs":[{"internalType":"uint256","name":"_eventId","type":"uint256"},{"internalType":"uint256","name":"_end","type":"uint256"}],"name":"adjust","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_bMembership","type":"address"},{"internalType":"address","name":"_qMembership","type":"address"}],"name":"globalRate","outputs":[{"components":[{"internalType":"uint256","name":"bValue","type":"uint256"},{"internalType":"uint256","name":"qValue","type":"uint256"}],"internalType":"struct Periphery2.XRate","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"periphery","outputs":[{"internalType":"contract IPeriphery","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_bMembership","type":"address"},{"internalType":"uint256","name":"_bMemberId","type":"uint256"},{"internalType":"address","name":"_qMembership","type":"address"},{"internalType":"uint256","name":"_qMemberId","type":"uint256"},{"internalType":"uint256","name":"_bAmount","type":"uint256"}],"name":"regularSwap","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_eventId","type":"uint256"}],"name":"schedule","outputs":[{"components":[{"internalType":"uint256","name":"start","type":"uint256"},{"internalType":"uint256","name":"end","type":"uint256"}],"internalType":"struct Periphery2.Schedule","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_eventId","type":"uint256"},{"internalType":"uint256","name":"_start","type":"uint256"},{"internalType":"uint256","name":"_end","type":"uint256"}],"name":"setSchedule","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_eventId","type":"uint256"},{"internalType":"address[]","name":"_baseMemberships","type":"address[]"},{"internalType":"address[]","name":"_quoteMemberships","type":"address[]"},{"internalType":"uint256[]","name":"_baseValues","type":"uint256[]"},{"internalType":"uint256[]","name":"_quoteValues","type":"uint256[]"}],"name":"setXRate","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_eventId","type":"uint256"},{"internalType":"address","name":"_bMembership","type":"address"},{"internalType":"address","name":"_qMembership","type":"address"}],"name":"specialRate","outputs":[{"components":[{"internalType":"uint256","name":"bValue","type":"uint256"},{"internalType":"uint256","name":"qValue","type":"uint256"}],"internalType":"struct Periphery2.XRate","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_eventId","type":"uint256"},{"internalType":"address","name":"_bMembership","type":"address"},{"internalType":"uint256","name":"_bMemberId","type":"uint256"},{"internalType":"address","name":"_qMembership","type":"address"},{"internalType":"uint256","name":"_qMemberId","type":"uint256"},{"internalType":"uint256","name":"_bAmount","type":"uint256"}],"name":"specialSwap","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"}]

60806040523480156200001157600080fd5b5060405162002633380380620026338339818101604052810190620000379190620001e9565b620000576200004b6200009f60201b60201c565b620000a760201b60201c565b80600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550506200021b565b600033905090565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006200019d8262000170565b9050919050565b6000620001b18262000190565b9050919050565b620001c381620001a4565b8114620001cf57600080fd5b50565b600081519050620001e381620001b8565b92915050565b6000602082840312156200020257620002016200016b565b5b60006200021284828501620001d2565b91505092915050565b612408806200022b6000396000f3fe608060405234801561001057600080fd5b50600436106100b45760003560e01c8063715018a611610071578063715018a61461018957806377aace1a146101935780638da5cb5b146101b1578063af104c7c146101cf578063eeacaef7146101eb578063f2fde38b1461021b576100b4565b8063064e9b0a146100b957806317d2bea4146100d55780633417400f146100f15780633c590ad314610121578063418ce7d61461013d5780636fbfd40914610159575b600080fd5b6100d360048036038101906100ce919061172d565b610237565b005b6100ef60048036038101906100ea91906117ba565b6102b8565b005b61010b600480360381019061010691906117fa565b610373565b604051610118919061188b565b60405180910390f35b61013b60048036038101906101369190611961565b610480565b005b61015760048036038101906101529190611a5d565b61052e565b005b610173600480360381019061016e9190611ab0565b610614565b6040516101809190611b0c565b60405180910390f35b610191610655565b005b61019b610669565b6040516101a89190611b86565b60405180910390f35b6101b961068f565b6040516101c69190611bb0565b60405180910390f35b6101e960048036038101906101e49190611bcb565b6106b8565b005b61020560048036038101906102009190611c46565b6106ce565b604051610212919061188b565b60405180910390f35b61023560048036038101906102309190611c86565b610779565b005b6000429050600061024788610614565b905081816000015111158015610261575080602001518211155b6102a0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161029790611d36565b60405180910390fd5b6102ae8888888888886107fd565b5050505050505050565b6102c0610d05565b600042905060006004600085815260200190815260200160002060405180604001604052908160008201548152602001600182015481525050905060008160000151141580156103135750806020015182105b610352576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161034990611da2565b60405180910390fd5b82600460008681526020019081526020016000206001018190555050505050565b61037b61165b565b600061038685610614565b6000015114156103cb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103c290611e0e565b60405180910390fd5b6003600085815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206040518060400160405290816000820154815260200160018201548152505090509392505050565b610488610d05565b600088889050905080858590501480156104a457508087879050145b80156104b257508083839050145b6104f1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016104e890611e7a565b60405180910390fd5b60008a146105105761050b818b8b8b8b8b8b8b8b8b610d83565b610522565b610521818a8a8a8a8a8a8a8a6111fe565b5b50505050505050505050565b610536610d05565b6000429050600061054685610614565b600001511461058a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161058190611ee6565b60405180910390fd5b80831015801561059957508183105b6105d8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105cf90611f52565b60405180910390fd5b82600460008681526020019081526020016000206000018190555081600460008681526020019081526020016000206001018190555050505050565b61061c611675565b60046000838152602001908152602001600020604051806040016040529081600082015481526020016001820154815250509050919050565b61065d610d05565b610667600061158f565b565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6106c7600086868686866107fd565b5050505050565b6106d661165b565b600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060405180604001604052908160008201548152602001600182015481525050905092915050565b610781610d05565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614156107f1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016107e890611fe4565b60405180910390fd5b6107fa8161158f565b50565b60003390508073ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff16636352211e876040518263ffffffff1660e01b81526004016108529190612013565b60206040518083038186803b15801561086a57600080fd5b505afa15801561087e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108a29190612043565b73ffffffffffffffffffffffffffffffffffffffff1614801561097857508073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff16636352211e856040518263ffffffff1660e01b81526004016109109190612013565b60206040518083038186803b15801561092857600080fd5b505afa15801561093c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109609190612043565b73ffffffffffffffffffffffffffffffffffffffff16145b6109b7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109ae906120bc565b60405180910390fd5b6109bf61165b565b600088146109d9576109d2888887610373565b90506109e6565b6109e387866106ce565b90505b6000816000015114158015610a0057506000816020015114155b610a3f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a3690612128565b60405180910390fd5b60008160000151826020015185610a569190612177565b610a609190612200565b90506000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690508073ffffffffffffffffffffffffffffffffffffffff166309af7d868a6040518263ffffffff1660e01b8152600401610ac29190611bb0565b60206040518083038186803b158015610ada57600080fd5b505afa158015610aee573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b129190612043565b73ffffffffffffffffffffffffffffffffffffffff166328a01367858760006040518463ffffffff1660e01b8152600401610b4f9392919061224c565b600060405180830381600087803b158015610b6957600080fd5b505af1158015610b7d573d6000803e3d6000fd5b505050508073ffffffffffffffffffffffffffffffffffffffff166309af7d86886040518263ffffffff1660e01b8152600401610bba9190611bb0565b60206040518083038186803b158015610bd257600080fd5b505afa158015610be6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c0a9190612043565b73ffffffffffffffffffffffffffffffffffffffff166328a01367858460016040518463ffffffff1660e01b8152600401610c479392919061224c565b600060405180830381600087803b158015610c6157600080fd5b505af1158015610c75573d6000803e3d6000fd5b505050508673ffffffffffffffffffffffffffffffffffffffff168973ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff167f435aa1cca6b5602db6dbb46b76b62825800dec85b04104844114804bcd2a1d3b8d8987604051610cf193929190612283565b60405180910390a450505050505050505050565b610d0d611653565b73ffffffffffffffffffffffffffffffffffffffff16610d2b61068f565b73ffffffffffffffffffffffffffffffffffffffff1614610d81576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d7890612306565b60405180910390fd5b565b60004290506000600460008c81526020019081526020016000206040518060400160405290816000820154815260200160018201548152505090506000816000015114158015610dd7575081816000015111155b8015610de7575080602001518211155b610e26576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e1d90611da2565b60405180910390fd5b505060008060005b8c6002610e3b9190612177565b8110156111ef578c811015610fff578a8a82818110610e5d57610e5c612326565b5b9050602002016020810190610e729190611c86565b9250888882818110610e8757610e86612326565b5b9050602002016020810190610e9c9190611c86565b9150868682818110610eb157610eb0612326565b5b90506020020135600360008e815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000181905550848482818110610f5f57610f5e612326565b5b90506020020135600360008e815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600101819055506111dc565b8a8a8e8361100d9190612355565b81811061101d5761101c612326565b5b90506020020160208101906110329190611c86565b925088888e836110429190612355565b81811061105257611051612326565b5b90506020020160208101906110679190611c86565b915084848e836110779190612355565b81811061108757611086612326565b5b90506020020135600360008e815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000018190555086868e836111309190612355565b8181106111405761113f612326565b5b90506020020135600360008e815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600101819055505b80806111e790612389565b915050610e2e565b50505050505050505050505050565b60008060005b8b60026112119190612177565b811015611581578b8110156113b3578a8a8281811061123357611232612326565b5b90506020020160208101906112489190611c86565b925088888281811061125d5761125c612326565b5b90506020020160208101906112729190611c86565b915086868281811061128757611286612326565b5b90506020020135600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000018190555084848281811061132457611323612326565b5b90506020020135600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206001018190555061156e565b8a8a8d836113c19190612355565b8181106113d1576113d0612326565b5b90506020020160208101906113e69190611c86565b925088888d836113f69190612355565b81811061140657611405612326565b5b905060200201602081019061141b9190611c86565b915084848d8361142b9190612355565b81811061143b5761143a612326565b5b90506020020135600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000018190555086868d836114d39190612355565b8181106114e3576114e2612326565b5b90506020020135600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600101819055505b808061157990612389565b915050611204565b505050505050505050505050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b600033905090565b604051806040016040528060008152602001600081525090565b604051806040016040528060008152602001600081525090565b600080fd5b600080fd5b6000819050919050565b6116ac81611699565b81146116b757600080fd5b50565b6000813590506116c9816116a3565b92915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006116fa826116cf565b9050919050565b61170a816116ef565b811461171557600080fd5b50565b60008135905061172781611701565b92915050565b60008060008060008060c0878903121561174a5761174961168f565b5b600061175889828a016116ba565b965050602061176989828a01611718565b955050604061177a89828a016116ba565b945050606061178b89828a01611718565b935050608061179c89828a016116ba565b92505060a06117ad89828a016116ba565b9150509295509295509295565b600080604083850312156117d1576117d061168f565b5b60006117df858286016116ba565b92505060206117f0858286016116ba565b9150509250929050565b6000806000606084860312156118135761181261168f565b5b6000611821868287016116ba565b935050602061183286828701611718565b925050604061184386828701611718565b9150509250925092565b61185681611699565b82525050565b604082016000820151611872600085018261184d565b506020820151611885602085018261184d565b50505050565b60006040820190506118a0600083018461185c565b92915050565b600080fd5b600080fd5b600080fd5b60008083601f8401126118cb576118ca6118a6565b5b8235905067ffffffffffffffff8111156118e8576118e76118ab565b5b602083019150836020820283011115611904576119036118b0565b5b9250929050565b60008083601f840112611921576119206118a6565b5b8235905067ffffffffffffffff81111561193e5761193d6118ab565b5b60208301915083602082028301111561195a576119596118b0565b5b9250929050565b600080600080600080600080600060a08a8c0312156119835761198261168f565b5b60006119918c828d016116ba565b99505060208a013567ffffffffffffffff8111156119b2576119b1611694565b5b6119be8c828d016118b5565b985098505060408a013567ffffffffffffffff8111156119e1576119e0611694565b5b6119ed8c828d016118b5565b965096505060608a013567ffffffffffffffff811115611a1057611a0f611694565b5b611a1c8c828d0161190b565b945094505060808a013567ffffffffffffffff811115611a3f57611a3e611694565b5b611a4b8c828d0161190b565b92509250509295985092959850929598565b600080600060608486031215611a7657611a7561168f565b5b6000611a84868287016116ba565b9350506020611a95868287016116ba565b9250506040611aa6868287016116ba565b9150509250925092565b600060208284031215611ac657611ac561168f565b5b6000611ad4848285016116ba565b91505092915050565b604082016000820151611af3600085018261184d565b506020820151611b06602085018261184d565b50505050565b6000604082019050611b216000830184611add565b92915050565b6000819050919050565b6000611b4c611b47611b42846116cf565b611b27565b6116cf565b9050919050565b6000611b5e82611b31565b9050919050565b6000611b7082611b53565b9050919050565b611b8081611b65565b82525050565b6000602082019050611b9b6000830184611b77565b92915050565b611baa816116ef565b82525050565b6000602082019050611bc56000830184611ba1565b92915050565b600080600080600060a08688031215611be757611be661168f565b5b6000611bf588828901611718565b9550506020611c06888289016116ba565b9450506040611c1788828901611718565b9350506060611c28888289016116ba565b9250506080611c39888289016116ba565b9150509295509295909350565b60008060408385031215611c5d57611c5c61168f565b5b6000611c6b85828601611718565b9250506020611c7c85828601611718565b9150509250929050565b600060208284031215611c9c57611c9b61168f565b5b6000611caa84828501611718565b91505092915050565b600082825260208201905092915050565b7f4576656e74206e6f74207965742073746172746564206f7220616c726561647960008201527f20656e6465640000000000000000000000000000000000000000000000000000602082015250565b6000611d20602683611cb3565b9150611d2b82611cc4565b604082019050919050565b60006020820190508181036000830152611d4f81611d13565b9050919050565b7f496e76616c696420726571756573740000000000000000000000000000000000600082015250565b6000611d8c600f83611cb3565b9150611d9782611d56565b602082019050919050565b60006020820190508181036000830152611dbb81611d7f565b9050919050565b7f4576656e744964206e6f74206578697374730000000000000000000000000000600082015250565b6000611df8601283611cb3565b9150611e0382611dc2565b602082019050919050565b60006020820190508181036000830152611e2781611deb565b9050919050565b7f496e76616c6964206c656e677468000000000000000000000000000000000000600082015250565b6000611e64600e83611cb3565b9150611e6f82611e2e565b602082019050919050565b60006020820190508181036000830152611e9381611e57565b9050919050565b7f4576656e74496420657869737473000000000000000000000000000000000000600082015250565b6000611ed0600e83611cb3565b9150611edb82611e9a565b602082019050919050565b60006020820190508181036000830152611eff81611ec3565b9050919050565b7f496e76616c6964207363686564756c6500000000000000000000000000000000600082015250565b6000611f3c601083611cb3565b9150611f4782611f06565b602082019050919050565b60006020820190508181036000830152611f6b81611f2f565b9050919050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b6000611fce602683611cb3565b9150611fd982611f72565b604082019050919050565b60006020820190508181036000830152611ffd81611fc1565b9050919050565b61200d81611699565b82525050565b60006020820190506120286000830184612004565b92915050565b60008151905061203d81611701565b92915050565b6000602082840312156120595761205861168f565b5b60006120678482850161202e565b91505092915050565b7f4d656d6265727368697073206e6f74207265636f726465640000000000000000600082015250565b60006120a6601883611cb3565b91506120b182612070565b602082019050919050565b600060208201905081810360008301526120d581612099565b9050919050565b7f556e737570706f7274207377617070696e672074686520706169720000000000600082015250565b6000612112601b83611cb3565b915061211d826120dc565b602082019050919050565b6000602082019050818103600083015261214181612105565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600061218282611699565b915061218d83611699565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04831182151516156121c6576121c5612148565b5b828202905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600061220b82611699565b915061221683611699565b925082612226576122256121d1565b5b828204905092915050565b60008115159050919050565b61224681612231565b82525050565b60006060820190506122616000830186611ba1565b61226e6020830185612004565b61227b604083018461223d565b949350505050565b60006060820190506122986000830186612004565b6122a56020830185612004565b6122b26040830184612004565b949350505050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b60006122f0602083611cb3565b91506122fb826122ba565b602082019050919050565b6000602082019050818103600083015261231f816122e3565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600061236082611699565b915061236b83611699565b92508282101561237e5761237d612148565b5b828203905092915050565b600061239482611699565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8214156123c7576123c6612148565b5b60018201905091905056fea264697066735822122013455735dfbf0c10cc3b520ccb01d3e2491d3fd8ace090cde73a5f06ec43df7464736f6c63430008090033000000000000000000000000533e331098ce304c8620270dc460ef57051c6147

Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)

000000000000000000000000533e331098ce304c8620270dc460ef57051c6147

-----Decoded View---------------
Arg [0] : _periphery (address): 0x533e331098ce304c8620270dc460ef57051c6147

-----Encoded View---------------
1 Constructor Arguments found :
Arg [0] : 000000000000000000000000533e331098ce304c8620270dc460ef57051c6147


Block Transaction Gas Used Reward
Age Block Fee Address BC Fee Address Voting Power Jailed Incoming
Block Uncle Number Difficulty Gas Used Reward
Loading