RebalancingManager

Description:

Proxy contract enabling upgradeable smart contract patterns. Delegates calls to an implementation contract.

Blockchain: Ethereum

Source Code: View Code On The Blockchain

Solidity Source Code:

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

pragma solidity ^0.8.20;

/**
 * @dev This abstract contract provides a fallback function that delegates all calls to another contract using the EVM
 * instruction `delegatecall`. We refer to the second contract as the _implementation_ behind the proxy, and it has to
 * be specified by overriding the virtual {_implementation} function.
 *
 * Additionally, delegation to the implementation can be triggered manually through the {_fallback} function, or to a
 * different contract through the {_delegate} function.
 *
 * The success and return data of the delegated call will be returned back to the caller of the proxy.
 */
abstract contract Proxy {
    /**
     * @dev Delegates the current call to `implementation`.
     *
     * This function does not return to its internal call site, it will return directly to the external caller.
     */
    function _delegate(address implementation) internal virtual {
        assembly {
            // Copy msg.data. We take full control of memory in this inline assembly
            // block because it will not return to Solidity code. We overwrite the
            // Solidity scratch pad at memory position 0.
            calldatacopy(0, 0, calldatasize())

            // Call the implementation.
            // out and outsize are 0 because we don't know the size yet.
            let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0)

            // Copy the returned data.
            returndatacopy(0, 0, returndatasize())

            switch result
            // delegatecall returns 0 on error.
            case 0 {
                revert(0, returndatasize())
            }
            default {
                return(0, returndatasize())
            }
        }
    }

    /**
     * @dev This is a virtual function that should be overridden so it returns the address to which the fallback
     * function and {_fallback} should delegate.
     */
    function _implementation() internal view virtual returns (address);

    /**
     * @dev Delegates the current call to the address returned by `_implementation()`.
     *
     * This function does not return to its internal call site, it will return directly to the external caller.
     */
    function _fallback() internal virtual {
        _delegate(_implementation());
    }

    /**
     * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if no other
     * function in the contract matches the call data.
     */
    fallback() external payable virtual {
        _fallback();
    }
}
"
    },
    "@openzeppelin/contracts/utils/Create2.sol": {
      "content": "// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (utils/Create2.sol)

pragma solidity ^0.8.20;

/**
 * @dev Helper to make usage of the `CREATE2` EVM opcode easier and safer.
 * `CREATE2` can be used to compute in advance the address where a smart
 * contract will be deployed, which allows for interesting new mechanisms known
 * as 'counterfactual interactions'.
 *
 * See the https://eips.ethereum.org/EIPS/eip-1014#motivation[EIP] for more
 * information.
 */
library Create2 {
    /**
     * @dev Not enough balance for performing a CREATE2 deploy.
     */
    error Create2InsufficientBalance(uint256 balance, uint256 needed);

    /**
     * @dev There's no code to deploy.
     */
    error Create2EmptyBytecode();

    /**
     * @dev The deployment failed.
     */
    error Create2FailedDeployment();

    /**
     * @dev Deploys a contract using `CREATE2`. The address where the contract
     * will be deployed can be known in advance via {computeAddress}.
     *
     * The bytecode for a contract can be obtained from Solidity with
     * `type(contractName).creationCode`.
     *
     * Requirements:
     *
     * - `bytecode` must not be empty.
     * - `salt` must have not been used for `bytecode` already.
     * - the factory must have a balance of at least `amount`.
     * - if `amount` is non-zero, `bytecode` must have a `payable` constructor.
     */
    function deploy(uint256 amount, bytes32 salt, bytes memory bytecode) internal returns (address addr) {
        if (address(this).balance < amount) {
            revert Create2InsufficientBalance(address(this).balance, amount);
        }
        if (bytecode.length == 0) {
            revert Create2EmptyBytecode();
        }
        /// @solidity memory-safe-assembly
        assembly {
            addr := create2(amount, add(bytecode, 0x20), mload(bytecode), salt)
        }
        if (addr == address(0)) {
            revert Create2FailedDeployment();
        }
    }

    /**
     * @dev Returns the address where a contract will be stored if deployed via {deploy}. Any change in the
     * `bytecodeHash` or `salt` will result in a new destination address.
     */
    function computeAddress(bytes32 salt, bytes32 bytecodeHash) internal view returns (address) {
        return computeAddress(salt, bytecodeHash, address(this));
    }

    /**
     * @dev Returns the address where a contract will be stored if deployed via {deploy} from a contract located at
     * `deployer`. If `deployer` is this contract's address, returns the same value as {computeAddress}.
     */
    function computeAddress(bytes32 salt, bytes32 bytecodeHash, address deployer) internal pure returns (address addr) {
        /// @solidity memory-safe-assembly
        assembly {
            let ptr := mload(0x40) // Get free memory pointer

            // |                   | ↓ ptr ...  ↓ ptr + 0x0B (start) ...  ↓ ptr + 0x20 ...  ↓ ptr + 0x40 ...   |
            // |-------------------|---------------------------------------------------------------------------|
            // | bytecodeHash      |                                                        CCCCCCCCCCCCC...CC |
            // | salt              |                                      BBBBBBBBBBBBB...BB                   |
            // | deployer          | 000000...0000AAAAAAAAAAAAAAAAAAA...AA                                     |
            // | 0xFF              |            FF                                                             |
            // |-------------------|---------------------------------------------------------------------------|
            // | memory            | 000000...00FFAAAAAAAAAAAAAAAAAAA...AABBBBBBBBBBBBB...BBCCCCCCCCCCCCC...CC |
            // | keccak(start, 85) |            ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑ |

            mstore(add(ptr, 0x40), bytecodeHash)
            mstore(add(ptr, 0x20), salt)
            mstore(ptr, deployer) // Right-aligned with 12 preceding garbage bytes
            let start := add(ptr, 0x0b) // The hashed data starts at the final garbage byte which we will set to 0xff
            mstore8(start, 0xff)
            addr := keccak256(start, 85)
        }
    }
}
"
    },
    "@openzeppelin/contracts/utils/cryptography/MessageHashUtils.sol": {
      "content": "// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (utils/cryptography/MessageHashUtils.sol)

pragma solidity ^0.8.20;

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

/**
 * @dev Signature message hash utilities for producing digests to be consumed by {ECDSA} recovery or signing.
 *
 * The library provides methods for generating a hash of a message that conforms to the
 * https://eips.ethereum.org/EIPS/eip-191[EIP 191] and https://eips.ethereum.org/EIPS/eip-712[EIP 712]
 * specifications.
 */
library MessageHashUtils {
    /**
     * @dev Returns the keccak256 digest of an EIP-191 signed data with version
     * `0x45` (`personal_sign` messages).
     *
     * The digest is calculated by prefixing a bytes32 `messageHash` with
     * `"\x19Ethereum Signed Message:\
32"` and hashing the result. It corresponds with the
     * hash signed when using the https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`] JSON-RPC method.
     *
     * NOTE: The `messageHash` parameter is intended to be the result of hashing a raw message with
     * keccak256, although any bytes32 value can be safely used because the final digest will
     * be re-hashed.
     *
     * See {ECDSA-recover}.
     */
    function toEthSignedMessageHash(bytes32 messageHash) internal pure returns (bytes32 digest) {
        /// @solidity memory-safe-assembly
        assembly {
            mstore(0x00, "\x19Ethereum Signed Message:\
32") // 32 is the bytes-length of messageHash
            mstore(0x1c, messageHash) // 0x1c (28) is the length of the prefix
            digest := keccak256(0x00, 0x3c) // 0x3c is the length of the prefix (0x1c) + messageHash (0x20)
        }
    }

    /**
     * @dev Returns the keccak256 digest of an EIP-191 signed data with version
     * `0x45` (`personal_sign` messages).
     *
     * The digest is calculated by prefixing an arbitrary `message` with
     * `"\x19Ethereum Signed Message:\
" + len(message)` and hashing the result. It corresponds with the
     * hash signed when using the https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`] JSON-RPC method.
     *
     * See {ECDSA-recover}.
     */
    function toEthSignedMessageHash(bytes memory message) internal pure returns (bytes32) {
        return
            keccak256(bytes.concat("\x19Ethereum Signed Message:\
", bytes(Strings.toString(message.length)), message));
    }

    /**
     * @dev Returns the keccak256 digest of an EIP-191 signed data with version
     * `0x00` (data with intended validator).
     *
     * The digest is calculated by prefixing an arbitrary `data` with `"\x19\x00"` and the intended
     * `validator` address. Then hashing the result.
     *
     * See {ECDSA-recover}.
     */
    function toDataWithIntendedValidatorHash(address validator, bytes memory data) internal pure returns (bytes32) {
        return keccak256(abi.encodePacked(hex"19_00", validator, data));
    }

    /**
     * @dev Returns the keccak256 digest of an EIP-712 typed data (EIP-191 version `0x01`).
     *
     * The digest is calculated from a `domainSeparator` and a `structHash`, by prefixing them with
     * `\x19\x01` and hashing the result. It corresponds to the hash signed by the
     * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`] JSON-RPC method as part of EIP-712.
     *
     * See {ECDSA-recover}.
     */
    function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32 digest) {
        /// @solidity memory-safe-assembly
        assembly {
            let ptr := mload(0x40)
            mstore(ptr, hex"19_01")
            mstore(add(ptr, 0x02), domainSeparator)
            mstore(add(ptr, 0x22), structHash)
            digest := keccak256(ptr, 0x42)
        }
    }
}
"
    },
    "@openzeppelin/contracts/utils/math/Math.sol": {
      "content": "// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (utils/math/Math.sol)

pragma solidity ^0.8.20;

/**
 * @dev Standard math utilities missing in the Solidity language.
 */
library Math {
    /**
     * @dev Muldiv operation overflow.
     */
    error MathOverflowedMulDiv();

    enum Rounding {
        Floor, // Toward negative infinity
        Ceil, // Toward positive infinity
        Trunc, // Toward zero
        Expand // Away from zero
    }

    /**
     * @dev Returns the addition of two unsigned integers, with an overflow flag.
     */
    function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        unchecked {
            uint256 c = a + b;
            if (c < a) return (false, 0);
            return (true, c);
        }
    }

    /**
     * @dev Returns the subtraction of two unsigned integers, with an overflow flag.
     */
    function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        unchecked {
            if (b > a) return (false, 0);
            return (true, a - b);
        }
    }

    /**
     * @dev Returns the multiplication of two unsigned integers, with an overflow flag.
     */
    function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        unchecked {
            // Gas optimization: this is cheaper than requiring 'a' not being zero, but the
            // benefit is lost if 'b' is also tested.
            // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522
            if (a == 0) return (true, 0);
            uint256 c = a * b;
            if (c / a != b) return (false, 0);
            return (true, c);
        }
    }

    /**
     * @dev Returns the division of two unsigned integers, with a division by zero flag.
     */
    function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        unchecked {
            if (b == 0) return (false, 0);
            return (true, a / b);
        }
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag.
     */
    function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        unchecked {
            if (b == 0) return (false, 0);
            return (true, a % b);
        }
    }

    /**
     * @dev Returns the largest of two numbers.
     */
    function max(uint256 a, uint256 b) internal pure returns (uint256) {
        return a > b ? a : b;
    }

    /**
     * @dev Returns the smallest of two numbers.
     */
    function min(uint256 a, uint256 b) internal pure returns (uint256) {
        return a < b ? a : b;
    }

    /**
     * @dev Returns the average of two numbers. The result is rounded towards
     * zero.
     */
    function average(uint256 a, uint256 b) internal pure returns (uint256) {
        // (a + b) / 2 can overflow.
        return (a & b) + (a ^ b) / 2;
    }

    /**
     * @dev Returns the ceiling of the division of two numbers.
     *
     * This differs from standard division with `/` in that it rounds towards infinity instead
     * of rounding towards zero.
     */
    function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {
        if (b == 0) {
            // Guarantee the same behavior as in a regular Solidity division.
            return a / b;
        }

        // (a + b - 1) / b can overflow on addition, so we distribute.
        return a == 0 ? 0 : (a - 1) / b + 1;
    }

    /**
     * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or
     * denominator == 0.
     * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv) with further edits by
     * Uniswap Labs also under MIT license.
     */
    function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) {
        unchecked {
            // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use
            // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256
            // variables such that product = prod1 * 2^256 + prod0.
            uint256 prod0 = x * y; // Least significant 256 bits of the product
            uint256 prod1; // Most significant 256 bits of the product
            assembly {
                let mm := mulmod(x, y, not(0))
                prod1 := sub(sub(mm, prod0), lt(mm, prod0))
            }

            // Handle non-overflow cases, 256 by 256 division.
            if (prod1 == 0) {
                // Solidity will revert if denominator == 0, unlike the div opcode on its own.
                // The surrounding unchecked block does not change this fact.
                // See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic.
                return prod0 / denominator;
            }

            // Make sure the result is less than 2^256. Also prevents denominator == 0.
            if (denominator <= prod1) {
                revert MathOverflowedMulDiv();
            }

            ///////////////////////////////////////////////
            // 512 by 256 division.
            ///////////////////////////////////////////////

            // Make division exact by subtracting the remainder from [prod1 prod0].
            uint256 remainder;
            assembly {
                // Compute remainder using mulmod.
                remainder := mulmod(x, y, denominator)

                // Subtract 256 bit number from 512 bit number.
                prod1 := sub(prod1, gt(remainder, prod0))
                prod0 := sub(prod0, remainder)
            }

            // Factor powers of two out of denominator and compute largest power of two divisor of denominator.
            // Always >= 1. See https://cs.stackexchange.com/q/138556/92363.

            uint256 twos = denominator & (0 - denominator);
            assembly {
                // Divide denominator by twos.
                denominator := div(denominator, twos)

                // Divide [prod1 prod0] by twos.
                prod0 := div(prod0, twos)

                // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.
                twos := add(div(sub(0, twos), twos), 1)
            }

            // Shift in bits from prod1 into prod0.
            prod0 |= prod1 * twos;

            // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such
            // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for
            // four bits. That is, denominator * inv = 1 mod 2^4.
            uint256 inverse = (3 * denominator) ^ 2;

            // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also
            // works in modular arithmetic, doubling the correct bits in each step.
            inverse *= 2 - denominator * inverse; // inverse mod 2^8
            inverse *= 2 - denominator * inverse; // inverse mod 2^16
            inverse *= 2 - denominator * inverse; // inverse mod 2^32
            inverse *= 2 - denominator * inverse; // inverse mod 2^64
            inverse *= 2 - denominator * inverse; // inverse mod 2^128
            inverse *= 2 - denominator * inverse; // inverse mod 2^256

            // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.
            // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is
            // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1
            // is no longer required.
            result = prod0 * inverse;
            return result;
        }
    }

    /**
     * @notice Calculates x * y / denominator with full precision, following the selected rounding direction.
     */
    function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) {
        uint256 result = mulDiv(x, y, denominator);
        if (unsignedRoundsUp(rounding) && mulmod(x, y, denominator) > 0) {
            result += 1;
        }
        return result;
    }

    /**
     * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded
     * towards zero.
     *
     * Inspired by Henry S. Warren, Jr.'s "Hacker's Delight" (Chapter 11).
     */
    function sqrt(uint256 a) internal pure returns (uint256) {
        if (a == 0) {
            return 0;
        }

        // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.
        //
        // We know that the "msb" (most significant bit) of our target number `a` is a power of 2 such that we have
        // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`.
        //
        // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)`
        // → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))`
        // → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)`
        //
        // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit.
        uint256 result = 1 << (log2(a) >> 1);

        // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,
        // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at
        // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision
        // into the expected uint128 result.
        unchecked {
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            return min(result, a / result);
        }
    }

    /**
     * @notice Calculates sqrt(a), following the selected rounding direction.
     */
    function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {
        unchecked {
            uint256 result = sqrt(a);
            return result + (unsignedRoundsUp(rounding) && result * result < a ? 1 : 0);
        }
    }

    /**
     * @dev Return the log in base 2 of a positive value rounded towards zero.
     * Returns 0 if given 0.
     */
    function log2(uint256 value) internal pure returns (uint256) {
        uint256 result = 0;
        unchecked {
            if (value >> 128 > 0) {
                value >>= 128;
                result += 128;
            }
            if (value >> 64 > 0) {
                value >>= 64;
                result += 64;
            }
            if (value >> 32 > 0) {
                value >>= 32;
                result += 32;
            }
            if (value >> 16 > 0) {
                value >>= 16;
                result += 16;
            }
            if (value >> 8 > 0) {
                value >>= 8;
                result += 8;
            }
            if (value >> 4 > 0) {
                value >>= 4;
                result += 4;
            }
            if (value >> 2 > 0) {
                value >>= 2;
                result += 2;
            }
            if (value >> 1 > 0) {
                result += 1;
            }
        }
        return result;
    }

    /**
     * @dev Return the log in base 2, following the selected rounding direction, of a positive value.
     * Returns 0 if given 0.
     */
    function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {
        unchecked {
            uint256 result = log2(value);
            return result + (unsignedRoundsUp(rounding) && 1 << result < value ? 1 : 0);
        }
    }

    /**
     * @dev Return the log in base 10 of a positive value rounded towards zero.
     * Returns 0 if given 0.
     */
    function log10(uint256 value) internal pure returns (uint256) {
        uint256 result = 0;
        unchecked {
            if (value >= 10 ** 64) {
                value /= 10 ** 64;
                result += 64;
            }
            if (value >= 10 ** 32) {
                value /= 10 ** 32;
                result += 32;
            }
            if (value >= 10 ** 16) {
                value /= 10 ** 16;
                result += 16;
            }
            if (value >= 10 ** 8) {
                value /= 10 ** 8;
                result += 8;
            }
            if (value >= 10 ** 4) {
                value /= 10 ** 4;
                result += 4;
            }
            if (value >= 10 ** 2) {
                value /= 10 ** 2;
                result += 2;
            }
            if (value >= 10 ** 1) {
                result += 1;
            }
        }
        return result;
    }

    /**
     * @dev Return the log in base 10, following the selected rounding direction, of a positive value.
     * Returns 0 if given 0.
     */
    function log10(uint256 value, Rounding rounding) internal pure returns (uint256) {
        unchecked {
            uint256 result = log10(value);
            return result + (unsignedRoundsUp(rounding) && 10 ** result < value ? 1 : 0);
        }
    }

    /**
     * @dev Return the log in base 256 of a positive value rounded towards zero.
     * Returns 0 if given 0.
     *
     * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string.
     */
    function log256(uint256 value) internal pure returns (uint256) {
        uint256 result = 0;
        unchecked {
            if (value >> 128 > 0) {
                value >>= 128;
                result += 16;
            }
            if (value >> 64 > 0) {
                value >>= 64;
                result += 8;
            }
            if (value >> 32 > 0) {
                value >>= 32;
                result += 4;
            }
            if (value >> 16 > 0) {
                value >>= 16;
                result += 2;
            }
            if (value >> 8 > 0) {
                result += 1;
            }
        }
        return result;
    }

    /**
     * @dev Return the log in base 256, following the selected rounding direction, of a positive value.
     * Returns 0 if given 0.
     */
    function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {
        unchecked {
            uint256 result = log256(value);
            return result + (unsignedRoundsUp(rounding) && 1 << (result << 3) < value ? 1 : 0);
        }
    }

    /**
     * @dev Returns whether a provided rounding mode is considered rounding up for unsigned integers.
     */
    function unsignedRoundsUp(Rounding rounding) internal pure returns (bool) {
        return uint8(rounding) % 2 == 1;
    }
}
"
    },
    "@openzeppelin/contracts/utils/math/SignedMath.sol": {
      "content": "// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (utils/math/SignedMath.sol)

pragma solidity ^0.8.20;

/**
 * @dev Standard signed math utilities missing in the Solidity language.
 */
library SignedMath {
    /**
     * @dev Returns the largest of two signed numbers.
     */
    function max(int256 a, int256 b) internal pure returns (int256) {
        return a > b ? a : b;
    }

    /**
     * @dev Returns the smallest of two signed numbers.
     */
    function min(int256 a, int256 b) internal pure returns (int256) {
        return a < b ? a : b;
    }

    /**
     * @dev Returns the average of two signed numbers without overflow.
     * The result is rounded towards zero.
     */
    function average(int256 a, int256 b) internal pure returns (int256) {
        // Formula from the book "Hacker's Delight"
        int256 x = (a & b) + ((a ^ b) >> 1);
        return x + (int256(uint256(x) >> 255) & (a ^ b));
    }

    /**
     * @dev Returns the absolute unsigned value of a signed value.
     */
    function abs(int256 n) internal pure returns (uint256) {
        unchecked {
            // must be unchecked in order to support `n = type(int256).min`
            return uint256(n >= 0 ? n : -n);
        }
    }
}
"
    },
    "@openzeppelin/contracts/utils/Strings.sol": {
      "content": "// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (utils/Strings.sol)

pragma solidity ^0.8.20;

import {Math} from "./math/Math.sol";
import {SignedMath} from "./math/SignedMath.sol";

/**
 * @dev String operations.
 */
library Strings {
    bytes16 private constant HEX_DIGITS = "0123456789abcdef";
    uint8 private constant ADDRESS_LENGTH = 20;

    /**
     * @dev The `value` string doesn't fit in the specified `length`.
     */
    error StringsInsufficientHexLength(uint256 value, uint256 length);

    /**
     * @dev Converts a `uint256` to its ASCII `string` decimal representation.
     */
    function toString(uint256 value) internal pure returns (string memory) {
        unchecked {
            uint256 length = Math.log10(value) + 1;
            string memory buffer = new string(length);
            uint256 ptr;
            /// @solidity memory-safe-assembly
            assembly {
                ptr := add(buffer, add(32, length))
            }
            while (true) {
                ptr--;
                /// @solidity memory-safe-assembly
                assembly {
                    mstore8(ptr, byte(mod(value, 10), HEX_DIGITS))
                }
                value /= 10;
                if (value == 0) break;
            }
            return buffer;
        }
    }

    /**
     * @dev Converts a `int256` to its ASCII `string` decimal representation.
     */
    function toStringSigned(int256 value) internal pure returns (string memory) {
        return string.concat(value < 0 ? "-" : "", toString(SignedMath.abs(value)));
    }

    /**
     * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.
     */
    function toHexString(uint256 value) internal pure returns (string memory) {
        unchecked {
            return toHexString(value, Math.log256(value) + 1);
        }
    }

    /**
     * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.
     */
    function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {
        uint256 localValue = value;
        bytes memory buffer = new bytes(2 * length + 2);
        buffer[0] = "0";
        buffer[1] = "x";
        for (uint256 i = 2 * length + 1; i > 1; --i) {
            buffer[i] = HEX_DIGITS[localValue & 0xf];
            localValue >>= 4;
        }
        if (localValue != 0) {
            revert StringsInsufficientHexLength(value, length);
        }
        return string(buffer);
    }

    /**
     * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal
     * representation.
     */
    function toHexString(address addr) internal pure returns (string memory) {
        return toHexString(uint256(uint160(addr)), ADDRESS_LENGTH);
    }

    /**
     * @dev Returns true if the two strings are equal.
     */
    function equal(string memory a, string memory b) internal pure returns (bool) {
        return bytes(a).length == bytes(b).length && keccak256(bytes(a)) == keccak256(bytes(b));
    }
}
"
    },
    "contracts/interfaces/IEIP6492.sol": {
      "content": "// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.8.20;

/**
 * @title IEIP6492
 * @author MetaLend
 * @notice Minimal interface for EIP-6492 signature validation.
 * @dev This interface allows for the validation of signatures according to EIP-6492.
 */
interface IEIP6492 {
    /**
     * @notice Validates a signature against a given hash.
     * @dev This function can revert if the underlying call reverts.
     * @param _signer      The address of the signer.
     * @param _hash        The hash to validate against.
     * @param _signature   The signature to validate.
     * @return bool Returns true if the signature is valid, false otherwise.
     */
    function isValidSig(address _signer, bytes32 _hash, bytes calldata _signature) external returns (bool);
}
"
    },
    "contracts/lib/EncodeKeyLib.sol": {
      "content": "// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.8.20;

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

/**
 * @title EncodeKeyLib
 * @author MetaLend
 * @notice Library for encoding keys used in mappings
 * @dev This library provides functions to encode keys for mapping bytes32 identifiers
 */
library EncodeKeyLib {
    /**
     * @notice External function to get the encoded pool key
     * @param poolContract   The address of the pool contract
     * @param pool           The pool identifier
     * @param token          The address of the token
     * @return encodedKey    The encoded pool key
     */
    function _getEncodedPoolKey(address poolContract, PoolIdentifier pool, address token) internal pure returns (bytes32 encodedKey) {
        encodedKey = keccak256(abi.encodePacked(poolContract, pool, token));
    }

    /**
     * @notice External function to get the encoded operation key
     * @param operation     The operation type
     * @return encodedKey   The encoded operation key
     */
    function _getEncodedOperationKey(Operation operation) internal pure returns (bytes32 encodedKey) {
        encodedKey = keccak256(abi.encodePacked(operation));
    }
}
"
    },
    "contracts/lib/FeesLib.sol": {
      "content": "// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.8.20;

/**
 * @title IERC20
 * @author MetaLend
 * @notice Minimal interface for ERC20 tokens to get decimals
 * @dev This interface is used to interact with ERC20 tokens to retrieve their decimal places
 */
interface IERC20 {
    function decimals() external view returns (uint8);
}

/**
 * @title FeesLib
 * @author MetaLend
 * @notice Library for managing fees
 * @dev This library provides extension helper functions for fee management
 */
library FeesLib {
    uint256 private constant _DENOMINATOR = 1000; // supports milli-tokens (0.001)

    /**
     * @notice Convert a fractional human-readable fee to raw token units
     * @param constantFee   The numerator for the fee (e.g. `1` if fee = 0.001 tokens with denominator = 1000)
     * @param token         The ERC20 token address
     * @return rawValue     The fee converted into token smallest units
     */
    function convertConstantFeeToRawValue(uint256 constantFee, address token) external view returns (uint256 rawValue) {
        uint8 decimals = IERC20(token).decimals();
        uint256 base = 10 ** decimals;

        // Scale fee proportionally to token decimals
        rawValue = (constantFee * base) / _DENOMINATOR;
    }
}
"
    },
    "contracts/manager/access/AccessControl.sol": {
      "content": "// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.8.20;

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

/**
 * @title AccessControl
 * @author MetaLend
 * @notice Contract module that provides access control mechanisms
 */
abstract contract AccessControl is IAccessControl {
    /// @notice Operator role identifier
    bytes32 private constant _OPERATOR_ROLE = keccak256("OPERATOR_ROLE");

    /// @notice Admin address
    address private _admin;

    /// @notice Operator role mapping
    mapping(address account => bytes32 role) public roles;

    /// @notice Modifier to restrict access to admin
    modifier onlyAdmin() {
        if (msg.sender != _admin) revert Unauthorized();
        _;
    }

    /// @notice Modifier to restrict access to operator
    modifier onlyOperator() {
        if (roles[msg.sender] != _OPERATOR_ROLE) revert Unauthorized();
        _;
    }

    /**
     * @inheritdoc IAccessControl
     */
    function setAdmin(address newAdmin) external override onlyAdmin {
        require(newAdmin != address(0), "AccessControl: new admin is the zero address");
        address oldAdmin = _admin;
        _admin = newAdmin;
        emit AdminChanged(oldAdmin, newAdmin);
    }

    /**
     * @inheritdoc IAccessControl
     */
    function addOperator(address operator) external override onlyAdmin {
        require(operator != address(0), "AccessControl: operator is the zero address");
        roles[operator] = _OPERATOR_ROLE;
        emit OperatorAdded(operator);
    }

    /**
     * @inheritdoc IAccessControl
     */
    function removeOperator(address operator) external override onlyAdmin {
        delete roles[operator];
        emit OperatorRemoved(operator);
    }

    /**
     * @inheritdoc IAccessControl
     */
    function getAdmin() external view override returns (address admin) {
        admin = _admin;
    }

    /**
     * @inheritdoc IAccessControl
     */
    function isOperator(address operator) external view override returns (bool isOpr) {
        isOpr = roles[operator] == _OPERATOR_ROLE;
    }

    /**
     * @notice Initialize the admin address
     * @param admin_ The address of the admin
     */
    function _initializeAdmin(address admin_) internal {
        require(_admin == address(0), "AccessControl: admin already initialized");
        require(admin_ != address(0), "AccessControl: admin is the zero address");
        _admin = admin_;
    }
}
"
    },
    "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.
     */\

Tags:
Proxy, Yield, Upgradeable, Factory|addr:0x87f224ad62d90fee740d27c269647163b2d75499|verified:true|block:23619041|tx:0x7f2128c85437b8cf331891abe93ec783aca3edb711b8bf261ccc8755ed6cb977|first_check:1760968360

Submitted on: 2025-10-20 15:52:40

Comments

Log in to comment.

No comments yet.