编译器
0.8.19+commit.7dd6d404
文件 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:Constants.sol
pragma solidity 0.8.19;
library Constants {
uint256 public constant Q128 = 1 << 128;
uint256 public constant Q64 = 1 << 64;
}
文件 3 的 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);
}
文件 4 的 20: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);
}
文件 5 的 20:IFlashBorrower.sol
pragma solidity 0.8.19;
interface IFlashBorrower {
function onFlashLoan(
address initiator,
address token,
uint256 amount,
bytes calldata data
) external returns (bytes32);
}
文件 6 的 20:ISovereignALM.sol
pragma solidity 0.8.19;
import { ALMLiquidityQuoteInput, ALMLiquidityQuote } from '../structs/SovereignALMStructs.sol';
interface ISovereignALM {
function getLiquidityQuote(
ALMLiquidityQuoteInput memory _almLiquidityQuoteInput,
bytes calldata _externalContext,
bytes calldata _verifierData
) external returns (ALMLiquidityQuote memory);
function onDepositLiquidityCallback(uint256 _amount0, uint256 _amount1, bytes memory _data) external;
function onSwapCallback(bool _isZeroToOne, uint256 _amountIn, uint256 _amountOut) external;
}
文件 7 的 20:ISovereignOracle.sol
pragma solidity 0.8.19;
interface ISovereignOracle {
function pool() external view returns (address);
function writeOracleUpdate(bool isZeroToOne, uint256 amountInMinusFee, uint256 fee, uint256 amountOut) external;
}
文件 8 的 20:ISovereignPool.sol
pragma solidity 0.8.19;
import { IValantisPool } from '../interfaces/IValantisPool.sol';
import { PoolLocks } from '../structs/ReentrancyGuardStructs.sol';
import { SovereignPoolSwapContextData, SovereignPoolSwapParams } from '../structs/SovereignPoolStructs.sol';
interface ISovereignPool is IValantisPool {
event SwapFeeModuleSet(address swapFeeModule);
event ALMSet(address alm);
event GaugeSet(address gauge);
event PoolManagerSet(address poolManager);
event PoolManagerFeeSet(uint256 poolManagerFeeBips);
event SovereignOracleSet(address sovereignOracle);
event PoolManagerFeesClaimed(uint256 amount0, uint256 amount1);
event DepositLiquidity(uint256 amount0, uint256 amount1);
event WithdrawLiquidity(address indexed recipient, uint256 amount0, uint256 amount1);
event Swap(address indexed sender, bool isZeroToOne, uint256 amountIn, uint256 fee, uint256 amountOut);
function getTokens() external view returns (address[] memory tokens);
function sovereignVault() external view returns (address);
function protocolFactory() external view returns (address);
function gauge() external view returns (address);
function poolManager() external view returns (address);
function sovereignOracleModule() external view returns (address);
function swapFeeModule() external view returns (address);
function verifierModule() external view returns (address);
function isLocked() external view returns (bool);
function isRebaseTokenPool() external view returns (bool);
function poolManagerFeeBips() external view returns (uint256);
function defaultSwapFeeBips() external view returns (uint256);
function swapFeeModuleUpdateTimestamp() external view returns (uint256);
function alm() external view returns (address);
function getPoolManagerFees() external view returns (uint256 poolManagerFee0, uint256 poolManagerFee1);
function getReserves() external view returns (uint256 reserve0, uint256 reserve1);
function setPoolManager(address _manager) external;
function setGauge(address _gauge) external;
function setPoolManagerFeeBips(uint256 _poolManagerFeeBips) external;
function setSovereignOracle(address sovereignOracle) external;
function setSwapFeeModule(address _swapFeeModule) external;
function setALM(address _alm) external;
function swap(SovereignPoolSwapParams calldata _swapParams) external returns (uint256, uint256);
function depositLiquidity(
uint256 _amount0,
uint256 _amount1,
address _sender,
bytes calldata _verificationContext,
bytes calldata _depositData
) external returns (uint256 amount0Deposited, uint256 amount1Deposited);
function withdrawLiquidity(
uint256 _amount0,
uint256 _amount1,
address _sender,
address _recipient,
bytes calldata _verificationContext
) external;
}
文件 9 的 20:ISovereignPoolSwapCallback.sol
pragma solidity 0.8.19;
interface ISovereignPoolSwapCallback {
function sovereignPoolSwapCallback(
address _tokenIn,
uint256 _amountInUsed,
bytes calldata _swapCallbackContext
) external;
}
文件 10 的 20:ISovereignVaultMinimal.sol
pragma solidity 0.8.19;
interface ISovereignVaultMinimal {
function getTokensForPool(address _pool) external view returns (address[] memory);
function getReservesForPool(address _pool, address[] calldata _tokens) external view returns (uint256[] memory);
function claimPoolManagerFees(uint256 _feePoolManager0, uint256 _feePoolManager1) external;
}
文件 11 的 20:ISwapFeeModule.sol
pragma solidity 0.8.19;
struct SwapFeeModuleData {
uint256 feeInBips;
bytes internalContext;
}
interface ISwapFeeModuleMinimal {
function getSwapFeeInBips(
address _tokenIn,
address _tokenOut,
uint256 _amountIn,
address _user,
bytes memory _swapFeeModuleContext
) external returns (SwapFeeModuleData memory swapFeeModuleData);
}
interface ISwapFeeModule is ISwapFeeModuleMinimal {
function callbackOnSwapEnd(
uint256 _effectiveFee,
int24 _spotPriceTick,
uint256 _amountInUsed,
uint256 _amountOut,
SwapFeeModuleData memory _swapFeeModuleData
) external;
function callbackOnSwapEnd(
uint256 _effectiveFee,
uint256 _amountInUsed,
uint256 _amountOut,
SwapFeeModuleData memory _swapFeeModuleData
) external;
}
文件 12 的 20:IValantisPool.sol
pragma solidity 0.8.19;
import { IFlashBorrower } from './IFlashBorrower.sol';
interface IValantisPool {
event Flashloan(address indexed initiator, address indexed receiver, uint256 amount, address token);
error ValantisPool__flashloan_callbackFailed();
error ValantisPool__flashLoan_flashLoanDisabled();
error ValantisPool__flashLoan_flashLoanNotRepaid();
error ValantisPool__flashLoan_rebaseTokenNotAllowed();
function token0() external view returns (address);
function token1() external view returns (address);
function claimProtocolFees() external returns (uint256, uint256);
function claimPoolManagerFees(
uint256 _feeProtocol0Bips,
uint256 _feeProtocol1Bips
) external returns (uint256 feePoolManager0Received, uint256 feePoolManager1Received);
function setGauge(address _gauge) external;
function flashLoan(bool _isTokenZero, IFlashBorrower _receiver, uint256 _amount, bytes calldata _data) external;
}
文件 13 的 20:IVerifierModule.sol
pragma solidity 0.8.19;
interface IVerifierModule {
function verify(
address _user,
bytes calldata _verificationContext,
uint8 accessType
) external returns (bool success, bytes memory returnData);
}
文件 14 的 20:Math.sol
pragma solidity ^0.8.0;
library Math {
enum Rounding {
Down,
Up,
Zero
}
function max(uint256 a, uint256 b) internal pure returns (uint256) {
return a > b ? a : b;
}
function min(uint256 a, uint256 b) internal pure returns (uint256) {
return a < b ? a : b;
}
function average(uint256 a, uint256 b) internal pure returns (uint256) {
return (a & b) + (a ^ b) / 2;
}
function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {
return a == 0 ? 0 : (a - 1) / b + 1;
}
function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) {
unchecked {
uint256 prod0;
uint256 prod1;
assembly {
let mm := mulmod(x, y, not(0))
prod0 := mul(x, y)
prod1 := sub(sub(mm, prod0), lt(mm, prod0))
}
if (prod1 == 0) {
return prod0 / denominator;
}
require(denominator > prod1, "Math: mulDiv overflow");
uint256 remainder;
assembly {
remainder := mulmod(x, y, denominator)
prod1 := sub(prod1, gt(remainder, prod0))
prod0 := sub(prod0, remainder)
}
uint256 twos = denominator & (~denominator + 1);
assembly {
denominator := div(denominator, twos)
prod0 := div(prod0, twos)
twos := add(div(sub(0, twos), twos), 1)
}
prod0 |= prod1 * twos;
uint256 inverse = (3 * denominator) ^ 2;
inverse *= 2 - denominator * inverse;
inverse *= 2 - denominator * inverse;
inverse *= 2 - denominator * inverse;
inverse *= 2 - denominator * inverse;
inverse *= 2 - denominator * inverse;
inverse *= 2 - denominator * inverse;
result = prod0 * inverse;
return result;
}
}
function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) {
uint256 result = mulDiv(x, y, denominator);
if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {
result += 1;
}
return result;
}
function sqrt(uint256 a) internal pure returns (uint256) {
if (a == 0) {
return 0;
}
uint256 result = 1 << (log2(a) >> 1);
unchecked {
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
return min(result, a / result);
}
}
function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {
unchecked {
uint256 result = sqrt(a);
return result + (rounding == Rounding.Up && result * result < a ? 1 : 0);
}
}
function log2(uint256 value) internal pure returns (uint256) {
uint256 result = 0;
unchecked {
if (value >> 128 > 0) {
value >>= 128;
result += 128;
}
if (value >> 64 > 0) {
value >>= 64;
result += 64;
}
if (value >> 32 > 0) {
value >>= 32;
result += 32;
}
if (value >> 16 > 0) {
value >>= 16;
result += 16;
}
if (value >> 8 > 0) {
value >>= 8;
result += 8;
}
if (value >> 4 > 0) {
value >>= 4;
result += 4;
}
if (value >> 2 > 0) {
value >>= 2;
result += 2;
}
if (value >> 1 > 0) {
result += 1;
}
}
return result;
}
function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {
unchecked {
uint256 result = log2(value);
return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0);
}
}
function log10(uint256 value) internal pure returns (uint256) {
uint256 result = 0;
unchecked {
if (value >= 10 ** 64) {
value /= 10 ** 64;
result += 64;
}
if (value >= 10 ** 32) {
value /= 10 ** 32;
result += 32;
}
if (value >= 10 ** 16) {
value /= 10 ** 16;
result += 16;
}
if (value >= 10 ** 8) {
value /= 10 ** 8;
result += 8;
}
if (value >= 10 ** 4) {
value /= 10 ** 4;
result += 4;
}
if (value >= 10 ** 2) {
value /= 10 ** 2;
result += 2;
}
if (value >= 10 ** 1) {
result += 1;
}
}
return result;
}
function log10(uint256 value, Rounding rounding) internal pure returns (uint256) {
unchecked {
uint256 result = log10(value);
return result + (rounding == Rounding.Up && 10 ** result < value ? 1 : 0);
}
}
function log256(uint256 value) internal pure returns (uint256) {
uint256 result = 0;
unchecked {
if (value >> 128 > 0) {
value >>= 128;
result += 16;
}
if (value >> 64 > 0) {
value >>= 64;
result += 8;
}
if (value >> 32 > 0) {
value >>= 32;
result += 4;
}
if (value >> 16 > 0) {
value >>= 16;
result += 2;
}
if (value >> 8 > 0) {
result += 1;
}
}
return result;
}
function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {
unchecked {
uint256 result = log256(value);
return result + (rounding == Rounding.Up && 1 << (result << 3) < value ? 1 : 0);
}
}
}
文件 15 的 20:ReentrancyGuard.sol
pragma solidity 0.8.19;
abstract contract ReentrancyGuard {
uint256 internal constant _NOT_ENTERED = 1;
uint256 internal constant _ENTERED = 2;
uint256 internal _status;
constructor() {
_status = _NOT_ENTERED;
}
modifier nonReentrant() {
_nonReentrantBefore();
_;
_nonReentrantAfter();
}
function _nonReentrantBefore() internal {
require(_status != _ENTERED, 'ReentrancyGuard: reentrant call');
_status = _ENTERED;
}
function _nonReentrantAfter() internal {
_status = _NOT_ENTERED;
}
}
文件 16 的 20:ReentrancyGuardStructs.sol
pragma solidity 0.8.19;
enum Lock {
WITHDRAWAL,
DEPOSIT,
SWAP,
SPOT_PRICE_TICK
}
struct PoolLocks {
uint8 withdrawals;
uint8 deposit;
uint8 swap;
uint8 spotPriceTick;
}
文件 17 的 20:SafeERC20.sol
pragma solidity ^0.8.0;
import "../IERC20.sol";
import "../extensions/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 oldAllowance = token.allowance(address(this), spender);
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance + value));
}
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");
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance - value));
}
}
function forceApprove(IERC20 token, address spender, uint256 value) internal {
bytes memory approvalCall = abi.encodeWithSelector(token.approve.selector, spender, value);
if (!_callOptionalReturnBool(token, approvalCall)) {
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, 0));
_callOptionalReturn(token, approvalCall);
}
}
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");
require(returndata.length == 0 || abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed");
}
function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) {
(bool success, bytes memory returndata) = address(token).call(data);
return
success && (returndata.length == 0 || abi.decode(returndata, (bool))) && Address.isContract(address(token));
}
}
文件 18 的 20:SovereignALMStructs.sol
pragma solidity 0.8.19;
struct ALMLiquidityQuoteInput {
bool isZeroToOne;
uint256 amountInMinusFee;
uint256 feeInBips;
address sender;
address recipient;
address tokenOutSwap;
}
struct ALMLiquidityQuote {
bool isCallbackOnSwap;
uint256 amountOut;
uint256 amountInFilled;
}
文件 19 的 20:SovereignPool.sol
pragma solidity 0.8.19;
import { Math } from '../../lib/openzeppelin-contracts/contracts/utils/math/Math.sol';
import { IERC20 } from '../../lib/openzeppelin-contracts/contracts/token/ERC20/IERC20.sol';
import { SafeERC20 } from '../../lib/openzeppelin-contracts/contracts/token/ERC20/utils/SafeERC20.sol';
import { Constants } from '../utils/Constants.sol';
import { ReentrancyGuard } from '../utils/ReentrancyGuard.sol';
import { ISwapFeeModule, SwapFeeModuleData } from '../swap-fee-modules/interfaces/ISwapFeeModule.sol';
import { ISovereignPool } from './interfaces/ISovereignPool.sol';
import { ISovereignPoolSwapCallback } from './interfaces/ISovereignPoolSwapCallback.sol';
import { IVerifierModule } from './interfaces/IVerifierModule.sol';
import { ALMLiquidityQuoteInput, ALMLiquidityQuote } from '../ALM/structs/SovereignALMStructs.sol';
import { ISovereignVaultMinimal } from './interfaces/ISovereignVaultMinimal.sol';
import { ISovereignALM } from '../ALM/interfaces/ISovereignALM.sol';
import { ISovereignOracle } from '../oracles/interfaces/ISovereignOracle.sol';
import { SovereignPoolConstructorArgs, SwapCache, SovereignPoolSwapParams } from './structs/SovereignPoolStructs.sol';
import { IFlashBorrower } from './interfaces/IFlashBorrower.sol';
contract SovereignPool is ISovereignPool, ReentrancyGuard {
using SafeERC20 for IERC20;
enum AccessType {
SWAP,
DEPOSIT,
WITHDRAW
}
error SovereignPool__ALMAlreadySet();
error SovereignPool__excessiveToken0AbsErrorTolerance();
error SovereignPool__excessiveToken1AbsErrorTolerance();
error SovereignPool__onlyALM();
error SovereignPool__onlyGauge();
error SovereignPool__onlyPoolManager();
error SovereignPool__onlyProtocolFactory();
error SovereignPool__sameTokenNotAllowed();
error SovereignPool__ZeroAddress();
error SovereignPool__depositLiquidity_depositDisabled();
error SovereignPool__depositLiquidity_excessiveToken0ErrorOnTransfer();
error SovereignPool__depositLiquidity_excessiveToken1ErrorOnTransfer();
error SovereignPool__depositLiquidity_incorrectTokenAmount();
error SovereignPool__depositLiquidity_insufficientToken0Amount();
error SovereignPool__depositLiquidity_insufficientToken1Amount();
error SovereignPool__depositLiquidity_zeroTotalDepositAmount();
error SovereignPool__getReserves_invalidReservesLength();
error SovereignPool__setGauge_gaugeAlreadySet();
error SovereignPool__setGauge_invalidAddress();
error SovereignPool__setPoolManagerFeeBips_excessivePoolManagerFee();
error SovereignPool__setSovereignOracle_oracleDisabled();
error SovereignPool__setSovereignOracle_sovereignOracleAlreadySet();
error SovereignPool__swap_excessiveSwapFee();
error SovereignPool__swap_expired();
error SovereignPool__swap_invalidLiquidityQuote();
error SovereignPool__swap_invalidPoolTokenOut();
error SovereignPool__swap_invalidRecipient();
error SovereignPool__swap_insufficientAmountIn();
error SovereignPool__swap_invalidSwapTokenOut();
error SovereignPool__swap_zeroAmountInOrOut();
error SovereignPool__setSwapFeeModule_timelock();
error SovereignPool__withdrawLiquidity_withdrawDisabled();
error SovereignPool__withdrawLiquidity_insufficientReserve0();
error SovereignPool__withdrawLiquidity_insufficientReserve1();
error SovereignPool__withdrawLiquidity_invalidRecipient();
error SovereignPool___claimPoolManagerFees_invalidFeeReceived();
error SovereignPool___claimPoolManagerFees_invalidProtocolFee();
error SovereignPool___handleTokenInOnSwap_excessiveTokenInErrorOnTransfer();
error SovereignPool___handleTokenInOnSwap_invalidTokenInAmount();
error SovereignPool___verifyPermission_onlyPermissionedAccess(address sender, uint8 accessType);
uint256 private constant _MAX_SWAP_FEE_BIPS = 10_000;
uint256 private constant _FACTOR_ONE = 10_000;
uint256 private constant _MAX_POOL_MANAGER_FEE_BIPS = 5_000;
uint256 private constant _MAX_ABS_ERROR_TOLERANCE = 10;
bytes32 private constant _CALLBACK_SUCCESS = keccak256('ERC3156FlashBorrower.onFlashLoan');
address public immutable sovereignVault;
address public immutable protocolFactory;
uint256 public immutable defaultSwapFeeBips;
IVerifierModule private immutable _verifierModule;
IERC20 private immutable _token0;
IERC20 private immutable _token1;
bool public immutable isToken0Rebase;
bool public immutable isToken1Rebase;
uint256 public immutable token0AbsErrorTolerance;
uint256 public immutable token1AbsErrorTolerance;
address public alm;
address public gauge;
address public poolManager;
uint256 public poolManagerFeeBips;
uint256 public feePoolManager0;
uint256 public feePoolManager1;
uint256 public feeProtocol0;
uint256 public feeProtocol1;
uint256 public swapFeeModuleUpdateTimestamp;
uint256 private _reserve0;
uint256 private _reserve1;
ISovereignOracle private _sovereignOracleModule;
ISwapFeeModule private _swapFeeModule;
modifier onlyALM() {
_onlyALM();
_;
}
modifier onlyProtocolFactory() {
_onlyProtocolFactory();
_;
}
modifier onlyPoolManager() {
_onlyPoolManager();
_;
}
modifier onlyGauge() {
_onlyGauge();
_;
}
constructor(SovereignPoolConstructorArgs memory args) {
if (args.token0 == args.token1) {
revert SovereignPool__sameTokenNotAllowed();
}
if (args.token0 == address(0) || args.token1 == address(0)) {
revert SovereignPool__ZeroAddress();
}
sovereignVault = args.sovereignVault == address(0) ? address(this) : args.sovereignVault;
_verifierModule = IVerifierModule(args.verifierModule);
_token0 = IERC20(args.token0);
_token1 = IERC20(args.token1);
protocolFactory = args.protocolFactory;
poolManager = args.poolManager;
isToken0Rebase = args.isToken0Rebase;
isToken1Rebase = args.isToken1Rebase;
if (args.token0AbsErrorTolerance > _MAX_ABS_ERROR_TOLERANCE) {
revert SovereignPool__excessiveToken0AbsErrorTolerance();
}
if (args.token1AbsErrorTolerance > _MAX_ABS_ERROR_TOLERANCE) {
revert SovereignPool__excessiveToken1AbsErrorTolerance();
}
token0AbsErrorTolerance = args.token0AbsErrorTolerance;
token1AbsErrorTolerance = args.token1AbsErrorTolerance;
defaultSwapFeeBips = args.defaultSwapFeeBips <= _MAX_SWAP_FEE_BIPS
? args.defaultSwapFeeBips
: _MAX_SWAP_FEE_BIPS;
swapFeeModuleUpdateTimestamp = block.timestamp;
}
function getTokens() external view override returns (address[] memory tokens) {
if (sovereignVault == address(this)) {
tokens = new address[](2);
tokens[0] = address(_token0);
tokens[1] = address(_token1);
} else {
tokens = ISovereignVaultMinimal(sovereignVault).getTokensForPool(address(this));
}
}
function getReserves() public view override returns (uint256, uint256) {
if (sovereignVault == address(this)) {
return (_getReservesForToken(true), _getReservesForToken(false));
} else {
address[] memory tokens = new address[](2);
tokens[0] = address(_token0);
tokens[1] = address(_token1);
uint256[] memory reserves = ISovereignVaultMinimal(sovereignVault).getReservesForPool(
address(this),
tokens
);
if (reserves.length != 2) {
revert SovereignPool__getReserves_invalidReservesLength();
}
return (reserves[0], reserves[1]);
}
}
function getPoolManagerFees() public view override returns (uint256, uint256) {
return (feePoolManager0, feePoolManager1);
}
function isRebaseTokenPool() external view override returns (bool) {
return isToken0Rebase || isToken1Rebase;
}
function token0() external view override returns (address) {
return address(_token0);
}
function token1() external view override returns (address) {
return address(_token1);
}
function sovereignOracleModule() external view override returns (address) {
return address(_sovereignOracleModule);
}
function swapFeeModule() external view override returns (address) {
return address(_swapFeeModule);
}
function verifierModule() external view override returns (address) {
return address(_verifierModule);
}
function isLocked() external view override returns (bool) {
return _status == _ENTERED;
}
function setPoolManager(address _manager) external override onlyPoolManager nonReentrant {
poolManager = _manager;
if (_manager == address(0)) {
poolManagerFeeBips = 0;
_claimPoolManagerFees(0, 0, msg.sender);
emit PoolManagerFeeSet(0);
}
emit PoolManagerSet(_manager);
}
function setPoolManagerFeeBips(uint256 _poolManagerFeeBips) external override onlyPoolManager nonReentrant {
if (_poolManagerFeeBips > _MAX_POOL_MANAGER_FEE_BIPS) {
revert SovereignPool__setPoolManagerFeeBips_excessivePoolManagerFee();
}
poolManagerFeeBips = _poolManagerFeeBips;
emit PoolManagerFeeSet(_poolManagerFeeBips);
}
function setSovereignOracle(address sovereignOracle) external override onlyPoolManager nonReentrant {
if (sovereignOracle == address(0)) {
revert SovereignPool__ZeroAddress();
}
if (address(sovereignVault) != address(this)) revert SovereignPool__setSovereignOracle_oracleDisabled();
if (address(_sovereignOracleModule) != address(0)) {
revert SovereignPool__setSovereignOracle_sovereignOracleAlreadySet();
}
_sovereignOracleModule = ISovereignOracle(sovereignOracle);
emit SovereignOracleSet(sovereignOracle);
}
function setGauge(address _gauge) external override onlyProtocolFactory nonReentrant {
if (gauge != address(0)) {
revert SovereignPool__setGauge_gaugeAlreadySet();
}
if (_gauge == address(0)) {
revert SovereignPool__setGauge_invalidAddress();
}
gauge = _gauge;
emit GaugeSet(_gauge);
}
function setSwapFeeModule(address swapFeeModule_) external override onlyPoolManager nonReentrant {
if (block.timestamp < swapFeeModuleUpdateTimestamp) {
revert SovereignPool__setSwapFeeModule_timelock();
}
_swapFeeModule = ISwapFeeModule(swapFeeModule_);
swapFeeModuleUpdateTimestamp = block.timestamp + 3 days;
emit SwapFeeModuleSet(swapFeeModule_);
}
function setALM(address _alm) external override onlyPoolManager nonReentrant {
if (_alm == address(0)) {
revert SovereignPool__ZeroAddress();
}
if (alm != address(0)) {
revert SovereignPool__ALMAlreadySet();
}
alm = _alm;
emit ALMSet(_alm);
}
function flashLoan(
bool _isTokenZero,
IFlashBorrower _receiver,
uint256 _amount,
bytes calldata _data
) external nonReentrant {
if (sovereignVault != address(this)) revert ValantisPool__flashLoan_flashLoanDisabled();
IERC20 flashToken = _isTokenZero ? _token0 : _token1;
bool isRebaseFlashToken = _isTokenZero ? isToken0Rebase : isToken1Rebase;
if (isRebaseFlashToken) {
revert ValantisPool__flashLoan_rebaseTokenNotAllowed();
}
uint256 poolPreBalance = flashToken.balanceOf(address(this));
flashToken.safeTransfer(address(_receiver), _amount);
if (_receiver.onFlashLoan(msg.sender, address(flashToken), _amount, _data) != _CALLBACK_SUCCESS) {
revert ValantisPool__flashloan_callbackFailed();
}
flashToken.safeTransferFrom(address(_receiver), address(this), _amount);
if (flashToken.balanceOf(address(this)) != poolPreBalance) {
revert ValantisPool__flashLoan_flashLoanNotRepaid();
}
emit Flashloan(msg.sender, address(_receiver), _amount, address(flashToken));
}
function claimPoolManagerFees(
uint256 _feeProtocol0Bips,
uint256 _feeProtocol1Bips
)
external
override
nonReentrant
onlyPoolManager
returns (uint256 feePoolManager0Received, uint256 feePoolManager1Received)
{
(feePoolManager0Received, feePoolManager1Received) = _claimPoolManagerFees(
_feeProtocol0Bips,
_feeProtocol1Bips,
msg.sender
);
}
function claimProtocolFees() external override nonReentrant onlyGauge returns (uint256, uint256) {
uint256 feeProtocol0Cache = feeProtocol0;
uint256 feeProtocol1Cache = feeProtocol1;
if (feeProtocol0Cache > 0) {
feeProtocol0 = 0;
_token0.safeTransfer(msg.sender, feeProtocol0Cache);
}
if (feeProtocol1Cache > 0) {
feeProtocol1 = 0;
_token1.safeTransfer(msg.sender, feeProtocol1Cache);
}
return (feeProtocol0Cache, feeProtocol1Cache);
}
function swap(
SovereignPoolSwapParams calldata _swapParams
) external override nonReentrant returns (uint256 amountInUsed, uint256 amountOut) {
if (block.timestamp > _swapParams.deadline) {
revert SovereignPool__swap_expired();
}
if (_swapParams.amountIn == 0) {
revert SovereignPool__swap_insufficientAmountIn();
}
if (_swapParams.recipient == address(0)) {
revert SovereignPool__swap_invalidRecipient();
}
SwapCache memory swapCache = SwapCache({
swapFeeModule: _swapFeeModule,
tokenInPool: _swapParams.isZeroToOne ? _token0 : _token1,
tokenOutPool: _swapParams.isZeroToOne ? _token1 : _token0,
amountInWithoutFee: 0
});
if (_swapParams.swapTokenOut == address(0) || _swapParams.swapTokenOut == address(swapCache.tokenInPool)) {
revert SovereignPool__swap_invalidSwapTokenOut();
}
if (sovereignVault == address(this) && _swapParams.swapTokenOut != address(swapCache.tokenOutPool)) {
revert SovereignPool__swap_invalidPoolTokenOut();
}
bytes memory verifierData;
if (address(_verifierModule) != address(0)) {
verifierData = _verifyPermission(
msg.sender,
_swapParams.swapContext.verifierContext,
uint8(AccessType.SWAP)
);
}
SwapFeeModuleData memory swapFeeModuleData;
if (address(swapCache.swapFeeModule) != address(0)) {
swapFeeModuleData = swapCache.swapFeeModule.getSwapFeeInBips(
address(swapCache.tokenInPool),
address(swapCache.tokenOutPool),
_swapParams.amountIn,
msg.sender,
_swapParams.swapContext.swapFeeModuleContext
);
if (swapFeeModuleData.feeInBips > _MAX_SWAP_FEE_BIPS) {
revert SovereignPool__swap_excessiveSwapFee();
}
} else {
swapFeeModuleData = SwapFeeModuleData({ feeInBips: defaultSwapFeeBips, internalContext: new bytes(0) });
}
swapCache.amountInWithoutFee = Math.mulDiv(
_swapParams.amountIn,
_MAX_SWAP_FEE_BIPS,
_MAX_SWAP_FEE_BIPS + swapFeeModuleData.feeInBips
);
ALMLiquidityQuote memory liquidityQuote = ISovereignALM(alm).getLiquidityQuote(
ALMLiquidityQuoteInput({
isZeroToOne: _swapParams.isZeroToOne,
amountInMinusFee: swapCache.amountInWithoutFee,
feeInBips: swapFeeModuleData.feeInBips,
sender: msg.sender,
recipient: _swapParams.recipient,
tokenOutSwap: _swapParams.swapTokenOut
}),
_swapParams.swapContext.externalContext,
verifierData
);
amountOut = liquidityQuote.amountOut;
if (
!_checkLiquidityQuote(
_swapParams.isZeroToOne,
swapCache.amountInWithoutFee,
liquidityQuote.amountInFilled,
amountOut,
_swapParams.amountOutMin
)
) {
revert SovereignPool__swap_invalidLiquidityQuote();
}
if (amountOut == 0 || liquidityQuote.amountInFilled == 0) {
revert SovereignPool__swap_zeroAmountInOrOut();
}
uint256 effectiveFee;
if (liquidityQuote.amountInFilled != swapCache.amountInWithoutFee) {
effectiveFee = Math.mulDiv(
liquidityQuote.amountInFilled,
swapFeeModuleData.feeInBips,
_MAX_SWAP_FEE_BIPS,
Math.Rounding.Up
);
amountInUsed = liquidityQuote.amountInFilled + effectiveFee;
} else {
effectiveFee = _swapParams.amountIn - swapCache.amountInWithoutFee;
amountInUsed = _swapParams.amountIn;
}
_handleTokenInTransfersOnSwap(
_swapParams.isZeroToOne,
_swapParams.isSwapCallback,
swapCache.tokenInPool,
amountInUsed,
effectiveFee,
_swapParams.swapContext.swapCallbackContext
);
_updatePoolStateOnSwap(_swapParams.isZeroToOne, amountInUsed, amountOut, effectiveFee);
if (
address(_sovereignOracleModule) != address(0) &&
_swapParams.swapTokenOut == address(swapCache.tokenOutPool) &&
amountInUsed > 0
) {
_sovereignOracleModule.writeOracleUpdate(_swapParams.isZeroToOne, amountInUsed, effectiveFee, amountOut);
}
_handleTokenOutTransferOnSwap(IERC20(_swapParams.swapTokenOut), _swapParams.recipient, amountOut);
if (
address(swapCache.swapFeeModule) != address(0) &&
keccak256(swapFeeModuleData.internalContext) != keccak256(new bytes(0))
) {
swapCache.swapFeeModule.callbackOnSwapEnd(effectiveFee, amountInUsed, amountOut, swapFeeModuleData);
}
if (liquidityQuote.isCallbackOnSwap) {
ISovereignALM(alm).onSwapCallback(_swapParams.isZeroToOne, amountInUsed, amountOut);
}
emit Swap(msg.sender, _swapParams.isZeroToOne, amountInUsed, effectiveFee, amountOut);
}
function depositLiquidity(
uint256 _amount0,
uint256 _amount1,
address _sender,
bytes calldata _verificationContext,
bytes calldata _depositData
) external override onlyALM nonReentrant returns (uint256 amount0Deposited, uint256 amount1Deposited) {
if (sovereignVault != address(this)) revert SovereignPool__depositLiquidity_depositDisabled();
if (_amount0 | _amount1 == 0) {
revert SovereignPool__depositLiquidity_zeroTotalDepositAmount();
}
if (address(_verifierModule) != address(0)) {
_verifyPermission(_sender, _verificationContext, uint8(AccessType.DEPOSIT));
}
uint256 token0PreBalance = _token0.balanceOf(address(this));
uint256 token1PreBalance = _token1.balanceOf(address(this));
ISovereignALM(msg.sender).onDepositLiquidityCallback(_amount0, _amount1, _depositData);
amount0Deposited = _token0.balanceOf(address(this)) - token0PreBalance;
amount1Deposited = _token1.balanceOf(address(this)) - token1PreBalance;
if (_amount0 != 0) {
if (isToken0Rebase) {
uint256 amount0AbsDiff = amount0Deposited < _amount0
? _amount0 - amount0Deposited
: amount0Deposited - _amount0;
if (amount0AbsDiff > token0AbsErrorTolerance) {
revert SovereignPool__depositLiquidity_excessiveToken0ErrorOnTransfer();
}
} else {
if (amount0Deposited != _amount0) revert SovereignPool__depositLiquidity_insufficientToken0Amount();
_reserve0 += amount0Deposited;
}
} else if (amount0Deposited > 0) {
revert SovereignPool__depositLiquidity_incorrectTokenAmount();
}
if (_amount1 != 0) {
if (isToken1Rebase) {
uint256 amount1AbsDiff = amount1Deposited < _amount1
? _amount1 - amount1Deposited
: amount1Deposited - _amount1;
if (amount1AbsDiff > token1AbsErrorTolerance) {
revert SovereignPool__depositLiquidity_excessiveToken1ErrorOnTransfer();
}
} else {
if (amount1Deposited != _amount1) revert SovereignPool__depositLiquidity_insufficientToken1Amount();
_reserve1 += amount1Deposited;
}
} else if (amount1Deposited > 0) {
revert SovereignPool__depositLiquidity_incorrectTokenAmount();
}
emit DepositLiquidity(amount0Deposited, amount1Deposited);
}
function withdrawLiquidity(
uint256 _amount0,
uint256 _amount1,
address _sender,
address _recipient,
bytes calldata _verificationContext
) external override nonReentrant onlyALM {
if (_recipient == address(0)) {
revert SovereignPool__withdrawLiquidity_invalidRecipient();
}
if (sovereignVault != address(this)) revert SovereignPool__withdrawLiquidity_withdrawDisabled();
if (address(_verifierModule) != address(0)) {
_verifyPermission(_sender, _verificationContext, uint8(AccessType.WITHDRAW));
}
if (_amount0 > _getReservesForToken(true)) {
revert SovereignPool__withdrawLiquidity_insufficientReserve0();
}
if (_amount1 > _getReservesForToken(false)) {
revert SovereignPool__withdrawLiquidity_insufficientReserve1();
}
unchecked {
if (!isToken0Rebase) _reserve0 -= _amount0;
if (!isToken1Rebase) _reserve1 -= _amount1;
}
if (_amount0 > 0) {
_token0.safeTransfer(_recipient, _amount0);
}
if (_amount1 > 0) {
_token1.safeTransfer(_recipient, _amount1);
}
emit WithdrawLiquidity(_recipient, _amount0, _amount1);
}
function _claimPoolManagerFees(
uint256 _feeProtocol0Bips,
uint256 _feeProtocol1Bips,
address _recipient
) private returns (uint256 feePoolManager0Received, uint256 feePoolManager1Received) {
if (_feeProtocol0Bips > _FACTOR_ONE || _feeProtocol1Bips > _FACTOR_ONE) {
revert SovereignPool___claimPoolManagerFees_invalidProtocolFee();
}
(feePoolManager0Received, feePoolManager1Received) = getPoolManagerFees();
if (sovereignVault != address(this)) {
uint256 token0PreBalance = _token0.balanceOf(address(this));
uint256 token1PreBalance = _token1.balanceOf(address(this));
ISovereignVaultMinimal(sovereignVault).claimPoolManagerFees(
feePoolManager0Received,
feePoolManager1Received
);
uint256 fee0ReceivedCache = _token0.balanceOf(address(this)) - token0PreBalance;
uint256 fee1ReceivedCache = _token1.balanceOf(address(this)) - token1PreBalance;
if (fee0ReceivedCache > feePoolManager0Received || fee1ReceivedCache > feePoolManager1Received) {
revert SovereignPool___claimPoolManagerFees_invalidFeeReceived();
}
feePoolManager0Received = fee0ReceivedCache;
feePoolManager1Received = fee1ReceivedCache;
}
uint256 protocolFee0 = Math.mulDiv(_feeProtocol0Bips, feePoolManager0Received, _FACTOR_ONE);
uint256 protocolFee1 = Math.mulDiv(_feeProtocol1Bips, feePoolManager1Received, _FACTOR_ONE);
feeProtocol0 += protocolFee0;
feeProtocol1 += protocolFee1;
feePoolManager0 = 0;
feePoolManager1 = 0;
feePoolManager0Received -= protocolFee0;
feePoolManager1Received -= protocolFee1;
if (feePoolManager0Received > 0) {
_token0.safeTransfer(_recipient, feePoolManager0Received);
}
if (feePoolManager1Received > 0) {
_token1.safeTransfer(_recipient, feePoolManager1Received);
}
emit PoolManagerFeesClaimed(feePoolManager0Received, feePoolManager1Received);
}
function _verifyPermission(
address sender,
bytes calldata verificationContext,
uint8 accessType
) private returns (bytes memory verifierData) {
bool success;
(success, verifierData) = _verifierModule.verify(sender, verificationContext, accessType);
if (!success) {
revert SovereignPool___verifyPermission_onlyPermissionedAccess(sender, accessType);
}
}
function _handleTokenInTransfersOnSwap(
bool isZeroToOne,
bool isSwapCallback,
IERC20 token,
uint256 amountInUsed,
uint256 effectiveFee,
bytes calldata _swapCallbackContext
) private {
uint256 preBalance = token.balanceOf(sovereignVault);
if (isSwapCallback) {
ISovereignPoolSwapCallback(msg.sender).sovereignPoolSwapCallback(
address(token),
amountInUsed,
_swapCallbackContext
);
} else {
token.safeTransferFrom(msg.sender, sovereignVault, amountInUsed);
}
uint256 amountInReceived = token.balanceOf(sovereignVault) - preBalance;
bool isTokenInRebase = isZeroToOne ? isToken0Rebase : isToken1Rebase;
if (isTokenInRebase) {
uint256 tokenInAbsDiff = amountInUsed > amountInReceived
? amountInUsed - amountInReceived
: amountInReceived - amountInUsed;
uint256 tokenInAbsErrorTolerance = isZeroToOne ? token0AbsErrorTolerance : token1AbsErrorTolerance;
if (tokenInAbsDiff > tokenInAbsErrorTolerance)
revert SovereignPool___handleTokenInOnSwap_excessiveTokenInErrorOnTransfer();
} else {
if (amountInReceived != amountInUsed) revert SovereignPool___handleTokenInOnSwap_invalidTokenInAmount();
}
if (isTokenInRebase && sovereignVault == address(this) && poolManager != address(0)) {
uint256 poolManagerFee = Math.mulDiv(effectiveFee, poolManagerFeeBips, _FACTOR_ONE);
if (poolManagerFee > 0) {
token.safeTransfer(poolManager, poolManagerFee);
}
}
}
function _handleTokenOutTransferOnSwap(IERC20 swapTokenOut, address recipient, uint256 amountOut) private {
if (sovereignVault == address(this)) {
swapTokenOut.safeTransfer(recipient, amountOut);
} else {
swapTokenOut.safeTransferFrom(sovereignVault, recipient, amountOut);
}
}
function _updatePoolStateOnSwap(
bool isZeroToOne,
uint256 amountInUsed,
uint256 amountOut,
uint256 effectiveFee
) private {
if (isZeroToOne) {
if (!isToken0Rebase) {
uint256 poolManagerFee = Math.mulDiv(effectiveFee, poolManagerFeeBips, _FACTOR_ONE);
if (sovereignVault == address(this)) _reserve0 += (amountInUsed - poolManagerFee);
if (poolManagerFee > 0) feePoolManager0 += poolManagerFee;
}
if (sovereignVault == address(this) && !isToken1Rebase) {
_reserve1 -= amountOut;
}
} else {
if (sovereignVault == address(this) && !isToken0Rebase) {
_reserve0 -= amountOut;
}
if (!isToken1Rebase) {
uint256 poolManagerFee = Math.mulDiv(effectiveFee, poolManagerFeeBips, _FACTOR_ONE);
if (sovereignVault == address(this)) _reserve1 += (amountInUsed - poolManagerFee);
if (poolManagerFee > 0) feePoolManager1 += poolManagerFee;
}
}
}
function _onlyALM() private view {
if (msg.sender != alm) {
revert SovereignPool__onlyALM();
}
}
function _onlyProtocolFactory() private view {
if (msg.sender != protocolFactory) {
revert SovereignPool__onlyProtocolFactory();
}
}
function _onlyPoolManager() private view {
if (msg.sender != poolManager) {
revert SovereignPool__onlyPoolManager();
}
}
function _onlyGauge() private view {
if (msg.sender != gauge) {
revert SovereignPool__onlyGauge();
}
}
function _getReservesForToken(bool isToken0) private view returns (uint256 reserve) {
if (isToken0) {
if (isToken0Rebase) {
reserve = _token0.balanceOf(address(this));
} else {
reserve = _reserve0;
}
} else {
if (isToken1Rebase) {
reserve = _token1.balanceOf(address(this));
} else {
reserve = _reserve1;
}
}
}
function _checkLiquidityQuote(
bool isZeroToOne,
uint256 amountInWithoutFee,
uint256 amountInFilled,
uint256 amountOut,
uint256 amountOutMin
) private view returns (bool) {
if (sovereignVault == address(this)) {
if (amountOut > _getReservesForToken(!isZeroToOne)) {
return false;
}
}
if (amountOut < amountOutMin) {
return false;
}
if (amountInFilled > amountInWithoutFee) {
return false;
}
return true;
}
}
文件 20 的 20:SovereignPoolStructs.sol
pragma solidity 0.8.19;
import { IERC20 } from '../../../lib/openzeppelin-contracts/contracts/token/ERC20/IERC20.sol';
import { ISwapFeeModule } from '../../swap-fee-modules/interfaces/ISwapFeeModule.sol';
struct SovereignPoolConstructorArgs {
address token0;
address token1;
address protocolFactory;
address poolManager;
address sovereignVault;
address verifierModule;
bool isToken0Rebase;
bool isToken1Rebase;
uint256 token0AbsErrorTolerance;
uint256 token1AbsErrorTolerance;
uint256 defaultSwapFeeBips;
}
struct SovereignPoolSwapContextData {
bytes externalContext;
bytes verifierContext;
bytes swapCallbackContext;
bytes swapFeeModuleContext;
}
struct SwapCache {
ISwapFeeModule swapFeeModule;
IERC20 tokenInPool;
IERC20 tokenOutPool;
uint256 amountInWithoutFee;
}
struct SovereignPoolSwapParams {
bool isSwapCallback;
bool isZeroToOne;
uint256 amountIn;
uint256 amountOutMin;
uint256 deadline;
address recipient;
address swapTokenOut;
SovereignPoolSwapContextData swapContext;
}
{
"compilationTarget": {
"lib/valantis-core/src/pools/SovereignPool.sol": "SovereignPool"
},
"evmVersion": "paris",
"libraries": {},
"metadata": {
"bytecodeHash": "ipfs"
},
"optimizer": {
"enabled": true,
"runs": 20000
},
"remappings": [
":@uniswap/v3-core/=lib/v3-core/",
":@uniswap/v3-periphery/=lib/v3-periphery/",
":ds-test/=lib/forge-std/lib/ds-test/src/",
":erc4626-tests/=lib/valantis-core/lib/openzeppelin-contracts/lib/erc4626-tests/",
":forge-std/=lib/forge-std/src/",
":openzeppelin-contracts/=lib/valantis-core/lib/openzeppelin-contracts/",
":openzeppelin/=lib/valantis-core/lib/openzeppelin-contracts/contracts/",
":v3-core/=lib/v3-core/contracts/",
":v3-periphery/=lib/v3-periphery/contracts/",
":valantis-core/=lib/valantis-core/"
]
}
[{"inputs":[{"components":[{"internalType":"address","name":"token0","type":"address"},{"internalType":"address","name":"token1","type":"address"},{"internalType":"address","name":"protocolFactory","type":"address"},{"internalType":"address","name":"poolManager","type":"address"},{"internalType":"address","name":"sovereignVault","type":"address"},{"internalType":"address","name":"verifierModule","type":"address"},{"internalType":"bool","name":"isToken0Rebase","type":"bool"},{"internalType":"bool","name":"isToken1Rebase","type":"bool"},{"internalType":"uint256","name":"token0AbsErrorTolerance","type":"uint256"},{"internalType":"uint256","name":"token1AbsErrorTolerance","type":"uint256"},{"internalType":"uint256","name":"defaultSwapFeeBips","type":"uint256"}],"internalType":"struct SovereignPoolConstructorArgs","name":"args","type":"tuple"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"SovereignPool__ALMAlreadySet","type":"error"},{"inputs":[],"name":"SovereignPool__ZeroAddress","type":"error"},{"inputs":[],"name":"SovereignPool___claimPoolManagerFees_invalidFeeReceived","type":"error"},{"inputs":[],"name":"SovereignPool___claimPoolManagerFees_invalidProtocolFee","type":"error"},{"inputs":[],"name":"SovereignPool___handleTokenInOnSwap_excessiveTokenInErrorOnTransfer","type":"error"},{"inputs":[],"name":"SovereignPool___handleTokenInOnSwap_invalidTokenInAmount","type":"error"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"uint8","name":"accessType","type":"uint8"}],"name":"SovereignPool___verifyPermission_onlyPermissionedAccess","type":"error"},{"inputs":[],"name":"SovereignPool__depositLiquidity_depositDisabled","type":"error"},{"inputs":[],"name":"SovereignPool__depositLiquidity_excessiveToken0ErrorOnTransfer","type":"error"},{"inputs":[],"name":"SovereignPool__depositLiquidity_excessiveToken1ErrorOnTransfer","type":"error"},{"inputs":[],"name":"SovereignPool__depositLiquidity_incorrectTokenAmount","type":"error"},{"inputs":[],"name":"SovereignPool__depositLiquidity_insufficientToken0Amount","type":"error"},{"inputs":[],"name":"SovereignPool__depositLiquidity_insufficientToken1Amount","type":"error"},{"inputs":[],"name":"SovereignPool__depositLiquidity_zeroTotalDepositAmount","type":"error"},{"inputs":[],"name":"SovereignPool__excessiveToken0AbsErrorTolerance","type":"error"},{"inputs":[],"name":"SovereignPool__excessiveToken1AbsErrorTolerance","type":"error"},{"inputs":[],"name":"SovereignPool__getReserves_invalidReservesLength","type":"error"},{"inputs":[],"name":"SovereignPool__onlyALM","type":"error"},{"inputs":[],"name":"SovereignPool__onlyGauge","type":"error"},{"inputs":[],"name":"SovereignPool__onlyPoolManager","type":"error"},{"inputs":[],"name":"SovereignPool__onlyProtocolFactory","type":"error"},{"inputs":[],"name":"SovereignPool__sameTokenNotAllowed","type":"error"},{"inputs":[],"name":"SovereignPool__setGauge_gaugeAlreadySet","type":"error"},{"inputs":[],"name":"SovereignPool__setGauge_invalidAddress","type":"error"},{"inputs":[],"name":"SovereignPool__setPoolManagerFeeBips_excessivePoolManagerFee","type":"error"},{"inputs":[],"name":"SovereignPool__setSovereignOracle_oracleDisabled","type":"error"},{"inputs":[],"name":"SovereignPool__setSovereignOracle_sovereignOracleAlreadySet","type":"error"},{"inputs":[],"name":"SovereignPool__setSwapFeeModule_timelock","type":"error"},{"inputs":[],"name":"SovereignPool__swap_excessiveSwapFee","type":"error"},{"inputs":[],"name":"SovereignPool__swap_expired","type":"error"},{"inputs":[],"name":"SovereignPool__swap_insufficientAmountIn","type":"error"},{"inputs":[],"name":"SovereignPool__swap_invalidLiquidityQuote","type":"error"},{"inputs":[],"name":"SovereignPool__swap_invalidPoolTokenOut","type":"error"},{"inputs":[],"name":"SovereignPool__swap_invalidRecipient","type":"error"},{"inputs":[],"name":"SovereignPool__swap_invalidSwapTokenOut","type":"error"},{"inputs":[],"name":"SovereignPool__swap_zeroAmountInOrOut","type":"error"},{"inputs":[],"name":"SovereignPool__withdrawLiquidity_insufficientReserve0","type":"error"},{"inputs":[],"name":"SovereignPool__withdrawLiquidity_insufficientReserve1","type":"error"},{"inputs":[],"name":"SovereignPool__withdrawLiquidity_invalidRecipient","type":"error"},{"inputs":[],"name":"SovereignPool__withdrawLiquidity_withdrawDisabled","type":"error"},{"inputs":[],"name":"ValantisPool__flashLoan_flashLoanDisabled","type":"error"},{"inputs":[],"name":"ValantisPool__flashLoan_flashLoanNotRepaid","type":"error"},{"inputs":[],"name":"ValantisPool__flashLoan_rebaseTokenNotAllowed","type":"error"},{"inputs":[],"name":"ValantisPool__flashloan_callbackFailed","type":"error"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"alm","type":"address"}],"name":"ALMSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"amount0","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount1","type":"uint256"}],"name":"DepositLiquidity","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"initiator","type":"address"},{"indexed":true,"internalType":"address","name":"receiver","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"address","name":"token","type":"address"}],"name":"Flashloan","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"gauge","type":"address"}],"name":"GaugeSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"poolManagerFeeBips","type":"uint256"}],"name":"PoolManagerFeeSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"amount0","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount1","type":"uint256"}],"name":"PoolManagerFeesClaimed","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"poolManager","type":"address"}],"name":"PoolManagerSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"sovereignOracle","type":"address"}],"name":"SovereignOracleSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":false,"internalType":"bool","name":"isZeroToOne","type":"bool"},{"indexed":false,"internalType":"uint256","name":"amountIn","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"fee","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amountOut","type":"uint256"}],"name":"Swap","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"swapFeeModule","type":"address"}],"name":"SwapFeeModuleSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"recipient","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount0","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount1","type":"uint256"}],"name":"WithdrawLiquidity","type":"event"},{"inputs":[],"name":"alm","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_feeProtocol0Bips","type":"uint256"},{"internalType":"uint256","name":"_feeProtocol1Bips","type":"uint256"}],"name":"claimPoolManagerFees","outputs":[{"internalType":"uint256","name":"feePoolManager0Received","type":"uint256"},{"internalType":"uint256","name":"feePoolManager1Received","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"claimProtocolFees","outputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"defaultSwapFeeBips","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount0","type":"uint256"},{"internalType":"uint256","name":"_amount1","type":"uint256"},{"internalType":"address","name":"_sender","type":"address"},{"internalType":"bytes","name":"_verificationContext","type":"bytes"},{"internalType":"bytes","name":"_depositData","type":"bytes"}],"name":"depositLiquidity","outputs":[{"internalType":"uint256","name":"amount0Deposited","type":"uint256"},{"internalType":"uint256","name":"amount1Deposited","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"feePoolManager0","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"feePoolManager1","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"feeProtocol0","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"feeProtocol1","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"_isTokenZero","type":"bool"},{"internalType":"contract IFlashBorrower","name":"_receiver","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"flashLoan","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"gauge","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getPoolManagerFees","outputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getReserves","outputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getTokens","outputs":[{"internalType":"address[]","name":"tokens","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isLocked","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isRebaseTokenPool","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isToken0Rebase","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isToken1Rebase","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"poolManager","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"poolManagerFeeBips","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"protocolFactory","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_alm","type":"address"}],"name":"setALM","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_gauge","type":"address"}],"name":"setGauge","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_manager","type":"address"}],"name":"setPoolManager","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_poolManagerFeeBips","type":"uint256"}],"name":"setPoolManagerFeeBips","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"sovereignOracle","type":"address"}],"name":"setSovereignOracle","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"swapFeeModule_","type":"address"}],"name":"setSwapFeeModule","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"sovereignOracleModule","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"sovereignVault","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"bool","name":"isSwapCallback","type":"bool"},{"internalType":"bool","name":"isZeroToOne","type":"bool"},{"internalType":"uint256","name":"amountIn","type":"uint256"},{"internalType":"uint256","name":"amountOutMin","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"address","name":"swapTokenOut","type":"address"},{"components":[{"internalType":"bytes","name":"externalContext","type":"bytes"},{"internalType":"bytes","name":"verifierContext","type":"bytes"},{"internalType":"bytes","name":"swapCallbackContext","type":"bytes"},{"internalType":"bytes","name":"swapFeeModuleContext","type":"bytes"}],"internalType":"struct SovereignPoolSwapContextData","name":"swapContext","type":"tuple"}],"internalType":"struct SovereignPoolSwapParams","name":"_swapParams","type":"tuple"}],"name":"swap","outputs":[{"internalType":"uint256","name":"amountInUsed","type":"uint256"},{"internalType":"uint256","name":"amountOut","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"swapFeeModule","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"swapFeeModuleUpdateTimestamp","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"token0","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"token0AbsErrorTolerance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"token1","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"token1AbsErrorTolerance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"verifierModule","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount0","type":"uint256"},{"internalType":"uint256","name":"_amount1","type":"uint256"},{"internalType":"address","name":"_sender","type":"address"},{"internalType":"address","name":"_recipient","type":"address"},{"internalType":"bytes","name":"_verificationContext","type":"bytes"}],"name":"withdrawLiquidity","outputs":[],"stateMutability":"nonpayable","type":"function"}]