编译器
0.8.18+commit.87f61d96
文件 1 的 20:Address.sol
pragma solidity ^0.8.1;
library Address {
function isContract(address account) internal view returns (bool) {
return account.code.length > 0;
}
function sendValue(address payable recipient, uint256 amount) internal {
require(
address(this).balance >= amount,
"Address: insufficient balance"
);
(bool success, ) = recipient.call{value: amount}("");
require(
success,
"Address: unable to send value, recipient may have reverted"
);
}
function functionCall(
address target,
bytes memory data
) internal returns (bytes memory) {
return
functionCallWithValue(
target,
data,
0,
"Address: low-level call failed"
);
}
function functionCall(
address target,
bytes memory data,
string memory errorMessage
) internal returns (bytes memory) {
return functionCallWithValue(target, data, 0, errorMessage);
}
function functionCallWithValue(
address target,
bytes memory data,
uint256 value
) internal returns (bytes memory) {
return
functionCallWithValue(
target,
data,
value,
"Address: low-level call with value failed"
);
}
function functionCallWithValue(
address target,
bytes memory data,
uint256 value,
string memory errorMessage
) internal returns (bytes memory) {
require(
address(this).balance >= value,
"Address: insufficient balance for call"
);
(bool success, bytes memory returndata) = target.call{value: value}(
data
);
return
verifyCallResultFromTarget(
target,
success,
returndata,
errorMessage
);
}
function functionStaticCall(
address target,
bytes memory data
) internal view returns (bytes memory) {
return
functionStaticCall(
target,
data,
"Address: low-level static call failed"
);
}
function functionStaticCall(
address target,
bytes memory data,
string memory errorMessage
) internal view returns (bytes memory) {
(bool success, bytes memory returndata) = target.staticcall(data);
return
verifyCallResultFromTarget(
target,
success,
returndata,
errorMessage
);
}
function functionDelegateCall(
address target,
bytes memory data
) internal returns (bytes memory) {
return
functionDelegateCall(
target,
data,
"Address: low-level delegate call failed"
);
}
function functionDelegateCall(
address target,
bytes memory data,
string memory errorMessage
) internal returns (bytes memory) {
(bool success, bytes memory returndata) = target.delegatecall(data);
return
verifyCallResultFromTarget(
target,
success,
returndata,
errorMessage
);
}
function verifyCallResultFromTarget(
address target,
bool success,
bytes memory returndata,
string memory errorMessage
) internal view returns (bytes memory) {
if (success) {
if (returndata.length == 0) {
require(isContract(target), "Address: call to non-contract");
}
return returndata;
} else {
_revert(returndata, errorMessage);
}
}
function verifyCallResult(
bool success,
bytes memory returndata,
string memory errorMessage
) internal pure returns (bytes memory) {
if (success) {
return returndata;
} else {
_revert(returndata, errorMessage);
}
}
function _revert(
bytes memory returndata,
string memory errorMessage
) private pure {
if (returndata.length > 0) {
assembly {
let returndata_size := mload(returndata)
revert(add(32, returndata), returndata_size)
}
} else {
revert(errorMessage);
}
}
}
文件 2 的 20:AddressId.sol
pragma solidity ^0.8.0;
pragma abicoder v2;
library AddressId {
uint256 constant ADDRESS_ID_WETH9 = 1;
uint256 constant ADDRESS_ID_UNI_V3_FACTORY = 2;
uint256 constant ADDRESS_ID_UNI_V3_NONFUNGIBLE_POSITION_MANAGER = 3;
uint256 constant ADDRESS_ID_UNI_V3_SWAP_ROUTER = 4;
uint256 constant ADDRESS_ID_VELO_ROUTER = 5;
uint256 constant ADDRESS_ID_VELO_FACTORY = 6;
uint256 constant ADDRESS_ID_VAULT_POSITION_MANAGER = 7;
uint256 constant ADDRESS_ID_SWAP_EXECUTOR_MANAGER = 8;
uint256 constant ADDRESS_ID_LENDING_POOL = 9;
uint256 constant ADDRESS_ID_VAULT_FACTORY = 10;
uint256 constant ADDRESS_ID_TREASURY = 11;
uint256 constant ADDRESS_ID_VE_TOKEN = 12;
uint256 constant ADDRESS_ID_VELO_ROUTER_V2 = 13;
uint256 constant ADDRESS_ID_VELO_FACTORY_V2 = 14;
uint256 constant ADDRESS_ID_VAULT_DEPLOYER_SELECTOR = 101;
uint256 constant ADDRESS_ID_VELO_VAULT_INITIALIZER = 102;
uint256 constant ADDRESS_ID_VELO_VAULT_POSITION_LOGIC = 103;
uint256 constant ADDRESS_ID_VELO_VAULT_REWARDS_LOGIC = 104;
uint256 constant ADDRESS_ID_VELO_VAULT_OWNER_ACTIONS = 105;
uint256 constant ADDRESS_ID_VELO_SWAP_PATH_MANAGER = 106;
uint256 constant ADDRESS_ID_CHAINLINK_ORACLE = 107;
uint256 constant ADDRESS_ID_VAULT_DEPLOYER = 1001;
uint256 constant ADDRESS_ID_VAULT_INITIALIZER = 1002;
uint256 constant ADDRESS_ID_VAULT_POSITION_LOGIC = 1003;
uint256 constant ADDRESS_ID_VAULT_REWARDS_LOGIC = 1004;
uint256 constant ADDRESS_ID_VAULT_OWNER_ACTIONS = 1005;
function versionedAddressId(
uint16 vaultVersion,
uint256 addressId
) internal pure returns (uint256) {
if (addressId < 1000) {
return addressId;
}
return (uint256(vaultVersion) << 128) | addressId;
}
}
文件 3 的 20:Context.sol
pragma solidity ^0.8.0;
abstract contract Context {
function _msgSender() internal view virtual returns (address) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes calldata) {
return msg.data;
}
}
文件 4 的 20:Errors.sol
pragma solidity ^0.8.0;
library Errors {
string internal constant VL_TRANSACTION_TOO_OLD = "0";
string internal constant VL_NO_ACTIVE_RESERVE = "1";
string internal constant VL_RESERVE_FROZEN = "2";
string internal constant VL_CURRENT_AVAILABLE_LIQUIDITY_NOT_ENOUGH = "3";
string internal constant VL_NOT_ENOUGH_AVAILABLE_USER_BALANCE = "4";
string internal constant VL_TRANSFER_NOT_ALLOWED = "5";
string internal constant VL_BORROWING_NOT_ENABLED = "6";
string internal constant VL_INVALID_DEBT_OWNER = "7";
string internal constant VL_BORROWING_CALLER_NOT_IN_WHITELIST = "8";
string internal constant VL_DEPOSIT_TOO_MUCH = "9";
string internal constant VL_OUT_OF_CAPACITY = "10";
string internal constant VL_OUT_OF_CREDITS = "11";
string internal constant VL_PERCENT_TOO_LARGE = "12";
string internal constant VL_ADDRESS_CANNOT_ZERO = "13";
string internal constant VL_VAULT_UN_ACTIVE = "14";
string internal constant VL_VAULT_FROZEN = "15";
string internal constant VL_VAULT_BORROWING_DISABLED = "16";
string internal constant VL_NOT_WETH9 = "17";
string internal constant VL_INSUFFICIENT_WETH9 = "18";
string internal constant VL_INSUFFICIENT_TOKEN = "19";
string internal constant VL_LIQUIDATOR_NOT_IN_WHITELIST = "20";
string internal constant VL_COMPOUNDER_NOT_IN_WHITELIST = "21";
string internal constant VL_VAULT_ALREADY_INITIALIZED = "22";
string internal constant VL_TREASURY_ADDRESS_NOT_SET = "23";
string internal constant VT_INVALID_RESERVE_ID = "40";
string internal constant VT_INVALID_POOL = "41";
string internal constant VT_INVALID_VAULT_POSITION_MANAGER = "42";
string internal constant VT_VAULT_POSITION_NOT_ACTIVE = "43";
string internal constant VT_VAULT_POSITION_AUTO_COMPOUND_NOT_ENABLED = "44";
string internal constant VT_VAULT_POSITION_ID_INVALID = "45";
string internal constant VT_VAULT_PAUSED = "46";
string internal constant VT_VAULT_FROZEN = "47";
string internal constant VT_VAULT_CALLBACK_INVALID_SENDER = "48";
string internal constant VT_VAULT_DEBT_RATIO_TOO_LOW_TO_LIQUIDATE = "49";
string internal constant VT_VAULT_POSITION_MANAGER_INVALID = "50";
string internal constant VT_VAULT_POSITION_RANGE_STOP_DISABLED = "60";
string internal constant VT_VAULT_POSITION_RANGE_STOP_PRICE_INVALID = "61";
string internal constant VT_VAULT_POSITION_OUT_OF_MAX_LEVERAGE = "62";
string internal constant VT_VAULT_POSITION_SHARES_INVALID = "63";
string internal constant LP_NOT_ENOUGH_LIQUIDITY_TO_BORROW = "80";
string internal constant LP_CALLER_MUST_BE_LENDING_POOL = "81";
string internal constant LP_BORROW_INDEX_OVERFLOW = "82";
string internal constant LP_IS_PAUSED = "83";
}
文件 5 的 20:IAddressRegistry.sol
pragma solidity ^0.8.0;
import "../libraries/helpers/AddressId.sol";
interface IAddressRegistry {
event SetAddress(
address indexed setter,
uint256 indexed id,
address newAddress
);
function getAddress(uint256 id) external view returns (address);
}
文件 6 的 20:IERC20.sol
pragma solidity ^0.8.0;
interface IERC20 {
event Transfer(address indexed from, address indexed to, uint256 value);
event Approval(
address indexed owner,
address indexed spender,
uint256 value
);
function totalSupply() external view returns (uint256);
function balanceOf(address account) external view returns (uint256);
function transfer(address to, uint256 amount) external returns (bool);
function allowance(
address owner,
address spender
) external view returns (uint256);
function approve(address spender, uint256 amount) external returns (bool);
function transferFrom(
address from,
address to,
uint256 amount
) external returns (bool);
}
文件 7 的 20:IRouter.sol
pragma solidity ^0.8.0;
pragma abicoder v2;
interface IRouter {
function pairFor(
address tokenA,
address tokenB,
bool stable
) external view returns (address pair);
function getReserves(
address tokenA,
address tokenB,
bool stable
) external view returns (uint reserveA, uint reserveB);
function getAmountOut(
uint amountIn,
address tokenIn,
address tokenOut
) external view returns (uint amount, bool stable);
struct route {
address from;
address to;
bool stable;
}
function getAmountsOut(
uint amountIn,
route[] memory routes
) external view returns (uint[] memory amounts);
function isPair(address pair) external view returns (bool);
function quoteAddLiquidity(
address tokenA,
address tokenB,
bool stable,
uint amountADesired,
uint amountBDesired
) external view returns (uint amountA, uint amountB, uint liquidity);
function quoteRemoveLiquidity(
address tokenA,
address tokenB,
bool stable,
uint liquidity
) external view returns (uint amountA, uint amountB);
function addLiquidity(
address tokenA,
address tokenB,
bool stable,
uint amountADesired,
uint amountBDesired,
uint amountAMin,
uint amountBMin,
address to,
uint deadline
) external returns (uint amountA, uint amountB, uint liquidity);
function removeLiquidity(
address tokenA,
address tokenB,
bool stable,
uint liquidity,
uint amountAMin,
uint amountBMin,
address to,
uint deadline
) external returns (uint amountA, uint amountB);
function swapExactTokensForTokensSimple(
uint amountIn,
uint amountOutMin,
address tokenFrom,
address tokenTo,
bool stable,
address to,
uint deadline
) external returns (uint[] memory amounts);
function swapExactTokensForTokens(
uint amountIn,
uint amountOutMin,
route[] calldata routes,
address to,
uint deadline
) external returns (uint[] memory amounts);
function swapExactETHForTokens(
uint amountOutMin,
route[] calldata routes,
address to,
uint deadline
) external payable returns (uint[] memory amounts);
}
文件 8 的 20:IVaultFactory.sol
pragma solidity ^0.8.0;
pragma abicoder v2;
interface IVaultFactory {
event NewVault(
address indexed token0,
address indexed token1,
bool stable,
address vaultAddress,
uint256 indexed vaultId
);
function vaults(uint256 vaultId) external view returns (address);
}
文件 9 的 20:IVeloVault.sol
pragma solidity ^0.8.0;
pragma abicoder v2;
import "./IVeloVaultPositionManager.sol";
import "../libraries/types/VaultTypes.sol";
interface IVeloVault {
function token0() external view returns (address);
function token1() external view returns (address);
function stable() external view returns (bool);
function getVaultState()
external
view
returns (VaultTypes.VeloVaultState memory vault);
function adminSetVault(bytes calldata params) external;
function transferManagerTo(
address caller,
uint256 positionId,
address newManager
) external;
function setRangeStop(
address caller,
uint256 positionId,
bool enable,
uint256 minPrice,
uint256 maxPrice
) external;
function getPositionValue(
uint256 vaultPositionId
) external view returns (VaultTypes.VeloPositionValue memory positionValue);
function getPosition(
uint256 vaultPositionId
) external view returns (VaultTypes.VeloPosition memory position);
function newOrInvestToVaultPosition(
IVeloVaultPositionManager.NewOrInvestToVaultPositionParams
calldata params,
address caller
) external returns (uint256 positionId, uint256 liquidity);
function closeAndRepayPartially(
IVeloVaultPositionManager.CloseVaultPositionPartiallyParams
calldata params,
address caller
) external returns (uint256, uint256, uint256, uint256);
function closeAndRepayOutOfRangePosition(
IVeloVaultPositionManager.CloseVaultPositionPartiallyParams
calldata params
)
external
returns (
address manager,
uint256 price,
uint256 amount0Left,
uint256 amount1Left,
uint256 fee0,
uint256 fee1
);
struct LiquidateState {
address manager;
uint256 price;
uint256 amount0Left;
uint256 amount1Left;
uint256 amount0Repaid;
uint256 amount1Repaid;
uint256 repaidValue;
uint256 removedLiquidityValue;
uint256 liquidateFeeValue;
uint256 equivalentRepaid0;
uint256 equivalentRepaid1;
uint256 liquidatorReceive0;
uint256 liquidatorReceive1;
uint256 liquidateFee0;
uint256 liquidateFee1;
}
function repayAndLiquidatePositionPartially(
IVeloVaultPositionManager.LiquidateVaultPositionPartiallyParams
calldata params,
address caller
) external returns (LiquidateState memory);
function exactRepay(
IVeloVaultPositionManager.ExactRepayParam calldata params,
address caller
)
external
returns (
address positionMananger,
uint256 amount0Repaid,
uint256 amount1Repaid
);
function claimRewardsAndReInvestToLiquidity(
IVeloVaultPositionManager.InvestEarnedFeeToLiquidityParam
calldata params
)
external
returns (
uint256 liquidity,
uint256 fee0,
uint256 fee1,
uint256[] memory rewards
);
}
文件 10 的 20:IVeloVaultPositionManager.sol
pragma solidity ^0.8.0;
import "../external/velodrome/contracts/interfaces/IRouter.sol";
import "../libraries/types/VaultTypes.sol";
interface IVeloVaultPositionManager {
event NewVaultPosition(
uint256 indexed vaultId,
uint256 indexed vaultPositionId,
address indexed manager
);
event InvestToVaultPosition(
uint256 indexed vaultId,
uint256 indexed vaultPositionId,
address indexed manager,
uint256 amount0Invest,
uint256 amount1Invest,
uint256 amount0Borrow,
uint256 amount1Borrow,
uint256 liquidity
);
event CloseVaultPositionPartially(
uint256 indexed vaultId,
uint256 indexed vaultPositionId,
address indexed manager,
uint16 percent,
uint256 amount0Received,
uint256 amount1Received,
uint256 amount0Repaid,
uint256 amount1Repaid
);
event CloseOutOfRangePosition(
uint256 indexed vaultId,
uint256 indexed vaultPositionId,
address indexed manager,
address caller,
uint16 percent,
uint64 timestamp,
uint256 price,
uint256 amount0Received,
uint256 amount1Received,
uint256 fee0,
uint256 fee1
);
event LiquidateVaultPositionPartially(
uint256 indexed vaultId,
uint256 indexed vaultPositionId,
address indexed manager,
address liquidator,
uint16 percent,
uint64 timestamp,
uint256 price,
uint256 debtValueOfPosition,
uint256 liquidityValueOfPosition,
uint256 amount0Left,
uint256 amount1Left,
uint256 liquidateFee0,
uint256 liquidateFee1
);
event ExactRepay(
uint256 indexed vaultId,
uint256 indexed vaultPositionId,
address indexed manager,
address caller,
uint256 amount0Repaid,
uint256 amount1Repaid
);
event InvestEarnedFeeToLiquidity(
uint256 indexed vaultId,
address indexed caller,
uint256 liquidityAdded,
uint256 fee0,
uint256 fee1,
uint256[] rewards
);
event FeePaid(
uint256 indexed vaultId,
address indexed asset,
uint256 indexed feeType,
uint256 amount
);
function getVaultPosition(
uint256 vaultId,
uint256 vaultPositionId
) external view returns (VaultTypes.VeloPositionValue memory state);
function getVault(
uint256 vaultId
) external view returns (VaultTypes.VeloVaultState memory);
struct PayToVaultCallbackParams {
uint256 vaultId;
uint256 amount0;
uint256 amount1;
address payer;
}
function payToVaultCallback(
PayToVaultCallbackParams calldata params
) external;
function payFeeToTreasuryCallback(
uint256 vaultId,
address asset,
uint256 amount,
uint256 feeType
) external;
struct NewOrInvestToVaultPositionParams {
uint256 vaultId;
uint256 vaultPositionId;
uint256 amount0Invest;
uint256 amount0Borrow;
uint256 amount1Invest;
uint256 amount1Borrow;
uint256 amount0Min;
uint256 amount1Min;
uint256 deadline;
uint256 swapExecutorId;
bytes swapPath;
}
function newOrInvestToVaultPosition(
NewOrInvestToVaultPositionParams calldata params
) external payable;
struct CloseVaultPositionPartiallyParams {
uint256 vaultId;
uint256 vaultPositionId;
uint16 percent;
address receiver;
bool receiveNativeETH;
uint8 receiveType;
uint256 minAmount0WhenRemoveLiquidity;
uint256 minAmount1WhenRemoveLiquidity;
uint256 deadline;
uint256 swapExecutorId;
bytes swapPath;
}
function closeVaultPositionPartially(
CloseVaultPositionPartiallyParams calldata params
) external;
struct LiquidateVaultPositionPartiallyParams {
uint256 vaultId;
uint256 vaultPositionId;
uint16 percent;
address receiver;
bool receiveNativeETH;
uint8 receiveType;
uint256 minAmount0WhenRemoveLiquidity;
uint256 minAmount1WhenRemoveLiquidity;
uint256 deadline;
uint256 maxRepay0;
uint256 maxRepay1;
uint256 swapExecutorId;
bytes swapPath;
}
function liquidateVaultPositionPartially(
LiquidateVaultPositionPartiallyParams calldata params
) external payable;
struct InvestEarnedFeeToLiquidityParam {
uint256 vaultId;
address compoundFeeReceiver;
IRouter.route[][] routes;
bool receiveNativeETH;
uint256 deadline;
}
function investEarnedFeeToLiquidity(
InvestEarnedFeeToLiquidityParam calldata params
) external;
struct ExactRepayParam {
uint256 vaultId;
uint256 vaultPositionId;
uint256 amount0ToRepay;
uint256 amount1ToRepay;
bool receiveNativeETH;
uint256 deadline;
}
function exactRepay(
ExactRepayParam calldata params
) external payable returns (uint256, uint256);
function transferManagerOfVaultPosition(
uint256 vaultId,
uint256 vaultPositionId,
address newManager
) external;
function setRangeStop(
uint256 vaultId,
uint256 vaultPositionId,
bool enable,
uint256 minPrice,
uint256 maxPrice
) external;
}
文件 11 的 20:IWETH9.sol
pragma solidity ^0.8.0;
import "../external/openzeppelin/contracts/token/ERC20/IERC20.sol";
interface IWETH9 is IERC20 {
function deposit() external payable;
function withdraw(uint256) external;
}
文件 12 的 20:Ownable.sol
pragma solidity ^0.8.0;
import "../utils/Context.sol";
abstract contract Ownable is Context {
address private _owner;
event OwnershipTransferred(
address indexed previousOwner,
address indexed newOwner
);
constructor() {
_transferOwnership(_msgSender());
}
modifier onlyOwner() {
_checkOwner();
_;
}
function owner() public view virtual returns (address) {
return _owner;
}
function _checkOwner() internal view virtual {
require(owner() == _msgSender(), "Ownable: caller is not the owner");
}
function renounceOwnership() public virtual onlyOwner {
_transferOwnership(address(0));
}
function transferOwnership(address newOwner) public virtual onlyOwner {
require(
newOwner != address(0),
"Ownable: new owner is the zero address"
);
_transferOwnership(newOwner);
}
function _transferOwnership(address newOwner) internal virtual {
address oldOwner = _owner;
_owner = newOwner;
emit OwnershipTransferred(oldOwner, newOwner);
}
}
文件 13 的 20:Payments.sol
pragma solidity ^0.8.0;
pragma abicoder v2;
import "./interfaces/IWETH9.sol";
import "./libraries/TransferHelper.sol";
import "./libraries/helpers/Errors.sol";
abstract contract Payments {
address public immutable WETH9;
modifier avoidUsingNativeEther() {
require(msg.value == 0, "avoid using native ether");
_;
}
constructor(address _WETH9) {
WETH9 = _WETH9;
}
receive() external payable {
require(msg.sender == WETH9, Errors.VL_NOT_WETH9);
}
function unwrapWETH9(uint256 amountMinimum, address recipient) internal {
uint256 balanceWETH9 = IWETH9(WETH9).balanceOf(address(this));
require(balanceWETH9 >= amountMinimum, Errors.VL_INSUFFICIENT_WETH9);
if (balanceWETH9 > 0) {
IWETH9(WETH9).withdraw(balanceWETH9);
TransferHelper.safeTransferETH(recipient, balanceWETH9);
}
}
function refundETH() internal {
if (address(this).balance > 0)
TransferHelper.safeTransferETH(msg.sender, address(this).balance);
}
function pay(
address token,
address payer,
address recipient,
uint256 value
) internal {
if (token == WETH9 && address(this).balance >= value) {
IWETH9(WETH9).deposit{value: value}();
require(
IWETH9(WETH9).transfer(recipient, value),
"transfer failed"
);
} else if (payer == address(this)) {
TransferHelper.safeTransfer(token, recipient, value);
} else {
TransferHelper.safeTransferFrom(token, payer, recipient, value);
}
}
}
文件 14 的 20:ReentrancyGuard.sol
pragma solidity ^0.8.0;
abstract contract ReentrancyGuard {
uint256 private constant _NOT_ENTERED = 1;
uint256 private constant _ENTERED = 2;
uint256 private _status;
constructor() {
_status = _NOT_ENTERED;
}
modifier nonReentrant() {
_nonReentrantBefore();
_;
_nonReentrantAfter();
}
function _nonReentrantBefore() private {
require(_status != _ENTERED, "ReentrancyGuard: reentrant call");
_status = _ENTERED;
}
function _nonReentrantAfter() private {
_status = _NOT_ENTERED;
}
}
文件 15 的 20:SafeERC20.sol
pragma solidity ^0.8.0;
import "../IERC20.sol";
import "../extensions/draft-IERC20Permit.sol";
import "../../../utils/Address.sol";
library SafeERC20 {
using Address for address;
function safeTransfer(IERC20 token, address to, uint256 value) internal {
_callOptionalReturn(
token,
abi.encodeWithSelector(token.transfer.selector, to, value)
);
}
function safeTransferFrom(
IERC20 token,
address from,
address to,
uint256 value
) internal {
_callOptionalReturn(
token,
abi.encodeWithSelector(token.transferFrom.selector, from, to, value)
);
}
function safeApprove(
IERC20 token,
address spender,
uint256 value
) internal {
require(
(value == 0) || (token.allowance(address(this), spender) == 0),
"SafeERC20: approve from non-zero to non-zero allowance"
);
_callOptionalReturn(
token,
abi.encodeWithSelector(token.approve.selector, spender, value)
);
}
function safeIncreaseAllowance(
IERC20 token,
address spender,
uint256 value
) internal {
uint256 newAllowance = token.allowance(address(this), spender) + value;
_callOptionalReturn(
token,
abi.encodeWithSelector(
token.approve.selector,
spender,
newAllowance
)
);
}
function safeDecreaseAllowance(
IERC20 token,
address spender,
uint256 value
) internal {
unchecked {
uint256 oldAllowance = token.allowance(address(this), spender);
require(
oldAllowance >= value,
"SafeERC20: decreased allowance below zero"
);
uint256 newAllowance = oldAllowance - value;
_callOptionalReturn(
token,
abi.encodeWithSelector(
token.approve.selector,
spender,
newAllowance
)
);
}
}
function safePermit(
IERC20Permit token,
address owner,
address spender,
uint256 value,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) internal {
uint256 nonceBefore = token.nonces(owner);
token.permit(owner, spender, value, deadline, v, r, s);
uint256 nonceAfter = token.nonces(owner);
require(
nonceAfter == nonceBefore + 1,
"SafeERC20: permit did not succeed"
);
}
function _callOptionalReturn(IERC20 token, bytes memory data) private {
bytes memory returndata = address(token).functionCall(
data,
"SafeERC20: low-level call failed"
);
if (returndata.length > 0) {
require(
abi.decode(returndata, (bool)),
"SafeERC20: ERC20 operation did not succeed"
);
}
}
}
文件 16 的 20:SafeMath.sol
pragma solidity ^0.8.0;
library SafeMath {
function tryAdd(
uint256 a,
uint256 b
) internal pure returns (bool, uint256) {
unchecked {
uint256 c = a + b;
if (c < a) return (false, 0);
return (true, c);
}
}
function trySub(
uint256 a,
uint256 b
) internal pure returns (bool, uint256) {
unchecked {
if (b > a) return (false, 0);
return (true, a - b);
}
}
function tryMul(
uint256 a,
uint256 b
) internal pure returns (bool, uint256) {
unchecked {
if (a == 0) return (true, 0);
uint256 c = a * b;
if (c / a != b) return (false, 0);
return (true, c);
}
}
function tryDiv(
uint256 a,
uint256 b
) internal pure returns (bool, uint256) {
unchecked {
if (b == 0) return (false, 0);
return (true, a / b);
}
}
function tryMod(
uint256 a,
uint256 b
) internal pure returns (bool, uint256) {
unchecked {
if (b == 0) return (false, 0);
return (true, a % b);
}
}
function add(uint256 a, uint256 b) internal pure returns (uint256) {
return a + b;
}
function sub(uint256 a, uint256 b) internal pure returns (uint256) {
return a - b;
}
function mul(uint256 a, uint256 b) internal pure returns (uint256) {
return a * b;
}
function div(uint256 a, uint256 b) internal pure returns (uint256) {
return a / b;
}
function mod(uint256 a, uint256 b) internal pure returns (uint256) {
return a % b;
}
function sub(
uint256 a,
uint256 b,
string memory errorMessage
) internal pure returns (uint256) {
unchecked {
require(b <= a, errorMessage);
return a - b;
}
}
function div(
uint256 a,
uint256 b,
string memory errorMessage
) internal pure returns (uint256) {
unchecked {
require(b > 0, errorMessage);
return a / b;
}
}
function mod(
uint256 a,
uint256 b,
string memory errorMessage
) internal pure returns (uint256) {
unchecked {
require(b > 0, errorMessage);
return a % b;
}
}
}
文件 17 的 20:TransferHelper.sol
pragma solidity >=0.6.0;
import "../external/openzeppelin/contracts/token/ERC20/IERC20.sol";
library TransferHelper {
function safeTransferFrom(
address token,
address from,
address to,
uint256 value
) internal {
(bool success, bytes memory data) = token.call(
abi.encodeWithSelector(
IERC20.transferFrom.selector,
from,
to,
value
)
);
require(
success && (data.length == 0 || abi.decode(data, (bool))),
"STF"
);
}
function safeTransfer(address token, address to, uint256 value) internal {
(bool success, bytes memory data) = token.call(
abi.encodeWithSelector(IERC20.transfer.selector, to, value)
);
require(
success && (data.length == 0 || abi.decode(data, (bool))),
"ST"
);
}
function safeApprove(address token, address to, uint256 value) internal {
(bool success, bytes memory data) = token.call(
abi.encodeWithSelector(IERC20.approve.selector, to, value)
);
require(
success && (data.length == 0 || abi.decode(data, (bool))),
"SA"
);
}
function safeTransferETH(address to, uint256 value) internal {
(bool success, ) = to.call{value: value}(new bytes(0));
require(success, "STE");
}
}
文件 18 的 20:VaultTypes.sol
pragma solidity ^0.8.0;
pragma abicoder v2;
library VaultTypes {
struct VeloVaultStorage {
VeloVaultState state;
mapping(uint256 => VeloPosition) positions;
uint256 nextPositionId;
address[] rewardTokens;
address addressProvider;
address veloFactory;
address veloRouter;
address swapPathManager;
address lendingPool;
address vaultPositionManager;
address WETH9;
address veToken;
}
struct VeloPositionValue {
address manager;
bool isActive;
bool enableRangeStop;
uint64 openedAt;
uint64 current;
uint256 token0Principal;
uint256 token1Principal;
uint256 liquidityPrincipal;
uint256 token0Left;
uint256 token1Left;
uint256 token0InLiquidity;
uint256 token1InLiquidity;
uint256 liquidity;
uint256 debt0;
uint256 debt1;
uint256 borrowingIndex0;
uint256 borrowingIndex1;
uint256 minPriceOfRangeStop;
uint256 maxPriceOfRangeStop;
}
struct VeloPosition {
address manager;
bool isActive;
bool enableRangeStop;
uint64 openedAt;
uint256 token0Principal;
uint256 token1Principal;
uint256 liquidityPrincipal;
uint256 token0Left;
uint256 token1Left;
uint256 lpShares;
uint256 debtShare0;
uint256 debtShare1;
uint256 minPriceOfRangeStop;
uint256 maxPriceOfRangeStop;
}
struct VeloVaultState {
address gauge;
address pair;
address token0;
address token1;
bool stable;
bool paused;
bool frozen;
bool borrowingEnabled;
bool liquidateWithTWAP;
uint16 maxLeverage;
uint16 premiumMaxLeverage;
uint16 maxPriceDiff;
uint16 liquidateDebtRatio;
uint16 withdrawFeeRate;
uint16 compoundFeeRate;
uint16 liquidateFeeRate;
uint16 rangeStopFeeRate;
uint16 protocolFeeRate;
uint256 premiumRequirement;
uint256 protocolFee0Accumulated;
uint256 protocolFee1Accumulated;
uint256 minInvestValue;
uint256 minSwapAmount0;
uint256 minSwapAmount1;
uint256 totalLp;
uint256 totalLpShares;
uint256 premiumUtilizationOfReserve0;
uint256 debtLimit0;
uint256 debtPositionId0;
uint256 debtTotalShares0;
uint256 premiumUtilizationOfReserve1;
uint256 debtLimit1;
uint256 debtPositionId1;
uint256 debtTotalShares1;
}
}
文件 19 的 20:VeloPositionManager.sol
pragma solidity ^0.8.0;
pragma abicoder v2;
import "./external/openzeppelin/contracts/security/ReentrancyGuard.sol";
import "./external/openzeppelin/contracts/access/Ownable.sol";
import "./external/openzeppelin/contracts/utils/math/SafeMath.sol";
import "./external/openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import "./interfaces/IVeloVaultPositionManager.sol";
import "./interfaces/IVaultFactory.sol";
import "./interfaces/IVeloVault.sol";
import "./libraries/helpers/Errors.sol";
import "./Payments.sol";
import "./interfaces/IAddressRegistry.sol";
import "./libraries/helpers/AddressId.sol";
import "./libraries/types/VaultTypes.sol";
contract VeloPositionManager is
ReentrancyGuard,
IVeloVaultPositionManager,
Ownable,
Payments
{
using SafeMath for uint256;
address public immutable addressProvider;
address public immutable vaultFactory;
bool public permissionLessLiquidationEnabled;
mapping(address => bool) public liquidatorWhitelist;
bool public permissionLessCompoundEnabled;
mapping(address => bool) public compounderWhitelist;
bool public permissionLessRangeStopEnabled;
mapping(address => bool) public rangeStopCallerWhitelist;
modifier checkDeadline(uint256 deadline) {
require(block.timestamp <= deadline, Errors.VL_TRANSACTION_TOO_OLD);
_;
}
modifier liquidatorInWhitelist() {
require(
permissionLessLiquidationEnabled || liquidatorWhitelist[msg.sender],
Errors.VL_LIQUIDATOR_NOT_IN_WHITELIST
);
_;
}
modifier compounderInWhitelist() {
require(
permissionLessCompoundEnabled || compounderWhitelist[msg.sender],
Errors.VL_LIQUIDATOR_NOT_IN_WHITELIST
);
_;
}
modifier rangeStopCallerInWhitelist() {
require(
permissionLessRangeStopEnabled ||
rangeStopCallerWhitelist[msg.sender],
Errors.VL_LIQUIDATOR_NOT_IN_WHITELIST
);
_;
}
constructor(
address _addressProvider
)
Payments(
IAddressRegistry(_addressProvider).getAddress(
AddressId.ADDRESS_ID_WETH9
)
)
{
require(_addressProvider != address(0), Errors.VL_ADDRESS_CANNOT_ZERO);
addressProvider = _addressProvider;
vaultFactory = IAddressRegistry(addressProvider).getAddress(
AddressId.ADDRESS_ID_VAULT_FACTORY
);
disablePermissionLessLiquidation();
addPermissionedLiquidator(msg.sender);
disablePermissionLessCompound();
addPermissionedCompounder(msg.sender);
disablePermissonLessRangeStop();
addPermissionedRangeStopCaller(msg.sender);
}
function payToVaultCallback(
PayToVaultCallbackParams calldata params
) external {
address vaultAddress = IVaultFactory(vaultFactory).vaults(
params.vaultId
);
require(vaultAddress != address(0), Errors.VL_ADDRESS_CANNOT_ZERO);
require(
vaultAddress == _msgSender(),
Errors.VT_VAULT_CALLBACK_INVALID_SENDER
);
if (params.amount0 > 0) {
pay(
IVeloVault(vaultAddress).token0(),
params.payer,
vaultAddress,
params.amount0
);
}
if (params.amount1 > 0) {
pay(
IVeloVault(vaultAddress).token1(),
params.payer,
vaultAddress,
params.amount1
);
}
}
function payFeeToTreasuryCallback(
uint256 vaultId,
address asset,
uint256 amount,
uint256 feeType
) external {
address vaultAddress = IVaultFactory(vaultFactory).vaults(vaultId);
require(vaultAddress != address(0), Errors.VL_ADDRESS_CANNOT_ZERO);
require(
vaultAddress == _msgSender(),
Errors.VT_VAULT_CALLBACK_INVALID_SENDER
);
address treasury = IAddressRegistry(addressProvider).getAddress(
AddressId.ADDRESS_ID_TREASURY
);
require(treasury != address(0), "zero-address treasury");
SafeERC20.safeTransferFrom(
IERC20(asset),
vaultAddress,
treasury,
amount
);
emit FeePaid(vaultId, asset, feeType, amount);
}
function newOrInvestToVaultPosition(
NewOrInvestToVaultPositionParams calldata params
) external payable nonReentrant checkDeadline(params.deadline) {
address vaultAddress = IVaultFactory(vaultFactory).vaults(
params.vaultId
);
require(vaultAddress != address(0), Errors.VL_ADDRESS_CANNOT_ZERO);
(uint256 positionId, uint256 liquidity) = IVeloVault(vaultAddress)
.newOrInvestToVaultPosition(params, _msgSender());
if (params.vaultPositionId == 0) {
emit NewVaultPosition(params.vaultId, positionId, _msgSender());
}
if (msg.value > 0) {
refundETH();
}
emit InvestToVaultPosition(
params.vaultId,
positionId,
_msgSender(),
params.amount0Invest,
params.amount1Invest,
params.amount0Borrow,
params.amount1Borrow,
liquidity
);
}
function closeVaultPositionPartially(
CloseVaultPositionPartiallyParams calldata params
) external override nonReentrant checkDeadline(params.deadline) {
address vaultAddress = IVaultFactory(vaultFactory).vaults(
params.vaultId
);
require(vaultAddress != address(0), Errors.VL_ADDRESS_CANNOT_ZERO);
(
uint256 amount0,
uint256 amount1,
uint256 repay0,
uint256 repay1
) = IVeloVault(vaultAddress).closeAndRepayPartially(
params,
_msgSender()
);
if (
amount0 > 0 &&
IVeloVault(vaultAddress).token0() == WETH9 &&
params.receiveNativeETH
) {
unwrapWETH9(amount0, params.receiver);
}
if (
amount1 > 0 &&
IVeloVault(vaultAddress).token1() == WETH9 &&
params.receiveNativeETH
) {
unwrapWETH9(amount1, params.receiver);
}
emit CloseVaultPositionPartially(
params.vaultId,
params.vaultPositionId,
_msgSender(),
params.percent,
amount0,
amount1,
repay0,
repay1
);
}
function closeOutOfRangePosition(
CloseVaultPositionPartiallyParams calldata params
)
external
payable
nonReentrant
rangeStopCallerInWhitelist
avoidUsingNativeEther
{
address vaultAddress = IVaultFactory(vaultFactory).vaults(
params.vaultId
);
require(vaultAddress != address(0), Errors.VL_ADDRESS_CANNOT_ZERO);
(
address positionManager,
uint256 price,
uint256 amount0,
uint256 amount1,
uint256 fee0,
uint256 fee1
) = IVeloVault(vaultAddress).closeAndRepayOutOfRangePosition(params);
if (
fee0 > 0 &&
IVeloVault(vaultAddress).token0() == WETH9 &&
params.receiveNativeETH
) {
unwrapWETH9(fee0, params.receiver);
}
if (
fee1 > 0 &&
IVeloVault(vaultAddress).token1() == WETH9 &&
params.receiveNativeETH
) {
unwrapWETH9(fee1, params.receiver);
}
emit CloseOutOfRangePosition(
params.vaultId,
params.vaultPositionId,
positionManager,
_msgSender(),
params.percent,
uint64(block.timestamp),
price,
amount0,
amount1,
fee0,
fee1
);
}
function liquidateVaultPositionPartially(
LiquidateVaultPositionPartiallyParams calldata params
) external payable nonReentrant liquidatorInWhitelist {
address vaultAddress = IVaultFactory(vaultFactory).vaults(
params.vaultId
);
require(vaultAddress != address(0), Errors.VL_ADDRESS_CANNOT_ZERO);
IVeloVault.LiquidateState memory result = IVeloVault(vaultAddress)
.repayAndLiquidatePositionPartially(params, _msgSender());
if (
result.liquidatorReceive0 > 0 &&
IVeloVault(vaultAddress).token0() == WETH9 &&
params.receiveNativeETH
) {
unwrapWETH9(result.liquidatorReceive0, params.receiver);
}
if (
result.liquidatorReceive1 > 0 &&
IVeloVault(vaultAddress).token1() == WETH9 &&
params.receiveNativeETH
) {
unwrapWETH9(result.liquidatorReceive1, params.receiver);
}
if (msg.value > 0) {
refundETH();
}
emit LiquidateVaultPositionPartially(
params.vaultId,
params.vaultPositionId,
result.manager,
_msgSender(),
params.percent,
uint64(block.timestamp),
result.price,
result.repaidValue,
result.removedLiquidityValue,
result.amount0Left,
result.amount1Left,
result.liquidateFee0,
result.liquidateFee1
);
}
function investEarnedFeeToLiquidity(
InvestEarnedFeeToLiquidityParam calldata params
) external nonReentrant compounderInWhitelist {
address vaultAddress = IVaultFactory(vaultFactory).vaults(
params.vaultId
);
require(vaultAddress != address(0), Errors.VL_ADDRESS_CANNOT_ZERO);
(
uint256 liquidity,
uint256 fee0,
uint256 fee1,
uint256[] memory rewards
) = IVeloVault(vaultAddress).claimRewardsAndReInvestToLiquidity(params);
if (
fee0 > 0 &&
IVeloVault(vaultAddress).token0() == WETH9 &&
params.receiveNativeETH
) {
unwrapWETH9(fee0, params.compoundFeeReceiver);
}
if (
fee1 > 0 &&
IVeloVault(vaultAddress).token1() == WETH9 &&
params.receiveNativeETH
) {
unwrapWETH9(fee1, params.compoundFeeReceiver);
}
emit InvestEarnedFeeToLiquidity(
params.vaultId,
_msgSender(),
liquidity,
fee0,
fee1,
rewards
);
}
function exactRepay(
ExactRepayParam calldata params
)
external
payable
nonReentrant
returns (uint256 amount0Repaid, uint256 amount1Repaid)
{
address vaultAddress = IVaultFactory(vaultFactory).vaults(
params.vaultId
);
require(vaultAddress != address(0), Errors.VL_ADDRESS_CANNOT_ZERO);
address positionMananegr;
(positionMananegr, amount0Repaid, amount1Repaid) = IVeloVault(
vaultAddress
).exactRepay(params, _msgSender());
if (
params.amount0ToRepay > amount0Repaid &&
IVeloVault(vaultAddress).token0() == WETH9 &&
params.receiveNativeETH
) {
unwrapWETH9(params.amount0ToRepay.sub(amount0Repaid), _msgSender());
}
if (
params.amount1ToRepay > amount1Repaid &&
IVeloVault(vaultAddress).token1() == WETH9 &&
params.receiveNativeETH
) {
unwrapWETH9(params.amount1ToRepay.sub(amount1Repaid), _msgSender());
}
if (msg.value > 0) {
refundETH();
}
emit ExactRepay(
params.vaultId,
params.vaultPositionId,
positionMananegr,
_msgSender(),
amount0Repaid,
amount1Repaid
);
}
function adminSetVault(
uint256 vaultId,
bytes calldata params
) external nonReentrant onlyOwner {
address vaultAddress = IVaultFactory(vaultFactory).vaults(vaultId);
require(vaultAddress != address(0), Errors.VL_ADDRESS_CANNOT_ZERO);
IVeloVault(vaultAddress).adminSetVault(params);
}
function transferManagerOfVaultPosition(
uint256 vaultId,
uint256 vaultPositionId,
address newManager
) external override nonReentrant {
address vaultAddress = IVaultFactory(vaultFactory).vaults(vaultId);
require(vaultAddress != address(0), Errors.VL_ADDRESS_CANNOT_ZERO);
IVeloVault(vaultAddress).transferManagerTo(
_msgSender(),
vaultPositionId,
newManager
);
}
function setRangeStop(
uint256 vaultId,
uint256 vaultPositionId,
bool enable,
uint256 minPrice,
uint256 maxPrice
) external override nonReentrant {
address vaultAddress = IVaultFactory(vaultFactory).vaults(vaultId);
require(vaultAddress != address(0), Errors.VL_ADDRESS_CANNOT_ZERO);
IVeloVault(vaultAddress).setRangeStop(
_msgSender(),
vaultPositionId,
enable,
minPrice,
maxPrice
);
}
function enablePermissionLessLiquidation() public nonReentrant onlyOwner {
permissionLessLiquidationEnabled = true;
}
function disablePermissionLessLiquidation() public nonReentrant onlyOwner {
permissionLessLiquidationEnabled = false;
}
function addPermissionedLiquidator(
address addr
) public nonReentrant onlyOwner {
liquidatorWhitelist[addr] = true;
}
function removePermissionedLiquidator(
address addr
) public nonReentrant onlyOwner {
liquidatorWhitelist[addr] = false;
}
function enablePermissionLessCompound() public nonReentrant onlyOwner {
permissionLessCompoundEnabled = true;
}
function disablePermissionLessCompound() public nonReentrant onlyOwner {
permissionLessCompoundEnabled = false;
}
function addPermissionedCompounder(
address addr
) public nonReentrant onlyOwner {
compounderWhitelist[addr] = true;
}
function removePermissionedCompounder(
address addr
) public nonReentrant onlyOwner {
compounderWhitelist[addr] = false;
}
function enablePermissonLessRangeStop() public nonReentrant onlyOwner {
permissionLessRangeStopEnabled = true;
}
function disablePermissonLessRangeStop() public nonReentrant onlyOwner {
permissionLessRangeStopEnabled = false;
}
function addPermissionedRangeStopCaller(
address addr
) public nonReentrant onlyOwner {
rangeStopCallerWhitelist[addr] = true;
}
function removePermissionedRangeStopCaller(
address addr
) public nonReentrant onlyOwner {
rangeStopCallerWhitelist[addr] = false;
}
function getVault(
uint256 vaultId
) external view override returns (VaultTypes.VeloVaultState memory) {
address vaultAddress = IVaultFactory(vaultFactory).vaults(vaultId);
return IVeloVault(vaultAddress).getVaultState();
}
function getVaultPosition(
uint256 vaultId,
uint256 vaultPositionId
)
external
view
override
returns (VaultTypes.VeloPositionValue memory state)
{
address vaultAddress = IVaultFactory(vaultFactory).vaults(vaultId);
return IVeloVault(vaultAddress).getPositionValue(vaultPositionId);
}
}
文件 20 的 20:draft-IERC20Permit.sol
pragma solidity ^0.8.0;
interface IERC20Permit {
function permit(
address owner,
address spender,
uint256 value,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) external;
function nonces(address owner) external view returns (uint256);
function DOMAIN_SEPARATOR() external view returns (bytes32);
}
{
"compilationTarget": {
"contracts/VeloPositionManager.sol": "VeloPositionManager"
},
"evmVersion": "paris",
"libraries": {},
"metadata": {
"bytecodeHash": "ipfs"
},
"optimizer": {
"enabled": true,
"runs": 200
},
"remappings": []
}
[{"inputs":[{"internalType":"address","name":"_addressProvider","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"vaultId","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"vaultPositionId","type":"uint256"},{"indexed":true,"internalType":"address","name":"manager","type":"address"},{"indexed":false,"internalType":"address","name":"caller","type":"address"},{"indexed":false,"internalType":"uint16","name":"percent","type":"uint16"},{"indexed":false,"internalType":"uint64","name":"timestamp","type":"uint64"},{"indexed":false,"internalType":"uint256","name":"price","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount0Received","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount1Received","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"fee0","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"fee1","type":"uint256"}],"name":"CloseOutOfRangePosition","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"vaultId","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"vaultPositionId","type":"uint256"},{"indexed":true,"internalType":"address","name":"manager","type":"address"},{"indexed":false,"internalType":"uint16","name":"percent","type":"uint16"},{"indexed":false,"internalType":"uint256","name":"amount0Received","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount1Received","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount0Repaid","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount1Repaid","type":"uint256"}],"name":"CloseVaultPositionPartially","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"vaultId","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"vaultPositionId","type":"uint256"},{"indexed":true,"internalType":"address","name":"manager","type":"address"},{"indexed":false,"internalType":"address","name":"caller","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount0Repaid","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount1Repaid","type":"uint256"}],"name":"ExactRepay","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"vaultId","type":"uint256"},{"indexed":true,"internalType":"address","name":"asset","type":"address"},{"indexed":true,"internalType":"uint256","name":"feeType","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"FeePaid","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"vaultId","type":"uint256"},{"indexed":true,"internalType":"address","name":"caller","type":"address"},{"indexed":false,"internalType":"uint256","name":"liquidityAdded","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"fee0","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"fee1","type":"uint256"},{"indexed":false,"internalType":"uint256[]","name":"rewards","type":"uint256[]"}],"name":"InvestEarnedFeeToLiquidity","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"vaultId","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"vaultPositionId","type":"uint256"},{"indexed":true,"internalType":"address","name":"manager","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount0Invest","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount1Invest","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount0Borrow","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount1Borrow","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"liquidity","type":"uint256"}],"name":"InvestToVaultPosition","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"vaultId","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"vaultPositionId","type":"uint256"},{"indexed":true,"internalType":"address","name":"manager","type":"address"},{"indexed":false,"internalType":"address","name":"liquidator","type":"address"},{"indexed":false,"internalType":"uint16","name":"percent","type":"uint16"},{"indexed":false,"internalType":"uint64","name":"timestamp","type":"uint64"},{"indexed":false,"internalType":"uint256","name":"price","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"debtValueOfPosition","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"liquidityValueOfPosition","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount0Left","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount1Left","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"liquidateFee0","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"liquidateFee1","type":"uint256"}],"name":"LiquidateVaultPositionPartially","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"vaultId","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"vaultPositionId","type":"uint256"},{"indexed":true,"internalType":"address","name":"manager","type":"address"}],"name":"NewVaultPosition","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"inputs":[],"name":"WETH9","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"addr","type":"address"}],"name":"addPermissionedCompounder","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"addr","type":"address"}],"name":"addPermissionedLiquidator","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"addr","type":"address"}],"name":"addPermissionedRangeStopCaller","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"addressProvider","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"vaultId","type":"uint256"},{"internalType":"bytes","name":"params","type":"bytes"}],"name":"adminSetVault","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"uint256","name":"vaultId","type":"uint256"},{"internalType":"uint256","name":"vaultPositionId","type":"uint256"},{"internalType":"uint16","name":"percent","type":"uint16"},{"internalType":"address","name":"receiver","type":"address"},{"internalType":"bool","name":"receiveNativeETH","type":"bool"},{"internalType":"uint8","name":"receiveType","type":"uint8"},{"internalType":"uint256","name":"minAmount0WhenRemoveLiquidity","type":"uint256"},{"internalType":"uint256","name":"minAmount1WhenRemoveLiquidity","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"uint256","name":"swapExecutorId","type":"uint256"},{"internalType":"bytes","name":"swapPath","type":"bytes"}],"internalType":"struct IVeloVaultPositionManager.CloseVaultPositionPartiallyParams","name":"params","type":"tuple"}],"name":"closeOutOfRangePosition","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"components":[{"internalType":"uint256","name":"vaultId","type":"uint256"},{"internalType":"uint256","name":"vaultPositionId","type":"uint256"},{"internalType":"uint16","name":"percent","type":"uint16"},{"internalType":"address","name":"receiver","type":"address"},{"internalType":"bool","name":"receiveNativeETH","type":"bool"},{"internalType":"uint8","name":"receiveType","type":"uint8"},{"internalType":"uint256","name":"minAmount0WhenRemoveLiquidity","type":"uint256"},{"internalType":"uint256","name":"minAmount1WhenRemoveLiquidity","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"uint256","name":"swapExecutorId","type":"uint256"},{"internalType":"bytes","name":"swapPath","type":"bytes"}],"internalType":"struct IVeloVaultPositionManager.CloseVaultPositionPartiallyParams","name":"params","type":"tuple"}],"name":"closeVaultPositionPartially","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"compounderWhitelist","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"disablePermissionLessCompound","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"disablePermissionLessLiquidation","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"disablePermissonLessRangeStop","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"enablePermissionLessCompound","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"enablePermissionLessLiquidation","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"enablePermissonLessRangeStop","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"uint256","name":"vaultId","type":"uint256"},{"internalType":"uint256","name":"vaultPositionId","type":"uint256"},{"internalType":"uint256","name":"amount0ToRepay","type":"uint256"},{"internalType":"uint256","name":"amount1ToRepay","type":"uint256"},{"internalType":"bool","name":"receiveNativeETH","type":"bool"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"internalType":"struct IVeloVaultPositionManager.ExactRepayParam","name":"params","type":"tuple"}],"name":"exactRepay","outputs":[{"internalType":"uint256","name":"amount0Repaid","type":"uint256"},{"internalType":"uint256","name":"amount1Repaid","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"vaultId","type":"uint256"}],"name":"getVault","outputs":[{"components":[{"internalType":"address","name":"gauge","type":"address"},{"internalType":"address","name":"pair","type":"address"},{"internalType":"address","name":"token0","type":"address"},{"internalType":"address","name":"token1","type":"address"},{"internalType":"bool","name":"stable","type":"bool"},{"internalType":"bool","name":"paused","type":"bool"},{"internalType":"bool","name":"frozen","type":"bool"},{"internalType":"bool","name":"borrowingEnabled","type":"bool"},{"internalType":"bool","name":"liquidateWithTWAP","type":"bool"},{"internalType":"uint16","name":"maxLeverage","type":"uint16"},{"internalType":"uint16","name":"premiumMaxLeverage","type":"uint16"},{"internalType":"uint16","name":"maxPriceDiff","type":"uint16"},{"internalType":"uint16","name":"liquidateDebtRatio","type":"uint16"},{"internalType":"uint16","name":"withdrawFeeRate","type":"uint16"},{"internalType":"uint16","name":"compoundFeeRate","type":"uint16"},{"internalType":"uint16","name":"liquidateFeeRate","type":"uint16"},{"internalType":"uint16","name":"rangeStopFeeRate","type":"uint16"},{"internalType":"uint16","name":"protocolFeeRate","type":"uint16"},{"internalType":"uint256","name":"premiumRequirement","type":"uint256"},{"internalType":"uint256","name":"protocolFee0Accumulated","type":"uint256"},{"internalType":"uint256","name":"protocolFee1Accumulated","type":"uint256"},{"internalType":"uint256","name":"minInvestValue","type":"uint256"},{"internalType":"uint256","name":"minSwapAmount0","type":"uint256"},{"internalType":"uint256","name":"minSwapAmount1","type":"uint256"},{"internalType":"uint256","name":"totalLp","type":"uint256"},{"internalType":"uint256","name":"totalLpShares","type":"uint256"},{"internalType":"uint256","name":"premiumUtilizationOfReserve0","type":"uint256"},{"internalType":"uint256","name":"debtLimit0","type":"uint256"},{"internalType":"uint256","name":"debtPositionId0","type":"uint256"},{"internalType":"uint256","name":"debtTotalShares0","type":"uint256"},{"internalType":"uint256","name":"premiumUtilizationOfReserve1","type":"uint256"},{"internalType":"uint256","name":"debtLimit1","type":"uint256"},{"internalType":"uint256","name":"debtPositionId1","type":"uint256"},{"internalType":"uint256","name":"debtTotalShares1","type":"uint256"}],"internalType":"struct VaultTypes.VeloVaultState","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"vaultId","type":"uint256"},{"internalType":"uint256","name":"vaultPositionId","type":"uint256"}],"name":"getVaultPosition","outputs":[{"components":[{"internalType":"address","name":"manager","type":"address"},{"internalType":"bool","name":"isActive","type":"bool"},{"internalType":"bool","name":"enableRangeStop","type":"bool"},{"internalType":"uint64","name":"openedAt","type":"uint64"},{"internalType":"uint64","name":"current","type":"uint64"},{"internalType":"uint256","name":"token0Principal","type":"uint256"},{"internalType":"uint256","name":"token1Principal","type":"uint256"},{"internalType":"uint256","name":"liquidityPrincipal","type":"uint256"},{"internalType":"uint256","name":"token0Left","type":"uint256"},{"internalType":"uint256","name":"token1Left","type":"uint256"},{"internalType":"uint256","name":"token0InLiquidity","type":"uint256"},{"internalType":"uint256","name":"token1InLiquidity","type":"uint256"},{"internalType":"uint256","name":"liquidity","type":"uint256"},{"internalType":"uint256","name":"debt0","type":"uint256"},{"internalType":"uint256","name":"debt1","type":"uint256"},{"internalType":"uint256","name":"borrowingIndex0","type":"uint256"},{"internalType":"uint256","name":"borrowingIndex1","type":"uint256"},{"internalType":"uint256","name":"minPriceOfRangeStop","type":"uint256"},{"internalType":"uint256","name":"maxPriceOfRangeStop","type":"uint256"}],"internalType":"struct VaultTypes.VeloPositionValue","name":"state","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"uint256","name":"vaultId","type":"uint256"},{"internalType":"address","name":"compoundFeeReceiver","type":"address"},{"components":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"bool","name":"stable","type":"bool"}],"internalType":"struct IRouter.route[][]","name":"routes","type":"tuple[][]"},{"internalType":"bool","name":"receiveNativeETH","type":"bool"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"internalType":"struct IVeloVaultPositionManager.InvestEarnedFeeToLiquidityParam","name":"params","type":"tuple"}],"name":"investEarnedFeeToLiquidity","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"uint256","name":"vaultId","type":"uint256"},{"internalType":"uint256","name":"vaultPositionId","type":"uint256"},{"internalType":"uint16","name":"percent","type":"uint16"},{"internalType":"address","name":"receiver","type":"address"},{"internalType":"bool","name":"receiveNativeETH","type":"bool"},{"internalType":"uint8","name":"receiveType","type":"uint8"},{"internalType":"uint256","name":"minAmount0WhenRemoveLiquidity","type":"uint256"},{"internalType":"uint256","name":"minAmount1WhenRemoveLiquidity","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"uint256","name":"maxRepay0","type":"uint256"},{"internalType":"uint256","name":"maxRepay1","type":"uint256"},{"internalType":"uint256","name":"swapExecutorId","type":"uint256"},{"internalType":"bytes","name":"swapPath","type":"bytes"}],"internalType":"struct IVeloVaultPositionManager.LiquidateVaultPositionPartiallyParams","name":"params","type":"tuple"}],"name":"liquidateVaultPositionPartially","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"liquidatorWhitelist","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"uint256","name":"vaultId","type":"uint256"},{"internalType":"uint256","name":"vaultPositionId","type":"uint256"},{"internalType":"uint256","name":"amount0Invest","type":"uint256"},{"internalType":"uint256","name":"amount0Borrow","type":"uint256"},{"internalType":"uint256","name":"amount1Invest","type":"uint256"},{"internalType":"uint256","name":"amount1Borrow","type":"uint256"},{"internalType":"uint256","name":"amount0Min","type":"uint256"},{"internalType":"uint256","name":"amount1Min","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"uint256","name":"swapExecutorId","type":"uint256"},{"internalType":"bytes","name":"swapPath","type":"bytes"}],"internalType":"struct IVeloVaultPositionManager.NewOrInvestToVaultPositionParams","name":"params","type":"tuple"}],"name":"newOrInvestToVaultPosition","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"vaultId","type":"uint256"},{"internalType":"address","name":"asset","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"feeType","type":"uint256"}],"name":"payFeeToTreasuryCallback","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"uint256","name":"vaultId","type":"uint256"},{"internalType":"uint256","name":"amount0","type":"uint256"},{"internalType":"uint256","name":"amount1","type":"uint256"},{"internalType":"address","name":"payer","type":"address"}],"internalType":"struct IVeloVaultPositionManager.PayToVaultCallbackParams","name":"params","type":"tuple"}],"name":"payToVaultCallback","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"permissionLessCompoundEnabled","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"permissionLessLiquidationEnabled","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"permissionLessRangeStopEnabled","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"rangeStopCallerWhitelist","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"addr","type":"address"}],"name":"removePermissionedCompounder","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"addr","type":"address"}],"name":"removePermissionedLiquidator","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"addr","type":"address"}],"name":"removePermissionedRangeStopCaller","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"vaultId","type":"uint256"},{"internalType":"uint256","name":"vaultPositionId","type":"uint256"},{"internalType":"bool","name":"enable","type":"bool"},{"internalType":"uint256","name":"minPrice","type":"uint256"},{"internalType":"uint256","name":"maxPrice","type":"uint256"}],"name":"setRangeStop","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"vaultId","type":"uint256"},{"internalType":"uint256","name":"vaultPositionId","type":"uint256"},{"internalType":"address","name":"newManager","type":"address"}],"name":"transferManagerOfVaultPosition","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"vaultFactory","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"stateMutability":"payable","type":"receive"}]