ETH Price: $2,274.52 (+8.60%)

Contract

0x8aEb9453EF22Cb38abC7a3Af9c208F65C1BfE31e
 

Overview

ETH Balance

0 ETH

Eth Value

$0.00

More Info

Private Name Tags

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To
Redeem Instant246444062026-03-12 22:36:113 days ago1773354971IN
0x8aEb9453...5C1BfE31e
0 ETH0.000020930.05164266
Redeem Instant246374142026-03-11 23:10:234 days ago1773270623IN
0x8aEb9453...5C1BfE31e
0 ETH0.000073940.17501642
Redeem Instant246169812026-03-09 2:39:237 days ago1773023963IN
0x8aEb9453...5C1BfE31e
0 ETH0.000695352.03227266
Redeem Instant246169452026-03-09 2:32:117 days ago1773023531IN
0x8aEb9453...5C1BfE31e
0 ETH0.000789022.0317753
Redeem Instant245966862026-03-06 6:39:3510 days ago1772779175IN
0x8aEb9453...5C1BfE31e
0 ETH0.000863612.043858
Redeem Instant245946032026-03-05 23:38:4710 days ago1772753927IN
0x8aEb9453...5C1BfE31e
0 ETH0.000013030.03758268
Redeem Instant245945502026-03-05 23:28:1110 days ago1772753291IN
0x8aEb9453...5C1BfE31e
0 ETH0.000013630.03929257
Redeem Instant245945162026-03-05 23:21:1110 days ago1772752871IN
0x8aEb9453...5C1BfE31e
0 ETH0.000015730.04184878
Redeem Instant245845182026-03-04 13:53:1112 days ago1772632391IN
0x8aEb9453...5C1BfE31e
0 ETH0.000831252.19348621
Redeem Instant245836832026-03-04 11:05:4712 days ago1772622347IN
0x8aEb9453...5C1BfE31e
0 ETH0.000886532.09820324
Redeem Instant245403922026-02-26 10:07:4718 days ago1772100467IN
0x8aEb9453...5C1BfE31e
0 ETH0.000017150.04526663
Redeem Instant245378062026-02-26 1:28:3518 days ago1772069315IN
0x8aEb9453...5C1BfE31e
0 ETH0.000866122.04991749
Redeem Instant245317262026-02-25 5:06:2319 days ago1771995983IN
0x8aEb9453...5C1BfE31e
0 ETH0.000010540.04951273
Redeem Instant245317252026-02-25 5:06:1119 days ago1771995971IN
0x8aEb9453...5C1BfE31e
0 ETH0.000038030.09002741
Redeem Instant245110292026-02-22 7:51:1122 days ago1771746671IN
0x8aEb9453...5C1BfE31e
0 ETH0.000020580.05430962
Redeem Instant245093062026-02-22 2:05:3522 days ago1771725935IN
0x8aEb9453...5C1BfE31e
0 ETH0.000859452.03411473
Redeem Instant244922982026-02-19 17:10:3524 days ago1771521035IN
0x8aEb9453...5C1BfE31e
0 ETH0.000048160.12402831
Redeem Instant244855512026-02-18 18:35:3525 days ago1771439735IN
0x8aEb9453...5C1BfE31e
0 ETH0.000084220.25909305
Redeem Instant244855422026-02-18 18:33:4725 days ago1771439627IN
0x8aEb9453...5C1BfE31e
0 ETH0.000089990.26302719
Redeem Instant244852932026-02-18 17:43:5925 days ago1771436639IN
0x8aEb9453...5C1BfE31e
0 ETH0.000053370.13743414
Redeem Instant244780532026-02-17 17:29:5926 days ago1771349399IN
0x8aEb9453...5C1BfE31e
0 ETH0.000834882.15013193
Redeem Instant244671952026-02-16 5:09:2328 days ago1771218563IN
0x8aEb9453...5C1BfE31e
0 ETH0.000014420.04438084
Redeem Instant244671902026-02-16 5:08:2328 days ago1771218503IN
0x8aEb9453...5C1BfE31e
0 ETH0.000014240.03837858
Redeem Instant244601532026-02-15 5:36:4729 days ago1771133807IN
0x8aEb9453...5C1BfE31e
0 ETH0.00005140.13236289
Redeem Instant244488922026-02-13 15:55:4731 days ago1770998147IN
0x8aEb9453...5C1BfE31e
0 ETH0.000235750.57467808
View all transactions

View more zero value Internal Transactions in Advanced View mode

Advanced mode:
Loading...
Loading
Loading...
Loading
Cross-Chain Transactions

Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

Validator Index Block Amount
View All Withdrawals

Transaction Hash Block Value Eth2 PubKey Valid
View All Deposits
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
RedemptionGateway

Compiler Version
v0.8.30+commit.73712a01

Optimization Enabled:
Yes with 500 runs

Other Settings:
cancun EvmVersion
// SPDX-License-Identifier: MIT
pragma solidity 0.8.30;

import "@openzeppelin/contracts/access/manager/AccessManaged.sol";
import "@openzeppelin/contracts/utils/ReentrancyGuard.sol";
import "@openzeppelin/contracts/utils/Pausable.sol";
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "./IInstantRedemption.sol";
import "./IWindowRedemption.sol";
import "../token/IShareToken.sol";
import "../compliance/IKYCRegistry.sol";

/**
 * @title RedemptionGateway
 * @notice Single entry-point for users to redeem shares. Routes to instant or window modules.
 * @dev Business rule: a redemption window, when open, has exclusive precedence over instant mode.
 *
 * **Responsibilities**
 * - Enforce KYC and basic argument checks at the gateway boundary.
 * - Delegate to {IInstantRedemption} or {IWindowRedemption} and bubble up reverts.
 * - Expose consolidated read-only views used by frontends and monitoring.
 *
 * **Security**
 * - Pausable and reentrancy-protected; administrative setters gated by {AccessManaged}.
 */
contract RedemptionGateway is AccessManaged, ReentrancyGuard, Pausable {
    // ============ Types ============
    enum RedemptionMode {
        NONE,
        INSTANT,
        WINDOW
    }

    // ============ Roles ============
    // Roles are now managed by AccessManager

    // ============ State ============
    IInstantRedemption public instantRedemption;
    IWindowRedemption public windowRedemption;
    IShareToken public immutable shareToken;
    IKYCRegistry public immutable kyc;

    // ============ Events ============
    event InstantRedemptionSet(address indexed module);
    event WindowRedemptionSet(address indexed module);
    event InstantRedemptionRouted(address indexed user, uint256 shares, uint256 payout);
    event WindowRedemptionRouted(address indexed user, address indexed module, uint256 amount);

    // ============ Errors ============
    error InvalidModule();
    error KYCRequired();
    error InvalidAmount();
    error WrongMode(uint8 expected, uint8 actual);

    // ============ Constructor ============

    /**
     * @param _accessManager Address of the AccessManager
     * @param _instantRedemption Address of the InstantRedemption module
     * @param _windowRedemption Address of the WindowRedemption module
     * @param _shareToken Address of the ShareToken
     * @param _kyc Address of the KYC registry
     */
    constructor(
        address _accessManager,
        address _instantRedemption,
        address _windowRedemption,
        address _shareToken,
        address _kyc
    ) AccessManaged(_accessManager) {
        // Validate addresses are not zero
        if (_accessManager == address(0)) revert InvalidModule();
        if (_instantRedemption == address(0)) revert InvalidModule();
        if (_windowRedemption == address(0)) revert InvalidModule();
        if (_shareToken == address(0)) revert InvalidModule();
        if (_kyc == address(0)) revert InvalidModule();

        // Store validated addresses
        instantRedemption = IInstantRedemption(_instantRedemption);
        windowRedemption = IWindowRedemption(_windowRedemption);
        shareToken = IShareToken(_shareToken);
        kyc = IKYCRegistry(_kyc);
    }

    // ============ Instant Redemption Functions ============

    /**
     * @notice Process an instant redemption through the gateway
     * @param shares Amount of shares to redeem
     * @param minPayout Minimum payout amount (slippage protection)
     */
    function redeemInstant(uint256 shares, uint256 minPayout) external nonReentrant whenNotPaused {
        // Enforce mutual exclusivity: block instant while a window is open
        RedemptionMode mode = currentMode();
        if (mode != RedemptionMode.INSTANT) {
            revert WrongMode(uint8(RedemptionMode.INSTANT), uint8(mode));
        }

        if (!kyc.isKYCApproved(msg.sender)) revert KYCRequired();
        if (shares == 0) revert InvalidAmount();

        // Instant redemption module will transfer shares directly from user
        // and will revert if allowance is insufficient
        instantRedemption.redeemFor(msg.sender, shares, minPayout);

        emit InstantRedemptionRouted(msg.sender, shares, minPayout);
    }

    /**
     * @notice Preview instant redemption
     * @param user User address
     * @param shares Amount of shares
     * @return grossPayout Gross payout amount
     * @return fee Fee amount
     * @return netPayout Net payout after fee
     * @return available Whether redemption would succeed
     */
    function previewInstantRedemption(address user, uint256 shares)
        external
        view
        returns (uint256 grossPayout, uint256 fee, uint256 netPayout, bool available)
    {
        return instantRedemption.previewRedemption(user, shares);
    }

    // ============ Window Redemption Functions ============

    /**
     * @notice Submit a window redemption request
     * @param shares Amount of shares to request for redemption
     */
    function submitWindowRequest(uint256 shares) external nonReentrant whenNotPaused {
        // Enforce mutual exclusivity: only allow during window mode
        RedemptionMode mode = currentMode();
        if (mode != RedemptionMode.WINDOW) {
            revert WrongMode(uint8(RedemptionMode.WINDOW), uint8(mode));
        }

        if (!kyc.isKYCApproved(msg.sender)) revert KYCRequired();
        if (shares == 0) revert InvalidAmount();

        // Window module will transfer shares directly from user
        // and will revert if allowance is insufficient
        windowRedemption.submitRequestFor(msg.sender, shares);

        emit WindowRedemptionRouted(msg.sender, address(windowRedemption), shares);
    }

    /**
     * @notice Adjust a window redemption request
     * @param newShares New amount of shares for the request
     */
    function adjustWindowRequest(uint256 newShares) external nonReentrant whenNotPaused {
        // Enforce mutual exclusivity: only allow during window mode
        RedemptionMode mode = currentMode();
        if (mode != RedemptionMode.WINDOW) {
            revert WrongMode(uint8(RedemptionMode.WINDOW), uint8(mode));
        }

        if (!kyc.isKYCApproved(msg.sender)) revert KYCRequired();

        // Window module will handle token transfers directly with user
        windowRedemption.adjustRequestFor(msg.sender, newShares);
    }

    /**
     * @notice Cancel a window redemption request
     */
    function cancelWindowRequest() external nonReentrant whenNotPaused {
        // Enforce mutual exclusivity: only allow during window mode
        RedemptionMode mode = currentMode();
        if (mode != RedemptionMode.WINDOW) {
            revert WrongMode(uint8(RedemptionMode.WINDOW), uint8(mode));
        }

        // Window module will return shares directly to user
        windowRedemption.cancelRequestFor(msg.sender);
    }

    /**
     * @notice Claim payout from a settled window
     * @param windowId The window ID to claim from
     */
    function claimWindowPayout(uint256 windowId) external nonReentrant whenNotPaused {
        if (!kyc.isKYCApproved(msg.sender)) revert KYCRequired();

        // Window module will handle payouts directly to user
        windowRedemption.claimFor(windowId, msg.sender);
    }

    /**
     * @notice Get user's window request
     * @param windowId Window ID
     * @param user User address
     * @return shares Amount of shares requested
     * @return claimed Amount already claimed
     */
    function getWindowRequest(uint256 windowId, address user)
        external
        view
        returns (uint256 shares, uint256 claimed)
    {
        IWindowRedemption.UserRequest memory request =
            windowRedemption.getUserRequest(windowId, user);
        return (request.shares, request.claimed);
    }

    // ============ Admin Functions ============

    /**
     * @notice Update instant redemption module
     * @param _instantRedemption New instant redemption module address
     */
    function setInstantRedemption(address _instantRedemption) external restricted {
        if (_instantRedemption == address(0)) revert InvalidModule();

        // Validate interface by calling a view function
        try IInstantRedemption(_instantRedemption).paused() returns (bool) {
            // Interface is valid
        } catch {
            revert InvalidModule();
        }

        instantRedemption = IInstantRedemption(_instantRedemption);
        emit InstantRedemptionSet(_instantRedemption);
    }

    /**
     * @notice Update window redemption module
     * @param _windowRedemption New window redemption module address
     */
    function setWindowRedemption(address _windowRedemption) external restricted {
        if (_windowRedemption == address(0)) revert InvalidModule();

        // Validate interface by calling a view function
        try IWindowRedemption(_windowRedemption).isWindowOpen() returns (bool) {
            // Interface is valid
        } catch {
            revert InvalidModule();
        }

        windowRedemption = IWindowRedemption(_windowRedemption);
        emit WindowRedemptionSet(_windowRedemption);
    }

    /**
     * @notice Pause all redemptions
     */
    function pause() external restricted {
        _pause();
    }

    /**
     * @notice Unpause all redemptions
     */
    function unpause() external restricted {
        _unpause();
    }

    // ============ View Functions ============

    /**
     * @notice Get current redemption mode
     * @dev Rules:
     * - Gateway-level pause overrides and returns `NONE`.
     * - Window has precedence from opening through settlement (including closed-but-unsettled).
     * - Instant is available only when no window is open and the current window is settled.
     * - If the selected module is paused, returns `NONE`.
     * @return Current mode (NONE=0, INSTANT=1, WINDOW=2)
     */
    function currentMode() public view returns (RedemptionMode) {
        // Gateway-level pause overrides everything
        if (paused()) return RedemptionMode.NONE;

        // Window takes priority while open OR until it is settled
        // This enforces mutual exclusivity from window open through settlement.
        if (windowRedemption.isWindowOpen()) {
            return windowRedemption.paused() ? RedemptionMode.NONE : RedemptionMode.WINDOW;
        }

        // If a window was opened and is not yet settled, remain in WINDOW mode
        {
            uint256 id = windowRedemption.currentWindowId();
            IWindowRedemption.Window memory w = windowRedemption.getWindow(id);
            if (w.openTime != 0 && !w.isSettled) {
                return windowRedemption.paused() ? RedemptionMode.NONE : RedemptionMode.WINDOW;
            }
        }

        // Default to instant when no window is open
        return instantRedemption.paused() ? RedemptionMode.NONE : RedemptionMode.INSTANT;
    }

    /**
     * @notice Check if window is open for requests
     * @return isOpen Whether window is currently open
     */
    function isWindowOpen() external view returns (bool) {
        return windowRedemption.isWindowOpen();
    }

    /**
     * @notice Get current window ID
     * @return windowId Current window ID
     */
    function currentWindowId() external view returns (uint256) {
        return windowRedemption.currentWindowId();
    }

    /**
     * @notice Get current daily redemption stats
     * @return day Current day index
     * @return globalSpending Global spending for the day
     */
    function getDailyRedemptions() external view returns (uint256 day, uint256 globalSpending) {
        return instantRedemption.getDailyRedemptions();
    }

    /**
     * @notice Get user's instant redemption spending for today
     * @param user User address
     * @return spending User's spending for current day
     */
    function getUserDailySpending(address user) external view returns (uint256) {
        return instantRedemption.getUserDailySpending(user);
    }
}

// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.4.0) (access/manager/AccessManaged.sol)

pragma solidity ^0.8.20;

import {AuthorityUtils} from "./AuthorityUtils.sol";
import {IAccessManager} from "./IAccessManager.sol";
import {IAccessManaged} from "./IAccessManaged.sol";
import {Context} from "../../utils/Context.sol";

/**
 * @dev This contract module makes available a {restricted} modifier. Functions decorated with this modifier will be
 * permissioned according to an "authority": a contract like {AccessManager} that follows the {IAuthority} interface,
 * implementing a policy that allows certain callers to access certain functions.
 *
 * IMPORTANT: The `restricted` modifier should never be used on `internal` functions, judiciously used in `public`
 * functions, and ideally only used in `external` functions. See {restricted}.
 */
abstract contract AccessManaged is Context, IAccessManaged {
    address private _authority;

    bool private _consumingSchedule;

    /**
     * @dev Initializes the contract connected to an initial authority.
     */
    constructor(address initialAuthority) {
        _setAuthority(initialAuthority);
    }

    /**
     * @dev Restricts access to a function as defined by the connected Authority for this contract and the
     * caller and selector of the function that entered the contract.
     *
     * [IMPORTANT]
     * ====
     * In general, this modifier should only be used on `external` functions. It is okay to use it on `public`
     * functions that are used as external entry points and are not called internally. Unless you know what you're
     * doing, it should never be used on `internal` functions. Failure to follow these rules can have critical security
     * implications! This is because the permissions are determined by the function that entered the contract, i.e. the
     * function at the bottom of the call stack, and not the function where the modifier is visible in the source code.
     * ====
     *
     * [WARNING]
     * ====
     * Avoid adding this modifier to the https://docs.soliditylang.org/en/v0.8.20/contracts.html#receive-ether-function[`receive()`]
     * function or the https://docs.soliditylang.org/en/v0.8.20/contracts.html#fallback-function[`fallback()`]. These
     * functions are the only execution paths where a function selector cannot be unambiguously determined from the calldata
     * since the selector defaults to `0x00000000` in the `receive()` function and similarly in the `fallback()` function
     * if no calldata is provided. (See {_checkCanCall}).
     *
     * The `receive()` function will always panic whereas the `fallback()` may panic depending on the calldata length.
     * ====
     */
    modifier restricted() {
        _checkCanCall(_msgSender(), _msgData());
        _;
    }

    /// @inheritdoc IAccessManaged
    function authority() public view virtual returns (address) {
        return _authority;
    }

    /// @inheritdoc IAccessManaged
    function setAuthority(address newAuthority) public virtual {
        address caller = _msgSender();
        if (caller != authority()) {
            revert AccessManagedUnauthorized(caller);
        }
        if (newAuthority.code.length == 0) {
            revert AccessManagedInvalidAuthority(newAuthority);
        }
        _setAuthority(newAuthority);
    }

    /// @inheritdoc IAccessManaged
    function isConsumingScheduledOp() public view returns (bytes4) {
        return _consumingSchedule ? this.isConsumingScheduledOp.selector : bytes4(0);
    }

    /**
     * @dev Transfers control to a new authority. Internal function with no access restriction. Allows bypassing the
     * permissions set by the current authority.
     */
    function _setAuthority(address newAuthority) internal virtual {
        _authority = newAuthority;
        emit AuthorityUpdated(newAuthority);
    }

    /**
     * @dev Reverts if the caller is not allowed to call the function identified by a selector. Panics if the calldata
     * is less than 4 bytes long.
     */
    function _checkCanCall(address caller, bytes calldata data) internal virtual {
        (bool immediate, uint32 delay) = AuthorityUtils.canCallWithDelay(
            authority(),
            caller,
            address(this),
            bytes4(data[0:4])
        );
        if (!immediate) {
            if (delay > 0) {
                _consumingSchedule = true;
                IAccessManager(authority()).consumeScheduledOp(caller, data);
                _consumingSchedule = false;
            } else {
                revert AccessManagedUnauthorized(caller);
            }
        }
    }
}

// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.1.0) (utils/ReentrancyGuard.sol)

pragma solidity ^0.8.20;

/**
 * @dev Contract module that helps prevent reentrant calls to a function.
 *
 * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier
 * available, which can be applied to functions to make sure there are no nested
 * (reentrant) calls to them.
 *
 * Note that because there is a single `nonReentrant` guard, functions marked as
 * `nonReentrant` may not call one another. This can be worked around by making
 * those functions `private`, and then adding `external` `nonReentrant` entry
 * points to them.
 *
 * TIP: If EIP-1153 (transient storage) is available on the chain you're deploying at,
 * consider using {ReentrancyGuardTransient} instead.
 *
 * TIP: If you would like to learn more about reentrancy and alternative ways
 * to protect against it, check out our blog post
 * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].
 */
abstract contract ReentrancyGuard {
    // Booleans are more expensive than uint256 or any type that takes up a full
    // word because each write operation emits an extra SLOAD to first read the
    // slot's contents, replace the bits taken up by the boolean, and then write
    // back. This is the compiler's defense against contract upgrades and
    // pointer aliasing, and it cannot be disabled.

    // The values being non-zero value makes deployment a bit more expensive,
    // but in exchange the refund on every call to nonReentrant will be lower in
    // amount. Since refunds are capped to a percentage of the total
    // transaction's gas, it is best to keep them low in cases like this one, to
    // increase the likelihood of the full refund coming into effect.
    uint256 private constant NOT_ENTERED = 1;
    uint256 private constant ENTERED = 2;

    uint256 private _status;

    /**
     * @dev Unauthorized reentrant call.
     */
    error ReentrancyGuardReentrantCall();

    constructor() {
        _status = NOT_ENTERED;
    }

    /**
     * @dev Prevents a contract from calling itself, directly or indirectly.
     * Calling a `nonReentrant` function from another `nonReentrant`
     * function is not supported. It is possible to prevent this from happening
     * by making the `nonReentrant` function external, and making it call a
     * `private` function that does the actual work.
     */
    modifier nonReentrant() {
        _nonReentrantBefore();
        _;
        _nonReentrantAfter();
    }

    function _nonReentrantBefore() private {
        // On the first call to nonReentrant, _status will be NOT_ENTERED
        if (_status == ENTERED) {
            revert ReentrancyGuardReentrantCall();
        }

        // Any calls to nonReentrant after this point will fail
        _status = ENTERED;
    }

    function _nonReentrantAfter() private {
        // By storing the original value once again, a refund is triggered (see
        // https://eips.ethereum.org/EIPS/eip-2200)
        _status = NOT_ENTERED;
    }

    /**
     * @dev Returns true if the reentrancy guard is currently set to "entered", which indicates there is a
     * `nonReentrant` function in the call stack.
     */
    function _reentrancyGuardEntered() internal view returns (bool) {
        return _status == ENTERED;
    }
}

// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.3.0) (utils/Pausable.sol)

pragma solidity ^0.8.20;

import {Context} from "../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 {
    bool private _paused;

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

    /**
     * @dev The operation failed because the contract is paused.
     */
    error EnforcedPause();

    /**
     * @dev The operation failed because the contract is not paused.
     */
    error ExpectedPause();

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

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

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

    /**
     * @dev Throws if the contract is paused.
     */
    function _requireNotPaused() internal view virtual {
        if (paused()) {
            revert EnforcedPause();
        }
    }

    /**
     * @dev Throws if the contract is not paused.
     */
    function _requirePaused() internal view virtual {
        if (!paused()) {
            revert ExpectedPause();
        }
    }

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

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

pragma solidity >=0.4.16;

/**
 * @dev Interface of the ERC-20 standard as defined in the ERC.
 */
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 value of tokens in existence.
     */
    function totalSupply() external view returns (uint256);

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

    /**
     * @dev Moves a `value` amount of 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 value) 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 a `value` amount of tokens 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 value) external returns (bool);

    /**
     * @dev Moves a `value` amount of tokens from `from` to `to` using the
     * allowance mechanism. `value` 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 value) external returns (bool);
}

// SPDX-License-Identifier: MIT
pragma solidity 0.8.30;

/**
 * @title IInstantRedemption
 * @notice Interface for the "instant" redemption module invoked by {RedemptionGateway}.
 * @dev The concrete implementation should:
 * - Enforce KYC via an external registry.
 * - Enforce daily/global/user limits and fee logic.
 * - Transfer/burn shares and pull/withdraw payout tokens from the vault.
 *
 * All values are denominated as noted by the implementation; payout amounts are in payout-token units.
 */
interface IInstantRedemption {
    // Functions called by gateway
    function redeemFor(address user, uint256 shares, uint256 minPayout) external;
    function previewRedemption(address user, uint256 shares)
        external
        view
        returns (uint256 grossPayout, uint256 fee, uint256 netPayout, bool available);

    // View functions for status
    function paused() external view returns (bool);
    function getDailyRedemptions() external view returns (uint256 day, uint256 globalSpending);
    function getUserDailySpending(address user) external view returns (uint256);
}

// SPDX-License-Identifier: MIT
pragma solidity 0.8.30;

/**
 * @title IWindowRedemption
 * @notice Interface for the batched/windowed redemption module coordinated by {RedemptionGateway}.
 * @dev Windows collect share requests, later settle pro‑rata using snapshot prices. Provides
 * view methods for UI and off-chain settlement monitoring.
 */
interface IWindowRedemption {
    // Struct needed for return values
    struct Window {
        uint256 openTime;
        uint256 submissionDeadline;
        uint256 closeTime;
        uint256 totalSharesRequested;
        uint256 totalValueRequested;
        uint256 fundingAmount;
        uint256 fulfillmentRate;
        uint256 totalClaimed;
        bool isSettled;
        bool isFinalized;
        address payoutToken;
        uint256 sharePriceAtClose;
        uint256 payoutPriceAtSettlement;
    }

    struct UserRequest {
        uint256 shares;
        uint256 claimed;
    }

    // Functions called by gateway
    function submitRequestFor(address user, uint256 shares) external;
    function adjustRequestFor(address user, uint256 newShares) external;
    function cancelRequestFor(address user) external;
    function claimFor(uint256 windowId, address user) external;

    // View functions for status
    function paused() external view returns (bool);
    function isWindowOpen() external view returns (bool);
    function currentWindowId() external view returns (uint256);
    function getWindow(uint256 windowId) external view returns (Window memory);
    function getUserRequest(uint256 windowId, address user)
        external
        view
        returns (UserRequest memory);
}

// SPDX-License-Identifier: MIT
pragma solidity 0.8.30;

/**
 * @title IShareToken
 * @notice Minimal ERC20-compatible interface expected by the protocol's deposit and redemption flows.
 * @dev Implemented by {ShareToken}. Functions are deliberately narrow to reduce coupling.
 * - All amounts use the token's own decimals.
 * - {mint} and {burn} are typically restricted via AccessManager roles in the implementation.
 */
interface IShareToken {
    function burn(address user, uint256 amount) external;
    function mint(address to, uint256 amount) external;
    function transferFrom(address from, address to, uint256 amount) external returns (bool);
    function transfer(address to, uint256 amount) external returns (bool);
    function balanceOf(address account) external view returns (uint256);
    function decimals() external view returns (uint8);
}

// SPDX-License-Identifier: MIT
pragma solidity 0.8.30;

interface IKYCRegistry {
    function isKYCApproved(address user) external view returns (bool);
}

File 10 of 14 : AuthorityUtils.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.3.0) (access/manager/AuthorityUtils.sol)

pragma solidity ^0.8.20;

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

library AuthorityUtils {
    /**
     * @dev Since `AccessManager` implements an extended IAuthority interface, invoking `canCall` with backwards compatibility
     * for the preexisting `IAuthority` interface requires special care to avoid reverting on insufficient return data.
     * This helper function takes care of invoking `canCall` in a backwards compatible way without reverting.
     */
    function canCallWithDelay(
        address authority,
        address caller,
        address target,
        bytes4 selector
    ) internal view returns (bool immediate, uint32 delay) {
        bytes memory data = abi.encodeCall(IAuthority.canCall, (caller, target, selector));

        assembly ("memory-safe") {
            mstore(0x00, 0x00)
            mstore(0x20, 0x00)

            if staticcall(gas(), authority, add(data, 0x20), mload(data), 0x00, 0x40) {
                immediate := mload(0x00)
                delay := mload(0x20)

                // If delay does not fit in a uint32, return 0 (no delay)
                // equivalent to: if gt(delay, 0xFFFFFFFF) { delay := 0 }
                delay := mul(delay, iszero(shr(32, delay)))
            }
        }
    }
}

// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.4.0) (access/manager/IAccessManager.sol)

pragma solidity >=0.8.4;

interface IAccessManager {
    /**
     * @dev A delayed operation was scheduled.
     */
    event OperationScheduled(
        bytes32 indexed operationId,
        uint32 indexed nonce,
        uint48 schedule,
        address caller,
        address target,
        bytes data
    );

    /**
     * @dev A scheduled operation was executed.
     */
    event OperationExecuted(bytes32 indexed operationId, uint32 indexed nonce);

    /**
     * @dev A scheduled operation was canceled.
     */
    event OperationCanceled(bytes32 indexed operationId, uint32 indexed nonce);

    /**
     * @dev Informational labelling for a roleId.
     */
    event RoleLabel(uint64 indexed roleId, string label);

    /**
     * @dev Emitted when `account` is granted `roleId`.
     *
     * NOTE: The meaning of the `since` argument depends on the `newMember` argument.
     * If the role is granted to a new member, the `since` argument indicates when the account becomes a member of the role,
     * otherwise it indicates the execution delay for this account and roleId is updated.
     */
    event RoleGranted(uint64 indexed roleId, address indexed account, uint32 delay, uint48 since, bool newMember);

    /**
     * @dev Emitted when `account` membership or `roleId` is revoked. Unlike granting, revoking is instantaneous.
     */
    event RoleRevoked(uint64 indexed roleId, address indexed account);

    /**
     * @dev Role acting as admin over a given `roleId` is updated.
     */
    event RoleAdminChanged(uint64 indexed roleId, uint64 indexed admin);

    /**
     * @dev Role acting as guardian over a given `roleId` is updated.
     */
    event RoleGuardianChanged(uint64 indexed roleId, uint64 indexed guardian);

    /**
     * @dev Grant delay for a given `roleId` will be updated to `delay` when `since` is reached.
     */
    event RoleGrantDelayChanged(uint64 indexed roleId, uint32 delay, uint48 since);

    /**
     * @dev Target mode is updated (true = closed, false = open).
     */
    event TargetClosed(address indexed target, bool closed);

    /**
     * @dev Role required to invoke `selector` on `target` is updated to `roleId`.
     */
    event TargetFunctionRoleUpdated(address indexed target, bytes4 selector, uint64 indexed roleId);

    /**
     * @dev Admin delay for a given `target` will be updated to `delay` when `since` is reached.
     */
    event TargetAdminDelayUpdated(address indexed target, uint32 delay, uint48 since);

    error AccessManagerAlreadyScheduled(bytes32 operationId);
    error AccessManagerNotScheduled(bytes32 operationId);
    error AccessManagerNotReady(bytes32 operationId);
    error AccessManagerExpired(bytes32 operationId);
    error AccessManagerLockedRole(uint64 roleId);
    error AccessManagerBadConfirmation();
    error AccessManagerUnauthorizedAccount(address msgsender, uint64 roleId);
    error AccessManagerUnauthorizedCall(address caller, address target, bytes4 selector);
    error AccessManagerUnauthorizedConsume(address target);
    error AccessManagerUnauthorizedCancel(address msgsender, address caller, address target, bytes4 selector);
    error AccessManagerInvalidInitialAdmin(address initialAdmin);

    /**
     * @dev Check if an address (`caller`) is authorised to call a given function on a given contract directly (with
     * no restriction). Additionally, it returns the delay needed to perform the call indirectly through the {schedule}
     * & {execute} workflow.
     *
     * This function is usually called by the targeted contract to control immediate execution of restricted functions.
     * Therefore we only return true if the call can be performed without any delay. If the call is subject to a
     * previously set delay (not zero), then the function should return false and the caller should schedule the operation
     * for future execution.
     *
     * If `allowed` is true, the delay can be disregarded and the operation can be immediately executed, otherwise
     * the operation can be executed if and only if delay is greater than 0.
     *
     * NOTE: The IAuthority interface does not include the `uint32` delay. This is an extension of that interface that
     * is backward compatible. Some contracts may thus ignore the second return argument. In that case they will fail
     * to identify the indirect workflow, and will consider calls that require a delay to be forbidden.
     *
     * NOTE: This function does not report the permissions of the admin functions in the manager itself. These are defined by the
     * {AccessManager} documentation.
     */
    function canCall(
        address caller,
        address target,
        bytes4 selector
    ) external view returns (bool allowed, uint32 delay);

    /**
     * @dev Expiration delay for scheduled proposals. Defaults to 1 week.
     *
     * IMPORTANT: Avoid overriding the expiration with 0. Otherwise every contract proposal will be expired immediately,
     * disabling any scheduling usage.
     */
    function expiration() external view returns (uint32);

    /**
     * @dev Minimum setback for all delay updates, with the exception of execution delays. It
     * can be increased without setback (and reset via {revokeRole} in the case event of an
     * accidental increase). Defaults to 5 days.
     */
    function minSetback() external view returns (uint32);

    /**
     * @dev Get whether the contract is closed disabling any access. Otherwise role permissions are applied.
     *
     * NOTE: When the manager itself is closed, admin functions are still accessible to avoid locking the contract.
     */
    function isTargetClosed(address target) external view returns (bool);

    /**
     * @dev Get the role required to call a function.
     */
    function getTargetFunctionRole(address target, bytes4 selector) external view returns (uint64);

    /**
     * @dev Get the admin delay for a target contract. Changes to contract configuration are subject to this delay.
     */
    function getTargetAdminDelay(address target) external view returns (uint32);

    /**
     * @dev Get the id of the role that acts as an admin for the given role.
     *
     * The admin permission is required to grant the role, revoke the role and update the execution delay to execute
     * an operation that is restricted to this role.
     */
    function getRoleAdmin(uint64 roleId) external view returns (uint64);

    /**
     * @dev Get the role that acts as a guardian for a given role.
     *
     * The guardian permission allows canceling operations that have been scheduled under the role.
     */
    function getRoleGuardian(uint64 roleId) external view returns (uint64);

    /**
     * @dev Get the role current grant delay.
     *
     * Its value may change at any point without an event emitted following a call to {setGrantDelay}.
     * Changes to this value, including effect timepoint are notified in advance by the {RoleGrantDelayChanged} event.
     */
    function getRoleGrantDelay(uint64 roleId) external view returns (uint32);

    /**
     * @dev Get the access details for a given account for a given role. These details include the timepoint at which
     * membership becomes active, and the delay applied to all operation by this user that requires this permission
     * level.
     *
     * Returns:
     * [0] Timestamp at which the account membership becomes valid. 0 means role is not granted.
     * [1] Current execution delay for the account.
     * [2] Pending execution delay for the account.
     * [3] Timestamp at which the pending execution delay will become active. 0 means no delay update is scheduled.
     */
    function getAccess(
        uint64 roleId,
        address account
    ) external view returns (uint48 since, uint32 currentDelay, uint32 pendingDelay, uint48 effect);

    /**
     * @dev Check if a given account currently has the permission level corresponding to a given role. Note that this
     * permission might be associated with an execution delay. {getAccess} can provide more details.
     */
    function hasRole(uint64 roleId, address account) external view returns (bool isMember, uint32 executionDelay);

    /**
     * @dev Give a label to a role, for improved role discoverability by UIs.
     *
     * Requirements:
     *
     * - the caller must be a global admin
     *
     * Emits a {RoleLabel} event.
     */
    function labelRole(uint64 roleId, string calldata label) external;

    /**
     * @dev Add `account` to `roleId`, or change its execution delay.
     *
     * This gives the account the authorization to call any function that is restricted to this role. An optional
     * execution delay (in seconds) can be set. If that delay is non 0, the user is required to schedule any operation
     * that is restricted to members of this role. The user will only be able to execute the operation after the delay has
     * passed, before it has expired. During this period, admin and guardians can cancel the operation (see {cancel}).
     *
     * If the account has already been granted this role, the execution delay will be updated. This update is not
     * immediate and follows the delay rules. For example, if a user currently has a delay of 3 hours, and this is
     * called to reduce that delay to 1 hour, the new delay will take some time to take effect, enforcing that any
     * operation executed in the 3 hours that follows this update was indeed scheduled before this update.
     *
     * Requirements:
     *
     * - the caller must be an admin for the role (see {getRoleAdmin})
     * - granted role must not be the `PUBLIC_ROLE`
     *
     * Emits a {RoleGranted} event.
     */
    function grantRole(uint64 roleId, address account, uint32 executionDelay) external;

    /**
     * @dev Remove an account from a role, with immediate effect. If the account does not have the role, this call has
     * no effect.
     *
     * Requirements:
     *
     * - the caller must be an admin for the role (see {getRoleAdmin})
     * - revoked role must not be the `PUBLIC_ROLE`
     *
     * Emits a {RoleRevoked} event if the account had the role.
     */
    function revokeRole(uint64 roleId, address account) external;

    /**
     * @dev Renounce role permissions for the calling account with immediate effect. If the sender is not in
     * the role this call has no effect.
     *
     * Requirements:
     *
     * - the caller must be `callerConfirmation`.
     *
     * Emits a {RoleRevoked} event if the account had the role.
     */
    function renounceRole(uint64 roleId, address callerConfirmation) external;

    /**
     * @dev Change admin role for a given role.
     *
     * Requirements:
     *
     * - the caller must be a global admin
     *
     * Emits a {RoleAdminChanged} event
     */
    function setRoleAdmin(uint64 roleId, uint64 admin) external;

    /**
     * @dev Change guardian role for a given role.
     *
     * Requirements:
     *
     * - the caller must be a global admin
     *
     * Emits a {RoleGuardianChanged} event
     */
    function setRoleGuardian(uint64 roleId, uint64 guardian) external;

    /**
     * @dev Update the delay for granting a `roleId`.
     *
     * Requirements:
     *
     * - the caller must be a global admin
     *
     * Emits a {RoleGrantDelayChanged} event.
     */
    function setGrantDelay(uint64 roleId, uint32 newDelay) external;

    /**
     * @dev Set the role required to call functions identified by the `selectors` in the `target` contract.
     *
     * Requirements:
     *
     * - the caller must be a global admin
     *
     * Emits a {TargetFunctionRoleUpdated} event per selector.
     */
    function setTargetFunctionRole(address target, bytes4[] calldata selectors, uint64 roleId) external;

    /**
     * @dev Set the delay for changing the configuration of a given target contract.
     *
     * Requirements:
     *
     * - the caller must be a global admin
     *
     * Emits a {TargetAdminDelayUpdated} event.
     */
    function setTargetAdminDelay(address target, uint32 newDelay) external;

    /**
     * @dev Set the closed flag for a contract.
     *
     * Closing the manager itself won't disable access to admin methods to avoid locking the contract.
     *
     * Requirements:
     *
     * - the caller must be a global admin
     *
     * Emits a {TargetClosed} event.
     */
    function setTargetClosed(address target, bool closed) external;

    /**
     * @dev Return the timepoint at which a scheduled operation will be ready for execution. This returns 0 if the
     * operation is not yet scheduled, has expired, was executed, or was canceled.
     */
    function getSchedule(bytes32 id) external view returns (uint48);

    /**
     * @dev Return the nonce for the latest scheduled operation with a given id. Returns 0 if the operation has never
     * been scheduled.
     */
    function getNonce(bytes32 id) external view returns (uint32);

    /**
     * @dev Schedule a delayed operation for future execution, and return the operation identifier. It is possible to
     * choose the timestamp at which the operation becomes executable as long as it satisfies the execution delays
     * required for the caller. The special value zero will automatically set the earliest possible time.
     *
     * Returns the `operationId` that was scheduled. Since this value is a hash of the parameters, it can reoccur when
     * the same parameters are used; if this is relevant, the returned `nonce` can be used to uniquely identify this
     * scheduled operation from other occurrences of the same `operationId` in invocations of {execute} and {cancel}.
     *
     * Emits a {OperationScheduled} event.
     *
     * NOTE: It is not possible to concurrently schedule more than one operation with the same `target` and `data`. If
     * this is necessary, a random byte can be appended to `data` to act as a salt that will be ignored by the target
     * contract if it is using standard Solidity ABI encoding.
     */
    function schedule(
        address target,
        bytes calldata data,
        uint48 when
    ) external returns (bytes32 operationId, uint32 nonce);

    /**
     * @dev Execute a function that is delay restricted, provided it was properly scheduled beforehand, or the
     * execution delay is 0.
     *
     * Returns the nonce that identifies the previously scheduled operation that is executed, or 0 if the
     * operation wasn't previously scheduled (if the caller doesn't have an execution delay).
     *
     * Emits an {OperationExecuted} event only if the call was scheduled and delayed.
     */
    function execute(address target, bytes calldata data) external payable returns (uint32);

    /**
     * @dev Cancel a scheduled (delayed) operation. Returns the nonce that identifies the previously scheduled
     * operation that is cancelled.
     *
     * Requirements:
     *
     * - the caller must be the proposer, a guardian of the targeted function, or a global admin
     *
     * Emits a {OperationCanceled} event.
     */
    function cancel(address caller, address target, bytes calldata data) external returns (uint32);

    /**
     * @dev Consume a scheduled operation targeting the caller. If such an operation exists, mark it as consumed
     * (emit an {OperationExecuted} event and clean the state). Otherwise, throw an error.
     *
     * This is useful for contract that want to enforce that calls targeting them were scheduled on the manager,
     * with all the verifications that it implies.
     *
     * Emit a {OperationExecuted} event.
     */
    function consumeScheduledOp(address caller, bytes calldata data) external;

    /**
     * @dev Hashing function for delayed operations.
     */
    function hashOperation(address caller, address target, bytes calldata data) external view returns (bytes32);

    /**
     * @dev Changes the authority of a target managed by this manager instance.
     *
     * Requirements:
     *
     * - the caller must be a global admin
     */
    function updateAuthority(address target, address newAuthority) external;
}

// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.4.0) (access/manager/IAccessManaged.sol)

pragma solidity >=0.8.4;

interface IAccessManaged {
    /**
     * @dev Authority that manages this contract was updated.
     */
    event AuthorityUpdated(address authority);

    error AccessManagedUnauthorized(address caller);
    error AccessManagedRequiredDelay(address caller, uint32 delay);
    error AccessManagedInvalidAuthority(address authority);

    /**
     * @dev Returns the current authority.
     */
    function authority() external view returns (address);

    /**
     * @dev Transfers control to a new authority. The caller must be the current authority.
     */
    function setAuthority(address) external;

    /**
     * @dev Returns true only in the context of a delayed restricted call, at the moment that the scheduled operation is
     * being consumed. Prevents denial of service for delayed restricted calls in the case that the contract performs
     * attacker controlled calls.
     */
    function isConsumingScheduledOp() external view returns (bytes4);
}

// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.1) (utils/Context.sol)

pragma solidity ^0.8.20;

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

    function _contextSuffixLength() internal view virtual returns (uint256) {
        return 0;
    }
}

// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.4.0) (access/manager/IAuthority.sol)

pragma solidity >=0.4.16;

/**
 * @dev Standard interface for permissioning originally defined in Dappsys.
 */
interface IAuthority {
    /**
     * @dev Returns true if the caller can invoke on a target the function identified by a function selector.
     */
    function canCall(address caller, address target, bytes4 selector) external view returns (bool allowed);
}

Settings
{
  "remappings": [
    "@chainlink/=smart-contracts-public/lib/chainlink/",
    "@openzeppelin/contracts/=smart-contracts-public/lib/openzeppelin-contracts/contracts/",
    "@openzeppelin/contracts-upgradeable/=smart-contracts-public/lib/openzeppelin-contracts-upgradeable/contracts/",
    "forge-std/=smart-contracts-public/lib/forge-std/src/",
    "openzeppelin-foundry-upgrades/=lib/openzeppelin-foundry-upgrades/src/",
    "chainlink/=smart-contracts-public/lib/chainlink/",
    "erc4626-tests/=smart-contracts-public/lib/openzeppelin-contracts-upgradeable/lib/erc4626-tests/",
    "halmos-cheatcodes/=smart-contracts-public/lib/openzeppelin-contracts-upgradeable/lib/halmos-cheatcodes/src/",
    "openzeppelin-contracts-upgradeable/=smart-contracts-public/lib/openzeppelin-contracts-upgradeable/",
    "openzeppelin-contracts/=smart-contracts-public/lib/openzeppelin-contracts/"
  ],
  "optimizer": {
    "enabled": true,
    "runs": 500
  },
  "metadata": {
    "useLiteralContent": false,
    "bytecodeHash": "ipfs",
    "appendCBOR": true
  },
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "devdoc",
        "userdoc",
        "metadata",
        "abi"
      ]
    }
  },
  "evmVersion": "cancun",
  "viaIR": true
}

Contract Security Audit

Contract ABI

API
[{"inputs":[{"internalType":"address","name":"_accessManager","type":"address"},{"internalType":"address","name":"_instantRedemption","type":"address"},{"internalType":"address","name":"_windowRedemption","type":"address"},{"internalType":"address","name":"_shareToken","type":"address"},{"internalType":"address","name":"_kyc","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"address","name":"authority","type":"address"}],"name":"AccessManagedInvalidAuthority","type":"error"},{"inputs":[{"internalType":"address","name":"caller","type":"address"},{"internalType":"uint32","name":"delay","type":"uint32"}],"name":"AccessManagedRequiredDelay","type":"error"},{"inputs":[{"internalType":"address","name":"caller","type":"address"}],"name":"AccessManagedUnauthorized","type":"error"},{"inputs":[],"name":"EnforcedPause","type":"error"},{"inputs":[],"name":"ExpectedPause","type":"error"},{"inputs":[],"name":"InvalidAmount","type":"error"},{"inputs":[],"name":"InvalidModule","type":"error"},{"inputs":[],"name":"KYCRequired","type":"error"},{"inputs":[],"name":"ReentrancyGuardReentrantCall","type":"error"},{"inputs":[{"internalType":"uint8","name":"expected","type":"uint8"},{"internalType":"uint8","name":"actual","type":"uint8"}],"name":"WrongMode","type":"error"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"authority","type":"address"}],"name":"AuthorityUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"shares","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"payout","type":"uint256"}],"name":"InstantRedemptionRouted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"module","type":"address"}],"name":"InstantRedemptionSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Paused","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Unpaused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"address","name":"module","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"WindowRedemptionRouted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"module","type":"address"}],"name":"WindowRedemptionSet","type":"event"},{"inputs":[{"internalType":"uint256","name":"newShares","type":"uint256"}],"name":"adjustWindowRequest","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"authority","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"cancelWindowRequest","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"windowId","type":"uint256"}],"name":"claimWindowPayout","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"currentMode","outputs":[{"internalType":"enum RedemptionGateway.RedemptionMode","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"currentWindowId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getDailyRedemptions","outputs":[{"internalType":"uint256","name":"day","type":"uint256"},{"internalType":"uint256","name":"globalSpending","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"}],"name":"getUserDailySpending","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"windowId","type":"uint256"},{"internalType":"address","name":"user","type":"address"}],"name":"getWindowRequest","outputs":[{"internalType":"uint256","name":"shares","type":"uint256"},{"internalType":"uint256","name":"claimed","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"instantRedemption","outputs":[{"internalType":"contract IInstantRedemption","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isConsumingScheduledOp","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isWindowOpen","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"kyc","outputs":[{"internalType":"contract IKYCRegistry","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"},{"internalType":"uint256","name":"shares","type":"uint256"}],"name":"previewInstantRedemption","outputs":[{"internalType":"uint256","name":"grossPayout","type":"uint256"},{"internalType":"uint256","name":"fee","type":"uint256"},{"internalType":"uint256","name":"netPayout","type":"uint256"},{"internalType":"bool","name":"available","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"shares","type":"uint256"},{"internalType":"uint256","name":"minPayout","type":"uint256"}],"name":"redeemInstant","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newAuthority","type":"address"}],"name":"setAuthority","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_instantRedemption","type":"address"}],"name":"setInstantRedemption","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_windowRedemption","type":"address"}],"name":"setWindowRedemption","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"shareToken","outputs":[{"internalType":"contract IShareToken","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"shares","type":"uint256"}],"name":"submitWindowRequest","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"unpause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"windowRedemption","outputs":[{"internalType":"contract IWindowRedemption","name":"","type":"address"}],"stateMutability":"view","type":"function"}]

60c03461019757601f6117ea38819003918201601f19168301916001600160401b0383118484101761019b5780849260a09460405283398101031261019757610047816101af565b610053602083016101af565b91610060604082016101af565b6100786080610071606085016101af565b93016101af565b5f80546001600160a01b0319166001600160a01b0390951694851790556040518481529093907f2f658b440c35314f52658ea8a740e05b284cdc84dc9ae01e891f21b8933e7cad90602090a16001805515610188576001600160a01b03841615610188576001600160a01b0316908115610188576001600160a01b0316918215610188576001600160a01b03169283156101885760028054610100600160a81b03191660089290921b610100600160a81b0316919091179055600380546001600160a01b03191691909117905560805260a05260405161162690816101c48239608051816109f6015260a051818181610182015281816103660152818161065101528181610b0c0152610f180152f35b631bb2296560e31b5f5260045ffd5b5f80fd5b634e487b7160e01b5f52604160045260245ffd5b51906001600160a01b03821682036101975756fe6080806040526004361015610012575f80fd5b5f905f3560e01c90816330024fe91461103c5750806337038e9814610ec15780633a1526d014610e755780633f4ba83a14610e0b578063474fce9b14610de1578063492dea3a14610ccf5780634f55a22914610be157806356f7bae214610acf5780635c975abb14610aac57806364cec4d314610a1a5780636c9fa59e146109d65780637a9e5e4b1461092d5780638125092f146108ff578063837b152f146108d85780638456cb591461087b57806389748a03146107b55780638e26d1e6146106d25780638fb360371461067557806390d6b45f14610631578063bf7e214f1461060b578063d12c8e0a1461057e578063d5fecb1b146104d9578063de2c5cbb1461030c5763fbc3b80714610126575f80fd5b346103095760403660031901126103095760043560243561014561146e565b61014d61148e565b61015561116a565b60038110156102f557600181036102db57506040516373bed91960e11b81523360048201526020816024817f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03165afa9081156102d0578491610292575b501561028357811561027457826001600160a01b0360025460081c16803b156102705781809160646040518094819363b426b82560e01b83523360048401528960248401528860448401525af180156102655761024c575b505060405191825260208201527fa58dba63852b106a5b3bbc558fa3fbcfe606497cbc0af66837a83c3560ec622060403392a26001805580f35b816102569161113b565b61026157825f610212565b8280fd5b6040513d84823e3d90fd5b5080fd5b63162908e360e11b8352600483fd5b6320e155c960e21b8352600483fd5b90506020813d6020116102c8575b816102ad6020938361113b565b810103126102c4576102be9061115d565b5f6101ba565b8380fd5b3d91506102a0565b6040513d86823e3d90fd5b633f18e45160e21b8452600160045260ff16602452604483fd5b634e487b7160e01b84526021600452602484fd5b80fd5b50346103095760203660031901126103095760043561032961146e565b61033161148e565b61033961116a565b60038110156104c557600281036104ab57506040516373bed91960e11b81523360048201526020816024817f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03165afa9081156104a0578391610466575b501561045757801561044857816001600160a01b0360035416803b156102705760405163033f61b960e21b8152336004820152602481018490529082908290604490829084905af1801561026557610433575b50506001600160a01b0360035416906040519081527fc2c993c56272de3a5ff5c01d7394405e0b0031f1e06d3715e489b1a756728e7060203392a36001805580f35b8161043d9161113b565b61027057815f6103f1565b63162908e360e11b8252600482fd5b6320e155c960e21b8252600482fd5b90506020813d602011610498575b816104816020938361113b565b81010312610261576104929061115d565b5f61039e565b3d9150610474565b6040513d85823e3d90fd5b633f18e45160e21b8352600260045260ff16602452604482fd5b634e487b7160e01b83526021600452602483fd5b5034610309576020366003190112610309576104f3611125565b9060206001600160a01b0360248160025460081c1694604051958693849263d5fecb1b60e01b84521660048301525afa908115610572579061053b575b602090604051908152f35b506020813d60201161056a575b816105556020938361113b565b810103126105665760209051610530565b5f80fd5b3d9150610548565b604051903d90823e3d90fd5b503461030957806003193601126103095760049060206001600160a01b036003541660405193848092636896470560e11b82525afa9081156105725780916105ce575b6020826040519015158152f35b90506020823d602011610603575b816105e96020938361113b565b8101031261030957506105fd60209161115d565b5f6105c1565b3d91506105dc565b50346103095780600319360112610309576001600160a01b036020915416604051908152f35b503461030957806003193601126103095760206040516001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000168152f35b5034610309578060031936011261030957805460a01c60ff16156106ca57506020638fb3603760e01b5b6040517fffffffff000000000000000000000000000000000000000000000000000000009091168152f35b60209061069f565b5034610309576020366003190112610309576001600160a01b036106f4611125565b6106fe36336114a9565b1680156107a657604051636896470560e11b8152602081600481855afa908161076f575b5061073657631bb2296560e31b8252600482fd5b806001600160a01b031960035416176003557fd1254c81998c381f9dda669a2ec7b18d4ee1cff506e5b3a31d7b55aaa793072c8280a280f35b6020813d60201161079e575b816107886020938361113b565b810103126102c4576107999061115d565b610722565b3d915061077b565b631bb2296560e31b8252600482fd5b50346103095780600319360112610309576107ce61146e565b6107d661148e565b6107de61116a565b6003811015610867576002810361084d5750806001600160a01b0360035416803b1561084a57818091602460405180948193630d2485b160e01b83523360048401525af1801561026557610835575b506001805580f35b8161083f9161113b565b61030957805f61082d565b50fd5b633f18e45160e21b8252600260045260ff16602452604490fd5b634e487b7160e01b82526021600452602482fd5b503461030957806003193601126103095761089636336114a9565b61089e61148e565b600160ff1960025416176002557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a2586020604051338152a180f35b503461030957806003193601126103095760206001600160a01b0360035416604051908152f35b503461030957806003193601126103095761091861116a565b6040519060038110156104c557602092508152f35b503461030957602036600319011261030957610947611125565b9080546001600160a01b03811633036109c457823b156109a85760207f2f658b440c35314f52658ea8a740e05b284cdc84dc9ae01e891f21b8933e7cad916001600160a01b03851680916001600160a01b031916178455604051908152a180f35b506001600160a01b036024926361798f2f60e11b835216600452fd5b62d1953b60e31b825233600452602482fd5b503461030957806003193601126103095760206040516001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000168152f35b5034610309578060031936011261030957600460406001600160a01b0360025460081c168151928380926364cec4d360e01b82525afa80156102655782918391610a6f575b6040838382519182526020820152f35b9150506040813d604011610aa4575b81610a8b6040938361113b565b810103126102705760409150602081519101515f610a5f565b3d9150610a7e565b5034610309578060031936011261030957602060ff600254166040519015158152f35b503461030957602036600319011261030957610ae961146e565b610af161148e565b6040516373bed91960e11b81523360048201526020816024817f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03165afa908115610265578291610ba7575b5015610b9857806001600160a01b0360035416803b1561084a576040516210ee3f60e81b815260048035908201523360248201529082908290604490829084905af180156102655761083557506001805580f35b6320e155c960e21b8152600490fd5b90506020813d602011610bd9575b81610bc26020938361113b565b8101031261027057610bd39061115d565b5f610b44565b3d9150610bb5565b503461030957604036600319011261030957610c446080610c00611125565b6001600160a01b0360025460081c166040518080958194631b5f41c760e01b83526024359060048401602090939291936001600160a01b0360408201951681520152565b03915afa80156102655782918384918593610c78575b50608094506040519384526020840152604083015215156060820152f35b93505050506080813d608011610cc7575b81610c966080938361113b565b810103126102705760809150805190602081015191610cbc60606040840151930161115d565b90929190915f610c5a565b3d9150610c89565b503461030957602036600319011261030957610ce9611125565b610cf336336114a9565b6001600160a01b038116908115610dd257604051635c975abb60e01b8152602081600481865afa9081610d97575b50610d3557631bb2296560e31b8352600483fd5b74ffffffffffffffffffffffffffffffffffffffff006002549160081b169074ffffffffffffffffffffffffffffffffffffffff001916176002557fb01b538b187fa77f5f5708d9191bb3326a6f5fa4a734c9ac696fdd8283fc335b8280a280f35b6020813d602011610dca575b81610db06020938361113b565b81010312610dc657610dc19061115d565b610d21565b8480fd5b3d9150610da3565b631bb2296560e31b8352600483fd5b503461030957806003193601126103095760206001600160a01b0360025460081c16604051908152f35b5034610309578060031936011261030957610e2636336114a9565b60025460ff811615610e665760ff19166002557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa6020604051338152a180f35b638dfc202b60e01b8252600482fd5b503461030957806003193601126103095760049060206001600160a01b0360035416604051938480926303a1526d60e41b82525afa908115610572579061053b57602090604051908152f35b503461056657602036600319011261056657610edb61146e565b610ee361148e565b610eeb61116a565b6003811015611028576002810361100d57506040516373bed91960e11b81523360048201526020816024817f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03165afa908115610fb9575f91610fd3575b5015610fc4576001600160a01b0360035416803b1561056657604051637a0ecf8560e11b815233600480830191909152356024820152905f908290604490829084905af18015610fb957610fa657506001805580f35b610fb291505f9061113b565b5f5f61082d565b6040513d5f823e3d90fd5b6320e155c960e21b5f5260045ffd5b90506020813d602011611005575b81610fee6020938361113b565b8101031261056657610fff9061115d565b5f610f50565b3d9150610fe1565b60ff90633f18e45160e21b5f5260026004521660245260445ffd5b634e487b7160e01b5f52602160045260245ffd5b34610566576040366003190112610566576024356001600160a01b038116810361056657600354631f2263ad60e21b835260048035908401526001600160a01b03918216602484015260409183916044918391165afa8015610fb9575f906110b5575b8060206040925191015182519182526020820152f35b506040813d60401161111d575b816110cf6040938361113b565b81010312610566576040516040810181811067ffffffffffffffff821117611109576040926020918452805183520151602082015261109f565b634e487b7160e01b5f52604160045260245ffd5b3d91506110c2565b600435906001600160a01b038216820361056657565b90601f8019910116810190811067ffffffffffffffff82111761110957604052565b5190811515820361056657565b60025460ff8116611469576001600160a01b0360035416604051636896470560e11b8152602081600481855afa908115610fb9575f9161142f575b50611287576040516303a1526d60e41b8152602081600481855afa908115610fb9575f916113fd575b5060405190632ee70dc360e01b825260048201526101a081602481855afa908115610fb9575f91611307575b508051151590816112f9575b50611287575060206001600160a01b0391600460405180948193635c975abb60e01b835260081c165afa908115610fb9575f9161124d575b5015611248575f90565b600190565b90506020813d60201161127f575b816112686020938361113b565b81010312610566576112799061115d565b5f61123e565b3d915061125b565b604051635c975abb60e01b81529150602090829060049082905afa908115610fb9575f916112bf575b50156112ba575f90565b600290565b90506020813d6020116112f1575b816112da6020938361113b565b81010312610566576112eb9061115d565b5f6112b0565b3d91506112cd565b61010091500151155f611206565b90506101a0813d82116113f5575b816113236101a0938361113b565b8101031261056657604051906101a0820182811067ffffffffffffffff82111761110957604052805182526020810151602083015260408101516040830152606081015160608301526080810151608083015260a081015160a083015260c081015160c083015260e081015160e08301526113a1610100820161115d565b6101008301526113b4610120820161115d565b610120830152610140810151906001600160a01b0382168203610566576101809161014084015261016081015161016084015201516101808201525f6111fa565b3d9150611315565b90506020813d602011611427575b816114186020938361113b565b8101031261056657515f6111ce565b3d915061140b565b90506020813d602011611461575b8161144a6020938361113b565b810103126105665761145b9061115d565b5f6111a5565b3d915061143d565b505f90565b60026001541461147f576002600155565b633ee5aeb560e01b5f5260045ffd5b60ff6002541661149a57565b63d93c066560e01b5f5260045ffd5b905f915f54916001600160a01b0383169281600411610566575f5f9060405f8151966001600160a01b03602089019163b700961360e01b8352169788602482015230604482015263ffffffff60e01b83351660648201526064815261150f60848261113b565b828052826020525190895afa6115dd575b1561152e575b505050505050565b63ffffffff16156115cb5760ff60a01b1916600160a01b175f55823b15610566576064925f9283604051958680958194634a63ebf760e11b83526004830152604060248301528060448301528084848401378181018301849052601f01601f191681010301925af18015610fb9576115b8575b50805460ff60a01b191690555f8080808080611526565b6115c491505f9061113b565b5f5f6115a1565b8262d1953b60e31b5f5260045260245ffd5b50505f516020518060201c15029061152056fea26469706673582212203688778f391607f92a9f16d766501e16db5b92687525970da94b74067b7ccbef64736f6c634300081e00330000000000000000000000003f0da1c363e34802c6f12f9c27276dc0e6696fd8000000000000000000000000a31deebb3680a3007120e74bcbdf4df36f042a40000000000000000000000000b5930ad554f9da6783a3dd259a111e9d1bd85b750000000000000000000000005086bf358635b81d8c47c66d1c8b9e567db70c7200000000000000000000000082f1806aeab5ecb9a485eb041d5ed4940b123995

Deployed Bytecode

0x6080806040526004361015610012575f80fd5b5f905f3560e01c90816330024fe91461103c5750806337038e9814610ec15780633a1526d014610e755780633f4ba83a14610e0b578063474fce9b14610de1578063492dea3a14610ccf5780634f55a22914610be157806356f7bae214610acf5780635c975abb14610aac57806364cec4d314610a1a5780636c9fa59e146109d65780637a9e5e4b1461092d5780638125092f146108ff578063837b152f146108d85780638456cb591461087b57806389748a03146107b55780638e26d1e6146106d25780638fb360371461067557806390d6b45f14610631578063bf7e214f1461060b578063d12c8e0a1461057e578063d5fecb1b146104d9578063de2c5cbb1461030c5763fbc3b80714610126575f80fd5b346103095760403660031901126103095760043560243561014561146e565b61014d61148e565b61015561116a565b60038110156102f557600181036102db57506040516373bed91960e11b81523360048201526020816024817f00000000000000000000000082f1806aeab5ecb9a485eb041d5ed4940b1239956001600160a01b03165afa9081156102d0578491610292575b501561028357811561027457826001600160a01b0360025460081c16803b156102705781809160646040518094819363b426b82560e01b83523360048401528960248401528860448401525af180156102655761024c575b505060405191825260208201527fa58dba63852b106a5b3bbc558fa3fbcfe606497cbc0af66837a83c3560ec622060403392a26001805580f35b816102569161113b565b61026157825f610212565b8280fd5b6040513d84823e3d90fd5b5080fd5b63162908e360e11b8352600483fd5b6320e155c960e21b8352600483fd5b90506020813d6020116102c8575b816102ad6020938361113b565b810103126102c4576102be9061115d565b5f6101ba565b8380fd5b3d91506102a0565b6040513d86823e3d90fd5b633f18e45160e21b8452600160045260ff16602452604483fd5b634e487b7160e01b84526021600452602484fd5b80fd5b50346103095760203660031901126103095760043561032961146e565b61033161148e565b61033961116a565b60038110156104c557600281036104ab57506040516373bed91960e11b81523360048201526020816024817f00000000000000000000000082f1806aeab5ecb9a485eb041d5ed4940b1239956001600160a01b03165afa9081156104a0578391610466575b501561045757801561044857816001600160a01b0360035416803b156102705760405163033f61b960e21b8152336004820152602481018490529082908290604490829084905af1801561026557610433575b50506001600160a01b0360035416906040519081527fc2c993c56272de3a5ff5c01d7394405e0b0031f1e06d3715e489b1a756728e7060203392a36001805580f35b8161043d9161113b565b61027057815f6103f1565b63162908e360e11b8252600482fd5b6320e155c960e21b8252600482fd5b90506020813d602011610498575b816104816020938361113b565b81010312610261576104929061115d565b5f61039e565b3d9150610474565b6040513d85823e3d90fd5b633f18e45160e21b8352600260045260ff16602452604482fd5b634e487b7160e01b83526021600452602483fd5b5034610309576020366003190112610309576104f3611125565b9060206001600160a01b0360248160025460081c1694604051958693849263d5fecb1b60e01b84521660048301525afa908115610572579061053b575b602090604051908152f35b506020813d60201161056a575b816105556020938361113b565b810103126105665760209051610530565b5f80fd5b3d9150610548565b604051903d90823e3d90fd5b503461030957806003193601126103095760049060206001600160a01b036003541660405193848092636896470560e11b82525afa9081156105725780916105ce575b6020826040519015158152f35b90506020823d602011610603575b816105e96020938361113b565b8101031261030957506105fd60209161115d565b5f6105c1565b3d91506105dc565b50346103095780600319360112610309576001600160a01b036020915416604051908152f35b503461030957806003193601126103095760206040516001600160a01b037f00000000000000000000000082f1806aeab5ecb9a485eb041d5ed4940b123995168152f35b5034610309578060031936011261030957805460a01c60ff16156106ca57506020638fb3603760e01b5b6040517fffffffff000000000000000000000000000000000000000000000000000000009091168152f35b60209061069f565b5034610309576020366003190112610309576001600160a01b036106f4611125565b6106fe36336114a9565b1680156107a657604051636896470560e11b8152602081600481855afa908161076f575b5061073657631bb2296560e31b8252600482fd5b806001600160a01b031960035416176003557fd1254c81998c381f9dda669a2ec7b18d4ee1cff506e5b3a31d7b55aaa793072c8280a280f35b6020813d60201161079e575b816107886020938361113b565b810103126102c4576107999061115d565b610722565b3d915061077b565b631bb2296560e31b8252600482fd5b50346103095780600319360112610309576107ce61146e565b6107d661148e565b6107de61116a565b6003811015610867576002810361084d5750806001600160a01b0360035416803b1561084a57818091602460405180948193630d2485b160e01b83523360048401525af1801561026557610835575b506001805580f35b8161083f9161113b565b61030957805f61082d565b50fd5b633f18e45160e21b8252600260045260ff16602452604490fd5b634e487b7160e01b82526021600452602482fd5b503461030957806003193601126103095761089636336114a9565b61089e61148e565b600160ff1960025416176002557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a2586020604051338152a180f35b503461030957806003193601126103095760206001600160a01b0360035416604051908152f35b503461030957806003193601126103095761091861116a565b6040519060038110156104c557602092508152f35b503461030957602036600319011261030957610947611125565b9080546001600160a01b03811633036109c457823b156109a85760207f2f658b440c35314f52658ea8a740e05b284cdc84dc9ae01e891f21b8933e7cad916001600160a01b03851680916001600160a01b031916178455604051908152a180f35b506001600160a01b036024926361798f2f60e11b835216600452fd5b62d1953b60e31b825233600452602482fd5b503461030957806003193601126103095760206040516001600160a01b037f0000000000000000000000005086bf358635b81d8c47c66d1c8b9e567db70c72168152f35b5034610309578060031936011261030957600460406001600160a01b0360025460081c168151928380926364cec4d360e01b82525afa80156102655782918391610a6f575b6040838382519182526020820152f35b9150506040813d604011610aa4575b81610a8b6040938361113b565b810103126102705760409150602081519101515f610a5f565b3d9150610a7e565b5034610309578060031936011261030957602060ff600254166040519015158152f35b503461030957602036600319011261030957610ae961146e565b610af161148e565b6040516373bed91960e11b81523360048201526020816024817f00000000000000000000000082f1806aeab5ecb9a485eb041d5ed4940b1239956001600160a01b03165afa908115610265578291610ba7575b5015610b9857806001600160a01b0360035416803b1561084a576040516210ee3f60e81b815260048035908201523360248201529082908290604490829084905af180156102655761083557506001805580f35b6320e155c960e21b8152600490fd5b90506020813d602011610bd9575b81610bc26020938361113b565b8101031261027057610bd39061115d565b5f610b44565b3d9150610bb5565b503461030957604036600319011261030957610c446080610c00611125565b6001600160a01b0360025460081c166040518080958194631b5f41c760e01b83526024359060048401602090939291936001600160a01b0360408201951681520152565b03915afa80156102655782918384918593610c78575b50608094506040519384526020840152604083015215156060820152f35b93505050506080813d608011610cc7575b81610c966080938361113b565b810103126102705760809150805190602081015191610cbc60606040840151930161115d565b90929190915f610c5a565b3d9150610c89565b503461030957602036600319011261030957610ce9611125565b610cf336336114a9565b6001600160a01b038116908115610dd257604051635c975abb60e01b8152602081600481865afa9081610d97575b50610d3557631bb2296560e31b8352600483fd5b74ffffffffffffffffffffffffffffffffffffffff006002549160081b169074ffffffffffffffffffffffffffffffffffffffff001916176002557fb01b538b187fa77f5f5708d9191bb3326a6f5fa4a734c9ac696fdd8283fc335b8280a280f35b6020813d602011610dca575b81610db06020938361113b565b81010312610dc657610dc19061115d565b610d21565b8480fd5b3d9150610da3565b631bb2296560e31b8352600483fd5b503461030957806003193601126103095760206001600160a01b0360025460081c16604051908152f35b5034610309578060031936011261030957610e2636336114a9565b60025460ff811615610e665760ff19166002557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa6020604051338152a180f35b638dfc202b60e01b8252600482fd5b503461030957806003193601126103095760049060206001600160a01b0360035416604051938480926303a1526d60e41b82525afa908115610572579061053b57602090604051908152f35b503461056657602036600319011261056657610edb61146e565b610ee361148e565b610eeb61116a565b6003811015611028576002810361100d57506040516373bed91960e11b81523360048201526020816024817f00000000000000000000000082f1806aeab5ecb9a485eb041d5ed4940b1239956001600160a01b03165afa908115610fb9575f91610fd3575b5015610fc4576001600160a01b0360035416803b1561056657604051637a0ecf8560e11b815233600480830191909152356024820152905f908290604490829084905af18015610fb957610fa657506001805580f35b610fb291505f9061113b565b5f5f61082d565b6040513d5f823e3d90fd5b6320e155c960e21b5f5260045ffd5b90506020813d602011611005575b81610fee6020938361113b565b8101031261056657610fff9061115d565b5f610f50565b3d9150610fe1565b60ff90633f18e45160e21b5f5260026004521660245260445ffd5b634e487b7160e01b5f52602160045260245ffd5b34610566576040366003190112610566576024356001600160a01b038116810361056657600354631f2263ad60e21b835260048035908401526001600160a01b03918216602484015260409183916044918391165afa8015610fb9575f906110b5575b8060206040925191015182519182526020820152f35b506040813d60401161111d575b816110cf6040938361113b565b81010312610566576040516040810181811067ffffffffffffffff821117611109576040926020918452805183520151602082015261109f565b634e487b7160e01b5f52604160045260245ffd5b3d91506110c2565b600435906001600160a01b038216820361056657565b90601f8019910116810190811067ffffffffffffffff82111761110957604052565b5190811515820361056657565b60025460ff8116611469576001600160a01b0360035416604051636896470560e11b8152602081600481855afa908115610fb9575f9161142f575b50611287576040516303a1526d60e41b8152602081600481855afa908115610fb9575f916113fd575b5060405190632ee70dc360e01b825260048201526101a081602481855afa908115610fb9575f91611307575b508051151590816112f9575b50611287575060206001600160a01b0391600460405180948193635c975abb60e01b835260081c165afa908115610fb9575f9161124d575b5015611248575f90565b600190565b90506020813d60201161127f575b816112686020938361113b565b81010312610566576112799061115d565b5f61123e565b3d915061125b565b604051635c975abb60e01b81529150602090829060049082905afa908115610fb9575f916112bf575b50156112ba575f90565b600290565b90506020813d6020116112f1575b816112da6020938361113b565b81010312610566576112eb9061115d565b5f6112b0565b3d91506112cd565b61010091500151155f611206565b90506101a0813d82116113f5575b816113236101a0938361113b565b8101031261056657604051906101a0820182811067ffffffffffffffff82111761110957604052805182526020810151602083015260408101516040830152606081015160608301526080810151608083015260a081015160a083015260c081015160c083015260e081015160e08301526113a1610100820161115d565b6101008301526113b4610120820161115d565b610120830152610140810151906001600160a01b0382168203610566576101809161014084015261016081015161016084015201516101808201525f6111fa565b3d9150611315565b90506020813d602011611427575b816114186020938361113b565b8101031261056657515f6111ce565b3d915061140b565b90506020813d602011611461575b8161144a6020938361113b565b810103126105665761145b9061115d565b5f6111a5565b3d915061143d565b505f90565b60026001541461147f576002600155565b633ee5aeb560e01b5f5260045ffd5b60ff6002541661149a57565b63d93c066560e01b5f5260045ffd5b905f915f54916001600160a01b0383169281600411610566575f5f9060405f8151966001600160a01b03602089019163b700961360e01b8352169788602482015230604482015263ffffffff60e01b83351660648201526064815261150f60848261113b565b828052826020525190895afa6115dd575b1561152e575b505050505050565b63ffffffff16156115cb5760ff60a01b1916600160a01b175f55823b15610566576064925f9283604051958680958194634a63ebf760e11b83526004830152604060248301528060448301528084848401378181018301849052601f01601f191681010301925af18015610fb9576115b8575b50805460ff60a01b191690555f8080808080611526565b6115c491505f9061113b565b5f5f6115a1565b8262d1953b60e31b5f5260045260245ffd5b50505f516020518060201c15029061152056fea26469706673582212203688778f391607f92a9f16d766501e16db5b92687525970da94b74067b7ccbef64736f6c634300081e0033

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

0000000000000000000000003f0da1c363e34802c6f12f9c27276dc0e6696fd8000000000000000000000000a31deebb3680a3007120e74bcbdf4df36f042a40000000000000000000000000b5930ad554f9da6783a3dd259a111e9d1bd85b750000000000000000000000005086bf358635b81d8c47c66d1c8b9e567db70c7200000000000000000000000082f1806aeab5ecb9a485eb041d5ed4940b123995

-----Decoded View---------------
Arg [0] : _accessManager (address): 0x3f0DA1C363e34802C6f12F9C27276dC0e6696FD8
Arg [1] : _instantRedemption (address): 0xa31deEbb3680A3007120e74bCbDf4df36F042A40
Arg [2] : _windowRedemption (address): 0xb5930AD554F9DA6783A3DD259A111E9D1bD85b75
Arg [3] : _shareToken (address): 0x5086bf358635B81D8C47C66d1C8b9E567Db70c72
Arg [4] : _kyc (address): 0x82F1806AEab5Ecb9a485eb041d5Ed4940b123995

-----Encoded View---------------
5 Constructor Arguments found :
Arg [0] : 0000000000000000000000003f0da1c363e34802c6f12f9c27276dc0e6696fd8
Arg [1] : 000000000000000000000000a31deebb3680a3007120e74bcbdf4df36f042a40
Arg [2] : 000000000000000000000000b5930ad554f9da6783a3dd259a111e9d1bd85b75
Arg [3] : 0000000000000000000000005086bf358635b81d8c47c66d1c8b9e567db70c72
Arg [4] : 00000000000000000000000082f1806aeab5ecb9a485eb041d5ed4940b123995


Block Uncle Number Difficulty Gas Used Reward
View All Uncles
Loading...
Loading
Loading...
Loading
Loading...
Loading
[ Download: CSV Export  ]

A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.