Rebalancer

Description:

Multi-signature wallet contract requiring multiple confirmations for transaction execution.

Blockchain: Ethereum

Source Code: View Code On The Blockchain

Solidity Source Code:

{{
  "language": "Solidity",
  "sources": {
    "@openzeppelin/contracts/token/ERC20/extensions/IERC20Permit.sol": {
      "content": "// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/extensions/IERC20Permit.sol)

pragma solidity ^0.8.20;

/**
 * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in
 * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].
 *
 * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by
 * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't
 * need to send a transaction, and thus is not required to hold Ether at all.
 *
 * ==== Security Considerations
 *
 * There are two important considerations concerning the use of `permit`. The first is that a valid permit signature
 * expresses an allowance, and it should not be assumed to convey additional meaning. In particular, it should not be
 * considered as an intention to spend the allowance in any specific way. The second is that because permits have
 * built-in replay protection and can be submitted by anyone, they can be frontrun. A protocol that uses permits should
 * take this into consideration and allow a `permit` call to fail. Combining these two aspects, a pattern that may be
 * generally recommended is:
 *
 * ```solidity
 * function doThingWithPermit(..., uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s) public {
 *     try token.permit(msg.sender, address(this), value, deadline, v, r, s) {} catch {}
 *     doThing(..., value);
 * }
 *
 * function doThing(..., uint256 value) public {
 *     token.safeTransferFrom(msg.sender, address(this), value);
 *     ...
 * }
 * ```
 *
 * Observe that: 1) `msg.sender` is used as the owner, leaving no ambiguity as to the signer intent, and 2) the use of
 * `try/catch` allows the permit to fail and makes the code tolerant to frontrunning. (See also
 * {SafeERC20-safeTransferFrom}).
 *
 * Additionally, note that smart contract wallets (such as Argent or Safe) are not able to produce permit signatures, so
 * contracts should have entry points that don't rely on permit.
 */
interface IERC20Permit {
    /**
     * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,
     * given ``owner``'s signed approval.
     *
     * IMPORTANT: The same issues {IERC20-approve} has related to transaction
     * ordering also apply here.
     *
     * Emits an {Approval} event.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     * - `deadline` must be a timestamp in the future.
     * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`
     * over the EIP712-formatted function arguments.
     * - the signature must use ``owner``'s current nonce (see {nonces}).
     *
     * For more information on the signature format, see the
     * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP
     * section].
     *
     * CAUTION: See Security Considerations above.
     */
    function permit(
        address owner,
        address spender,
        uint256 value,
        uint256 deadline,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) external;

    /**
     * @dev Returns the current nonce for `owner`. This value must be
     * included whenever a signature is generated for {permit}.
     *
     * Every successful call to {permit} increases ``owner``'s nonce by one. This
     * prevents a signature from being used multiple times.
     */
    function nonces(address owner) external view returns (uint256);

    /**
     * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.
     */
    // solhint-disable-next-line func-name-mixedcase
    function DOMAIN_SEPARATOR() external view returns (bytes32);
}
"
    },
    "@openzeppelin/contracts/token/ERC20/IERC20.sol": {
      "content": "// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/IERC20.sol)

pragma solidity ^0.8.20;

/**
 * @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 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);
}
"
    },
    "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol": {
      "content": "// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/utils/SafeERC20.sol)

pragma solidity ^0.8.20;

import {IERC20} from "../IERC20.sol";
import {IERC20Permit} from "../extensions/IERC20Permit.sol";
import {Address} from "../../../utils/Address.sol";

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

    /**
     * @dev An operation with an ERC20 token failed.
     */
    error SafeERC20FailedOperation(address token);

    /**
     * @dev Indicates a failed `decreaseAllowance` request.
     */
    error SafeERC20FailedDecreaseAllowance(address spender, uint256 currentAllowance, uint256 requestedDecrease);

    /**
     * @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value,
     * non-reverting calls are assumed to be successful.
     */
    function safeTransfer(IERC20 token, address to, uint256 value) internal {
        _callOptionalReturn(token, abi.encodeCall(token.transfer, (to, value)));
    }

    /**
     * @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the
     * calling contract. If `token` returns no value, non-reverting calls are assumed to be successful.
     */
    function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {
        _callOptionalReturn(token, abi.encodeCall(token.transferFrom, (from, to, value)));
    }

    /**
     * @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value,
     * non-reverting calls are assumed to be successful.
     */
    function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {
        uint256 oldAllowance = token.allowance(address(this), spender);
        forceApprove(token, spender, oldAllowance + value);
    }

    /**
     * @dev Decrease the calling contract's allowance toward `spender` by `requestedDecrease`. If `token` returns no
     * value, non-reverting calls are assumed to be successful.
     */
    function safeDecreaseAllowance(IERC20 token, address spender, uint256 requestedDecrease) internal {
        unchecked {
            uint256 currentAllowance = token.allowance(address(this), spender);
            if (currentAllowance < requestedDecrease) {
                revert SafeERC20FailedDecreaseAllowance(spender, currentAllowance, requestedDecrease);
            }
            forceApprove(token, spender, currentAllowance - requestedDecrease);
        }
    }

    /**
     * @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value,
     * non-reverting calls are assumed to be successful. Meant to be used with tokens that require the approval
     * to be set to zero before setting it to a non-zero value, such as USDT.
     */
    function forceApprove(IERC20 token, address spender, uint256 value) internal {
        bytes memory approvalCall = abi.encodeCall(token.approve, (spender, value));

        if (!_callOptionalReturnBool(token, approvalCall)) {
            _callOptionalReturn(token, abi.encodeCall(token.approve, (spender, 0)));
            _callOptionalReturn(token, approvalCall);
        }
    }

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

        bytes memory returndata = address(token).functionCall(data);
        if (returndata.length != 0 && !abi.decode(returndata, (bool))) {
            revert SafeERC20FailedOperation(address(token));
        }
    }

    /**
     * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement
     * on the return value: the return value is optional (but if data is returned, it must not be false).
     * @param token The token targeted by the call.
     * @param data The call data (encoded using abi.encode or one of its variants).
     *
     * This is a variant of {_callOptionalReturn} that silents catches all reverts and returns a bool instead.
     */
    function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) {
        // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since
        // we're implementing it ourselves. We cannot use {Address-functionCall} here since this should return false
        // and not revert is the subcall reverts.

        (bool success, bytes memory returndata) = address(token).call(data);
        return success && (returndata.length == 0 || abi.decode(returndata, (bool))) && address(token).code.length > 0;
    }
}
"
    },
    "@openzeppelin/contracts/utils/Address.sol": {
      "content": "// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (utils/Address.sol)

pragma solidity ^0.8.20;

/**
 * @dev Collection of functions related to the address type
 */
library Address {
    /**
     * @dev The ETH balance of the account is not enough to perform the operation.
     */
    error AddressInsufficientBalance(address account);

    /**
     * @dev There's no code at `target` (it is not a contract).
     */
    error AddressEmptyCode(address target);

    /**
     * @dev A call to an address target failed. The target may have reverted.
     */
    error FailedInnerCall();

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

        (bool success, ) = recipient.call{value: amount}("");
        if (!success) {
            revert FailedInnerCall();
        }
    }

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

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but also transferring `value` wei to `target`.
     *
     * Requirements:
     *
     * - the calling contract must have an ETH balance of at least `value`.
     * - the called Solidity function must be `payable`.
     */
    function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {
        if (address(this).balance < value) {
            revert AddressInsufficientBalance(address(this));
        }
        (bool success, bytes memory returndata) = target.call{value: value}(data);
        return verifyCallResultFromTarget(target, success, returndata);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but performing a static call.
     */
    function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
        (bool success, bytes memory returndata) = target.staticcall(data);
        return verifyCallResultFromTarget(target, success, returndata);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but performing a delegate call.
     */
    function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
        (bool success, bytes memory returndata) = target.delegatecall(data);
        return verifyCallResultFromTarget(target, success, returndata);
    }

    /**
     * @dev Tool to verify that a low level call to smart-contract was successful, and reverts if the target
     * was not a contract or bubbling up the revert reason (falling back to {FailedInnerCall}) in case of an
     * unsuccessful call.
     */
    function verifyCallResultFromTarget(
        address target,
        bool success,
        bytes memory returndata
    ) internal view returns (bytes memory) {
        if (!success) {
            _revert(returndata);
        } else {
            // only check if target is a contract if the call was successful and the return data is empty
            // otherwise we already know that it was a contract
            if (returndata.length == 0 && target.code.length == 0) {
                revert AddressEmptyCode(target);
            }
            return returndata;
        }
    }

    /**
     * @dev Tool to verify that a low level call was successful, and reverts if it wasn't, either by bubbling the
     * revert reason or with a default {FailedInnerCall} error.
     */
    function verifyCallResult(bool success, bytes memory returndata) internal pure returns (bytes memory) {
        if (!success) {
            _revert(returndata);
        } else {
            return returndata;
        }
    }

    /**
     * @dev Reverts with returndata if present. Otherwise reverts with {FailedInnerCall}.
     */
    function _revert(bytes memory returndata) private pure {
        // Look for revert reason and bubble it up if present
        if (returndata.length > 0) {
            // The easiest way to bubble the revert reason is using memory via assembly
            /// @solidity memory-safe-assembly
            assembly {
                let returndata_size := mload(returndata)
                revert(add(32, returndata), returndata_size)
            }
        } else {
            revert FailedInnerCall();
        }
    }
}
"
    },
    "contracts/interfaces/IAave.sol": {
      "content": "// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.8.20;

/**
 * @title IAave
 * @author MetaLend
 * @notice Minimal interface for Aave lending pool
 * @dev This interface allows interaction with the Aave lending pool for supply and withdrawal of assets.
 */
interface IAave {
    /**
     * @notice Supplies an asset to the Aave lending pool
     * @param asset          The address of the asset to supply
     * @param amount         The amount of the asset to supply
     * @param onBehalfOf     The address that will receive the aTokens
     * @param referralCode   The referral code for the supply action
     */
    function supply(address asset, uint256 amount, address onBehalfOf, uint16 referralCode) external;

    /**
     * @notice Withdraws an asset from the Aave lending pool
     * @param asset    The address of the asset to withdraw
     * @param amount   The amount of the asset to withdraw, use type(uint256).max to withdraw all
     * @param to       The address that will receive the withdrawn asset
     * @return         The actual amount withdrawn
     */
    function withdraw(address asset, uint256 amount, address to) external returns (uint256);

    /**
     * @notice Claims all rewards for a user to the desired address, on all the assets of the pool,
     *  accumulating the pending rewards passed by the first input parameter. Rewards are received by the to address.
     * @param assets   The list of assets to check eligible distributions before claiming rewards (aToken or variableDebtToken addresses)
     * @param to       The address that will be receiving the rewards
     * @return rewardsList      The list of addresses of the reward tokens
     * @return claimedAmounts   The list that contains the claimed amount per reward, following the same order as rewardsList
     */
    function claimAllRewards(
        address[] calldata assets,
        address to
    ) external returns (address[] memory rewardsList, uint256[] memory claimedAmounts);
}
"
    },
    "contracts/interfaces/IEIP3009.sol": {
      "content": "// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.8.20;

/**
 * @title IEIP3009
 * @notice Interface for EIP-3009 compliant token contracts
 * @dev This interface allows for the transfer of tokens with a signed authorization.
 */
interface IEIP3009 {
    /**
     * @notice Receive a transfer with a signed authorization from the payer
     * @dev This has an additional check to ensure that the payee's address
     * matches the caller of this function to prevent front-running attacks.
     * @param from          Payer's address (Authorizer)
     * @param to            Payee's address
     * @param value         Amount to be transferred
     * @param validAfter    The time after which this is valid (unix time)
     * @param validBefore   The time before which this is valid (unix time)
     * @param nonce         Unique nonce
     * @param v             v of the signature
     * @param r             r of the signature
     * @param s             s of the signature
     */
    function receiveWithAuthorization(
        address from,
        address to,
        uint256 value,
        uint256 validAfter,
        uint256 validBefore,
        bytes32 nonce,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) external;
}
"
    },
    "contracts/interfaces/IUsdcCctp.sol": {
      "content": "// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.8.20;

/**
 * @title IUsdcCctp
 * @author MetaLend
 * @notice Minimal interface for USDC CCTP
 * @dev This interface allows interaction with the USDC CCTP contract for bridging USDC tokens.
 */
interface IUsdcCctp {
    /**
     * @notice Recieves USDC tokens from the CCTP contract
     * @dev Get attestation from the CCTP API
     * @param message       The message emitted by MessageSent event during depositForBurn
     * @param attestation   The attestation retrieved from the CCTP API
     */
    function receiveMessage(bytes calldata message, bytes calldata attestation) external;

    /**
     * @notice Deposits USDC tokens for burning and bridging to another domain
     * @param amount                 The amount of USDC to deposit
     * @param destinationDomain      The domain to which the USDC will be bridged
     * @param mintRecipient          The recipient address on the destination domain converted to bytes32
     * @param burnToken              The address of the USDC token contract
     * @param destinationCaller      The address of the caller on the destination domain converted to bytes32
     * @param maxFee                 The max fee paid for fast burn, specified in units of burnToken
     * @param minFinalityThreshold   The minimum finality threshold at which burn will be attested
     *  As per Circle docs, use 1000 for fast and 2000 for slow transfers
     */
    function depositForBurn(
        uint256 amount,
        uint32 destinationDomain,
        bytes32 mintRecipient,
        address burnToken,
        bytes32 destinationCaller,
        uint256 maxFee,
        uint32 minFinalityThreshold
    ) external;
}
"
    },
    "contracts/interfaces/IVault.sol": {
      "content": "// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.8.20;

/**
 * @title IVault
 * @author MetaLend
 * @notice Minimal interface for vaults.
 * @dev This interface allows interaction with the vaults for supply and withdrawal of assets and claiming of rewards.
 */
interface IVault {
    /**
     * @notice Mints vault shares to the receiver by depositing exactly amount of underlying tokens.
     * @dev most implementations will require pre-approval of the vault with the vault’s underlying asset token.
     * @param assets     The amount of underlying tokens to deposit.
     * @param receiver   The address that will receive the shares.
     * @return shares    The amount of shares minted to the receiver.
     */
    function deposit(uint256 assets, address receiver) external returns (uint256 shares);

    /**
     * @notice Used to withdraw specific amount of underlying tokens. `Asset-First Approach`
     * @param assets     The amount of underlying tokens to withdraw.
     * @param receiver   The address that will receive the underlying tokens.
     * @param owner      The address of the owner of the assets being withdrawn.
     * @return shares    The amount of shares burned from the owner.
     */
    function withdraw(uint256 assets, address receiver, address owner) external returns (uint256 shares);

    /**
     * @notice Used to redeem shares for underlying tokens. `Shares-First Approach`
     * @param shares     The amount of shares to redeem.
     * @param receiver   The address that will receive the underlying tokens.
     * @param owner      The address of the owner of the shares being redeemed.
     * @return assets    The amount of underlying tokens received by the receiver.
     */
    function redeem(uint256 shares, address receiver, address owner) external returns (uint256 assets);

    /**
     * @notice Claims rewards for the specified account.
     * @param account     The address to claim rewards for.
     * @param reward      The address of the reward token contract.
     * @param claimable   The overall claimable amount of token rewards.
     * @param proof       The Merkle proof array that verifies the claim's validity
     */
    function claim(address account, address reward, uint256 claimable, bytes32[] calldata proof) external returns (uint256 amount);

    /**
     * @notice Claims rewards for the specified accounts.
     * @param accounts    The addresses to claim rewards for.
     * @param rewards     The addresses of the reward token contracts.
     * @param claimable   The overall claimable amounts of token rewards.
     * @param proofs      The Merkle proof arrays that verify the claims' validity
     */
    function claim(
        address[] calldata accounts,
        address[] calldata rewards,
        uint256[] calldata claimable,
        bytes32[][] calldata proofs
    ) external;
}
"
    },
    "contracts/manager/access/IAccessControl.sol": {
      "content": "// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.8.20;

/**
 * @title IAccessControl
 * @author MetaLend
 * @notice Interface for access control mechanisms
 */
interface IAccessControl {
    /**
     * @notice Emitted when admin is changed
     * @param oldAdmin Previous admin address
     * @param newAdmin New admin address
     */
    event AdminChanged(address indexed oldAdmin, address indexed newAdmin);

    /**
     * @notice Emitted when operator is added
     * @param operator Operator address
     */
    event OperatorAdded(address indexed operator);

    /**
     * @notice Emitted when operator is removed
     * @param operator Operator address
     */
    event OperatorRemoved(address indexed operator);

    /// @notice Thrown when caller is not authorized
    error Unauthorized();

    /**
     * @notice Set admin address
     * @param newAdmin New admin address
     */
    function setAdmin(address newAdmin) external;

    /**
     * @notice Add operator
     * @param operator Operator address
     */
    function addOperator(address operator) external;

    /**
     * @notice Remove operator
     * @param operator Operator address
     */
    function removeOperator(address operator) external;

    /**
     * @notice Get the admin address
     * @return admin The admin address
     */
    function getAdmin() external view returns (address admin);

    /**
     * @notice Check if the address is an operator
     * @param operator Operator address
     * @return isOpr True if the address is an operator
     */
    function isOperator(address operator) external view returns (bool isOpr);
}
"
    },
    "contracts/manager/args/EIP3009Args.sol": {
      "content": "// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.8.20;

/**
 * @title EIP3009Args
 * @author MetaLend
 * @notice This struct is used to pass arguments for EIP-3009 authorization.
 */
struct EIP3009Args {
    /// @notice The amount of tokens to transfer.
    uint256 value;
    /// @notice After which timestamp the authorization is valid.
    uint256 validAfter;
    /// @notice Before which timestamp the authorization is valid.
    uint256 validBefore;
    /// @notice Unique nonce for the authorization.
    bytes32 nonce;
    /// @notice The signature of the authorization.
    bytes signature;
}
"
    },
    "contracts/manager/args/RebalancingArgs.sol": {
      "content": "// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.8.20;

import {PoolIdentifier} from "../pool/PoolIdentifier.sol";

/**
 * @title RebalancingArgs
 * @author MetaLend
 * @notice This struct is used to pass arguments related to a pool and its pool (vault) contract.
 * @dev It is used in rebalancing operations to specify the pool and pool contract.
 *  The `poolContract` is the address of the pool (vault) contract associated with the pool to interact with.
 *  This struct is typically used in conjunction with rebalancing operations to ensure that
 *  the correct pool and its associated contract are targeted for the operation.
 */
struct RebalancingArgs {
    /// @notice The identifier of the pool
    PoolIdentifier pool;
    /// @notice The address of the pool (vault) contract associated with the pool.
    address poolContract;
}
"
    },
    "contracts/manager/args/RebalancingConfigArgs.sol": {
      "content": "// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.8.20;

import {PoolIdentifier} from "../pool/PoolIdentifier.sol";

/**
 * @title RebalancingConfigArgs
 * @author MetaLend
 * @notice This struct is used to pass configurations related to rebalancing operations.
 * @dev Use this for validating rebalancing operations by specifying approved pools, pool contracts, and destination domains.
 *  The `approvedPools` is an array of `PoolIdentifier` that represents the pools that are approved for the operation.
 *  The `approvedPoolContracts` is an array of addresses representing the pool (vault) contracts that are approved for the operation.
 *  The `approvedDestinationDomains` is an array of `uint32` representing the domains that are approved for the operation.
 *  The `fundingCap` is a `uint256` that represents maximum configured spendable cap in USDC based on aTokens (AAVE)
 *  in user's wallet on Linea domain (11). This is a special usecase where funds are redirected to Linea domain (11) to top up the
 *  wallet for spending with a MetaMask card. In this case the funds leave the rebalancer and are transferred to the owner.
 *  The `signature` is a bytes array that contains the signature for the approved pools,
 *  pool contracts, destination domains and `fundingCap` (if applicable).
 *  This signature is created by signing the concatenated bytes of the approved pools, pool contracts, and destination domains.
 *  Additionally, the `fundingCap` is included in the signature if it is greater than zero.
 *  This struct is typically used in conjunction with rebalancing operations to ensure that the operation
 *  is valid and authorized for the specified pool, pool contract, destination domain and funding cap.
 *  The length of `approvedPools`, `approvedPoolContracts`, and `approvedDestinationDomains` must match.
 *  Each entry by index in `approvedPools`, `approvedPoolContracts`, and `approvedDestinationDomains`
 *  corresponds to the approved pool, pool contract, and destination domain respectively.
 */
struct RebalancingConfigArgs {
    /// @notice The list of approved pools for an operation
    PoolIdentifier[] approvedPools;
    /// @notice The list of all approved pool (vault) contracts for an operation.
    address[] approvedPoolContracts;
    /// @notice The list of all approved destination domains for an operation.
    /// @dev Even for same domain operations, this must be defined to ensure the signature is valid.
    uint32[] approvedDestinationDomains;
    /// @notice The maximum configured spendable cap in USDC based on aTokens (AAVE) in user's wallet on Linea domain (11).
    uint256 fundingCap;
    /// @notice The signature for the approved pools, pool contracts, and destination domains.
    /// @dev Created by signing the concatenated bytes of the approved pools, pool contracts, and destination domains.
    bytes signature;
}
"
    },
    "contracts/manager/IRebalancingManager.sol": {
      "content": "// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.8.20;

import {EIP3009Args} from "../manager/args/EIP3009Args.sol";
import {RebalancingArgs} from "../manager/args/RebalancingArgs.sol";
import {RebalancingConfigArgs} from "../manager/args/RebalancingConfigArgs.sol";
import {Operation} from "../manager/operation/Operation.sol";
import {PoolIdentifier} from "../manager/pool/PoolIdentifier.sol";
import {IRebalancingManagerCore} from "./IRebalancingManagerCore.sol";

/**
 * @title IRebalancingManager
 * @author MetaLend
 * @notice This interface defines the functions for the RebalancingManager contract.
 */
interface IRebalancingManager is IRebalancingManagerCore {
    /**
     * @notice Emitted when a deposit with authorization is made to the pool.
     * @param token        The address of the token being deposited.
     * @param onBehalfOf   The address on behalf of which the deposit is made.
     * @param amount       The amount of tokens deposited.
     */
    event DepositWithAuthorization(address indexed token, address indexed onBehalfOf, uint256 indexed amount);

    /**
     * @notice Emitted when a deposit is made to the pool.
     * @param token        The address of the token being deposited.
     * @param onBehalfOf   The address on behalf of which the deposit is made.
     * @param amount       The amount of tokens deposited.
     */
    event Deposit(address indexed token, address indexed onBehalfOf, uint256 indexed amount);

    /**
     * @notice Emitted when a rebalance is initiated from the source domain.
     * @param onBehalfOf          The address on behalf of which the rebalance is made.
     * @param destinationDomain   The destination domain for the rebalance.
     * @param pool                The pool identifier for the rebalance.
     * @param token               The address of the token being rebalanced.
     */
    event RebalanceSrc(address indexed onBehalfOf, uint32 indexed destinationDomain, PoolIdentifier indexed pool, address token);

    /**
     * @notice Emitted when a rebalance is initiated to the destination domain.
     * @param onBehalfOf   The address on behalf of which the rebalance is made.
     * @param pool         The pool identifier for the rebalance.
     * @param token        The address of the token being rebalanced.
     */
    event RebalanceDst(address indexed onBehalfOf, PoolIdentifier indexed pool, address token);

    /**
     * @notice Emitted when Rebalancer contract is deployed.
     * @param owner        The address of the owner of the Rebalancer contract.
     * @param rebalancer   The address of the deployed Rebalancer contract.
     */
    event RebalancerDeployed(address indexed owner, address indexed rebalancer);

    /**
     * @notice Emitted when pool contract is updated to a specific pool and token.
     * @param destinationDomain   The domain supporting the pool contract
     * @param poolContract        The address of the pool contract being updated.
     * @param pool                The pool identifier for which the contract is being updated.
     * @param token               The address of the token associated with the pool.
     * @param supported           Boolean indicating whether the pool contract is supported or not.
     */
    event PoolContractUpdated(uint32 destinationDomain, address indexed poolContract, PoolIdentifier pool, address token, bool supported);

    /**
     * @notice Emitted when a rebalancer's last rebalance timestamp is updated.
     * @param rebalancer               The address of the rebalancer.
     * @param token                    The address of the token for which the timestamp is updated.
     * @param lastRebalanceTimestamp   The last rebalance timestamp.
     */
    event RebalancerLastRebalanceTimestampUpdated(
        address indexed rebalancer,
        address indexed token,
        uint256 indexed lastRebalanceTimestamp
    );

    /**
     * @notice Emitted when the implementation address of the rebalancer contract is updated.
     * @param rebalancerImplementation The address of the new rebalancer implementation contract.
     */
    event RebalancerImplementationUpdated(address indexed rebalancerImplementation);

    /**
     * @notice Emitted when the rebalance fee percent is updated.
     * @param rebalanceFeePercent The new rebalance fee percent.
     */
    event RebalanceFeePercentUpdated(uint256 indexed rebalanceFeePercent);

    /// @notice Thrown when Rebalancer contract is not found.
    error RebalancerNotFound(address owner);

    /// @notice Thrown when pool contract is not supported.
    error PoolContractNotSupported(address poolContract);

    /// @notice Thrown when the destination domain is not supported.
    error DestinationDomainNotSupported(uint32 destinationDomain);

    /// @notice Thrown when the signature is invalid.
    error InvalidSignature(address signer, bytes signature);

    /// @notice Thrown when the deadline for the transaction has passed.
    error InvalidDeadline(uint256 deadline);

    /// @notice Thrown when signature is used already.
    error SignatureUsedAlready(bytes signature);

    /// @notice Thrown when the cooldown period for rebalancing has not passed.
    error RebalanceCooldownNotPassed(uint256 lastRebalanceTimestamp, uint256 rebalanceCooldown);

    /// @notice Thrown when the input length is invalid.
    error InvalidInputLength();

    /// @notice Thrown when the operation is not allowed.
    error InvalidOperation();

    /**
     * @notice Initializes the RebalancingManager contract.
     * @param admin_                      The address of the admin.
     * @param rebalancerImplementation_   The address of the rebalancer implementation contract.
     * @param tokenMessenger_             The address of the token messenger contract.
     * @param messageTransmitter_         The address of the message transmitter contract.
     * @param usdcToken_                  The address of the USDC token contract.
     * @param thisDestinationDomain_      The destination domain for this contract.
     * @param universalSigValidator_      The address of the universal signature validator contract.
     */
    function initialize(
        address admin_,
        address rebalancerImplementation_,
        address tokenMessenger_,
        address messageTransmitter_,
        address usdcToken_,
        uint32 thisDestinationDomain_,
        address universalSigValidator_
    ) external;

    /**
     * @notice Gets or deploys a Rebalancer contract for the specified owner. Then calls the rebalancer to deposit tokens to a yield.
     *  When destination domain is other than this domain, the deposit is made directly to bridge for rebalance.
     * @param token                   The address of the token being deposited. Currently only USDC is supported.
     * @param onBehalfOf              The address on behalf of which the deposit is made. Also the payer.
     * @param destinationDomain       The destination domain for the deposit.
     * @param tranferArgs             The transfer arguments for the EIP-3009 transfer. See `EIP3009Args` struct for details.
     * @param rebalancingArgs         The rebalancing arguments for the deposit. See `RebalancingArgs` struct for details.
     * @param rebalancingConfigArgs   The rebalancing configuration arguments. See `RebalancingConfigArgs` struct for details.
     */
    function depositWithAuthorization(
        address token,
        address onBehalfOf,
        uint32 destinationDomain,
        EIP3009Args calldata tranferArgs,
        RebalancingArgs calldata rebalancingArgs,
        RebalancingConfigArgs calldata rebalancingConfigArgs
    ) external;

    /**
     * @notice Gets or deploys a Rebalancer contract for the specified owner. Then calls the rebalancer to deposit tokens to a yield.
     *  When destination domain is other than this domain, the deposit is made directly to bridge for rebalance.
     * @dev The rebalancer contract must be pre-approved to spend the tokens on behalf of the owner.
     *  This is used for deposits with contract wallets. USDC token does not support EIP-6492 signature validation.
     *  That means contract wallets that are not deployed yet cannot have their signatures validated by USDC token.
     * @param token                   The address of the token being deposited. Currently only USDC is supported.
     * @param onBehalfOf              The address on behalf of which the deposit is made. Also the payer.
     * @param destinationDomain       The destination domain for the deposit.
     * @param rebalancingArgs         The rebalancing arguments for the deposit. See `RebalancingArgs` struct for details.
     * @param rebalancingConfigArgs   The rebalancing configuration arguments. See `RebalancingConfigArgs` struct for details.
     */
    function deposit(
        address token,
        address onBehalfOf,
        uint32 destinationDomain,
        RebalancingArgs calldata rebalancingArgs,
        RebalancingConfigArgs calldata rebalancingConfigArgs
    ) external;

    /**
     * @notice Gets a Rebalancer contract for the specified owner. Then calls the rebalancer to rebalance tokens from the source domain.
     * @dev In this case the Rebalancer must already exist.
     * @param onBehalfOf              The address on behalf of which the rebalance is made.
     * @param destinationDomain       The destination domain for the rebalance.
     * @param amount                  The amount of tokens being rebalanced. Use MAX_UINT256 for full amount.
     * @param rebalancingArgsFrom     The rebalancing arguments for the rebalance. See `RebalancingArgs` struct for details.
     * @param rebalancingArgsTo       The rebalancing arguments for the destination. See `RebalancingArgs` struct for details.
     * @param rebalancingConfigArgs   The rebalancing configuration arguments. See `RebalancingConfigArgs` struct for details.
     */
    function rebalanceUsdcSrc(
        address onBehalfOf,
        uint32 destinationDomain,
        uint256 amount,
        RebalancingArgs calldata rebalancingArgsFrom,
        RebalancingArgs calldata rebalancingArgsTo,
        RebalancingConfigArgs calldata rebalancingConfigArgs
    ) external;

    /**
     * @notice Gets or deploys a Rebalancer contract for the specified owner. Then calls the rebalancer to rebalance on destination domain.
     * @param onBehalfOf              The address on behalf of which the rebalance is made.
     * @param rebalancingArgs         The rebalancing arguments for the deposit. See `RebalancingArgs` struct for details.
     * @param rebalancingConfigArgs   The rebalancing configuration arguments. See `RebalancingConfigArgs` struct for details.
     * @param message                 The message emitted by MessageSent event during depositForBurn.
     * @param attestation             The attestation retrieved from the CCTP API.
     */
    function rebalanceUsdcDst(
        address onBehalfOf,
        RebalancingArgs calldata rebalancingArgs,
        RebalancingConfigArgs calldata rebalancingConfigArgs,
        bytes calldata message,
        bytes calldata attestation
    ) external;

    /**
     * @notice Gets a Rebalancer contract for the specified owner. Then calls the rebalancer to rebalance token on this domain.
     * @dev In this case the Rebalancer must already exist.
     * @param onBehalfOf              The address on behalf of which the rebalance is made.
     * @param rebalancingArgsFrom     The rebalancing arguments for the source pool. See `RebalancingArgs` struct for details.
     * @param rebalancingArgsTo       The rebalancing arguments for the destination pool. See `RebalancingArgs` struct for details.
     * @param rebalancingConfigArgs   The rebalancing configuration arguments. See `RebalancingConfigArgs` struct for details.
     */
    function rebalanceThisDomain(
        address onBehalfOf,
        address token,
        RebalancingArgs calldata rebalancingArgsFrom,
        RebalancingArgs calldata rebalancingArgsTo,
        RebalancingConfigArgs calldata rebalancingConfigArgs
    ) external;

    /**
     * @notice Gets a Rebalancer contract for the specified owner. Then calls the rebalancer to fund the owner tokens.
     * @dev In this case the Rebalancer must already exist. Can be called only on Linea domain (11).
     * @param onBehalfOf              The address on behalf of which the funding is made.
     * @param rebalancingConfigArgs   The rebalancing configuration arguments. See `RebalancingConfigArgs` struct for details.
     */
    function fundOwner(address onBehalfOf, RebalancingConfigArgs calldata rebalancingConfigArgs) external;

    /**
     * @notice Gets a Rebalancer contract for the specified owner. Then calls the rebalancer to withdraw tokens from specified pool.
     * @dev In this case the Rebalancer must already exist. Callable by either the owner or by operator on their behalf.
     * @param onBehalfOf     The address on behalf of which the withdrawal is made.
     * @param token          The address of the token being withdrawn.
     * @param pool           The pool identifier from which the tokens are withdrawn.
     * @param poolContract   The address of the pool contract from which the tokens are withdrawn.
     * @param amount         The amount of tokens withdrawn.
     * @param deadline       The timestamp before which the withdrawal is valid. Needed only when done by the operator.
     * @param signature      The signature for the authorization. Necessary only when done by the operator.
     */
    function withdrawFromPool(
        address onBehalfOf,
        address token,
        PoolIdentifier pool,
        address poolContract,
        uint256 amount,
        uint256 deadline,
        bytes calldata signature
    ) external;

    /**
     * @notice Claims rewards from Morpho vaults.
     * @dev Callable by only the owner.
     * @param rewardDistributor   The address of the reward distributor contract.
     * @param rewardToken         The address of the reward token contract.
     * @param claimable           The overall claimable amount of token rewards.
     * @param proof               The Merkle proof array that verifies the claim's validity.
     */
    function claimRewardsMorpho(address rewardDistributor, address rewardToken, uint256 claimable, bytes32[] calldata proof) external;

    /**
     * @notice Claims rewards. Rewards are from Morpho, Merkl, and any other similar reward distributor.
     * @dev Callable by only the owner.
     * @param rewardDistributor    The address of the reward distributor contracts.
     * @param rewardTokens         The addresses of the reward token contracts.
     * @param claimable            The overall claimable amounts of token rewards.
     * @param proofs               The Merkle proof arrays that verify the claims' validity.
     */
    function claimRewards(
        address rewardDistributor,
        address[] calldata rewardTokens,
        uint256[] calldata claimable,
        bytes32[][] calldata proofs
    ) external;

    /**
     * @notice Claims rewards from Aave lending pool.
     * @dev Callable by only the owner.
     * @param rewardsController   The address of the Aave rewards controller contract.
     * @param assets              The list of asset addresses to claim rewards for.
     */
    function claimRewardsAave(address rewardsController, address[] calldata assets) external;

    /**
     * @notice Updates the pool contract addresses to specified pools and associated tokens.
     * @dev This function is only callable by the admin.
     *  The length of `poolContracts`, `pools`, `tokens` and `supported` must be the same.
     * @param destinationDomain   The destination domain for which the pool contracts are being updated.
     * @param poolContracts       The addresses of the pool contracts to be updated.
     * @param pools               The pool identifiers corresponding to the pool contracts.
     * @param tokens              The addresses of the tokens for the pools.
     * @param supported           The boolean array indicating whether the pool contract is supported or not.
     */
    function updatePoolContract(
        uint32 destinationDomain,
        address[] calldata poolContracts,
        PoolIdentifier[] calldata pools,
        address[] calldata tokens,
        bool[] calldata supported
    ) external;

    /**
     * @notice Updates the implementation address of the rebalancer contract.
     * @dev This function is only callable by the admin.
     * @param rebalancerImplementation  The address of the new rebalancer implementation contract.
     */
    function updateRebalancerImplementation(address rebalancerImplementation) external;

    /**
     * @notice Updates the fees for operations on specified domains. Effectively supporting the domain.
     * @dev This function is only callable by the admin.
     *  The value must be a fractional human-readable fee with 3 decimal precision (e.g. `1` if fee = 0.001 tokens with denominator = 1000).
     *  The length of `domains`, `operations` and `fees` must be the same.
     * @param domains              The destination domains for which the fees are being updated.
     * @param operations           The operations for which the fees are being updated.
     * @param fees                 The new fees for the specified domains and operations
     *  > 0 if the operation on destination domain is supported, 0 if not.
     */
    function setDomainFeeForOperation(uint32[] calldata domains, Operation[] calldata operations, uint256[] calldata fees) external;

    /**
     * @notice Updates the rebalance fee percent.
     * @dev This function is only callable by the admin.
     * @param rebalanceFeePercent The new rebalance fee percent.
     */
    function setRebalanceFeePercent(uint256 rebalanceFeePercent) external;

    /**
     * @notice Sets the rebalance cooldown period.
     * @dev This function is only callable by the admin.
     * @param cooldown The new cooldown period for rebalancing in seconds.
     */
    function setRebalanceCooldown(uint256 cooldown) external;

    /**
     * @notice Gets the amount of rebalance fee for a given amount.
     * @dev Ignored on Linea domain.
     * @param amount The amount of tokens for which the rebalance fee is being calculated.
     * @return rebalanceFee The calculated rebalance fee for the specified amount.
     */
    function getRebalanceFee(uint256 amount) external view returns (uint256 rebalanceFee);

    /**
     * @notice Retrieves the transaction fee for operation on a specific destination domain.
     * @param destinationDomain   The destination domain for which the gas transaction fee is being queried.
     * @param token               The address of the token for which the gas transaction fee is being queried.
     * @param operation           The operation for which the gas transaction fee is being queried.
     * @param useThisDomain       Boolean indicating whether to use this domain's fee for same domain operations.
     *  In this case the destinationDomain is ignored.
     */
    function getDestinationDomainGasTransactionFeeForOperation(
        uint32 destinationDomain,
        address token,
        Operation operation,
        bool useThisDomain
    ) external view returns (uint256 gasTransactionFee);

    /**
     * @notice Retrieves the token messenger contract address.
     * @return tokenMessenger The address of the token messenger contract.
     */
    function getUsdcCctpTokenMessenger() external view returns (address tokenMessenger);

    /**
     * @notice Retrieves the message transmitter contract address.
     * @return messageTransmitter The address of the message transmitter contract.
     */
    function getUsdcCctpMessageTransmitter() external view returns (address messageTransmitter);

    /**
     * @notice Retrieves the USDC token contract address.
     * @return usdcToken The address of the USDC token contract.
     */
    function getUsdcToken() external view returns (address usdcToken);

    /**
     * @notice Retrieves the pool and token for given pool contract.
     * @param destinationDomain   The destination domain for which the pool contracts is queried.
     * @param poolContract        The address of the pool contract for which the pool and token are queried.
     * @param pool                The pool identifier for which the contract is being queried.
     * @param token               The address of the token associated with the pool contract being queried.
     * @return supported          True if the pool contract is supported, false otherwise.
     */
    function getPoolContractSupported(
        uint32 destinationDomain,
        address poolContract,
        PoolIdentifier pool,
        address token
    ) external view returns (bool supported);

    /**
     * @notice Checks if the current domain is Linea.
     * @return isLinea True if the current domain is Linea, false otherwise.
     */
    function isLineaDomain() external view returns (bool isLinea);

    /**
     * @notice Retrieves the Linea AAVE USDC aToken contract address.
     * @return aToken The address of the Linea AAVE USDC aToken contract.
     */
    function getLineaUsdcAaveToken() external pure returns (address aToken);
}
"
    },
    "contracts/manager/IRebalancingManagerCore.sol": {
      "content": "// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.8.20;

/**
 * @title IRebalancingManagerCore
 * @author MetaLend
 * @notice Core rebalancing manager interface to read rebalancer implementation
 */
interface IRebalancingManagerCore {
    /**
     * @notice Returns the address of the rebalancer implementation contract
     * @dev Use this with _implementation() in the proxy contract to get the implementation address
     * @return rebalancerImplementation The address of the rebalancer implementation contract
     */
    function getRebalancerImplementation() external view returns (address rebalancerImplementation);
}
"
    },
    "contracts/manager/operation/Operation.sol": {
      "content": "// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.8.20;

/**
 * @title Operation
 * @author MetaLend
 * @notice Enum representing operations.
 * @dev This enum is used to identify different supported operations in the system.
 */
enum Operation {
    DEPOSIT,
    WITHDRAW,
    REBALANCE_THIS_DOMAIN,
    REBALANCE_SRC_DOMAIN,
    REBALANCE_DST_DOMAIN,
    FUND_OWNER
}
"
    },
    "contracts/manager/pool/PoolIdentifier.sol": {
      "content": "// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.8.20;

/**
 * @title PoolIdentifier
 * @author MetaLend
 * @notice Enum representing different pool identifiers.
 * @dev This enum is used to identify different supported pools in the system.
 */
enum PoolIdentifier {
    AAVE_POOL,
    MORPHO_POOL,
    EULER_POOL
}
"
    },
    "contracts/rebalancer/IRebalancer.sol": {
      "content": "// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.8.20;

import {PoolIdentifier} from "../manager/pool/PoolIdentifier.sol";

/**
 * @title IRebalancer
 * @author MetaLend
 * @notice This interface defines the functions for the Rebalancer contract.
 */
interface IRebalancer {
    /**
     * @notice Emitted when the Rebalancer contract pays the rebalance fee.
     * @param token    The address of the token used to pay the rebalance fee.
     * @param owner    The address of the owner who pays the rebalance fee.
     * @param amount   The amount of tokens paid as the rebalance fee.
     */
    event PayRebalanceFee(address indexed token, address indexed owner, uint256 amount);

    /**
     * @notice Emitted when the Rebalancer contract funds the owner with tokens.
     * @param owner    The address of the owner who receives the tokens.
     * @param token    The address of the token transferred to the owner.
     * @param amount   The amount of tokens transferred to the owner.
     */
    event FundOwner(address indexed owner, address indexed token, uint256 amount);

    /**
     * @notice Emitted when deposit to the pool fails and the Rebalancer contract withdraws tokens to the owner.
     * @param token    The address of the token that failed to deposit.
     * @param amount   The amount of tokens that failed to deposit.
     */
    event OnDepositFailureWithdraw(address indexed token, uint256 amount);

    /// @notice Thrown when caller is not authorized
    error Unauthorized();

    /// @notice Thrown if there is not enough tokens to cover the gas transaction fee
    error InsufficientAmountForGasTransactionFee();

    /// @notice Thrown if there is not enough allowance for transferring tokens
    error ERC20InsufficientAllowance(address token);

    /// @notice Thrown if the funding cannot be completed
    error FundingUnavailable();

    /**
     * @notice Approves the pool and deposits the specified amount of tokens.
     * @dev This function is called by the RebalancingManager contract.
     * @param destinationDomain   The domain to which the tokens will be bridged. For same domain, use MAX_UINT32.
     * @param pool                The identifier of the pool to deposit into.
     * @param poolContract        The address of the pool contract to approve and deposit into.
     * @param token               The address of the token to deposit.
     * @param amount              The amount of tokens to deposit.
     * @param validAfter          The timestamp after which the approval is valid.
     * @param validBefore         The timestamp before which the approval is valid.
     * @param nonce               The nonce for the approval.
     * @param v                   v of approval signature
     * @param r                   r of approval signature
     * @param s                   s of approval signature
     */
    function approveAndDeposit(
        uint32 destinationDomain,
        PoolIdentifier pool,
        address poolContract,
        address token,
        uint256 amount,
        uint256 validAfter,
        uint256 validBefore,
        bytes32 nonce,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) external;

    /**
     * @notice Approves the pool and deposits the specified amount of tokens.
     * @dev This function is called by the RebalancingManager contract.
     *  This rebalancer must be pre-approved to spend the tokens.
     * @param destinationDomain   The domain to which the tokens will be bridged. For same domain, use MAX_UINT32.
     * @param pool                The identifier of the pool to deposit into.
     * @param poolContract        The address of the pool contract to approve and deposit into.
     * @param token               The address of the token to deposit.
     * @return amount             The amount of tokens deposited.
     */
    function approveAndDeposit(
        uint32 destinationDomain,
        PoolIdentifier pool,
        address poolContract,
        address token
    ) external returns (uint256 amount);

    /**
     * @notice Receives USDC tokens from bridge, approves the pool contract, and deposits the tokens.
     * @dev This function is called by the RebalancingManager contract.
     * @param pool          The identifier of the pool to deposit into.
     * @param poolContract  The address of the pool contract to approve and deposit into.
     * @param message       The message emitted by MessageSent event during depositForBurn.
     * @param attestation   The attestation retrieved from the CCTP API.
     */
    function receiveUsdcApproveAndDeposit(
        PoolIdentifier pool,
        address poolContract,
        bytes calldata message,
        bytes calldata attestation
    ) external;

    /**
     * @notice Withdraws USDC from pool and deposits it for burning on the specified destination domain.
     * @dev This function is called by the RebalancingManager contract.
     * @param amount              The amount of USDC to withdraw and deposit for burning.
     * @param pool                The identifier of the pool to withdraw from.
     * @param poolContract        The address of the pool contract to withdraw from.
     * @param destinationDomain   The domain to which the USDC will be bridged.
     */
    function withdrawAndDepositForBurnUsdc(uint256 amount, PoolIdentifier pool, address poolContract, uint32 destinationDomain) external;

    /**
     * @notice Withdraws tokens from the source pool and redeposits them into the destination pool on the same domain.
     * @dev This function is called by the RebalancingManager contract.
     * @param token              The address of the token to withdraw and deposit.
     * @param srcPool            The identifier of the source pool to withdraw from.
     * @param srcPoolContract    The address of the source pool contract to withdraw from.
     * @param dstPool            The identifier of the destination pool to deposit into.
     * @param dstPoolContract    The address of the destination pool contract to deposit into.
     */
    function withdrawAndRedeposit(
        address token,
        PoolIdentifier srcPool,
        address srcPoolContract,
        PoolIdentifier dstPool,
        address dstPoolContract
    ) external;

    /**
     * @notice Funds the owner with aTokens (AAVE).
     * @dev This function is called by the RebalancingManager contract.
     * @param fundingCap The maximum configured spendable cap in USDC based on aTokens (AAVE) in user's wallet on Linea domain (11).
     */
    function fundOwnerWithUsdcAaveToken(uint256 fundingCap) external;

    /**
     * @notice Withdraws the specified amount of tokens from pool and transfers them to the owner.
     * @dev This function is called by the RebalancingManager contract.
     *  If amount is MAX_UINT256, it withdraws all available tokens.
     * @param token          The address of the token to withdraw.
     * @param pool           The identifier of the pool to withdraw from.
     * @param poolContract   The address of the pool contract to withdraw from.
     * @param amount         The amount of tokens to withdraw.
     * @param payFee         Whether to pay the gas transaction fee. This depends if the tx is called on behalf of the owner or not.
     */
    function withdrawFromPoolToOwner(address token, PoolIdentifier pool, address poolContract, uint256 amount, bool payFee) external;

    /**
     * @notice Claims rewards from Morpho vaults.
     * @dev This function is called by the RebalancingManager contract.
     * @param rewardDistributor   The address of the reward dis

Tags:
ERC20, Multisig, Yield, Upgradeable, Multi-Signature, Factory|addr:0x95d3a0aec2daa913082ffb09b4fd34de89ab9ac0|verified:true|block:23520238|tx:0x0a8a3d458f787d7b38d720728ab39dcaa9e58cb5bf1ed571692af001466e59d3|first_check:1759779183

Submitted on: 2025-10-06 21:33:04

Comments

Log in to comment.

No comments yet.