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.
*/\
Submitted on: 2025-10-20 15:52:40
Comments
Log in to comment.
No comments yet.