// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.1) (utils/Context.sol)
pragma solidity ^0.8.20;
/**
* @dev Provides information about the current execution context, including the
* sender of the transaction and its data. While these are generally available
* via msg.sender and msg.data, they should not be accessed in such a direct
* manner, since when dealing with meta-transactions the account sending and
* paying for execution may not be the actual sender (as far as an application
* is concerned).
*
* This contract is only required for intermediate, library-like contracts.
*/
abstract contract Context {
function _msgSender() internal view virtual returns (address) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes calldata) {
return msg.data;
}
function _contextSuffixLength() internal view virtual returns (uint256) {
return 0;
}
}
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/ERC20.sol)
pragma solidity ^0.8.20;
import {IERC20} from "./IERC20.sol";
import {IERC20Metadata} from "./extensions/IERC20Metadata.sol";
import {Context} from "../../utils/Context.sol";
import {IERC20Errors} from "../../interfaces/draft-IERC6093.sol";
/**
* @dev Implementation of the {IERC20} interface.
*
* This implementation is agnostic to the way tokens are created. This means
* that a supply mechanism has to be added in a derived contract using {_mint}.
*
* TIP: For a detailed writeup see our guide
* https://forum.openzeppelin.com/t/how-to-implement-erc20-supply-mechanisms/226[How
* to implement supply mechanisms].
*
* The default value of {decimals} is 18. To change this, you should override
* this function so it returns a different value.
*
* We have followed general OpenZeppelin Contracts guidelines: functions revert
* instead returning `false` on failure. This behavior is nonetheless
* conventional and does not conflict with the expectations of ERC20
* applications.
*
* Additionally, an {Approval} event is emitted on calls to {transferFrom}.
* This allows applications to reconstruct the allowance for all accounts just
* by listening to said events. Other implementations of the EIP may not emit
* these events, as it isn't required by the specification.
*/
abstract contract ERC20 is Context, IERC20, IERC20Metadata, IERC20Errors {
mapping(address account => uint256) private _balances;
mapping(address account => mapping(address spender => uint256)) private _allowances;
uint256 private _totalSupply;
string private _name;
string private _symbol;
/**
* @dev Sets the values for {name} and {symbol}.
*
* All two of these values are immutable: they can only be set once during
* construction.
*/
constructor(string memory name_, string memory symbol_) {
_name = name_;
_symbol = symbol_;
}
/**
* @dev Returns the name of the token.
*/
function name() public view virtual returns (string memory) {
return _name;
}
/**
* @dev Returns the symbol of the token, usually a shorter version of the
* name.
*/
function symbol() public view virtual returns (string memory) {
return _symbol;
}
/**
* @dev Returns the number of decimals used to get its user representation.
* For example, if `decimals` equals `2`, a balance of `505` tokens should
* be displayed to a user as `5.05` (`505 / 10 ** 2`).
*
* Tokens usually opt for a value of 18, imitating the relationship between
* Ether and Wei. This is the default value returned by this function, unless
* it's overridden.
*
* NOTE: This information is only used for _display_ purposes: it in
* no way affects any of the arithmetic of the contract, including
* {IERC20-balanceOf} and {IERC20-transfer}.
*/
function decimals() public view virtual returns (uint8) {
return 18;
}
/**
* @dev See {IERC20-totalSupply}.
*/
function totalSupply() public view virtual returns (uint256) {
return _totalSupply;
}
/**
* @dev See {IERC20-balanceOf}.
*/
function balanceOf(address account) public view virtual returns (uint256) {
return _balances[account];
}
/**
* @dev See {IERC20-transfer}.
*
* Requirements:
*
* - `to` cannot be the zero address.
* - the caller must have a balance of at least `value`.
*/
function transfer(address to, uint256 value) public virtual returns (bool) {
address owner = _msgSender();
_transfer(owner, to, value);
return true;
}
/**
* @dev See {IERC20-allowance}.
*/
function allowance(address owner, address spender) public view virtual returns (uint256) {
return _allowances[owner][spender];
}
/**
* @dev See {IERC20-approve}.
*
* NOTE: If `value` is the maximum `uint256`, the allowance is not updated on
* `transferFrom`. This is semantically equivalent to an infinite approval.
*
* Requirements:
*
* - `spender` cannot be the zero address.
*/
function approve(address spender, uint256 value) public virtual returns (bool) {
address owner = _msgSender();
_approve(owner, spender, value);
return true;
}
/**
* @dev See {IERC20-transferFrom}.
*
* Emits an {Approval} event indicating the updated allowance. This is not
* required by the EIP. See the note at the beginning of {ERC20}.
*
* NOTE: Does not update the allowance if the current allowance
* is the maximum `uint256`.
*
* Requirements:
*
* - `from` and `to` cannot be the zero address.
* - `from` must have a balance of at least `value`.
* - the caller must have allowance for ``from``'s tokens of at least
* `value`.
*/
function transferFrom(address from, address to, uint256 value) public virtual returns (bool) {
address spender = _msgSender();
_spendAllowance(from, spender, value);
_transfer(from, to, value);
return true;
}
/**
* @dev Moves a `value` amount of tokens from `from` to `to`.
*
* This internal function is equivalent to {transfer}, and can be used to
* e.g. implement automatic token fees, slashing mechanisms, etc.
*
* Emits a {Transfer} event.
*
* NOTE: This function is not virtual, {_update} should be overridden instead.
*/
function _transfer(address from, address to, uint256 value) internal {
if (from == address(0)) {
revert ERC20InvalidSender(address(0));
}
if (to == address(0)) {
revert ERC20InvalidReceiver(address(0));
}
_update(from, to, value);
}
/**
* @dev Transfers a `value` amount of tokens from `from` to `to`, or alternatively mints (or burns) if `from`
* (or `to`) is the zero address. All customizations to transfers, mints, and burns should be done by overriding
* this function.
*
* Emits a {Transfer} event.
*/
function _update(address from, address to, uint256 value) internal virtual {
if (from == address(0)) {
// Overflow check required: The rest of the code assumes that totalSupply never overflows
_totalSupply += value;
} else {
uint256 fromBalance = _balances[from];
if (fromBalance < value) {
revert ERC20InsufficientBalance(from, fromBalance, value);
}
unchecked {
// Overflow not possible: value <= fromBalance <= totalSupply.
_balances[from] = fromBalance - value;
}
}
if (to == address(0)) {
unchecked {
// Overflow not possible: value <= totalSupply or value <= fromBalance <= totalSupply.
_totalSupply -= value;
}
} else {
unchecked {
// Overflow not possible: balance + value is at most totalSupply, which we know fits into a uint256.
_balances[to] += value;
}
}
emit Transfer(from, to, value);
}
/**
* @dev Creates a `value` amount of tokens and assigns them to `account`, by transferring it from address(0).
* Relies on the `_update` mechanism
*
* Emits a {Transfer} event with `from` set to the zero address.
*
* NOTE: This function is not virtual, {_update} should be overridden instead.
*/
function _mint(address account, uint256 value) internal {
if (account == address(0)) {
revert ERC20InvalidReceiver(address(0));
}
_update(address(0), account, value);
}
/**
* @dev Destroys a `value` amount of tokens from `account`, lowering the total supply.
* Relies on the `_update` mechanism.
*
* Emits a {Transfer} event with `to` set to the zero address.
*
* NOTE: This function is not virtual, {_update} should be overridden instead
*/
function _burn(address account, uint256 value) internal {
if (account == address(0)) {
revert ERC20InvalidSender(address(0));
}
_update(account, address(0), value);
}
/**
* @dev Sets `value` as the allowance of `spender` over the `owner` s tokens.
*
* This internal function is equivalent to `approve`, and can be used to
* e.g. set automatic allowances for certain subsystems, etc.
*
* Emits an {Approval} event.
*
* Requirements:
*
* - `owner` cannot be the zero address.
* - `spender` cannot be the zero address.
*
* Overrides to this logic should be done to the variant with an additional `bool emitEvent` argument.
*/
function _approve(address owner, address spender, uint256 value) internal {
_approve(owner, spender, value, true);
}
/**
* @dev Variant of {_approve} with an optional flag to enable or disable the {Approval} event.
*
* By default (when calling {_approve}) the flag is set to true. On the other hand, approval changes made by
* `_spendAllowance` during the `transferFrom` operation set the flag to false. This saves gas by not emitting any
* `Approval` event during `transferFrom` operations.
*
* Anyone who wishes to continue emitting `Approval` events on the`transferFrom` operation can force the flag to
* true using the following override:
* ```
* function _approve(address owner, address spender, uint256 value, bool) internal virtual override {
* super._approve(owner, spender, value, true);
* }
* ```
*
* Requirements are the same as {_approve}.
*/
function _approve(address owner, address spender, uint256 value, bool emitEvent) internal virtual {
if (owner == address(0)) {
revert ERC20InvalidApprover(address(0));
}
if (spender == address(0)) {
revert ERC20InvalidSpender(address(0));
}
_allowances[owner][spender] = value;
if (emitEvent) {
emit Approval(owner, spender, value);
}
}
/**
* @dev Updates `owner` s allowance for `spender` based on spent `value`.
*
* Does not update the allowance value in case of infinite allowance.
* Revert if not enough allowance is available.
*
* Does not emit an {Approval} event.
*/
function _spendAllowance(address owner, address spender, uint256 value) internal virtual {
uint256 currentAllowance = allowance(owner, spender);
if (currentAllowance != type(uint256).max) {
if (currentAllowance < value) {
revert ERC20InsufficientAllowance(spender, currentAllowance, value);
}
unchecked {
_approve(owner, spender, currentAllowance - value, false);
}
}
}
}
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/IERC20.sol)
pragma solidity ^0.8.20;
/**
* @dev Interface of the ERC20 standard as defined in the EIP.
*/
interface IERC20 {
/**
* @dev Emitted when `value` tokens are moved from one account (`from`) to
* another (`to`).
*
* Note that `value` may be zero.
*/
event Transfer(address indexed from, address indexed to, uint256 value);
/**
* @dev Emitted when the allowance of a `spender` for an `owner` is set by
* a call to {approve}. `value` is the new allowance.
*/
event Approval(address indexed owner, address indexed spender, uint256 value);
/**
* @dev Returns the value of tokens in existence.
*/
function totalSupply() external view returns (uint256);
/**
* @dev Returns the value of tokens owned by `account`.
*/
function balanceOf(address account) external view returns (uint256);
/**
* @dev Moves a `value` amount of tokens from the caller's account to `to`.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transfer(address to, uint256 value) external returns (bool);
/**
* @dev Returns the remaining number of tokens that `spender` will be
* allowed to spend on behalf of `owner` through {transferFrom}. This is
* zero by default.
*
* This value changes when {approve} or {transferFrom} are called.
*/
function allowance(address owner, address spender) external view returns (uint256);
/**
* @dev Sets a `value` amount of tokens as the allowance of `spender` over the
* caller's tokens.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* IMPORTANT: Beware that changing an allowance with this method brings the risk
* that someone may use both the old and the new allowance by unfortunate
* transaction ordering. One possible solution to mitigate this race
* condition is to first reduce the spender's allowance to 0 and set the
* desired value afterwards:
* https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
*
* Emits an {Approval} event.
*/
function approve(address spender, uint256 value) external returns (bool);
/**
* @dev Moves a `value` amount of tokens from `from` to `to` using the
* allowance mechanism. `value` is then deducted from the caller's
* allowance.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transferFrom(address from, address to, uint256 value) external returns (bool);
}
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/extensions/IERC20Metadata.sol)
pragma solidity ^0.8.20;
import {IERC20} from "../IERC20.sol";
/**
* @dev Interface for the optional metadata functions from the ERC20 standard.
*/
interface IERC20Metadata is IERC20 {
/**
* @dev Returns the name of the token.
*/
function name() external view returns (string memory);
/**
* @dev Returns the symbol of the token.
*/
function symbol() external view returns (string memory);
/**
* @dev Returns the decimals places of the token.
*/
function decimals() external view returns (uint8);
}
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (interfaces/IERC6372.sol)
pragma solidity ^0.8.20;
interface IERC6372 {
/**
* @dev Clock used for flagging checkpoints. Can be overridden to implement timestamp based checkpoints (and voting).
*/
function clock() external view returns (uint48);
/**
* @dev Description of the clock
*/
// solhint-disable-next-line func-name-mixedcase
function CLOCK_MODE() external view returns (string memory);
}
// SPDX-License-Identifier: GPL-2.0-or-later
pragma solidity ^0.8.25;
interface IHistoricalBalance {
/**
* @notice This function retrieves the historical balance of an account at
* a specific point in time.
* @param account The address of the account for which to retrieve the
* historical balance.
* @param timepoint The timepoint (block number or timestamp depending on
* implementation) at which to query the balance (uint256).
* @return balance The balance of the account at the specified timepoint.
*/
function getPastBalanceOf(address account, uint256 timepoint) external view returns (uint256 balance);
}
// SPDX-License-Identifier: GPL-2.0-or-later
// As the copyright holder of this work, Ubiquity Labs retains
// the right to distribute, use, and modify this code under any license of
// their choosing, in addition to the terms of the GPL-v2 or later.
pragma solidity ^0.8.25;
import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import {IMaverickV2Pool} from "./IMaverickV2Pool.sol";
interface IMaverickV2Factory {
error FactoryInvalidProtocolFeeRatio(uint8 protocolFeeRatioD3);
error FactoryInvalidLendingFeeRate(uint256 protocolLendingFeeRateD18);
error FactoryProtocolFeeOnRenounce(uint8 protocolFeeRatioD3);
error FactorAlreadyInitialized();
error FactorNotInitialized();
error FactoryInvalidTokenOrder(IERC20 _tokenA, IERC20 _tokenB);
error FactoryInvalidFee();
error FactoryInvalidKinds(uint8 kinds);
error FactoryInvalidTickSpacing(uint256 tickSpacing);
error FactoryInvalidLookback(uint256 lookback);
error FactoryInvalidTokenDecimals(uint8 decimalsA, uint8 decimalsB);
error FactoryPoolAlreadyExists(
uint256 feeAIn,
uint256 feeBIn,
uint256 tickSpacing,
uint256 lookback,
IERC20 tokenA,
IERC20 tokenB,
uint8 kinds,
address accessor
);
error FactoryAccessorMustBeNonZero();
event PoolCreated(
IMaverickV2Pool poolAddress,
uint8 protocolFeeRatio,
uint256 feeAIn,
uint256 feeBIn,
uint256 tickSpacing,
uint256 lookback,
int32 activeTick,
IERC20 tokenA,
IERC20 tokenB,
uint8 kinds,
address accessor
);
event SetFactoryProtocolFeeRatio(uint8 protocolFeeRatioD3);
event SetFactoryProtocolLendingFeeRate(uint256 lendingFeeRateD18);
event SetFactoryProtocolFeeReceiver(address receiver);
struct DeployParameters {
uint64 feeAIn;
uint64 feeBIn;
uint32 lookback;
int32 activeTick;
uint64 tokenAScale;
uint64 tokenBScale;
// slot
IERC20 tokenA;
// slot
IERC20 tokenB;
// slot
uint16 tickSpacing;
uint8 options;
address accessor;
}
/**
* @notice Called by deployer library to initialize a pool.
*/
function deployParameters()
external
view
returns (
uint64 feeAIn,
uint64 feeBIn,
uint32 lookback,
int32 activeTick,
uint64 tokenAScale,
uint64 tokenBScale,
// slot
IERC20 tokenA,
// slot
IERC20 tokenB,
// slot
uint16 tickSpacing,
uint8 options,
address accessor
);
/**
* @notice Create a new MaverickV2Pool with symmetric swap fees.
* @param fee Fraction of the pool swap amount that is retained as an LP in
* D18 scale.
* @param tickSpacing Tick spacing of pool where 1.0001^tickSpacing is the
* bin width.
* @param lookback Pool lookback in seconds.
* @param tokenA Address of tokenA.
* @param tokenB Address of tokenB.
* @param activeTick Tick position that contains the active bins.
* @param kinds 1-15 number to represent the active kinds
* 0b0001 = static;
* 0b0010 = right;
* 0b0100 = left;
* 0b1000 = both.
* E.g. a pool with all 4 modes will have kinds = b1111 = 15
*/
function create(
uint64 fee,
uint16 tickSpacing,
uint32 lookback,
IERC20 tokenA,
IERC20 tokenB,
int32 activeTick,
uint8 kinds
) external returns (IMaverickV2Pool);
/**
* @notice Create a new MaverickV2Pool.
* @param feeAIn Fraction of the pool swap amount for tokenA-input swaps
* that is retained as an LP in D18 scale.
* @param feeBIn Fraction of the pool swap amount for tokenB-input swaps
* that is retained as an LP in D18 scale.
* @param tickSpacing Tick spacing of pool where 1.0001^tickSpacing is the
* bin width.
* @param lookback Pool lookback in seconds.
* @param tokenA Address of tokenA.
* @param tokenB Address of tokenB.
* @param activeTick Tick position that contains the active bins.
* @param kinds 1-15 number to represent the active kinds
* 0b0001 = static;
* 0b0010 = right;
* 0b0100 = left;
* 0b1000 = both.
* e.g. a pool with all 4 modes will have kinds = b1111 = 15
*/
function create(
uint64 feeAIn,
uint64 feeBIn,
uint16 tickSpacing,
uint32 lookback,
IERC20 tokenA,
IERC20 tokenB,
int32 activeTick,
uint8 kinds
) external returns (IMaverickV2Pool);
/**
* @notice Create a new MaverickV2PoolPermissioned with symmetric swap fees
* with all functions permissioned. Set fee to zero to make the pool fee settable by the accessor.
* @param fee Fraction of the pool swap amount that is retained as an LP in
* D18 scale.
* @param tickSpacing Tick spacing of pool where 1.0001^tickSpacing is the
* bin width.
* @param lookback Pool lookback in seconds.
* @param tokenA Address of tokenA.
* @param tokenB Address of tokenB.
* @param activeTick Tick position that contains the active bins.
* @param kinds 1-15 number to represent the active kinds
* 0b0001 = static;
* 0b0010 = right;
* 0b0100 = left;
* 0b1000 = both.
* E.g. a pool with all 4 modes will have kinds = b1111 = 15
* @param accessor Only address that can access the pool's public write functions.
*/
function createPermissioned(
uint64 fee,
uint16 tickSpacing,
uint32 lookback,
IERC20 tokenA,
IERC20 tokenB,
int32 activeTick,
uint8 kinds,
address accessor
) external returns (IMaverickV2Pool);
/**
* @notice Create a new MaverickV2PoolPermissioned with all functions
* permissioned. Set fees to zero to make the pool fee settable by the
* accessor.
* @param feeAIn Fraction of the pool swap amount for tokenA-input swaps
* that is retained as an LP in D18 scale.
* @param feeBIn Fraction of the pool swap amount for tokenB-input swaps
* that is retained as an LP in D18 scale.
* @param tickSpacing Tick spacing of pool where 1.0001^tickSpacing is the
* bin width.
* @param lookback Pool lookback in seconds.
* @param tokenA Address of tokenA.
* @param tokenB Address of tokenB.
* @param activeTick Tick position that contains the active bins.
* @param kinds 1-15 number to represent the active kinds
* 0b0001 = static;
* 0b0010 = right;
* 0b0100 = left;
* 0b1000 = both.
* E.g. a pool with all 4 modes will have kinds = b1111 = 15
* @param accessor only address that can access the pool's public write functions.
*/
function createPermissioned(
uint64 feeAIn,
uint64 feeBIn,
uint16 tickSpacing,
uint32 lookback,
IERC20 tokenA,
IERC20 tokenB,
int32 activeTick,
uint8 kinds,
address accessor
) external returns (IMaverickV2Pool);
/**
* @notice Create a new MaverickV2PoolPermissioned with the option to make
* a subset of function permissionless. Set fee to zero to make the pool
* fee settable by the accessor.
* @param feeAIn Fraction of the pool swap amount for tokenA-input swaps
* that is retained as an LP in D18 scale.
* @param feeBIn Fraction of the pool swap amount for tokenB-input swaps
* that is retained as an LP in D18 scale.
* @param tickSpacing Tick spacing of pool where 1.0001^tickSpacing is the
* bin width.
* @param lookback Pool lookback in seconds.
* @param tokenA Address of tokenA.
* @param tokenB Address of tokenB.
* @param activeTick Tick position that contains the active bins.
* @param kinds 1-15 number to represent the active kinds
* 0b0001 = static;
* 0b0010 = right;
* 0b0100 = left;
* 0b1000 = both.
* E.g. a pool with all 4 modes will have kinds = b1111 = 15
* @param accessor only address that can access the pool's public permissioned write functions.
* @param permissionedLiquidity If true, then only accessor can call
* pool's liquidity management functions: `flashLoan`,
* `migrateBinsUpstack`, `addLiquidity`, `removeLiquidity`.
* @param permissionedSwap If true, then only accessor can call
* pool's swap function.
*/
function createPermissioned(
uint64 feeAIn,
uint64 feeBIn,
uint16 tickSpacing,
uint32 lookback,
IERC20 tokenA,
IERC20 tokenB,
int32 activeTick,
uint8 kinds,
address accessor,
bool permissionedLiquidity,
bool permissionedSwap
) external returns (IMaverickV2Pool pool);
/**
* @notice Update the protocol fee ratio for a pool. Can be called
* permissionlessly allowing any user to sync the pool protocol fee value
* with the factory protocol fee value.
* @param pool The pool for which to update.
*/
function updateProtocolFeeRatioForPool(IMaverickV2Pool pool) external;
/**
* @notice Update the protocol lending fee rate for a pool. Can be called
* permissionlessly allowing any user to sync the pool protocol lending fee
* rate value with the factory value.
* @param pool The pool for which to update.
*/
function updateProtocolLendingFeeRateForPool(IMaverickV2Pool pool) external;
/**
* @notice Claim protocol fee for a pool and transfer it to the protocolFeeReceiver.
* @param pool The pool from which to claim the protocol fee.
* @param isTokenA A boolean indicating whether tokenA (true) or tokenB
* (false) is being collected.
*/
function claimProtocolFeeForPool(IMaverickV2Pool pool, bool isTokenA) external;
/**
* @notice Claim protocol fee for a pool and transfer it to the protocolFeeReceiver.
* @param pool The pool from which to claim the protocol fee.
*/
function claimProtocolFeeForPool(IMaverickV2Pool pool) external;
/**
* @notice Bool indicating whether the pool was deployed from this factory.
*/
function isFactoryPool(IMaverickV2Pool pool) external view returns (bool);
/**
* @notice Address that receives the protocol fee when users call
* `claimProtocolFeeForPool`.
*/
function protocolFeeReceiver() external view returns (address);
/**
* @notice Lookup a pool for given parameters.
*
* @dev options bit map of kinds and function permissions
* 0b000001 = static;
* 0b000010 = right;
* 0b000100 = left;
* 0b001000 = both;
* 0b010000 = liquidity functions are permissioned
* 0b100000 = swap function is permissioned
*/
function lookupPermissioned(
uint256 feeAIn,
uint256 feeBIn,
uint256 tickSpacing,
uint256 lookback,
IERC20 tokenA,
IERC20 tokenB,
uint8 options,
address accessor
) external view returns (IMaverickV2Pool);
/**
* @notice Lookup a pool for given parameters.
*/
function lookupPermissioned(
IERC20 _tokenA,
IERC20 _tokenB,
address accessor,
uint256 startIndex,
uint256 endIndex
) external view returns (IMaverickV2Pool[] memory pools);
/**
* @notice Lookup a pool for given parameters.
*/
function lookupPermissioned(
uint256 startIndex,
uint256 endIndex
) external view returns (IMaverickV2Pool[] memory pools);
/**
* @notice Lookup a pool for given parameters.
*/
function lookup(
uint256 feeAIn,
uint256 feeBIn,
uint256 tickSpacing,
uint256 lookback,
IERC20 tokenA,
IERC20 tokenB,
uint8 kinds
) external view returns (IMaverickV2Pool);
/**
* @notice Lookup a pool for given parameters.
*/
function lookup(
IERC20 _tokenA,
IERC20 _tokenB,
uint256 startIndex,
uint256 endIndex
) external view returns (IMaverickV2Pool[] memory pools);
/**
* @notice Lookup a pool for given parameters.
*/
function lookup(uint256 startIndex, uint256 endIndex) external view returns (IMaverickV2Pool[] memory pools);
/**
* @notice Count of permissionless pools.
*/
function poolCount() external view returns (uint256 _poolCount);
/**
* @notice Count of permissioned pools.
*/
function poolPermissionedCount() external view returns (uint256 _poolCount);
/**
* @notice Count of pools for a given accessor and token pair. For
* permissionless pools, pass `accessor = address(0)`.
*/
function poolByTokenCount(
IERC20 _tokenA,
IERC20 _tokenB,
address accessor
) external view returns (uint256 _poolCount);
/**
* @notice Get the current factory owner.
*/
function owner() external view returns (address);
/**
* @notice Proportion of protocol fee to collect on each swap. Value is in
* 3-decimal format with a maximum value of 0.25e3.
*/
function protocolFeeRatioD3() external view returns (uint8);
/**
* @notice Fee rate charged by the protocol for flashloans. Value is in
* 18-decimal format with a maximum value of 0.02e18.
*/
function protocolLendingFeeRateD18() external view returns (uint256);
}
// SPDX-License-Identifier: GPL-2.0-or-later
// As the copyright holder of this work, Ubiquity Labs retains
// the right to distribute, use, and modify this code under any license of
// their choosing, in addition to the terms of the GPL-v2 or later.
pragma solidity ^0.8.25;
import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import {IMaverickV2Factory} from "./IMaverickV2Factory.sol";
interface IMaverickV2Pool {
error PoolZeroLiquidityAdded();
error PoolMinimumLiquidityNotMet();
error PoolLocked();
error PoolInvalidFee();
error PoolTicksNotSorted(uint256 index, int256 previousTick, int256 tick);
error PoolTicksAmountsLengthMismatch(uint256 ticksLength, uint256 amountsLength);
error PoolBinIdsAmountsLengthMismatch(uint256 binIdsLength, uint256 amountsLength);
error PoolKindNotSupported(uint256 kinds, uint256 kind);
error PoolInsufficientBalance(uint256 deltaLpAmount, uint256 accountBalance);
error PoolReservesExceedMaximum(uint256 amount);
error PoolValueExceedsBits(uint256 amount, uint256 bits);
error PoolTickMaxExceeded(uint256 tick);
error PoolMigrateBinFirst();
error PoolCurrentTickBeyondSwapLimit(int32 startingTick);
error PoolSenderNotAccessor(address sender_, address accessor);
error PoolSenderNotFactory(address sender_, address accessor);
error PoolFunctionNotImplemented();
error PoolTokenNotSolvent(uint256 internalReserve, uint256 tokenBalance, IERC20 token);
event PoolSwap(address sender, address recipient, SwapParams params, uint256 amountIn, uint256 amountOut);
event PoolAddLiquidity(
address sender,
address recipient,
uint256 subaccount,
AddLiquidityParams params,
uint256 tokenAAmount,
uint256 tokenBAmount,
uint32[] binIds
);
event PoolMigrateBinsUpStack(address sender, uint32 binId, uint32 maxRecursion);
event PoolRemoveLiquidity(
address sender,
address recipient,
uint256 subaccount,
RemoveLiquidityParams params,
uint256 tokenAOut,
uint256 tokenBOut
);
event PoolSetVariableFee(uint256 newFeeAIn, uint256 newFeeBIn);
/**
* @notice Tick state parameters.
*/
struct TickState {
uint128 reserveA;
uint128 reserveB;
uint128 totalSupply;
uint32[4] binIdsByTick;
}
/**
* @notice Tick data parameters.
* @param currentReserveA Current reserve of token A.
* @param currentReserveB Current reserve of token B.
* @param currentLiquidity Current liquidity amount.
*/
struct TickData {
uint256 currentReserveA;
uint256 currentReserveB;
uint256 currentLiquidity;
}
/**
* @notice Bin state parameters.
* @param mergeBinBalance LP token balance that this bin possesses of the merge bin.
* @param mergeId Bin ID of the bin that this bin has merged into.
* @param totalSupply Total amount of LP tokens in this bin.
* @param kind One of the 4 kinds (0=static, 1=right, 2=left, 3=both).
* @param tick The lower price tick of the bin in its current state.
* @param tickBalance Balance of the tick.
*/
struct BinState {
uint128 mergeBinBalance;
uint128 tickBalance;
uint128 totalSupply;
uint8 kind;
int32 tick;
uint32 mergeId;
}
/**
* @notice Parameters for swap.
* @param amount Amount of the token that is either the input if exactOutput is false
* or the output if exactOutput is true.
* @param tokenAIn Boolean indicating whether tokenA is the input.
* @param exactOutput Boolean indicating whether the amount specified is
* the exact output amount (true).
* @param tickLimit The furthest tick a swap will execute in. If no limit
* is desired, value should be set to type(int32).max for a tokenAIn swap
* and type(int32).min for a swap where tokenB is the input.
*/
struct SwapParams {
uint256 amount;
bool tokenAIn;
bool exactOutput;
int32 tickLimit;
}
/**
* @notice Parameters associated with adding liquidity.
* @param kind One of the 4 kinds (0=static, 1=right, 2=left, 3=both).
* @param ticks Array of ticks to add liquidity to.
* @param amounts Array of bin LP amounts to add.
*/
struct AddLiquidityParams {
uint8 kind;
int32[] ticks;
uint128[] amounts;
}
/**
* @notice Parameters for each bin that will have liquidity removed.
* @param binIds Index array of the bins losing liquidity.
* @param amounts Array of bin LP amounts to remove.
*/
struct RemoveLiquidityParams {
uint32[] binIds;
uint128[] amounts;
}
/**
* @notice State of the pool.
* @param reserveA Pool tokenA balanceOf at end of last operation
* @param reserveB Pool tokenB balanceOf at end of last operation
* @param lastTwaD8 Value of log time weighted average price at last block.
* Value is 8-decimal scale and is in the fractional tick domain. E.g. a
* value of 12.3e8 indicates the TWAP was 3/10ths of the way into the 12th
* tick.
* @param lastLogPriceD8 Value of log price at last block. Value is
* 8-decimal scale and is in the fractional tick domain. E.g. a value of
* 12.3e8 indicates the price was 3/10ths of the way into the 12th tick.
* @param lastTimestamp Last block.timestamp value in seconds for latest
* swap transaction.
* @param activeTick Current tick position that contains the active bins.
* @param isLocked Pool isLocked, E.g., locked or unlocked; isLocked values
* defined in Pool.sol.
* @param binCounter Index of the last bin created.
* @param protocolFeeRatioD3 Ratio of the swap fee that is kept for the
* protocol.
*/
struct State {
uint128 reserveA;
uint128 reserveB;
int64 lastTwaD8;
int64 lastLogPriceD8;
uint40 lastTimestamp;
int32 activeTick;
bool isLocked;
uint32 binCounter;
uint8 protocolFeeRatioD3;
}
/**
* @notice Internal data used for data passing between Pool and Bin code.
*/
struct BinDelta {
uint128 deltaA;
uint128 deltaB;
}
/**
* @notice 1-15 number to represent the active kinds.
* @notice 0b0001 = static;
* @notice 0b0010 = right;
* @notice 0b0100 = left;
* @notice 0b1000 = both;
*
* E.g. a pool with all 4 modes will have kinds = b1111 = 15
*/
function kinds() external view returns (uint8 _kinds);
/**
* @notice Returns whether a pool has permissioned functions. If true, the
* `accessor()` of the pool can set the pool fees. Other functions in the
* pool may also be permissioned; whether or not they are can be determined
* through calls to `permissionedLiquidity()` and `permissionedSwap()`.
*/
function permissionedPool() external view returns (bool _permissionedPool);
/**
* @notice Returns whether a pool has permissioned liquidity management
* functions. If true, the pool is incompatible with permissioned pool
* liquidity management infrastructure.
*/
function permissionedLiquidity() external view returns (bool _permissionedLiquidity);
/**
* @notice Returns whether a pool has a permissioned swap functions. If
* true, the pool is incompatible with permissioned pool swap router
* infrastructure.
*/
function permissionedSwap() external view returns (bool _permissionedSwap);
/**
* @notice Pool swap fee for the given direction (A-in or B-in swap) in
* 18-decimal format. E.g. 0.01e18 is a 1% swap fee.
*/
function fee(bool tokenAIn) external view returns (uint256);
/**
* @notice TickSpacing of pool where 1.0001^tickSpacing is the bin width.
*/
function tickSpacing() external view returns (uint256);
/**
* @notice Lookback period of pool in seconds.
*/
function lookback() external view returns (uint256);
/**
* @notice Address of Pool accessor. This is Zero address for
* permissionless pools.
*/
function accessor() external view returns (address);
/**
* @notice Pool tokenA. Address of tokenA is such that tokenA < tokenB.
*/
function tokenA() external view returns (IERC20);
/**
* @notice Pool tokenB.
*/
function tokenB() external view returns (IERC20);
/**
* @notice Deploying factory of the pool and also contract that has ability
* to set and collect protocol fees for the pool.
*/
function factory() external view returns (IMaverickV2Factory);
/**
* @notice Most significant bit of scale value is a flag to indicate whether
* tokenA has more or less than 18 decimals. Scale is used in conjuction
* with Math.toScale/Math.fromScale functions to convert from token amounts
* to D18 scale internal pool accounting.
*/
function tokenAScale() external view returns (uint256);
/**
* @notice Most significant bit of scale value is a flag to indicate whether
* tokenA has more or less than 18 decimals. Scale is used in conjuction
* with Math.toScale/Math.fromScale functions to convert from token amounts
* to D18 scale internal pool accounting.
*/
function tokenBScale() external view returns (uint256);
/**
* @notice ID of bin at input tick position and kind.
*/
function binIdByTickKind(int32 tick, uint256 kind) external view returns (uint32);
/**
* @notice Accumulated tokenA protocol fee.
*/
function protocolFeeA() external view returns (uint128);
/**
* @notice Accumulated tokenB protocol fee.
*/
function protocolFeeB() external view returns (uint128);
/**
* @notice Lending fee rate on flash loans.
*/
function lendingFeeRateD18() external view returns (uint256);
/**
* @notice External function to get the current time-weighted average price.
*/
function getCurrentTwa() external view returns (int256);
/**
* @notice External function to get the state of the pool.
*/
function getState() external view returns (State memory);
/**
* @notice Return state of Bin at input binId.
*/
function getBin(uint32 binId) external view returns (BinState memory bin);
/**
* @notice Return state of Tick at input tick position.
*/
function getTick(int32 tick) external view returns (TickState memory tickState);
/**
* @notice Retrieves the balance of a user within a bin.
* @param user The user's address.
* @param subaccount The subaccount for the user.
* @param binId The ID of the bin.
*/
function balanceOf(address user, uint256 subaccount, uint32 binId) external view returns (uint128 lpToken);
/**
* @notice Add liquidity to a pool. This function allows users to deposit
* tokens into a liquidity pool.
* @dev This function will call `maverickV2AddLiquidityCallback` on the
* calling contract to collect the tokenA/tokenB payment.
* @param recipient The account that will receive credit for the added liquidity.
* @param subaccount The account that will receive credit for the added liquidity.
* @param params Parameters containing the details for adding liquidity,
* such as token types and amounts.
* @param data Bytes information that gets passed to the callback.
* @return tokenAAmount The amount of token A added to the pool.
* @return tokenBAmount The amount of token B added to the pool.
* @return binIds An array of bin IDs where the liquidity is stored.
*/
function addLiquidity(
address recipient,
uint256 subaccount,
AddLiquidityParams calldata params,
bytes calldata data
) external returns (uint256 tokenAAmount, uint256 tokenBAmount, uint32[] memory binIds);
/**
* @notice Removes liquidity from the pool.
* @dev Liquidy can only be removed from a bin that is either unmerged or
* has a mergeId of an unmerged bin. If a bin is merged more than one
* level deep, it must be migrated up the merge stack to the root bin
* before liquidity removal.
* @param recipient The address to receive the tokens.
* @param subaccount The subaccount for the recipient.
* @param params The parameters for removing liquidity.
* @return tokenAOut The amount of token A received.
* @return tokenBOut The amount of token B received.
*/
function removeLiquidity(
address recipient,
uint256 subaccount,
RemoveLiquidityParams calldata params
) external returns (uint256 tokenAOut, uint256 tokenBOut);
/**
* @notice Migrate bins up the linked list of merged bins so that its
* mergeId is the currrent active bin.
* @dev Liquidy can only be removed from a bin that is either unmerged or
* has a mergeId of an unmerged bin. If a bin is merged more than one
* level deep, it must be migrated up the merge stack to the root bin
* before liquidity removal.
* @param binId The ID of the bin to migrate.
* @param maxRecursion The maximum recursion depth for the migration.
*/
function migrateBinUpStack(uint32 binId, uint32 maxRecursion) external;
/**
* @notice Swap tokenA/tokenB assets in the pool. The swap user has two
* options for funding their swap.
* - The user can push the input token amount to the pool before calling
* the swap function. In order to avoid having the pool call the callback,
* the user should pass a zero-length `data` bytes object with the swap
* call.
* - The user can send the input token amount to the pool when the pool
* calls the `maverickV2SwapCallback` function on the calling contract.
* That callback has input parameters that specify the token address of the
* input token, the input and output amounts, and the bytes data sent to
* the swap function.
* @dev If the users elects to do a callback-based swap, the output
* assets will be sent before the callback is called, allowing the user to
* execute flash swaps. However, the pool does have reentrancy protection,
* so a swapper will not be able to interact with the same pool again
* while they are in the callback function.
* @param recipient The address to receive the output tokens.
* @param params Parameters containing the details of the swap
* @param data Bytes information that gets passed to the callback.
*/
function swap(
address recipient,
SwapParams memory params,
bytes calldata data
) external returns (uint256 amountIn, uint256 amountOut);
/**
* @notice Loan tokenA/tokenB assets from the pool to recipient. The fee
* rate of a loan is determined by `lendingFeeRateD18`, which is set at the
* protocol level by the factory. This function calls
* `maverickV2FlashLoanCallback` on the calling contract. At the end of
* the callback, the caller must pay back the loan with fee (if there is a
* fee).
* @param recipient The address to receive the loaned tokens.
* @param amountB Loan amount of tokenA sent to recipient.
* @param amountB Loan amount of tokenB sent to recipient.
* @param data Bytes information that gets passed to the callback.
*/
function flashLoan(
address recipient,
uint256 amountA,
uint256 amountB,
bytes calldata data
) external returns (uint128 lendingFeeA, uint128 lendingFeeB);
/**
* @notice Sets fee for permissioned pools. May only be called by the
* accessor.
*/
function setFee(uint256 newFeeAIn, uint256 newFeeBIn) external;
}
// SPDX-License-Identifier: GPL-2.0-or-later
pragma solidity ^0.8.25;
import {IMaverickV2Pool} from "../../v2-common/interfaces/IMaverickV2Pool.sol";
interface IMaverickV2Quoter {
error QuoterInvalidSwap();
error QuoterInvalidAddLiquidity();
/**
* @notice Calculates a swap on a MaverickV2Pool and returns the resulting
* amount and estimated gas. The gas estimate is only a rough estimate and
* may not match a swap's gas.
* @param pool The MaverickV2Pool to swap on.
* @param amount The input amount.
* @param tokenAIn Indicates if token A is the input token.
* @param exactOutput Indicates if the amount is the output amount (true)
* or input amount (false). If the tickLimit is reached, the full value of
* the exactOutput may not be returned because the pool will stop swapping
* before the whole order is filled.
* @param tickLimit The tick limit for the swap. Once the swap lands in
* this tick, it will stop and return the output amount swapped up to that
* tick.
*/
function calculateSwap(
IMaverickV2Pool pool,
uint128 amount,
bool tokenAIn,
bool exactOutput,
int32 tickLimit
) external returns (uint256 amountIn, uint256 amountOut, uint256 gasEstimate);
/**
* @notice Calculates a multihop swap and returns the resulting amount and
* estimated gas. The gas estimate is only a rough estimate and
* may not match a swap's gas.
* @param path The path of pools to swap through. Path is given by an
* packed array of (pool, tokenAIn) tuples. So each step in the path is 160
* + 8 = 168 bits of data. e.g. path = abi.encodePacked(pool1, true, pool2, false);
* @param amount The input amount.
* @param exactOutput A boolean indicating if exact output is required.
*/
function calculateMultiHopSwap(
bytes memory path,
uint256 amount,
bool exactOutput
) external returns (uint256 returnAmount, uint256 gasEstimate);
/**
* @notice Computes the token amounts required for a given set of
* addLiquidity parameters. The gas estimate is only a rough estimate and
* may not match a add's gas.
*/
function calculateAddLiquidity(
IMaverickV2Pool pool,
IMaverickV2Pool.AddLiquidityParams calldata params
) external returns (uint256 amountA, uint256 amountB, uint256 gasEstimate);
/**
* @notice Pool's sqrt price.
*/
function poolSqrtPrice(IMaverickV2Pool pool) external view returns (uint256 sqrtPrice);
}
// SPDX-License-Identifier: GPL-2.0-or-later
pragma solidity ^0.8.25;
import {IVotes} from "@openzeppelin/contracts/governance/utils/IVotes.sol";
import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import {IERC20Metadata} from "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol";
import {IERC6372} from "@openzeppelin/contracts/interfaces/IERC6372.sol";
import {IHistoricalBalance} from "./IHistoricalBalance.sol";
interface IMaverickV2VotingEscrowBase is IVotes, IHistoricalBalance {
error VotingEscrowTransferNotSupported();
error VotingEscrowInvalidAddress(address);
error VotingEscrowInvalidAmount(uint256);
error VotingEscrowInvalidDuration(uint256 duration, uint256 minDuration, uint256 maxDuration);
error VotingEscrowInvalidEndTime(uint256 newEnd, uint256 oldEnd);
error VotingEscrowStakeStillLocked(uint256 currentTime, uint256 endTime);
error VotingEscrowStakeAlreadyRedeemed();
error VotingEscrowNotApprovedExtender(address account, address extender, uint256 lockupId);
error VotingEscrowIncentiveAlreadyClaimed(address account, uint256 batchIndex);
error VotingEscrowNoIncentivesToClaim(address account, uint256 batchIndex);
error VotingEscrowInvalidExtendIncentiveToken(IERC20 incentiveToken);
error VotingEscrowNoSupplyAtTimepoint();
error VotingEscrowIncentiveTimepointInFuture(uint256 timestamp, uint256 claimTimepoint);
event Stake(address indexed user, uint256 lockupId, Lockup);
event Unstake(address indexed user, uint256 lockupId, Lockup);
event ExtenderApproval(address staker, address extender, uint256 lockupId, bool newState);
event ClaimIncentiveBatch(uint256 batchIndex, address account, uint256 claimAmount);
event CreateNewIncentiveBatch(
address user,
uint256 amount,
uint256 timepoint,
uint256 stakeDuration,
IERC20 incentiveToken
);
struct Lockup {
uint128 amount;
uint128 end;
uint256 votes;
}
struct ClaimInformation {
bool timepointInPast;
bool hasClaimed;
uint128 claimAmount;
}
struct BatchInformation {
uint128 totalIncentives;
uint128 stakeDuration;
uint48 claimTimepoint;
IERC20 incentiveToken;
}
struct TokenIncentiveTotals {
uint128 totalIncentives;
uint128 claimedIncentives;
}
// solhint-disable-next-line func-name-mixedcase
function MIN_STAKE_DURATION() external returns (uint256 duration);
// solhint-disable-next-line func-name-mixedcase
function MAX_STAKE_DURATION() external returns (uint256 duration);
// solhint-disable-next-line func-name-mixedcase
function YEAR_BASE() external returns (uint256);
/**
* @notice This function retrieves the address of the ERC20 token used as the base token for staking and rewards.
* @return baseToken The address of the IERC20 base token contract.
*/
function baseToken() external returns (IERC20);
/**
* @notice This function retrieves the starting timestamp. This may be used
* for reward calculations or other time-based logic.
*/
function startTimestamp() external returns (uint256 timestamp);
/**
* @notice This function retrieves the details of a specific lockup for a given staker and lockup index.
* @param staker The address of the staker for which to retrieve the lockup details.
* @param index The index of the lockup within the staker's lockup history.
* @return lockup A Lockup struct containing details about the lockup (see struct definition for details).
*/
function getLockup(address staker, uint256 index) external view returns (Lockup memory lockup);
/**
* @notice This function retrieves the total number of lockups associated with a specific staker.
* @param staker The address of the staker for which to retrieve the lockup count.
* @return count The total number of lockups for the staker.
*/
function lockupCount(address staker) external view returns (uint256 count);
/**
* @notice This function simulates a lockup scenario, providing details about the resulting lockup structure for a specified amount and duration.
* @param amount The amount of tokens to be locked.
* @param duration The duration of the lockup period.
* @return lockup A Lockup struct containing details about the simulated lockup (see struct definition for details).
*/
function previewVotes(uint128 amount, uint256 duration) external view returns (Lockup memory lockup);
/**
* @notice This function grants approval for a designated extender contract to manage a specific lockup on behalf of the staker.
* @param extender The address of the extender contract to be approved.
* @param lockupId The ID of the lockup for which to grant approval.
*/
function approveExtender(address extender, uint256 lockupId) external;
/**
* @notice This function revokes approval previously granted to an extender contract for managing a specific lockup.
* @param extender The address of the extender contract whose approval is being revoked.
* @param lockupId The ID of the lockup for which to revoke approval.
*/
function revokeExtender(address extender, uint256 lockupId) external;
/**
* @notice This function checks whether a specific account has been approved by a staker to manage a particular lockup through an extender contract.
* @param account The address of the account to check for approval (may be the extender or another account).
* @param extender The address of the extender contract for which to check approval.
* @param lockupId The ID of the lockup to verify approval for.
* @return isApproved True if the account is approved for the lockup, False otherwise (bool).
*/
function isApprovedExtender(address account, address extender, uint256 lockupId) external view returns (bool);
/**
* @notice This function extends the lockup period for the caller (msg.sender) for a specified lockup ID, adding a new duration and amount.
* @param lockupId The ID of the lockup to be extended.
* @param duration The additional duration to extend the lockup by.
* @param amount The additional amount of tokens to be locked.
* @return newLockup A Lockup struct containing details about the newly extended lockup (see struct definition for details).
*/
function extendForSender(
uint256 lockupId,
uint256 duration,
uint128 amount
) external returns (Lockup memory newLockup);
/**
* @notice This function extends the lockup period for a specified account, adding a new duration and amount. The caller (msg.sender) must be authorized to manage the lockup through an extender contract.
* @param account The address of the account whose lockup is being extended.
* @param lockupId The ID of the lockup to be extended.
* @param duration The additional duration to extend the lockup by.
* @param amount The additional amount of tokens to be locked.
* @return newLockup A Lockup struct containing details about the newly extended lockup (see struct definition for details).
*/
function extendForAccount(
address account,
uint256 lockupId,
uint256 duration,
uint128 amount
) external returns (Lockup memory newLockup);
/**
* @notice This function merges multiple lockups associated with the caller
* (msg.sender) into a single new lockup.
* @param lockupIds An array containing the IDs of the lockups to be merged.
* @return newLockup A Lockup struct containing details about the newly merged lockup (see struct definition for details).
*/
function merge(uint256[] memory lockupIds) external returns (Lockup memory newLockup);
/**
* @notice This function unstakes the specified lockup ID for the caller (msg.sender), returning the details of the unstaked lockup.
* @param lockupId The ID of the lockup to be unstaked.
* @param to The address to which the unstaked tokens should be sent (optional, defaults to msg.sender).
* @return lockup A Lockup struct containing details about the unstaked lockup (see struct definition for details).
*/
function unstake(uint256 lockupId, address to) external returns (Lockup memory lockup);
/**
* @notice This function is a simplified version of `unstake` that automatically sends the unstaked tokens to the caller (msg.sender).
* @param lockupId The ID of the lockup to be unstaked.
* @return lockup A Lockup struct containing details about the unstaked lockup (see struct definition for details).
*/
function unstakeToSender(uint256 lockupId) external returns (Lockup memory lockup);
/**
* @notice This function stakes a specified amount of tokens for the caller
* (msg.sender) for a defined duration.
* @param amount The amount of tokens to be staked.
* @param duration The duration of the lockup period.
* @return lockup A Lockup struct containing details about the newly
* created lockup (see struct definition for details).
*/
function stakeToSender(uint128 amount, uint256 duration) external returns (Lockup memory lockup);
/**
* @notice This function stakes a specified amount of tokens for a defined
* duration, allowing the caller (msg.sender) to specify an optional
* recipient for the staked tokens.
* @param amount The amount of tokens to be staked.
* @param duration The duration of the lockup period.
* @param to The address to which the staked tokens will be credited (optional, defaults to msg.sender).
* @return lockup A Lockup struct containing details about the newly
* created lockup (see struct definition for details).
*/
function stake(uint128 amount, uint256 duration, address to) external returns (Lockup memory);
/**
* @notice This function retrieves the total incentive information for a specific ERC-20 token.
* @param token The address of the ERC20 token for which to retrieve incentive totals.
* @return totals A TokenIncentiveTotals struct containing details about
* the token's incentives (see struct definition for details).
*/
function incentiveTotals(IERC20 token) external view returns (TokenIncentiveTotals memory);
/**
* @notice This function retrieves the total number of created incentive batches.
* @return count The total number of incentive batches.
*/
function incentiveBatchCount() external view returns (uint256);
/**
* @notice This function retrieves claim information for a specific account and incentive batch index.
* @param account The address of the account for which to retrieve claim information.
* @param batchIndex The index of the incentive batch for which to retrieve
* claim information.
* @return claimInformation A ClaimInformation struct containing details about the
* account's claims for the specified batch (see struct definition for
* details).
* @return batchInformation A BatchInformation struct containing details about the
* specified batch (see struct definition for details).
*/
function claimAndBatchInformation(
address account,
uint256 batchIndex
) external view returns (ClaimInformation memory claimInformation, BatchInformation memory batchInformation);
/**
* @notice This function retrieves batch information for a incentive batch index.
* @param batchIndex The index of the incentive batch for which to retrieve
* claim information.
* @return info A BatchInformation struct containing details about the
* specified batch (see struct definition for details).
*/
function incentiveBatchInformation(uint256 batchIndex) external view returns (BatchInformation memory info);
/**
* @notice This function allows claiming rewards from a specific incentive
* batch while simultaneously extending a lockup with the claimed tokens.
* @param batchIndex The index of the incentive batch from which to claim rewards.
* @param lockupId The ID of the lockup to be extended with the claimed tokens.
* @return lockup A Lockup struct containing details about the updated
* lockup after extension (see struct definition for details).
* @return claimAmount The amount of tokens claimed from the incentive batch.
*/
function claimFromIncentiveBatchAndExtend(
uint256 batchIndex,
uint256 lockupId
) external returns (Lockup memory lockup, uint128 claimAmount);
/**
* @notice This function allows claiming rewards from a specific incentive
* batch, without extending any lockups.
* @param batchIndex The index of the incentive batch from which to claim rewards.
* @return lockup A Lockup struct containing details about the user's
* lockup that might have been affected by the claim (see struct definition
* for details).
* @return claimAmount The amount of tokens claimed from the incentive batch.
*/
function claimFromIncentiveBatch(uint256 batchIndex) external returns (Lockup memory lockup, uint128 claimAmount);
/**
* @notice This function creates a new incentive batch for a specified amount
* of incentive tokens, timepoint, stake duration, and associated ERC-20
* token. An incentive batch is a reward of incentives put up by the
* caller at a certain timepoint. The incentive batch is claimable by ve
* holders after the timepoint has passed. The ve holders will receive
* their incentive pro rata of their vote balance (`pastbalanceOf`) at that
* timepoint. The incentivizer can specify that users have to stake the
* resulting incentive for a given `stakeDuration` number of seconds.
* `stakeDuration` can either be zero, meaning that no staking is required
* on redemption, or can be a number between `MIN_STAKE_DURATION()` and
* `MAX_STAKE_DURATION()`.
* @param amount The total amount of incentive tokens to be distributed in the batch.
* @param timepoint The timepoint at which the incentive batch starts accruing rewards.
* @param stakeDuration The duration of the lockup period required to be
* eligible for the incentive batch rewards.
* @param incentiveToken The address of the ERC20 token used for the incentive rewards.
* @return index The index of the newly created incentive batch.
*/
function createIncentiveBatch(
uint128 amount,
uint48 timepoint,
uint128 stakeDuration,
IERC20 incentiveToken
) external returns (uint256 index);
}
interface IMaverickV2VotingEscrow is IMaverickV2VotingEscrowBase, IERC20Metadata, IERC6372 {}
// SPDX-License-Identifier: GPL-2.0-or-later
pragma solidity ^0.8.25;
import {IERC20} from "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import {IMaverickV2VotingEscrow} from "./IMaverickV2VotingEscrow.sol";
interface IMaverickV2VotingEscrowFactory {
error VotingEscrowTokenAlreadyExists(IERC20 baseToken, IMaverickV2VotingEscrow veToken);
/**
* @notice This function retrieves the address of the legacy Maverick V1
* Voting Escrow (veMAV) token. The address will be zero for blockchains
* where this contract is deployed that do not have a legacy MAV contract
* deployed.
* @return legacyVeMav The address of the IERC20 legacy veMav token.
*/
function legacyVeMav() external view returns (IERC20);
/**
* @notice This function checks whether a provided IMaverickV2VotingEscrow
* contract address was created by this factory.
* @param veToken The address of the IMaverickV2VotingEscrow contract to be checked.
* @return isFactoryToken True if the veToken was created by this factory, False otherwise (bool).
*/
function isFactoryToken(IMaverickV2VotingEscrow veToken) external view returns (bool);
/**
* @notice This function creates a new Maverick V2 Voting Escrow (veToken)
* contract for a specified ERC20 base token.
* @dev Once the ve contract is created, it will call `name()` and
* `symbol()` on the `baseToken`. If those functions do not exist, the ve
* creation will revert.
* @param baseToken The address of the ERC-20 token to be used as the base token for the new veToken.
* @return veToken The address of the newly created IMaverickV2VotingEscrow contract.
*/
function createVotingEscrow(IERC20 baseToken) external returns (IMaverickV2VotingEscrow veToken);
/**
* @notice This function retrieves a paginated list of existing Maverick V2
* Voting Escrow (veToken) contracts within a specified index range.
* @param startIndex The starting index for the desired range of veTokens.
* @param endIndex The ending index for the desired range of veTokens.
* @return votingEscrows An array of IMaverickV2VotingEscrow addresses
* representing the veTokens within the specified range.
*/
function votingEscrows(
uint256 startIndex,
uint256 endIndex
) external view returns (IMaverickV2VotingEscrow[] memory votingEscrows);
/**
* @notice This function retrieves the total number of deployed Maverick V2
* Voting Escrow (veToken) contracts.
* @return count The total number of veTokens.
*/
function votingEscrowsCount() external view returns (uint256 count);
/**
* @notice This function retrieves the address of the existing Maverick V2
* Voting Escrow (veToken) contract associated with a specific ERC20 base
* token.
* @param baseToken The address of the ERC-20 base token for which to retrieve the veToken address.
* @return veToken The address of the IMaverickV2VotingEscrow contract
* associated with the base token, or the zero address if none exists.
*/
function veForBaseToken(IERC20 baseToken) external view returns (IMaverickV2VotingEscrow veToken);
/**
* @notice This function retrieves the default base token used for creating
* new voting escrow contracts. This state variable is only used
* temporarily when a new veToken is deployed.
* @return baseToken The address of the default ERC-20 base token.
*/
function baseTokenParameter() external returns (IERC20);
}
// SPDX-License-Identifier: GPL-2.0-or-later
pragma solidity ^0.8.25;
import {IMaverickV2VotingEscrow, IMaverickV2VotingEscrowFactory} from "./external/IMaverickV2VotingEscrowFactory.sol";
import {IWETH9} from "./external/IWETH9.sol";
import {IMaverickV2Pool} from "../v2-common/interfaces/IMaverickV2Pool.sol";
import {IMaverickV2Factory} from "../v2-common/interfaces/IMaverickV2Factory.sol";
import {IMaverickV2Quoter} from "./external/IMaverickV2Quoter.sol";
interface IVeZap {
error AmountMinimumNotMet(uint256 amountOut, uint256 minTokenStaked);
error NotFactoryPool();
/**
* @notice Gets the WETH contract address
*/
function weth() external view returns (IWETH9);
/**
* @notice Gets the Maverick V2 voting escrow factory
*/
function veFactory() external view returns (IMaverickV2VotingEscrowFactory);
/**
* @notice Gets the Maverick V2 price quoter
*/
function quoter() external view returns (IMaverickV2Quoter);
/**
* @notice Gets the Maverick V2 pool factory
*/
function poolFactory() external view returns (IMaverickV2Factory);
/**
* @notice Function take user's sent eth, swaps it in the specified pool,
* and then stakes it in the output token's ve contract. The ve stake is
* staked on behalf of the caller.
*/
function ethToStakeForSender(
IMaverickV2Pool ethToTokenPool,
uint256 duration,
uint256 minTokenStaked
) external payable returns (IMaverickV2VotingEscrow.Lockup memory lockup, IMaverickV2VotingEscrow ve);
/**
* @notice Function take user's sent eth, swaps it in the specified pool,
* and then stakes it in the output token's ve contract. The ve stake is
* staked on behalf of the specified recipient.
*/
function ethToStake(
address recipient,
IMaverickV2Pool ethToTokenPool,
uint256 duration,
uint256 minTokenStaked
) external payable returns (IMaverickV2VotingEscrow.Lockup memory lockup, IMaverickV2VotingEscrow ve);
/**
* @notice Estimates the stake. Lockup.amount provides the expected
* underlying stake amount of token.
*/
function estimateEthToStake(
IMaverickV2Pool ethToTokenPool,
uint256 amountIn,
uint256 duration
) external returns (IMaverickV2VotingEscrow.Lockup memory lockup, IMaverickV2VotingEscrow ve);
}
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (governance/utils/IVotes.sol)
pragma solidity ^0.8.20;
/**
* @dev Common interface for {ERC20Votes}, {ERC721Votes}, and other {Votes}-enabled contracts.
*/
interface IVotes {
/**
* @dev The signature used has expired.
*/
error VotesExpiredSignature(uint256 expiry);
/**
* @dev Emitted when an account changes their delegate.
*/
event DelegateChanged(address indexed delegator, address indexed fromDelegate, address indexed toDelegate);
/**
* @dev Emitted when a token transfer or delegate change results in changes to a delegate's number of voting units.
*/
event DelegateVotesChanged(address indexed delegate, uint256 previousVotes, uint256 newVotes);
/**
* @dev Returns the current amount of votes that `account` has.
*/
function getVotes(address account) external view returns (uint256);
/**
* @dev Returns the amount of votes that `account` had at a specific moment in the past. If the `clock()` is
* configured to use block numbers, this will return the value at the end of the corresponding block.
*/
function getPastVotes(address account, uint256 timepoint) external view returns (uint256);
/**
* @dev Returns the total supply of votes available at a specific moment in the past. If the `clock()` is
* configured to use block numbers, this will return the value at the end of the corresponding block.
*
* NOTE: This value is the sum of all available votes, which is not necessarily the sum of all delegated votes.
* Votes that have not been delegated are still part of total supply, even though they would not participate in a
* vote.
*/
function getPastTotalSupply(uint256 timepoint) external view returns (uint256);
/**
* @dev Returns the delegate that `account` has chosen.
*/
function delegates(address account) external view returns (address);
/**
* @dev Delegates votes from the sender to `delegatee`.
*/
function delegate(address delegatee) external;
/**
* @dev Delegates votes from signer to `delegatee`.
*/
function delegateBySig(address delegatee, uint256 nonce, uint256 expiry, uint8 v, bytes32 r, bytes32 s) external;
}
// SPDX-License-Identifier: GPL-2.0-or-later
pragma solidity ^0.8.25;
import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
interface IWETH9 is IERC20 {
event Deposit(address indexed dst, uint256 wad);
event Withdrawal(address indexed src, uint256 wad);
function deposit() external payable;
function withdraw(uint256) external;
}
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (utils/math/SafeCast.sol)
// This file was procedurally generated from scripts/generate/templates/SafeCast.js.
pragma solidity ^0.8.20;
/**
* @dev Wrappers over Solidity's uintXX/intXX casting operators with added overflow
* checks.
*
* Downcasting from uint256/int256 in Solidity does not revert on overflow. This can
* easily result in undesired exploitation or bugs, since developers usually
* assume that overflows raise errors. `SafeCast` restores this intuition by
* reverting the transaction when such an operation overflows.
*
* Using this library instead of the unchecked operations eliminates an entire
* class of bugs, so it's recommended to use it always.
*/
library SafeCast {
/**
* @dev Value doesn't fit in an uint of `bits` size.
*/
error SafeCastOverflowedUintDowncast(uint8 bits, uint256 value);
/**
* @dev An int value doesn't fit in an uint of `bits` size.
*/
error SafeCastOverflowedIntToUint(int256 value);
/**
* @dev Value doesn't fit in an int of `bits` size.
*/
error SafeCastOverflowedIntDowncast(uint8 bits, int256 value);
/**
* @dev An uint value doesn't fit in an int of `bits` size.
*/
error SafeCastOverflowedUintToInt(uint256 value);
/**
* @dev Returns the downcasted uint248 from uint256, reverting on
* overflow (when the input is greater than largest uint248).
*
* Counterpart to Solidity's `uint248` operator.
*
* Requirements:
*
* - input must fit into 248 bits
*/
function toUint248(uint256 value) internal pure returns (uint248) {
if (value > type(uint248).max) {
revert SafeCastOverflowedUintDowncast(248, value);
}
return uint248(value);
}
/**
* @dev Returns the downcasted uint240 from uint256, reverting on
* overflow (when the input is greater than largest uint240).
*
* Counterpart to Solidity's `uint240` operator.
*
* Requirements:
*
* - input must fit into 240 bits
*/
function toUint240(uint256 value) internal pure returns (uint240) {
if (value > type(uint240).max) {
revert SafeCastOverflowedUintDowncast(240, value);
}
return uint240(value);
}
/**
* @dev Returns the downcasted uint232 from uint256, reverting on
* overflow (when the input is greater than largest uint232).
*
* Counterpart to Solidity's `uint232` operator.
*
* Requirements:
*
* - input must fit into 232 bits
*/
function toUint232(uint256 value) internal pure returns (uint232) {
if (value > type(uint232).max) {
revert SafeCastOverflowedUintDowncast(232, value);
}
return uint232(value);
}
/**
* @dev Returns the downcasted uint224 from uint256, reverting on
* overflow (when the input is greater than largest uint224).
*
* Counterpart to Solidity's `uint224` operator.
*
* Requirements:
*
* - input must fit into 224 bits
*/
function toUint224(uint256 value) internal pure returns (uint224) {
if (value > type(uint224).max) {
revert SafeCastOverflowedUintDowncast(224, value);
}
return uint224(value);
}
/**
* @dev Returns the downcasted uint216 from uint256, reverting on
* overflow (when the input is greater than largest uint216).
*
* Counterpart to Solidity's `uint216` operator.
*
* Requirements:
*
* - input must fit into 216 bits
*/
function toUint216(uint256 value) internal pure returns (uint216) {
if (value > type(uint216).max) {
revert SafeCastOverflowedUintDowncast(216, value);
}
return uint216(value);
}
/**
* @dev Returns the downcasted uint208 from uint256, reverting on
* overflow (when the input is greater than largest uint208).
*
* Counterpart to Solidity's `uint208` operator.
*
* Requirements:
*
* - input must fit into 208 bits
*/
function toUint208(uint256 value) internal pure returns (uint208) {
if (value > type(uint208).max) {
revert SafeCastOverflowedUintDowncast(208, value);
}
return uint208(value);
}
/**
* @dev Returns the downcasted uint200 from uint256, reverting on
* overflow (when the input is greater than largest uint200).
*
* Counterpart to Solidity's `uint200` operator.
*
* Requirements:
*
* - input must fit into 200 bits
*/
function toUint200(uint256 value) internal pure returns (uint200) {
if (value > type(uint200).max) {
revert SafeCastOverflowedUintDowncast(200, value);
}
return uint200(value);
}
/**
* @dev Returns the downcasted uint192 from uint256, reverting on
* overflow (when the input is greater than largest uint192).
*
* Counterpart to Solidity's `uint192` operator.
*
* Requirements:
*
* - input must fit into 192 bits
*/
function toUint192(uint256 value) internal pure returns (uint192) {
if (value > type(uint192).max) {
revert SafeCastOverflowedUintDowncast(192, value);
}
return uint192(value);
}
/**
* @dev Returns the downcasted uint184 from uint256, reverting on
* overflow (when the input is greater than largest uint184).
*
* Counterpart to Solidity's `uint184` operator.
*
* Requirements:
*
* - input must fit into 184 bits
*/
function toUint184(uint256 value) internal pure returns (uint184) {
if (value > type(uint184).max) {
revert SafeCastOverflowedUintDowncast(184, value);
}
return uint184(value);
}
/**
* @dev Returns the downcasted uint176 from uint256, reverting on
* overflow (when the input is greater than largest uint176).
*
* Counterpart to Solidity's `uint176` operator.
*
* Requirements:
*
* - input must fit into 176 bits
*/
function toUint176(uint256 value) internal pure returns (uint176) {
if (value > type(uint176).max) {
revert SafeCastOverflowedUintDowncast(176, value);
}
return uint176(value);
}
/**
* @dev Returns the downcasted uint168 from uint256, reverting on
* overflow (when the input is greater than largest uint168).
*
* Counterpart to Solidity's `uint168` operator.
*
* Requirements:
*
* - input must fit into 168 bits
*/
function toUint168(uint256 value) internal pure returns (uint168) {
if (value > type(uint168).max) {
revert SafeCastOverflowedUintDowncast(168, value);
}
return uint168(value);
}
/**
* @dev Returns the downcasted uint160 from uint256, reverting on
* overflow (when the input is greater than largest uint160).
*
* Counterpart to Solidity's `uint160` operator.
*
* Requirements:
*
* - input must fit into 160 bits
*/
function toUint160(uint256 value) internal pure returns (uint160) {
if (value > type(uint160).max) {
revert SafeCastOverflowedUintDowncast(160, value);
}
return uint160(value);
}
/**
* @dev Returns the downcasted uint152 from uint256, reverting on
* overflow (when the input is greater than largest uint152).
*
* Counterpart to Solidity's `uint152` operator.
*
* Requirements:
*
* - input must fit into 152 bits
*/
function toUint152(uint256 value) internal pure returns (uint152) {
if (value > type(uint152).max) {
revert SafeCastOverflowedUintDowncast(152, value);
}
return uint152(value);
}
/**
* @dev Returns the downcasted uint144 from uint256, reverting on
* overflow (when the input is greater than largest uint144).
*
* Counterpart to Solidity's `uint144` operator.
*
* Requirements:
*
* - input must fit into 144 bits
*/
function toUint144(uint256 value) internal pure returns (uint144) {
if (value > type(uint144).max) {
revert SafeCastOverflowedUintDowncast(144, value);
}
return uint144(value);
}
/**
* @dev Returns the downcasted uint136 from uint256, reverting on
* overflow (when the input is greater than largest uint136).
*
* Counterpart to Solidity's `uint136` operator.
*
* Requirements:
*
* - input must fit into 136 bits
*/
function toUint136(uint256 value) internal pure returns (uint136) {
if (value > type(uint136).max) {
revert SafeCastOverflowedUintDowncast(136, value);
}
return uint136(value);
}
/**
* @dev Returns the downcasted uint128 from uint256, reverting on
* overflow (when the input is greater than largest uint128).
*
* Counterpart to Solidity's `uint128` operator.
*
* Requirements:
*
* - input must fit into 128 bits
*/
function toUint128(uint256 value) internal pure returns (uint128) {
if (value > type(uint128).max) {
revert SafeCastOverflowedUintDowncast(128, value);
}
return uint128(value);
}
/**
* @dev Returns the downcasted uint120 from uint256, reverting on
* overflow (when the input is greater than largest uint120).
*
* Counterpart to Solidity's `uint120` operator.
*
* Requirements:
*
* - input must fit into 120 bits
*/
function toUint120(uint256 value) internal pure returns (uint120) {
if (value > type(uint120).max) {
revert SafeCastOverflowedUintDowncast(120, value);
}
return uint120(value);
}
/**
* @dev Returns the downcasted uint112 from uint256, reverting on
* overflow (when the input is greater than largest uint112).
*
* Counterpart to Solidity's `uint112` operator.
*
* Requirements:
*
* - input must fit into 112 bits
*/
function toUint112(uint256 value) internal pure returns (uint112) {
if (value > type(uint112).max) {
revert SafeCastOverflowedUintDowncast(112, value);
}
return uint112(value);
}
/**
* @dev Returns the downcasted uint104 from uint256, reverting on
* overflow (when the input is greater than largest uint104).
*
* Counterpart to Solidity's `uint104` operator.
*
* Requirements:
*
* - input must fit into 104 bits
*/
function toUint104(uint256 value) internal pure returns (uint104) {
if (value > type(uint104).max) {
revert SafeCastOverflowedUintDowncast(104, value);
}
return uint104(value);
}
/**
* @dev Returns the downcasted uint96 from uint256, reverting on
* overflow (when the input is greater than largest uint96).
*
* Counterpart to Solidity's `uint96` operator.
*
* Requirements:
*
* - input must fit into 96 bits
*/
function toUint96(uint256 value) internal pure returns (uint96) {
if (value > type(uint96).max) {
revert SafeCastOverflowedUintDowncast(96, value);
}
return uint96(value);
}
/**
* @dev Returns the downcasted uint88 from uint256, reverting on
* overflow (when the input is greater than largest uint88).
*
* Counterpart to Solidity's `uint88` operator.
*
* Requirements:
*
* - input must fit into 88 bits
*/
function toUint88(uint256 value) internal pure returns (uint88) {
if (value > type(uint88).max) {
revert SafeCastOverflowedUintDowncast(88, value);
}
return uint88(value);
}
/**
* @dev Returns the downcasted uint80 from uint256, reverting on
* overflow (when the input is greater than largest uint80).
*
* Counterpart to Solidity's `uint80` operator.
*
* Requirements:
*
* - input must fit into 80 bits
*/
function toUint80(uint256 value) internal pure returns (uint80) {
if (value > type(uint80).max) {
revert SafeCastOverflowedUintDowncast(80, value);
}
return uint80(value);
}
/**
* @dev Returns the downcasted uint72 from uint256, reverting on
* overflow (when the input is greater than largest uint72).
*
* Counterpart to Solidity's `uint72` operator.
*
* Requirements:
*
* - input must fit into 72 bits
*/
function toUint72(uint256 value) internal pure returns (uint72) {
if (value > type(uint72).max) {
revert SafeCastOverflowedUintDowncast(72, value);
}
return uint72(value);
}
/**
* @dev Returns the downcasted uint64 from uint256, reverting on
* overflow (when the input is greater than largest uint64).
*
* Counterpart to Solidity's `uint64` operator.
*
* Requirements:
*
* - input must fit into 64 bits
*/
function toUint64(uint256 value) internal pure returns (uint64) {
if (value > type(uint64).max) {
revert SafeCastOverflowedUintDowncast(64, value);
}
return uint64(value);
}
/**
* @dev Returns the downcasted uint56 from uint256, reverting on
* overflow (when the input is greater than largest uint56).
*
* Counterpart to Solidity's `uint56` operator.
*
* Requirements:
*
* - input must fit into 56 bits
*/
function toUint56(uint256 value) internal pure returns (uint56) {
if (value > type(uint56).max) {
revert SafeCastOverflowedUintDowncast(56, value);
}
return uint56(value);
}
/**
* @dev Returns the downcasted uint48 from uint256, reverting on
* overflow (when the input is greater than largest uint48).
*
* Counterpart to Solidity's `uint48` operator.
*
* Requirements:
*
* - input must fit into 48 bits
*/
function toUint48(uint256 value) internal pure returns (uint48) {
if (value > type(uint48).max) {
revert SafeCastOverflowedUintDowncast(48, value);
}
return uint48(value);
}
/**
* @dev Returns the downcasted uint40 from uint256, reverting on
* overflow (when the input is greater than largest uint40).
*
* Counterpart to Solidity's `uint40` operator.
*
* Requirements:
*
* - input must fit into 40 bits
*/
function toUint40(uint256 value) internal pure returns (uint40) {
if (value > type(uint40).max) {
revert SafeCastOverflowedUintDowncast(40, value);
}
return uint40(value);
}
/**
* @dev Returns the downcasted uint32 from uint256, reverting on
* overflow (when the input is greater than largest uint32).
*
* Counterpart to Solidity's `uint32` operator.
*
* Requirements:
*
* - input must fit into 32 bits
*/
function toUint32(uint256 value) internal pure returns (uint32) {
if (value > type(uint32).max) {
revert SafeCastOverflowedUintDowncast(32, value);
}
return uint32(value);
}
/**
* @dev Returns the downcasted uint24 from uint256, reverting on
* overflow (when the input is greater than largest uint24).
*
* Counterpart to Solidity's `uint24` operator.
*
* Requirements:
*
* - input must fit into 24 bits
*/
function toUint24(uint256 value) internal pure returns (uint24) {
if (value > type(uint24).max) {
revert SafeCastOverflowedUintDowncast(24, value);
}
return uint24(value);
}
/**
* @dev Returns the downcasted uint16 from uint256, reverting on
* overflow (when the input is greater than largest uint16).
*
* Counterpart to Solidity's `uint16` operator.
*
* Requirements:
*
* - input must fit into 16 bits
*/
function toUint16(uint256 value) internal pure returns (uint16) {
if (value > type(uint16).max) {
revert SafeCastOverflowedUintDowncast(16, value);
}
return uint16(value);
}
/**
* @dev Returns the downcasted uint8 from uint256, reverting on
* overflow (when the input is greater than largest uint8).
*
* Counterpart to Solidity's `uint8` operator.
*
* Requirements:
*
* - input must fit into 8 bits
*/
function toUint8(uint256 value) internal pure returns (uint8) {
if (value > type(uint8).max) {
revert SafeCastOverflowedUintDowncast(8, value);
}
return uint8(value);
}
/**
* @dev Converts a signed int256 into an unsigned uint256.
*
* Requirements:
*
* - input must be greater than or equal to 0.
*/
function toUint256(int256 value) internal pure returns (uint256) {
if (value < 0) {
revert SafeCastOverflowedIntToUint(value);
}
return uint256(value);
}
/**
* @dev Returns the downcasted int248 from int256, reverting on
* overflow (when the input is less than smallest int248 or
* greater than largest int248).
*
* Counterpart to Solidity's `int248` operator.
*
* Requirements:
*
* - input must fit into 248 bits
*/
function toInt248(int256 value) internal pure returns (int248 downcasted) {
downcasted = int248(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(248, value);
}
}
/**
* @dev Returns the downcasted int240 from int256, reverting on
* overflow (when the input is less than smallest int240 or
* greater than largest int240).
*
* Counterpart to Solidity's `int240` operator.
*
* Requirements:
*
* - input must fit into 240 bits
*/
function toInt240(int256 value) internal pure returns (int240 downcasted) {
downcasted = int240(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(240, value);
}
}
/**
* @dev Returns the downcasted int232 from int256, reverting on
* overflow (when the input is less than smallest int232 or
* greater than largest int232).
*
* Counterpart to Solidity's `int232` operator.
*
* Requirements:
*
* - input must fit into 232 bits
*/
function toInt232(int256 value) internal pure returns (int232 downcasted) {
downcasted = int232(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(232, value);
}
}
/**
* @dev Returns the downcasted int224 from int256, reverting on
* overflow (when the input is less than smallest int224 or
* greater than largest int224).
*
* Counterpart to Solidity's `int224` operator.
*
* Requirements:
*
* - input must fit into 224 bits
*/
function toInt224(int256 value) internal pure returns (int224 downcasted) {
downcasted = int224(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(224, value);
}
}
/**
* @dev Returns the downcasted int216 from int256, reverting on
* overflow (when the input is less than smallest int216 or
* greater than largest int216).
*
* Counterpart to Solidity's `int216` operator.
*
* Requirements:
*
* - input must fit into 216 bits
*/
function toInt216(int256 value) internal pure returns (int216 downcasted) {
downcasted = int216(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(216, value);
}
}
/**
* @dev Returns the downcasted int208 from int256, reverting on
* overflow (when the input is less than smallest int208 or
* greater than largest int208).
*
* Counterpart to Solidity's `int208` operator.
*
* Requirements:
*
* - input must fit into 208 bits
*/
function toInt208(int256 value) internal pure returns (int208 downcasted) {
downcasted = int208(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(208, value);
}
}
/**
* @dev Returns the downcasted int200 from int256, reverting on
* overflow (when the input is less than smallest int200 or
* greater than largest int200).
*
* Counterpart to Solidity's `int200` operator.
*
* Requirements:
*
* - input must fit into 200 bits
*/
function toInt200(int256 value) internal pure returns (int200 downcasted) {
downcasted = int200(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(200, value);
}
}
/**
* @dev Returns the downcasted int192 from int256, reverting on
* overflow (when the input is less than smallest int192 or
* greater than largest int192).
*
* Counterpart to Solidity's `int192` operator.
*
* Requirements:
*
* - input must fit into 192 bits
*/
function toInt192(int256 value) internal pure returns (int192 downcasted) {
downcasted = int192(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(192, value);
}
}
/**
* @dev Returns the downcasted int184 from int256, reverting on
* overflow (when the input is less than smallest int184 or
* greater than largest int184).
*
* Counterpart to Solidity's `int184` operator.
*
* Requirements:
*
* - input must fit into 184 bits
*/
function toInt184(int256 value) internal pure returns (int184 downcasted) {
downcasted = int184(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(184, value);
}
}
/**
* @dev Returns the downcasted int176 from int256, reverting on
* overflow (when the input is less than smallest int176 or
* greater than largest int176).
*
* Counterpart to Solidity's `int176` operator.
*
* Requirements:
*
* - input must fit into 176 bits
*/
function toInt176(int256 value) internal pure returns (int176 downcasted) {
downcasted = int176(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(176, value);
}
}
/**
* @dev Returns the downcasted int168 from int256, reverting on
* overflow (when the input is less than smallest int168 or
* greater than largest int168).
*
* Counterpart to Solidity's `int168` operator.
*
* Requirements:
*
* - input must fit into 168 bits
*/
function toInt168(int256 value) internal pure returns (int168 downcasted) {
downcasted = int168(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(168, value);
}
}
/**
* @dev Returns the downcasted int160 from int256, reverting on
* overflow (when the input is less than smallest int160 or
* greater than largest int160).
*
* Counterpart to Solidity's `int160` operator.
*
* Requirements:
*
* - input must fit into 160 bits
*/
function toInt160(int256 value) internal pure returns (int160 downcasted) {
downcasted = int160(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(160, value);
}
}
/**
* @dev Returns the downcasted int152 from int256, reverting on
* overflow (when the input is less than smallest int152 or
* greater than largest int152).
*
* Counterpart to Solidity's `int152` operator.
*
* Requirements:
*
* - input must fit into 152 bits
*/
function toInt152(int256 value) internal pure returns (int152 downcasted) {
downcasted = int152(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(152, value);
}
}
/**
* @dev Returns the downcasted int144 from int256, reverting on
* overflow (when the input is less than smallest int144 or
* greater than largest int144).
*
* Counterpart to Solidity's `int144` operator.
*
* Requirements:
*
* - input must fit into 144 bits
*/
function toInt144(int256 value) internal pure returns (int144 downcasted) {
downcasted = int144(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(144, value);
}
}
/**
* @dev Returns the downcasted int136 from int256, reverting on
* overflow (when the input is less than smallest int136 or
* greater than largest int136).
*
* Counterpart to Solidity's `int136` operator.
*
* Requirements:
*
* - input must fit into 136 bits
*/
function toInt136(int256 value) internal pure returns (int136 downcasted) {
downcasted = int136(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(136, value);
}
}
/**
* @dev Returns the downcasted int128 from int256, reverting on
* overflow (when the input is less than smallest int128 or
* greater than largest int128).
*
* Counterpart to Solidity's `int128` operator.
*
* Requirements:
*
* - input must fit into 128 bits
*/
function toInt128(int256 value) internal pure returns (int128 downcasted) {
downcasted = int128(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(128, value);
}
}
/**
* @dev Returns the downcasted int120 from int256, reverting on
* overflow (when the input is less than smallest int120 or
* greater than largest int120).
*
* Counterpart to Solidity's `int120` operator.
*
* Requirements:
*
* - input must fit into 120 bits
*/
function toInt120(int256 value) internal pure returns (int120 downcasted) {
downcasted = int120(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(120, value);
}
}
/**
* @dev Returns the downcasted int112 from int256, reverting on
* overflow (when the input is less than smallest int112 or
* greater than largest int112).
*
* Counterpart to Solidity's `int112` operator.
*
* Requirements:
*
* - input must fit into 112 bits
*/
function toInt112(int256 value) internal pure returns (int112 downcasted) {
downcasted = int112(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(112, value);
}
}
/**
* @dev Returns the downcasted int104 from int256, reverting on
* overflow (when the input is less than smallest int104 or
* greater than largest int104).
*
* Counterpart to Solidity's `int104` operator.
*
* Requirements:
*
* - input must fit into 104 bits
*/
function toInt104(int256 value) internal pure returns (int104 downcasted) {
downcasted = int104(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(104, value);
}
}
/**
* @dev Returns the downcasted int96 from int256, reverting on
* overflow (when the input is less than smallest int96 or
* greater than largest int96).
*
* Counterpart to Solidity's `int96` operator.
*
* Requirements:
*
* - input must fit into 96 bits
*/
function toInt96(int256 value) internal pure returns (int96 downcasted) {
downcasted = int96(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(96, value);
}
}
/**
* @dev Returns the downcasted int88 from int256, reverting on
* overflow (when the input is less than smallest int88 or
* greater than largest int88).
*
* Counterpart to Solidity's `int88` operator.
*
* Requirements:
*
* - input must fit into 88 bits
*/
function toInt88(int256 value) internal pure returns (int88 downcasted) {
downcasted = int88(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(88, value);
}
}
/**
* @dev Returns the downcasted int80 from int256, reverting on
* overflow (when the input is less than smallest int80 or
* greater than largest int80).
*
* Counterpart to Solidity's `int80` operator.
*
* Requirements:
*
* - input must fit into 80 bits
*/
function toInt80(int256 value) internal pure returns (int80 downcasted) {
downcasted = int80(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(80, value);
}
}
/**
* @dev Returns the downcasted int72 from int256, reverting on
* overflow (when the input is less than smallest int72 or
* greater than largest int72).
*
* Counterpart to Solidity's `int72` operator.
*
* Requirements:
*
* - input must fit into 72 bits
*/
function toInt72(int256 value) internal pure returns (int72 downcasted) {
downcasted = int72(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(72, value);
}
}
/**
* @dev Returns the downcasted int64 from int256, reverting on
* overflow (when the input is less than smallest int64 or
* greater than largest int64).
*
* Counterpart to Solidity's `int64` operator.
*
* Requirements:
*
* - input must fit into 64 bits
*/
function toInt64(int256 value) internal pure returns (int64 downcasted) {
downcasted = int64(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(64, value);
}
}
/**
* @dev Returns the downcasted int56 from int256, reverting on
* overflow (when the input is less than smallest int56 or
* greater than largest int56).
*
* Counterpart to Solidity's `int56` operator.
*
* Requirements:
*
* - input must fit into 56 bits
*/
function toInt56(int256 value) internal pure returns (int56 downcasted) {
downcasted = int56(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(56, value);
}
}
/**
* @dev Returns the downcasted int48 from int256, reverting on
* overflow (when the input is less than smallest int48 or
* greater than largest int48).
*
* Counterpart to Solidity's `int48` operator.
*
* Requirements:
*
* - input must fit into 48 bits
*/
function toInt48(int256 value) internal pure returns (int48 downcasted) {
downcasted = int48(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(48, value);
}
}
/**
* @dev Returns the downcasted int40 from int256, reverting on
* overflow (when the input is less than smallest int40 or
* greater than largest int40).
*
* Counterpart to Solidity's `int40` operator.
*
* Requirements:
*
* - input must fit into 40 bits
*/
function toInt40(int256 value) internal pure returns (int40 downcasted) {
downcasted = int40(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(40, value);
}
}
/**
* @dev Returns the downcasted int32 from int256, reverting on
* overflow (when the input is less than smallest int32 or
* greater than largest int32).
*
* Counterpart to Solidity's `int32` operator.
*
* Requirements:
*
* - input must fit into 32 bits
*/
function toInt32(int256 value) internal pure returns (int32 downcasted) {
downcasted = int32(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(32, value);
}
}
/**
* @dev Returns the downcasted int24 from int256, reverting on
* overflow (when the input is less than smallest int24 or
* greater than largest int24).
*
* Counterpart to Solidity's `int24` operator.
*
* Requirements:
*
* - input must fit into 24 bits
*/
function toInt24(int256 value) internal pure returns (int24 downcasted) {
downcasted = int24(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(24, value);
}
}
/**
* @dev Returns the downcasted int16 from int256, reverting on
* overflow (when the input is less than smallest int16 or
* greater than largest int16).
*
* Counterpart to Solidity's `int16` operator.
*
* Requirements:
*
* - input must fit into 16 bits
*/
function toInt16(int256 value) internal pure returns (int16 downcasted) {
downcasted = int16(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(16, value);
}
}
/**
* @dev Returns the downcasted int8 from int256, reverting on
* overflow (when the input is less than smallest int8 or
* greater than largest int8).
*
* Counterpart to Solidity's `int8` operator.
*
* Requirements:
*
* - input must fit into 8 bits
*/
function toInt8(int256 value) internal pure returns (int8 downcasted) {
downcasted = int8(value);
if (downcasted != value) {
revert SafeCastOverflowedIntDowncast(8, value);
}
}
/**
* @dev Converts an unsigned uint256 into a signed int256.
*
* Requirements:
*
* - input must be less than or equal to maxInt256.
*/
function toInt256(uint256 value) internal pure returns (int256) {
// Note: Unsafe cast below is okay because `type(int256).max` is guaranteed to be positive
if (value > uint256(type(int256).max)) {
revert SafeCastOverflowedUintToInt(value);
}
return int256(value);
}
}
// SPDX-License-Identifier: GPL-2.0-or-later
pragma solidity ^0.8.25;
import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import {SafeCast as Cast} from "@openzeppelin/contracts/utils/math/SafeCast.sol";
import {IWETH9} from "./interfaces/external/IWETH9.sol";
import {IMaverickV2Pool} from "./v2-common/interfaces/IMaverickV2Pool.sol";
import {IMaverickV2VotingEscrow, IMaverickV2VotingEscrowFactory} from "./interfaces/external/IMaverickV2VotingEscrowFactory.sol";
import {IMaverickV2Factory} from "./v2-common/interfaces/IMaverickV2Factory.sol";
import {IMaverickV2Quoter} from "./interfaces/external/IMaverickV2Quoter.sol";
import {IVeZap} from "./interfaces/IVeZap.sol";
/**
* @notice Facilitate buying and staking to ve in one transaction
*/
contract VeZap is IVeZap {
using Cast for *;
IWETH9 public immutable weth;
IMaverickV2VotingEscrowFactory public immutable veFactory;
IMaverickV2Quoter public immutable quoter;
IMaverickV2Factory public immutable poolFactory;
constructor(
IWETH9 _weth,
IMaverickV2VotingEscrowFactory _veFactory,
IMaverickV2Quoter _quoter,
IMaverickV2Factory _poolFactory
) {
weth = _weth;
veFactory = _veFactory;
quoter = _quoter;
poolFactory = _poolFactory;
}
/// @inheritdoc IVeZap
function ethToStakeForSender(
IMaverickV2Pool ethToTokenPool,
uint256 duration,
uint256 minTokenStaked
) external payable returns (IMaverickV2VotingEscrow.Lockup memory lockup, IMaverickV2VotingEscrow ve) {
uint256 amountOut;
(amountOut, ve) = _ethToTokenAndApproveVe(ethToTokenPool, minTokenStaked);
lockup = ve.stake(amountOut.toUint128(), duration, msg.sender);
}
/// @inheritdoc IVeZap
function ethToStake(
address recipient,
IMaverickV2Pool ethToTokenPool,
uint256 duration,
uint256 minTokenStaked
) external payable returns (IMaverickV2VotingEscrow.Lockup memory lockup, IMaverickV2VotingEscrow ve) {
uint256 amountOut;
(amountOut, ve) = _ethToTokenAndApproveVe(ethToTokenPool, minTokenStaked);
lockup = ve.stake(amountOut.toUint128(), duration, recipient);
}
/// @inheritdoc IVeZap
function estimateEthToStake(
IMaverickV2Pool ethToTokenPool,
uint256 amountIn,
uint256 duration
) external returns (IMaverickV2VotingEscrow.Lockup memory lockup, IMaverickV2VotingEscrow ve) {
bool tokenAIn;
(tokenAIn, ve, ) = _getTokenInfo(ethToTokenPool);
uint256 amountOut;
(, amountOut, ) = quoter.calculateSwap(
ethToTokenPool,
amountIn.toUint128(),
tokenAIn,
false,
tokenAIn ? type(int32).max : type(int32).min
);
lockup = ve.previewVotes(amountOut.toUint128(), duration);
}
function _getTokenInfo(
IMaverickV2Pool ethToTokenPool
) internal view returns (bool tokenAIn, IMaverickV2VotingEscrow ve, IERC20 token) {
// check pool is factory pool
if (!poolFactory.isFactoryPool(ethToTokenPool)) revert NotFactoryPool();
// check which token is eth
tokenAIn = address(ethToTokenPool.tokenA()) == address(weth);
// other token is stake token
token = tokenAIn ? ethToTokenPool.tokenB() : ethToTokenPool.tokenB();
// look up ve in vefactory by token
ve = veFactory.veForBaseToken(token);
}
function _ethToTokenAndApproveVe(
IMaverickV2Pool ethToTokenPool,
uint256 minTokenStaked
) internal returns (uint256 amountOut, IMaverickV2VotingEscrow ve) {
bool tokenAIn;
IERC20 token;
(tokenAIn, ve, token) = _getTokenInfo(ethToTokenPool);
// swap eth for token
{
uint256 amountIn = msg.value;
// this contract has weth now
weth.deposit{value: amountIn}();
// send to pool
weth.transfer(address(ethToTokenPool), amountIn);
IMaverickV2Pool.SwapParams memory swapParams = IMaverickV2Pool.SwapParams({
amount: amountIn,
tokenAIn: tokenAIn,
exactOutput: false,
tickLimit: tokenAIn ? type(int32).max : type(int32).min
});
// swap
(, amountOut) = ethToTokenPool.swap(address(this), swapParams, "");
}
if (amountOut < minTokenStaked) revert AmountMinimumNotMet(amountOut, minTokenStaked);
token.approve(address(ve), amountOut);
}
}
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (interfaces/draft-IERC6093.sol)
pragma solidity ^0.8.20;
/**
* @dev Standard ERC20 Errors
* Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC20 tokens.
*/
interface IERC20Errors {
/**
* @dev Indicates an error related to the current `balance` of a `sender`. Used in transfers.
* @param sender Address whose tokens are being transferred.
* @param balance Current balance for the interacting account.
* @param needed Minimum amount required to perform a transfer.
*/
error ERC20InsufficientBalance(address sender, uint256 balance, uint256 needed);
/**
* @dev Indicates a failure with the token `sender`. Used in transfers.
* @param sender Address whose tokens are being transferred.
*/
error ERC20InvalidSender(address sender);
/**
* @dev Indicates a failure with the token `receiver`. Used in transfers.
* @param receiver Address to which tokens are being transferred.
*/
error ERC20InvalidReceiver(address receiver);
/**
* @dev Indicates a failure with the `spender`’s `allowance`. Used in transfers.
* @param spender Address that may be allowed to operate on tokens without being their owner.
* @param allowance Amount of tokens a `spender` is allowed to operate with.
* @param needed Minimum amount required to perform a transfer.
*/
error ERC20InsufficientAllowance(address spender, uint256 allowance, uint256 needed);
/**
* @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals.
* @param approver Address initiating an approval operation.
*/
error ERC20InvalidApprover(address approver);
/**
* @dev Indicates a failure with the `spender` to be approved. Used in approvals.
* @param spender Address that may be allowed to operate on tokens without being their owner.
*/
error ERC20InvalidSpender(address spender);
}
/**
* @dev Standard ERC721 Errors
* Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC721 tokens.
*/
interface IERC721Errors {
/**
* @dev Indicates that an address can't be an owner. For example, `address(0)` is a forbidden owner in EIP-20.
* Used in balance queries.
* @param owner Address of the current owner of a token.
*/
error ERC721InvalidOwner(address owner);
/**
* @dev Indicates a `tokenId` whose `owner` is the zero address.
* @param tokenId Identifier number of a token.
*/
error ERC721NonexistentToken(uint256 tokenId);
/**
* @dev Indicates an error related to the ownership over a particular token. Used in transfers.
* @param sender Address whose tokens are being transferred.
* @param tokenId Identifier number of a token.
* @param owner Address of the current owner of a token.
*/
error ERC721IncorrectOwner(address sender, uint256 tokenId, address owner);
/**
* @dev Indicates a failure with the token `sender`. Used in transfers.
* @param sender Address whose tokens are being transferred.
*/
error ERC721InvalidSender(address sender);
/**
* @dev Indicates a failure with the token `receiver`. Used in transfers.
* @param receiver Address to which tokens are being transferred.
*/
error ERC721InvalidReceiver(address receiver);
/**
* @dev Indicates a failure with the `operator`’s approval. Used in transfers.
* @param operator Address that may be allowed to operate on tokens without being their owner.
* @param tokenId Identifier number of a token.
*/
error ERC721InsufficientApproval(address operator, uint256 tokenId);
/**
* @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals.
* @param approver Address initiating an approval operation.
*/
error ERC721InvalidApprover(address approver);
/**
* @dev Indicates a failure with the `operator` to be approved. Used in approvals.
* @param operator Address that may be allowed to operate on tokens without being their owner.
*/
error ERC721InvalidOperator(address operator);
}
/**
* @dev Standard ERC1155 Errors
* Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC1155 tokens.
*/
interface IERC1155Errors {
/**
* @dev Indicates an error related to the current `balance` of a `sender`. Used in transfers.
* @param sender Address whose tokens are being transferred.
* @param balance Current balance for the interacting account.
* @param needed Minimum amount required to perform a transfer.
* @param tokenId Identifier number of a token.
*/
error ERC1155InsufficientBalance(address sender, uint256 balance, uint256 needed, uint256 tokenId);
/**
* @dev Indicates a failure with the token `sender`. Used in transfers.
* @param sender Address whose tokens are being transferred.
*/
error ERC1155InvalidSender(address sender);
/**
* @dev Indicates a failure with the token `receiver`. Used in transfers.
* @param receiver Address to which tokens are being transferred.
*/
error ERC1155InvalidReceiver(address receiver);
/**
* @dev Indicates a failure with the `operator`’s approval. Used in transfers.
* @param operator Address that may be allowed to operate on tokens without being their owner.
* @param owner Address of the current owner of a token.
*/
error ERC1155MissingApprovalForAll(address operator, address owner);
/**
* @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals.
* @param approver Address initiating an approval operation.
*/
error ERC1155InvalidApprover(address approver);
/**
* @dev Indicates a failure with the `operator` to be approved. Used in approvals.
* @param operator Address that may be allowed to operate on tokens without being their owner.
*/
error ERC1155InvalidOperator(address operator);
/**
* @dev Indicates an array length mismatch between ids and values in a safeBatchTransferFrom operation.
* Used in batch transfers.
* @param idsLength Length of the array of token identifiers
* @param valuesLength Length of the array of token amounts
*/
error ERC1155InvalidArrayLength(uint256 idsLength, uint256 valuesLength);
}
{
"compilationTarget": {
"@fairlaunch/contracts/src/VeZap.sol": "VeZap"
},
"evmVersion": "paris",
"libraries": {},
"metadata": {
"bytecodeHash": "ipfs",
"useLiteralContent": true
},
"optimizer": {
"enabled": true,
"runs": 10
},
"remappings": []
}
[{"inputs":[{"internalType":"contract IWETH9","name":"_weth","type":"address"},{"internalType":"contract IMaverickV2VotingEscrowFactory","name":"_veFactory","type":"address"},{"internalType":"contract IMaverickV2Quoter","name":"_quoter","type":"address"},{"internalType":"contract IMaverickV2Factory","name":"_poolFactory","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"uint256","name":"amountOut","type":"uint256"},{"internalType":"uint256","name":"minTokenStaked","type":"uint256"}],"name":"AmountMinimumNotMet","type":"error"},{"inputs":[],"name":"NotFactoryPool","type":"error"},{"inputs":[{"internalType":"uint8","name":"bits","type":"uint8"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"SafeCastOverflowedUintDowncast","type":"error"},{"inputs":[{"internalType":"contract IMaverickV2Pool","name":"ethToTokenPool","type":"address"},{"internalType":"uint256","name":"amountIn","type":"uint256"},{"internalType":"uint256","name":"duration","type":"uint256"}],"name":"estimateEthToStake","outputs":[{"components":[{"internalType":"uint128","name":"amount","type":"uint128"},{"internalType":"uint128","name":"end","type":"uint128"},{"internalType":"uint256","name":"votes","type":"uint256"}],"internalType":"struct IMaverickV2VotingEscrowBase.Lockup","name":"lockup","type":"tuple"},{"internalType":"contract IMaverickV2VotingEscrow","name":"ve","type":"address"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"recipient","type":"address"},{"internalType":"contract IMaverickV2Pool","name":"ethToTokenPool","type":"address"},{"internalType":"uint256","name":"duration","type":"uint256"},{"internalType":"uint256","name":"minTokenStaked","type":"uint256"}],"name":"ethToStake","outputs":[{"components":[{"internalType":"uint128","name":"amount","type":"uint128"},{"internalType":"uint128","name":"end","type":"uint128"},{"internalType":"uint256","name":"votes","type":"uint256"}],"internalType":"struct IMaverickV2VotingEscrowBase.Lockup","name":"lockup","type":"tuple"},{"internalType":"contract IMaverickV2VotingEscrow","name":"ve","type":"address"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"contract IMaverickV2Pool","name":"ethToTokenPool","type":"address"},{"internalType":"uint256","name":"duration","type":"uint256"},{"internalType":"uint256","name":"minTokenStaked","type":"uint256"}],"name":"ethToStakeForSender","outputs":[{"components":[{"internalType":"uint128","name":"amount","type":"uint128"},{"internalType":"uint128","name":"end","type":"uint128"},{"internalType":"uint256","name":"votes","type":"uint256"}],"internalType":"struct IMaverickV2VotingEscrowBase.Lockup","name":"lockup","type":"tuple"},{"internalType":"contract IMaverickV2VotingEscrow","name":"ve","type":"address"}],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"poolFactory","outputs":[{"internalType":"contract IMaverickV2Factory","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"quoter","outputs":[{"internalType":"contract IMaverickV2Quoter","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"veFactory","outputs":[{"internalType":"contract IMaverickV2VotingEscrowFactory","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"weth","outputs":[{"internalType":"contract IWETH9","name":"","type":"address"}],"stateMutability":"view","type":"function"}]