编译器
0.8.18+commit.87f61d96
文件 1 的 27:AccessControl.sol
pragma solidity ^0.8.0;
import "./IAccessControl.sol";
import "../utils/Context.sol";
import "../utils/Strings.sol";
import "../utils/introspection/ERC165.sol";
abstract contract AccessControl is Context, IAccessControl, ERC165 {
struct RoleData {
mapping(address => bool) members;
bytes32 adminRole;
}
mapping(bytes32 => RoleData) private _roles;
bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00;
modifier onlyRole(bytes32 role) {
_checkRole(role);
_;
}
function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
return interfaceId == type(IAccessControl).interfaceId || super.supportsInterface(interfaceId);
}
function hasRole(bytes32 role, address account) public view virtual override returns (bool) {
return _roles[role].members[account];
}
function _checkRole(bytes32 role) internal view virtual {
_checkRole(role, _msgSender());
}
function _checkRole(bytes32 role, address account) internal view virtual {
if (!hasRole(role, account)) {
revert(
string(
abi.encodePacked(
"AccessControl: account ",
Strings.toHexString(account),
" is missing role ",
Strings.toHexString(uint256(role), 32)
)
)
);
}
}
function getRoleAdmin(bytes32 role) public view virtual override returns (bytes32) {
return _roles[role].adminRole;
}
function grantRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {
_grantRole(role, account);
}
function revokeRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {
_revokeRole(role, account);
}
function renounceRole(bytes32 role, address account) public virtual override {
require(account == _msgSender(), "AccessControl: can only renounce roles for self");
_revokeRole(role, account);
}
function _setupRole(bytes32 role, address account) internal virtual {
_grantRole(role, account);
}
function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual {
bytes32 previousAdminRole = getRoleAdmin(role);
_roles[role].adminRole = adminRole;
emit RoleAdminChanged(role, previousAdminRole, adminRole);
}
function _grantRole(bytes32 role, address account) internal virtual {
if (!hasRole(role, account)) {
_roles[role].members[account] = true;
emit RoleGranted(role, account, _msgSender());
}
}
function _revokeRole(bytes32 role, address account) internal virtual {
if (hasRole(role, account)) {
_roles[role].members[account] = false;
emit RoleRevoked(role, account, _msgSender());
}
}
}
文件 2 的 27:Constants.sol
pragma solidity ^0.8.0;
library Constants {
address public constant UNISWAP_V3_FACTORY_ADDRESS =
address(0x1F98431c8aD98523631AE4a59f267346ea31F984);
address public constant NONFUNGIBLE_POSITION_MANAGER_ADDRESS =
address(0xC36442b4a4522E871399CD717aBDD847Ab11FE88);
address public constant SWAP_ROUTER_ADDRESS =
address(0xE592427A0AEce92De3Edee1F18E0157C05861564);
address public constant WETH_ADDRESS =
address(0x82aF49447D8a07e3bd95BD0d56f35241523fBab1);
address public constant ARB_ADDRESS =
address(0x912CE59144191C1204E64559FE8253a0e49E6548);
address public constant WBTC_ADDRESS =
address(0x2f2a2543B76A4166549F7aaB2e75Bef0aefC5B0f);
address public constant USDC_ADDRESS =
address(0xaf88d065e77c8cC2239327C5EDb3A432268e5831);
address public constant USDCE_ADDRESS =
address(0xFF970A61A04b1cA14834A43f5dE4533eBDDB5CC8);
address public constant USDT_ADDRESS =
address(0xFd086bC7CD5C481DCC9C85ebE478A1C0b69FCbb9);
address public constant RDNT_ADDRESS =
address(0x3082CC23568eA640225c2467653dB90e9250AaA0);
address public constant LINK_ADDRESS =
address(0xf97f4df75117a78c1A5a0DBb814Af92458539FB4);
address public constant BLACK_HOLE_ADDRESS =
address(0x000000000000000000000000000000000000dEaD);
}
文件 3 的 27: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 的 27:Controller.sol
pragma solidity ^0.8.0;
import "./interfaces/IFundManagerVault.sol";
import "./interfaces/IRescaleTickBoundaryCalculator.sol";
import "./interfaces/IController.sol";
import "./interfaces/IControllerEvent.sol";
import "./interfaces/IStrategyInfo.sol";
import "./interfaces/IStrategy.sol";
import "./interfaces/IStrategySetter.sol";
import "./libraries/constants/Constants.sol";
import "./libraries/LiquidityNftHelper.sol";
import "./libraries/ParameterVerificationHelper.sol";
import "@openzeppelin/contracts/access/AccessControl.sol";
import "@openzeppelin/contracts/utils/math/SafeMath.sol";
contract Controller is AccessControl, IControllerEvent, IController {
using SafeMath for uint256;
bytes32 public constant EXECUTOR_ROLE = keccak256("EXECUTOR_ROLE");
mapping(address => int24) public tickSpreadUpper;
mapping(address => int24) public tickSpreadLower;
mapping(address => int24) public tickGapUpper;
mapping(address => int24) public tickGapLower;
mapping(address => int24) public tickUpperBoundaryOffset;
mapping(address => int24) public tickLowerBoundaryOffset;
mapping(address => int24) public rescaleTickUpperBoundaryOffset;
mapping(address => int24) public rescaleTickLowerBoundaryOffset;
mapping(address => int24) public lastRescaleTick;
mapping(address => int24) public rescaleTickTolerance;
constructor(address _executor) {
_setRoleAdmin(EXECUTOR_ROLE, DEFAULT_ADMIN_ROLE);
_setupRole(DEFAULT_ADMIN_ROLE, msg.sender);
_setupRole(EXECUTOR_ROLE, _executor);
}
function isNftWithinRange(address _strategyContract) public view returns (bool isWithinRange) {
uint256 liquidityNftId = IStrategyInfo(_strategyContract).liquidityNftId();
require(liquidityNftId != 0, "not allow calling when liquidityNftId is 0");
(isWithinRange,) = LiquidityNftHelper.verifyCurrentPriceInLiquidityNftRange(
liquidityNftId, Constants.UNISWAP_V3_FACTORY_ADDRESS, Constants.NONFUNGIBLE_POSITION_MANAGER_ADDRESS
);
}
function getEarningFlag(address _strategyContract) public view returns (bool isEarningFlag) {
return IStrategyInfo(_strategyContract).isEarning();
}
function getRescalingFlag(address _strategyContract) public view returns (bool isRescalingFlag) {
uint256 liquidityNftId = IStrategyInfo(_strategyContract).liquidityNftId();
if (liquidityNftId == 0) {
return true;
} else {
return false;
}
}
function getRemainingEarnCountDown(address _strategyContract) public view returns (uint256 remainingEarn) {
bool isEarningFlag = getEarningFlag(_strategyContract);
if (isEarningFlag == false) {
return 0;
}
uint256 userListLength = IStrategyInfo(_strategyContract).getAllUsersInUserList().length;
uint256 earnLoopStartIndex = IStrategyInfo(_strategyContract).earnLoopStartIndex();
uint256 remainingUserNumber = userListLength.sub(earnLoopStartIndex);
uint256 earnLoopSegmentSize = IStrategyInfo(_strategyContract).earnLoopSegmentSize();
(uint256 quotient, uint256 remainder) = calculateQuotientAndRemainder(remainingUserNumber, earnLoopSegmentSize);
return remainder > 0 ? (quotient.add(1)) : quotient;
}
function calculateQuotientAndRemainder(uint256 dividend, uint256 divisor)
internal
pure
returns (uint256 quotient, uint256 remainder)
{
quotient = dividend.div(divisor);
remainder = dividend.mod(divisor);
}
function getAllFundManagers(address _fundManagerVaultContract)
public
view
returns (IFundManagerVault.FundManager[8] memory)
{
return IFundManagerVault(_fundManagerVaultContract).getAllFundManagers();
}
function setTransactionDeadlineDuration(address _strategyContract, uint256 _transactionDeadlineDuration)
public
onlyRole(EXECUTOR_ROLE)
{
IStrategySetter(_strategyContract).setTransactionDeadlineDuration(_transactionDeadlineDuration);
emit SetTransactionDeadlineDuration(_strategyContract, msg.sender, _transactionDeadlineDuration);
}
function setTickSpreadUpper(address _strategyContract, int24 _tickSpreadUpper) public onlyRole(EXECUTOR_ROLE) {
ParameterVerificationHelper.verifyGreaterThanOrEqualToZero(_tickSpreadUpper);
tickSpreadUpper[_strategyContract] = _tickSpreadUpper;
emit SetTickSpreadUpper(_strategyContract, msg.sender, _tickSpreadUpper);
}
function setTickSpreadLower(address _strategyContract, int24 _tickSpreadLower) public onlyRole(EXECUTOR_ROLE) {
ParameterVerificationHelper.verifyGreaterThanOrEqualToZero(_tickSpreadLower);
tickSpreadLower[_strategyContract] = _tickSpreadLower;
emit SetTickSpreadLower(_strategyContract, msg.sender, _tickSpreadLower);
}
function setTickGapUpper(address _strategyContract, int24 _tickGapUpper) public onlyRole(EXECUTOR_ROLE) {
ParameterVerificationHelper.verifyGreaterThanOne(_tickGapUpper);
tickGapUpper[_strategyContract] = _tickGapUpper;
emit SetTickGapUpper(_strategyContract, msg.sender, _tickGapUpper);
}
function setTickGapLower(address _strategyContract, int24 _tickGapLower) public onlyRole(EXECUTOR_ROLE) {
ParameterVerificationHelper.verifyGreaterThanOne(_tickGapLower);
tickGapLower[_strategyContract] = _tickGapLower;
emit SetTickGapLower(_strategyContract, msg.sender, _tickGapLower);
}
function setBuyBackToken(address _strategyContract, address _buyBackToken) public onlyRole(EXECUTOR_ROLE) {
IStrategySetter(_strategyContract).setBuyBackToken(_buyBackToken);
emit SetBuyBackToken(_strategyContract, msg.sender, _buyBackToken);
}
function setBuyBackNumerator(address _strategyContract, uint24 _buyBackNumerator) public onlyRole(EXECUTOR_ROLE) {
IStrategySetter(_strategyContract).setBuyBackNumerator(_buyBackNumerator);
emit SetBuyBackNumerator(_strategyContract, msg.sender, _buyBackNumerator);
}
function setFundManagerVaultByIndex(
address _strategyContract,
uint256 _index,
address _fundManagerVaultAddress,
uint24 _fundManagerProfitVaultNumerator
) public onlyRole(EXECUTOR_ROLE) {
IStrategySetter(_strategyContract).setFundManagerVaultByIndex(
_index, _fundManagerVaultAddress, _fundManagerProfitVaultNumerator
);
emit SetFundManagerVaultByIndex(
_strategyContract, msg.sender, _index, _fundManagerVaultAddress, _fundManagerProfitVaultNumerator
);
}
function setFundManagerByIndex(
address _fundManagerVaultContract,
uint256 _index,
address _fundManagerAddress,
uint24 _fundManagerProfitNumerator
) public onlyRole(EXECUTOR_ROLE) {
IFundManagerVault(_fundManagerVaultContract).setFundManagerByIndex(
_index, _fundManagerAddress, _fundManagerProfitNumerator
);
emit SetFundManagerByIndex(
_fundManagerVaultContract, msg.sender, _index, _fundManagerAddress, _fundManagerProfitNumerator
);
}
function setEarnLoopSegmentSize(address _strategyContract, uint256 _earnLoopSegmentSize)
public
onlyRole(EXECUTOR_ROLE)
{
IStrategySetter(_strategyContract).setEarnLoopSegmentSize(_earnLoopSegmentSize);
emit SetEarnLoopSegmentSize(_strategyContract, msg.sender, _earnLoopSegmentSize);
}
function setTickUpperBoundaryOffset(address _strategyContract, int24 _tickUpperBoundaryOffset)
public
onlyRole(EXECUTOR_ROLE)
{
ParameterVerificationHelper.verifyGreaterThanOrEqualToZero(_tickUpperBoundaryOffset);
tickUpperBoundaryOffset[_strategyContract] = _tickUpperBoundaryOffset;
emit SetTickUpperBoundaryOffset(_strategyContract, msg.sender, _tickUpperBoundaryOffset);
}
function setTickLowerBoundaryOffset(address _strategyContract, int24 _tickLowerBoundaryOffset)
public
onlyRole(EXECUTOR_ROLE)
{
ParameterVerificationHelper.verifyGreaterThanOrEqualToZero(_tickLowerBoundaryOffset);
tickLowerBoundaryOffset[_strategyContract] = _tickLowerBoundaryOffset;
emit SetTickLowerBoundaryOffset(_strategyContract, msg.sender, _tickLowerBoundaryOffset);
}
function setRescaleTickUpperBoundaryOffset(address _strategyContract, int24 _rescaleTickUpperBoundaryOffset)
public
onlyRole(EXECUTOR_ROLE)
{
ParameterVerificationHelper.verifyGreaterThanOrEqualToZero(_rescaleTickUpperBoundaryOffset);
rescaleTickUpperBoundaryOffset[_strategyContract] = _rescaleTickUpperBoundaryOffset;
emit SetRescaleTickUpperBoundaryOffset(_strategyContract, msg.sender, _rescaleTickUpperBoundaryOffset);
}
function setRescaleTickLowerBoundaryOffset(address _strategyContract, int24 _rescaleTickLowerBoundaryOffset)
public
onlyRole(EXECUTOR_ROLE)
{
ParameterVerificationHelper.verifyGreaterThanOrEqualToZero(_rescaleTickLowerBoundaryOffset);
rescaleTickLowerBoundaryOffset[_strategyContract] = _rescaleTickLowerBoundaryOffset;
emit SetRescaleTickLowerBoundaryOffset(_strategyContract, msg.sender, _rescaleTickLowerBoundaryOffset);
}
function setRescaleTickTolerance(address _strategyContract, int24 _rescaleTickTolerance)
public
onlyRole(EXECUTOR_ROLE)
{
ParameterVerificationHelper.verifyGreaterThanOrEqualToZero(_rescaleTickTolerance);
rescaleTickTolerance[_strategyContract] = _rescaleTickTolerance;
emit SetRescaleTickTolerance(_strategyContract, msg.sender, _rescaleTickTolerance);
}
function collectRewards(address _strategyContract) public onlyRole(EXECUTOR_ROLE) {
IStrategy(_strategyContract).collectRewards();
emit CollectRewards(
_strategyContract,
msg.sender,
IStrategyInfo(_strategyContract).liquidityNftId(),
IStrategyInfo(_strategyContract).rewardToken0Amount(),
IStrategyInfo(_strategyContract).rewardToken1Amount(),
IStrategyInfo(_strategyContract).rewardWbtcAmount()
);
}
function earnPreparation(
address _strategyContract,
uint256 _minimumToken0SwapOutAmount,
uint256 _minimumToken1SwapOutAmount,
uint256 _minimumBuybackSwapOutAmount
) public onlyRole(EXECUTOR_ROLE) {
IStrategy(_strategyContract).earnPreparation(
_minimumToken0SwapOutAmount, _minimumToken1SwapOutAmount, _minimumBuybackSwapOutAmount
);
require(getEarningFlag(_strategyContract) == true, "earn prep error");
emit EarnPreparation(
_strategyContract,
msg.sender,
IStrategyInfo(_strategyContract).liquidityNftId(),
IStrategyInfo(_strategyContract).rewardWbtcAmount(),
getRemainingEarnCountDown(_strategyContract)
);
}
function earn(address _strategyContract) public onlyRole(EXECUTOR_ROLE) {
IStrategy(_strategyContract).earn();
emit Earn(
_strategyContract,
msg.sender,
IStrategyInfo(_strategyContract).liquidityNftId(),
getRemainingEarnCountDown(_strategyContract)
);
}
function earnPreparation(address _fundManagerVaultContract) public onlyRole(EXECUTOR_ROLE) {
distribute(_fundManagerVaultContract);
}
function allocate(address _fundManagerVaultContract) public onlyRole(EXECUTOR_ROLE) {
distribute(_fundManagerVaultContract);
}
function distribute(address _fundManagerVaultContract) private {
uint256 wbtcBeforeTx = IFundManagerVault(_fundManagerVaultContract).getWbtcBalance();
IFundManagerVault(_fundManagerVaultContract).allocate();
uint256 wbtcAfterTx = IFundManagerVault(_fundManagerVaultContract).getWbtcBalance();
emit Allocate(_fundManagerVaultContract, msg.sender, wbtcBeforeTx.sub(wbtcAfterTx), wbtcAfterTx);
}
function rescale(
address _strategyContract,
address _rescaleTickBoundaryCalculatorContract,
bool _wasInRange,
int24 _tickBeforeRescale
) public onlyRole(EXECUTOR_ROLE) {
(bool allowRescale, int24 newTickUpper, int24 newTickLower) = IRescaleTickBoundaryCalculator(
_rescaleTickBoundaryCalculatorContract
).verifyAndGetNewRescaleTickBoundary(
_wasInRange, lastRescaleTick[_strategyContract], _strategyContract, address(this)
);
require(allowRescale, "current condition not allow rescale");
triggerRescaleStartEvent(_strategyContract, _wasInRange, _tickBeforeRescale);
(int24 currentTick,,) = LiquidityNftHelper.getTickInfo(
IStrategyInfo(_strategyContract).liquidityNftId(),
Constants.UNISWAP_V3_FACTORY_ADDRESS,
Constants.NONFUNGIBLE_POSITION_MANAGER_ADDRESS
);
require(
currentTick <= (_tickBeforeRescale + rescaleTickTolerance[_strategyContract])
&& currentTick >= (_tickBeforeRescale - rescaleTickTolerance[_strategyContract]),
"out of tick tolerance range"
);
IStrategy(_strategyContract).rescale(newTickUpper, newTickLower);
lastRescaleTick[_strategyContract] = currentTick;
triggerRescaleEndEvent(_strategyContract, newTickUpper, newTickLower);
}
function triggerRescaleStartEvent(address _strategyContract, bool _wasInRange, int24 _tickBeforeRescale) internal {
(int24 currentTick, int24 originalTickLower, int24 originalTickUpper) = LiquidityNftHelper.getTickInfo(
IStrategyInfo(_strategyContract).liquidityNftId(),
Constants.UNISWAP_V3_FACTORY_ADDRESS,
Constants.NONFUNGIBLE_POSITION_MANAGER_ADDRESS
);
emit RescaleStart(
_strategyContract,
_wasInRange,
IStrategyInfo(_strategyContract).tickSpacing(),
tickGapUpper[_strategyContract],
tickGapLower[_strategyContract],
tickUpperBoundaryOffset[_strategyContract],
tickLowerBoundaryOffset[_strategyContract],
lastRescaleTick[_strategyContract],
_tickBeforeRescale,
currentTick,
originalTickUpper,
originalTickLower
);
}
function triggerRescaleEndEvent(address _strategyContract, int24 newTickUpper, int24 newTickLower) internal {
(int24 currentTick,,) = LiquidityNftHelper.getTickInfo(
IStrategyInfo(_strategyContract).liquidityNftId(),
Constants.UNISWAP_V3_FACTORY_ADDRESS,
Constants.NONFUNGIBLE_POSITION_MANAGER_ADDRESS
);
emit RescaleEnd(
_strategyContract,
msg.sender,
IStrategyInfo(_strategyContract).dustToken0Amount(),
IStrategyInfo(_strategyContract).dustToken1Amount(),
IStrategyInfo(_strategyContract).tickSpacing(),
currentTick,
tickSpreadUpper[_strategyContract],
tickSpreadLower[_strategyContract],
rescaleTickUpperBoundaryOffset[_strategyContract],
rescaleTickLowerBoundaryOffset[_strategyContract],
newTickUpper,
newTickLower
);
}
function depositDustToken(address _strategyContract, bool _depositDustToken0) public onlyRole(EXECUTOR_ROLE) {
(uint256 increasedToken0Amount, uint256 increasedToken1Amount) =
IStrategy(_strategyContract).depositDustToken(_depositDustToken0);
emit DepositDustToken(
_strategyContract,
msg.sender,
IStrategyInfo(_strategyContract).liquidityNftId(),
_depositDustToken0,
increasedToken0Amount,
increasedToken1Amount,
IStrategyInfo(_strategyContract).dustToken0Amount(),
IStrategyInfo(_strategyContract).dustToken1Amount()
);
}
}
文件 5 的 27:ERC165.sol
pragma solidity ^0.8.0;
import "./IERC165.sol";
abstract contract ERC165 is IERC165 {
function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
return interfaceId == type(IERC165).interfaceId;
}
}
文件 6 的 27:IAccessControl.sol
pragma solidity ^0.8.0;
interface IAccessControl {
event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole);
event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender);
event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender);
function hasRole(bytes32 role, address account) external view returns (bool);
function getRoleAdmin(bytes32 role) external view returns (bytes32);
function grantRole(bytes32 role, address account) external;
function revokeRole(bytes32 role, address account) external;
function renounceRole(bytes32 role, address account) external;
}
文件 7 的 27:IController.sol
pragma solidity ^0.8.0;
interface IController {
function tickSpreadUpper(address strategyAddress) external view returns (int24);
function tickSpreadLower(address strategyAddress) external view returns (int24);
function tickGapUpper(address strategyAddress) external view returns (int24);
function tickGapLower(address strategyAddress) external view returns (int24);
function tickUpperBoundaryOffset(address strategyAddress) external view returns (int24);
function tickLowerBoundaryOffset(address strategyAddress) external view returns (int24);
function rescaleTickUpperBoundaryOffset(address strategyAddress) external view returns (int24);
function rescaleTickLowerBoundaryOffset(address strategyAddress) external view returns (int24);
function lastRescaleTick(address strategyAddress) external view returns (int24);
}
文件 8 的 27:IControllerEvent.sol
pragma solidity ^0.8.0;
interface IControllerEvent {
event SetTransactionDeadlineDuration(
address indexed strategyContract, address indexed executorAddress, uint256 transactionDeadlineDuration
);
event SetTickSpreadUpper(address indexed strategyContract, address indexed executorAddress, int24 tickSpreadUpper);
event SetTickSpreadLower(address indexed strategyContract, address indexed executorAddress, int24 tickSpreadLower);
event SetTickGapUpper(address indexed strategyContract, address indexed executorAddress, int24 tickGapUpper);
event SetTickGapLower(address indexed strategyContract, address indexed executorAddress, int24 tickGapLower);
event SetBuyBackToken(address indexed strategyContract, address indexed executorAddress, address buyBackToken);
event SetBuyBackNumerator(
address indexed strategyContract, address indexed executorAddress, uint24 buyBackNumerator
);
event SetFundManagerVaultByIndex(
address indexed strategyContract,
address indexed executorAddress,
uint256 index,
address fundManagerVaultAddress,
uint24 fundManagerProfitVaultNumerator
);
event SetFundManagerByIndex(
address indexed fundManagerVaultAddress,
address indexed executorAddress,
uint256 index,
address fundManagerAddress,
uint24 fundManagerProfitNumerator
);
event SetEarnLoopSegmentSize(
address indexed strategyContract, address indexed executorAddress, uint256 earnLoopSegmentSize
);
event SetTickUpperBoundaryOffset(
address indexed strategyContract, address indexed executorAddress, int24 tickUpperBoundaryOffset
);
event SetTickLowerBoundaryOffset(
address indexed strategyContract, address indexed executorAddress, int24 tickLowerBoundaryOffset
);
event SetRescaleTickUpperBoundaryOffset(
address indexed strategyContract, address indexed executorAddress, int24 rescaleTickUpperBoundaryOffset
);
event SetRescaleTickLowerBoundaryOffset(
address indexed strategyContract, address indexed executorAddress, int24 rescaleTickLowerBoundaryOffset
);
event SetRescaleTickTolerance(
address indexed strategyContract, address indexed executorAddress, int24 rescaleTickTolerance
);
event CollectRewards(
address indexed strategyContract,
address indexed executorAddress,
uint256 indexed liquidityNftId,
uint256 rewardToken0Amount,
uint256 rewardToken1Amount,
uint256 rewardWbtcAmount
);
event EarnPreparation(
address indexed strategyContract,
address indexed executorAddress,
uint256 indexed liquidityNftId,
uint256 rewardWbtcAmount,
uint256 remainingEarnCountDown
);
event Earn(
address indexed strategyContract,
address indexed executorAddress,
uint256 indexed liquidityNftId,
uint256 remainingEarnCountDown
);
event Allocate(
address indexed fundManagerVaultAddress,
address indexed executorAddress,
uint256 allocatedWbtcAmount,
uint256 remainingWbtcAmount
);
event RescaleStart(
address indexed strategyContract,
bool wasInRange,
int24 tickSpacing,
int24 tickGapUpper,
int24 tickGapLower,
int24 tickUpperBoundaryOffset,
int24 tickLowerBoundaryOffset,
int24 lastRescaleTick,
int24 tickBeforeRescale,
int24 thisRescaleTick,
int24 originalTickUpper,
int24 originalTickLower
);
event RescaleEnd(
address indexed strategyContract,
address indexed executorAddress,
uint256 dustToken0Amount,
uint256 dustToken1Amount,
int24 tickSpacing,
int24 thisRescaleTick,
int24 tickSpreadUpper,
int24 tickSpreadLower,
int24 rescaleTickUpperBoundaryOffset,
int24 rescaleTickLowerBoundaryOffset,
int24 newTickUpper,
int24 newTickLower
);
event DepositDustToken(
address indexed strategyContract,
address indexed executorAddress,
uint256 indexed liquidityNftId,
bool depositDustToken0,
uint256 increasedToken0Amount,
uint256 increasedToken1Amount,
uint256 dustToken0Amount,
uint256 dustToken1Amount
);
}
文件 9 的 27:IERC165.sol
pragma solidity ^0.8.0;
interface IERC165 {
function supportsInterface(bytes4 interfaceId) external view returns (bool);
}
文件 10 的 27: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);
}
文件 11 的 27:IERC20Querier.sol
pragma solidity ^0.8.0;
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
interface IERC20Querier is IERC20 {
function decimals() external view returns (uint256);
function name() external view returns (string memory);
function symbol() external view returns (string memory);
}
文件 12 的 27:IFundManagerVault.sol
pragma solidity ^0.8.0;
interface IFundManagerVault {
struct FundManager {
address fundManagerAddress;
uint256 fundManagerProfitNumerator;
}
function getWbtcBalance() external view returns (uint256);
function getAllFundManagers() external view returns (FundManager[8] memory);
function setFundManagerByIndex(
uint256 index,
address fundManagerAddress,
uint24 fundManagerProfitNumerator
) external;
function allocate() external;
}
文件 13 的 27:INonfungiblePositionManager.sol
pragma solidity >=0.7.5;
pragma abicoder v2;
interface INonfungiblePositionManager {
function positions(
uint256 tokenId
)
external
view
returns (
uint96 nonce,
address operator,
address token0,
address token1,
uint24 fee,
int24 tickLower,
int24 tickUpper,
uint128 liquidity,
uint256 feeGrowthInside0LastX128,
uint256 feeGrowthInside1LastX128,
uint128 tokensOwed0,
uint128 tokensOwed1
);
function refundETH() external payable;
struct MintParams {
address token0;
address token1;
uint24 fee;
int24 tickLower;
int24 tickUpper;
uint256 amount0Desired;
uint256 amount1Desired;
uint256 amount0Min;
uint256 amount1Min;
address recipient;
uint256 deadline;
}
function mint(
MintParams calldata params
)
external
payable
returns (
uint256 tokenId,
uint128 liquidity,
uint256 amount0,
uint256 amount1
);
struct IncreaseLiquidityParams {
uint256 tokenId;
uint256 amount0Desired;
uint256 amount1Desired;
uint256 amount0Min;
uint256 amount1Min;
uint256 deadline;
}
function increaseLiquidity(
IncreaseLiquidityParams calldata params
)
external
payable
returns (uint128 liquidity, uint256 amount0, uint256 amount1);
struct DecreaseLiquidityParams {
uint256 tokenId;
uint128 liquidity;
uint256 amount0Min;
uint256 amount1Min;
uint256 deadline;
}
function decreaseLiquidity(
DecreaseLiquidityParams calldata params
) external payable returns (uint256 amount0, uint256 amount1);
struct CollectParams {
uint256 tokenId;
address recipient;
uint128 amount0Max;
uint128 amount1Max;
}
function collect(
CollectParams calldata params
) external payable returns (uint256 amount0, uint256 amount1);
function burn(uint256 tokenId) external payable;
}
文件 14 的 27:IRescaleTickBoundaryCalculator.sol
pragma solidity ^0.8.0;
interface IRescaleTickBoundaryCalculator {
function verifyAndGetNewRescaleTickBoundary(
bool wasInRange,
int24 lastRescaleTick,
address strategyAddress,
address controllerAddress
)
external
view
returns (bool allowRescale, int24 newTickUpper, int24 newTickLower);
}
文件 15 的 27:IStrategy.sol
pragma solidity ^0.8.0;
interface IStrategy {
function depositLiquidity(
bool isETH,
address userAddress,
address inputToken,
uint256 inputAmount,
uint256 swapInAmount,
uint256 minimumSwapOutAmount
)
external
payable
returns (
uint256 increasedToken0Amount,
uint256 increasedToken1Amount,
uint256 sendBackToken0Amount,
uint256 sendBackToken1Amount
);
function withdrawLiquidity(
address userAddress,
uint256 withdrawShares
)
external
returns (
uint256 userReceivedToken0Amount,
uint256 userReceivedToken1Amount
);
function collectRewards() external;
function earnPreparation(
uint256 minimumToken0SwapOutAmount,
uint256 minimumToken1SwapOutAmount,
uint256 minimumBuybackSwapOutAmount
) external;
function earn() external;
function claimReward(address userAddress) external;
function rescale(int24 newTickUpper, int24 newTickLower) external;
function depositDustToken(
bool depositDustToken0
)
external
returns (uint256 increasedToken0Amount, uint256 increasedToken1Amount);
}
文件 16 的 27:IStrategyInfo.sol
pragma solidity ^0.8.0;
interface IStrategyInfo {
function transactionDeadlineDuration() external view returns (uint256);
function liquidityNftId() external view returns (uint256);
function tickSpacing() external view returns (int24);
function poolAddress() external view returns (address);
function poolFee() external view returns (uint24);
function token0Address() external view returns (address);
function token1Address() external view returns (address);
function trackerTokenAddress() external view returns (address);
function isInUserList(address userAddress) external view returns (bool);
function userIndex(address userAddress) external view returns (uint256);
function getAllUsersInUserList() external view returns (address[] memory);
function userShare(address userAddress) external view returns (uint256);
function totalUserShare() external view returns (uint256);
function rewardToken0Amount() external view returns (uint256);
function rewardToken1Amount() external view returns (uint256);
function rewardWbtcAmount() external view returns (uint256);
function userWbtcReward(
address userAddress
) external view returns (uint256);
function totalUserWbtcReward() external view returns (uint256);
function buyBackToken() external view returns (address);
function buyBackNumerator() external view returns (uint24);
struct FundManagerVault {
address fundManagerVaultAddress;
uint256 fundManagerProfitVaultNumerator;
}
function getAllFundManagerVaults()
external
view
returns (FundManagerVault[3] memory);
function earnLoopSegmentSize() external view returns (uint256);
function earnLoopDistributedAmount() external view returns (uint256);
function earnLoopStartIndex() external view returns (uint256);
function isEarning() external view returns (bool);
function dustToken0Amount() external view returns (uint256);
function dustToken1Amount() external view returns (uint256);
function getBuyBackDenominator() external pure returns (uint24);
function getFundManagerProfitVaultDenominator()
external
pure
returns (uint24);
function getFarmAddress() external pure returns (address);
function getControllerAddress() external pure returns (address);
function getSwapAmountCalculatorAddress() external pure returns (address);
function getZapAddress() external pure returns (address);
}
文件 17 的 27:IStrategySetter.sol
pragma solidity ^0.8.0;
interface IStrategySetter {
function setTransactionDeadlineDuration(
uint256 _transactionDeadlineDuration
) external;
function setBuyBackToken(address _buyBackToken) external;
function setBuyBackNumerator(uint24 _buyBackNumerator) external;
function setFundManagerVaultByIndex(
uint256 index,
address _fundManagerVaultAddress,
uint24 _fundManagerProfitVaultNumerator
) external;
function setEarnLoopSegmentSize(uint256 _earnLoopSegmentSize) external;
}
文件 18 的 27:IUniswapV3Factory.sol
pragma solidity >=0.5.0;
interface IUniswapV3Factory {
function getPool(
address tokenA,
address tokenB,
uint24 fee
) external view returns (address pool);
}
文件 19 的 27:IUniswapV3Pool.sol
pragma solidity >=0.5.0;
interface IUniswapV3Pool {
function slot0()
external
view
returns (
uint160 sqrtPriceX96,
int24 tick,
uint16 observationIndex,
uint16 observationCardinality,
uint16 observationCardinalityNext,
uint8 feeProtocol,
bool unlocked
);
function token0() external view returns (address);
function token1() external view returns (address);
function fee() external view returns (uint24);
function tickSpacing() external view returns (int24);
}
文件 20 的 27:LiquidityNftHelper.sol
pragma solidity ^0.8.0;
import "../interfaces/uniswapV3/INonfungiblePositionManager.sol";
import "./uniswapV3/TickMath.sol";
import "./PoolHelper.sol";
import "@openzeppelin/contracts/utils/math/SafeMath.sol";
library LiquidityNftHelper {
using SafeMath for uint256;
function getLiquidityAmountByNftId(
uint256 liquidityNftId,
address nonfungiblePositionManagerAddress
) internal view returns (uint128 liquidity) {
(, , , , , , , liquidity, , , , ) = INonfungiblePositionManager(
nonfungiblePositionManagerAddress
).positions(liquidityNftId);
}
function getPoolInfoByLiquidityNft(
uint256 liquidityNftId,
address uniswapV3FactoryAddress,
address nonfungiblePositionManagerAddress
)
internal
view
returns (
address poolAddress,
int24 tick,
uint160 sqrtPriceX96,
uint256 decimal0,
uint256 decimal1
)
{
(
address token0,
address token1,
uint24 poolFee,
,
,
,
) = getLiquidityNftPositionsInfo(
liquidityNftId,
nonfungiblePositionManagerAddress
);
poolAddress = PoolHelper.getPoolAddress(
uniswapV3FactoryAddress,
token0,
token1,
poolFee
);
(, , , tick, sqrtPriceX96, decimal0, decimal1) = PoolHelper.getPoolInfo(
poolAddress
);
}
function getLiquidityNftPositionsInfo(
uint256 liquidityNftId,
address nonfungiblePositionManagerAddress
)
internal
view
returns (
address token0,
address token1,
uint24 poolFee,
int24 tickLower,
int24 tickUpper,
uint160 sqrtRatioAX96,
uint160 sqrtRatioBX96
)
{
(
,
,
token0,
token1,
poolFee,
tickLower,
tickUpper,
,
,
,
,
) = INonfungiblePositionManager(nonfungiblePositionManagerAddress)
.positions(liquidityNftId);
sqrtRatioAX96 = TickMath.getSqrtRatioAtTick(tickLower);
sqrtRatioBX96 = TickMath.getSqrtRatioAtTick(tickUpper);
}
function getInRangeLiquidityRatioWithDecimals(
uint256 liquidityNftId,
uint256 decimalPrecision,
address uniswapV3FactoryAddress,
address nonfungiblePositionManagerAddress
) internal view returns (uint256 liquidityRatioWithDecimals) {
(
,
,
,
,
,
uint160 sqrtRatioAX96,
uint160 sqrtRatioBX96
) = getLiquidityNftPositionsInfo(
liquidityNftId,
nonfungiblePositionManagerAddress
);
(
,
,
uint160 sqrtPriceX96,
uint256 decimal0,
uint256 decimal1
) = getPoolInfoByLiquidityNft(
liquidityNftId,
uniswapV3FactoryAddress,
nonfungiblePositionManagerAddress
);
uint256 scaledPriceX96 = uint256(sqrtPriceX96)
.mul(10 ** decimalPrecision)
.div(2 ** 96);
uint256 scaledPriceBX96 = uint256(sqrtRatioBX96)
.mul(10 ** decimalPrecision)
.div(2 ** 96);
uint256 decimalAdj = decimalPrecision.add(decimal1).sub(decimal0);
uint256 preLiquidityRatioWithDecimals = scaledPriceX96
.mul(scaledPriceBX96)
.div(10 ** decimalAdj);
liquidityRatioWithDecimals = preLiquidityRatioWithDecimals
.mul(uint256(sqrtPriceX96).sub(sqrtRatioAX96))
.div(uint256(sqrtRatioBX96).sub(sqrtPriceX96));
}
function verifyInputTokenIsLiquidityNftTokenPair(
uint256 liquidityNftId,
address inputToken,
address nonfungiblePositionManagerAddress
) internal view {
(
address token0,
address token1,
,
,
,
,
) = getLiquidityNftPositionsInfo(
liquidityNftId,
nonfungiblePositionManagerAddress
);
require(
inputToken == token0 || inputToken == token1,
"inputToken not in token pair"
);
}
function verifyCurrentPriceInLiquidityNftRange(
uint256 liquidityNftId,
address uniswapV3FactoryAddress,
address nonfungiblePositionManagerAddress
) internal view returns (bool isInRange, address liquidity0Token) {
(, int24 tick, , , ) = getPoolInfoByLiquidityNft(
liquidityNftId,
uniswapV3FactoryAddress,
nonfungiblePositionManagerAddress
);
(
address token0,
address token1,
,
int24 tickLower,
int24 tickUpper,
,
) = getLiquidityNftPositionsInfo(
liquidityNftId,
nonfungiblePositionManagerAddress
);
if (tick <= tickLower) {
return (false, token0);
} else if (tick < tickUpper) {
return (true, address(0));
} else {
return (false, token1);
}
}
function getTickInfo(
uint256 liquidityNftId,
address uniswapV3FactoryAddress,
address nonfungiblePositionManagerAddress
) internal view returns (int24 tick, int24 tickLower, int24 tickUpper) {
(, tick, , , ) = getPoolInfoByLiquidityNft(
liquidityNftId,
uniswapV3FactoryAddress,
nonfungiblePositionManagerAddress
);
(, , , tickLower, tickUpper, , ) = getLiquidityNftPositionsInfo(
liquidityNftId,
nonfungiblePositionManagerAddress
);
}
function verifyNoDuplicateTickAndTickLower(
uint256 liquidityNftId,
address uniswapV3FactoryAddress,
address nonfungiblePositionManagerAddress
) internal view {
(int24 tick, int24 tickLower, ) = getTickInfo(
liquidityNftId,
uniswapV3FactoryAddress,
nonfungiblePositionManagerAddress
);
require(tickLower != tick, "tickLower == tick");
}
function calculateInitTickBoundary(
address poolAddress,
int24 tickSpread,
int24 tickSpacing
) internal view returns (int24 tickLower, int24 tickUpper) {
require(tickSpacing != 1, "tickSpacing == 1");
(, , , int24 currentTick, , , ) = PoolHelper.getPoolInfo(poolAddress);
int24 tickFloor = floorTick(currentTick, tickSpacing);
tickLower = tickFloor - tickSpacing * tickSpread;
int24 tickToTickLower = currentTick - tickLower;
tickUpper = floorTick((currentTick + tickToTickLower), tickSpacing);
int24 tickUpperToTick = tickUpper - currentTick;
if (
tickSpacing > 1 &&
(tickToTickLower - tickUpperToTick) >= (tickSpacing / 2)
) {
tickUpper += tickSpacing;
}
}
function floorTick(
int24 tick,
int24 tickSpacing
) internal pure returns (int24) {
int24 baseFloor = tick / tickSpacing;
if (tick < 0 && tick % tickSpacing != 0) {
return (baseFloor - 1) * tickSpacing;
}
return baseFloor * tickSpacing;
}
function ceilingTick(
int24 tick,
int24 tickSpacing
) internal pure returns (int24) {
int24 baseFloor = tick / tickSpacing;
if (tick > 0 && tick % tickSpacing != 0) {
return (baseFloor + 1) * tickSpacing;
}
return baseFloor * tickSpacing;
}
}
文件 21 的 27: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);
}
}
}
文件 22 的 27:ParameterVerificationHelper.sol
pragma solidity ^0.8.0;
library ParameterVerificationHelper {
function verifyNotZeroAddress(address inputAddress) internal pure {
require(inputAddress != address(0), "input zero address");
}
function verifyGreaterThanZero(uint256 inputNumber) internal pure {
require(inputNumber > 0, "input 0");
}
function verifyGreaterThanZero(int24 inputNumber) internal pure {
require(inputNumber > 0, "input 0");
}
function verifyGreaterThanOne(int24 inputNumber) internal pure {
require(inputNumber > 1, "input <= 1");
}
function verifyGreaterThanOrEqualToZero(int24 inputNumber) internal pure {
require(inputNumber >= 0, "input less than 0");
}
function verifyPairTokensHaveWeth(
address token0Address,
address token1Address,
address wethAddress
) internal pure {
require(
token0Address == wethAddress || token1Address == wethAddress,
"pair token not have WETH"
);
}
function verifyMsgValueEqualsInputAmount(
uint256 inputAmount
) internal view {
require(msg.value == inputAmount, "msg.value != inputAmount");
}
function verifyPairTokensHaveInputToken(
address token0Address,
address token1Address,
address inputToken
) internal pure {
require(
token0Address == inputToken || token1Address == inputToken,
"pair token not have inputToken"
);
}
}
文件 23 的 27:PoolHelper.sol
pragma solidity ^0.8.0;
import "../interfaces/external/IERC20Querier.sol";
import "../interfaces/uniswapV3/IUniswapV3Factory.sol";
import "../interfaces/uniswapV3/IUniswapV3Pool.sol";
import "@openzeppelin/contracts/utils/math/SafeMath.sol";
library PoolHelper {
using SafeMath for uint256;
function getPoolAddress(
address uniswapV3FactoryAddress,
address tokenA,
address tokenB,
uint24 poolFee
) internal view returns (address poolAddress) {
return
IUniswapV3Factory(uniswapV3FactoryAddress).getPool(
tokenA,
tokenB,
poolFee
);
}
function getPoolInfo(
address poolAddress
)
internal
view
returns (
address token0,
address token1,
uint24 poolFee,
int24 tick,
uint160 sqrtPriceX96,
uint256 decimal0,
uint256 decimal1
)
{
(sqrtPriceX96, tick, , , , , ) = IUniswapV3Pool(poolAddress).slot0();
token0 = IUniswapV3Pool(poolAddress).token0();
token1 = IUniswapV3Pool(poolAddress).token1();
poolFee = IUniswapV3Pool(poolAddress).fee();
decimal0 = IERC20Querier(token0).decimals();
decimal1 = IERC20Querier(token1).decimals();
}
function getTokenPriceWithDecimalsByPool(
address poolAddress,
uint256 decimalPrecision
) internal view returns (uint256 tokenPriceWithDecimals) {
(
,
,
,
,
uint160 sqrtPriceX96,
uint256 decimal0,
uint256 decimal1
) = getPoolInfo(poolAddress);
uint256 scaledPriceX96 = uint256(sqrtPriceX96)
.mul(10 ** decimalPrecision)
.div(2 ** 96);
uint256 tokenPriceWithoutDecimalAdj = scaledPriceX96.mul(
scaledPriceX96
);
uint256 decimalAdj = decimalPrecision.add(decimal1).sub(decimal0);
uint256 result = tokenPriceWithoutDecimalAdj.div(10 ** decimalAdj);
require(result > 0, "token price too small");
tokenPriceWithDecimals = result;
}
function getTokenDecimalAdjustment(
address token
) internal view returns (uint256 decimalAdjustment) {
uint256 tokenDecimalStandard = 18;
uint256 decimal = IERC20Querier(token).decimals();
return tokenDecimalStandard.sub(decimal);
}
}
文件 24 的 27: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;
}
}
}
文件 25 的 27:SignedMath.sol
pragma solidity ^0.8.0;
library SignedMath {
function max(int256 a, int256 b) internal pure returns (int256) {
return a > b ? a : b;
}
function min(int256 a, int256 b) internal pure returns (int256) {
return a < b ? a : b;
}
function average(int256 a, int256 b) internal pure returns (int256) {
int256 x = (a & b) + ((a ^ b) >> 1);
return x + (int256(uint256(x) >> 255) & (a ^ b));
}
function abs(int256 n) internal pure returns (uint256) {
unchecked {
return uint256(n >= 0 ? n : -n);
}
}
}
文件 26 的 27:Strings.sol
pragma solidity ^0.8.0;
import "./math/Math.sol";
import "./math/SignedMath.sol";
library Strings {
bytes16 private constant _SYMBOLS = "0123456789abcdef";
uint8 private constant _ADDRESS_LENGTH = 20;
function toString(uint256 value) internal pure returns (string memory) {
unchecked {
uint256 length = Math.log10(value) + 1;
string memory buffer = new string(length);
uint256 ptr;
assembly {
ptr := add(buffer, add(32, length))
}
while (true) {
ptr--;
assembly {
mstore8(ptr, byte(mod(value, 10), _SYMBOLS))
}
value /= 10;
if (value == 0) break;
}
return buffer;
}
}
function toString(int256 value) internal pure returns (string memory) {
return string(abi.encodePacked(value < 0 ? "-" : "", toString(SignedMath.abs(value))));
}
function toHexString(uint256 value) internal pure returns (string memory) {
unchecked {
return toHexString(value, Math.log256(value) + 1);
}
}
function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {
bytes memory buffer = new bytes(2 * length + 2);
buffer[0] = "0";
buffer[1] = "x";
for (uint256 i = 2 * length + 1; i > 1; --i) {
buffer[i] = _SYMBOLS[value & 0xf];
value >>= 4;
}
require(value == 0, "Strings: hex length insufficient");
return string(buffer);
}
function toHexString(address addr) internal pure returns (string memory) {
return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);
}
function equal(string memory a, string memory b) internal pure returns (bool) {
return keccak256(bytes(a)) == keccak256(bytes(b));
}
}
文件 27 的 27:TickMath.sol
pragma solidity ^0.8.0;
library TickMath {
int24 internal constant MIN_TICK = -887272;
int24 internal constant MAX_TICK = -MIN_TICK;
uint160 internal constant MIN_SQRT_RATIO = 4295128739;
uint160 internal constant MAX_SQRT_RATIO =
1461446703485210103287273052203988822378723970342;
function getSqrtRatioAtTick(
int24 tick
) internal pure returns (uint160 sqrtPriceX96) {
uint256 absTick = tick < 0
? uint256(-int256(tick))
: uint256(int256(tick));
require(absTick <= uint256(int256(MAX_TICK)), "T");
uint256 ratio = absTick & 0x1 != 0
? 0xfffcb933bd6fad37aa2d162d1a594001
: 0x100000000000000000000000000000000;
if (absTick & 0x2 != 0)
ratio = (ratio * 0xfff97272373d413259a46990580e213a) >> 128;
if (absTick & 0x4 != 0)
ratio = (ratio * 0xfff2e50f5f656932ef12357cf3c7fdcc) >> 128;
if (absTick & 0x8 != 0)
ratio = (ratio * 0xffe5caca7e10e4e61c3624eaa0941cd0) >> 128;
if (absTick & 0x10 != 0)
ratio = (ratio * 0xffcb9843d60f6159c9db58835c926644) >> 128;
if (absTick & 0x20 != 0)
ratio = (ratio * 0xff973b41fa98c081472e6896dfb254c0) >> 128;
if (absTick & 0x40 != 0)
ratio = (ratio * 0xff2ea16466c96a3843ec78b326b52861) >> 128;
if (absTick & 0x80 != 0)
ratio = (ratio * 0xfe5dee046a99a2a811c461f1969c3053) >> 128;
if (absTick & 0x100 != 0)
ratio = (ratio * 0xfcbe86c7900a88aedcffc83b479aa3a4) >> 128;
if (absTick & 0x200 != 0)
ratio = (ratio * 0xf987a7253ac413176f2b074cf7815e54) >> 128;
if (absTick & 0x400 != 0)
ratio = (ratio * 0xf3392b0822b70005940c7a398e4b70f3) >> 128;
if (absTick & 0x800 != 0)
ratio = (ratio * 0xe7159475a2c29b7443b29c7fa6e889d9) >> 128;
if (absTick & 0x1000 != 0)
ratio = (ratio * 0xd097f3bdfd2022b8845ad8f792aa5825) >> 128;
if (absTick & 0x2000 != 0)
ratio = (ratio * 0xa9f746462d870fdf8a65dc1f90e061e5) >> 128;
if (absTick & 0x4000 != 0)
ratio = (ratio * 0x70d869a156d2a1b890bb3df62baf32f7) >> 128;
if (absTick & 0x8000 != 0)
ratio = (ratio * 0x31be135f97d08fd981231505542fcfa6) >> 128;
if (absTick & 0x10000 != 0)
ratio = (ratio * 0x9aa508b5b7a84e1c677de54f3e99bc9) >> 128;
if (absTick & 0x20000 != 0)
ratio = (ratio * 0x5d6af8dedb81196699c329225ee604) >> 128;
if (absTick & 0x40000 != 0)
ratio = (ratio * 0x2216e584f5fa1ea926041bedfe98) >> 128;
if (absTick & 0x80000 != 0)
ratio = (ratio * 0x48a170391f7dc42444e8fa2) >> 128;
if (tick > 0) ratio = type(uint256).max / ratio;
sqrtPriceX96 = uint160(
(ratio >> 32) + (ratio % (1 << 32) == 0 ? 0 : 1)
);
}
}
{
"compilationTarget": {
"contracts/Controller.sol": "Controller"
},
"evmVersion": "paris",
"libraries": {},
"metadata": {
"bytecodeHash": "ipfs"
},
"optimizer": {
"enabled": true,
"runs": 200
},
"remappings": []
}
[{"inputs":[{"internalType":"address","name":"_executor","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"fundManagerVaultAddress","type":"address"},{"indexed":true,"internalType":"address","name":"executorAddress","type":"address"},{"indexed":false,"internalType":"uint256","name":"allocatedWbtcAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"remainingWbtcAmount","type":"uint256"}],"name":"Allocate","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"strategyContract","type":"address"},{"indexed":true,"internalType":"address","name":"executorAddress","type":"address"},{"indexed":true,"internalType":"uint256","name":"liquidityNftId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"rewardToken0Amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"rewardToken1Amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"rewardWbtcAmount","type":"uint256"}],"name":"CollectRewards","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"strategyContract","type":"address"},{"indexed":true,"internalType":"address","name":"executorAddress","type":"address"},{"indexed":true,"internalType":"uint256","name":"liquidityNftId","type":"uint256"},{"indexed":false,"internalType":"bool","name":"depositDustToken0","type":"bool"},{"indexed":false,"internalType":"uint256","name":"increasedToken0Amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"increasedToken1Amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"dustToken0Amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"dustToken1Amount","type":"uint256"}],"name":"DepositDustToken","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"strategyContract","type":"address"},{"indexed":true,"internalType":"address","name":"executorAddress","type":"address"},{"indexed":true,"internalType":"uint256","name":"liquidityNftId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"remainingEarnCountDown","type":"uint256"}],"name":"Earn","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"strategyContract","type":"address"},{"indexed":true,"internalType":"address","name":"executorAddress","type":"address"},{"indexed":true,"internalType":"uint256","name":"liquidityNftId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"rewardWbtcAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"remainingEarnCountDown","type":"uint256"}],"name":"EarnPreparation","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"strategyContract","type":"address"},{"indexed":true,"internalType":"address","name":"executorAddress","type":"address"},{"indexed":false,"internalType":"uint256","name":"dustToken0Amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"dustToken1Amount","type":"uint256"},{"indexed":false,"internalType":"int24","name":"tickSpacing","type":"int24"},{"indexed":false,"internalType":"int24","name":"thisRescaleTick","type":"int24"},{"indexed":false,"internalType":"int24","name":"tickSpreadUpper","type":"int24"},{"indexed":false,"internalType":"int24","name":"tickSpreadLower","type":"int24"},{"indexed":false,"internalType":"int24","name":"rescaleTickUpperBoundaryOffset","type":"int24"},{"indexed":false,"internalType":"int24","name":"rescaleTickLowerBoundaryOffset","type":"int24"},{"indexed":false,"internalType":"int24","name":"newTickUpper","type":"int24"},{"indexed":false,"internalType":"int24","name":"newTickLower","type":"int24"}],"name":"RescaleEnd","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"strategyContract","type":"address"},{"indexed":false,"internalType":"bool","name":"wasInRange","type":"bool"},{"indexed":false,"internalType":"int24","name":"tickSpacing","type":"int24"},{"indexed":false,"internalType":"int24","name":"tickGapUpper","type":"int24"},{"indexed":false,"internalType":"int24","name":"tickGapLower","type":"int24"},{"indexed":false,"internalType":"int24","name":"tickUpperBoundaryOffset","type":"int24"},{"indexed":false,"internalType":"int24","name":"tickLowerBoundaryOffset","type":"int24"},{"indexed":false,"internalType":"int24","name":"lastRescaleTick","type":"int24"},{"indexed":false,"internalType":"int24","name":"tickBeforeRescale","type":"int24"},{"indexed":false,"internalType":"int24","name":"thisRescaleTick","type":"int24"},{"indexed":false,"internalType":"int24","name":"originalTickUpper","type":"int24"},{"indexed":false,"internalType":"int24","name":"originalTickLower","type":"int24"}],"name":"RescaleStart","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"previousAdminRole","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"newAdminRole","type":"bytes32"}],"name":"RoleAdminChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleGranted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleRevoked","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"strategyContract","type":"address"},{"indexed":true,"internalType":"address","name":"executorAddress","type":"address"},{"indexed":false,"internalType":"uint24","name":"buyBackNumerator","type":"uint24"}],"name":"SetBuyBackNumerator","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"strategyContract","type":"address"},{"indexed":true,"internalType":"address","name":"executorAddress","type":"address"},{"indexed":false,"internalType":"address","name":"buyBackToken","type":"address"}],"name":"SetBuyBackToken","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"strategyContract","type":"address"},{"indexed":true,"internalType":"address","name":"executorAddress","type":"address"},{"indexed":false,"internalType":"uint256","name":"earnLoopSegmentSize","type":"uint256"}],"name":"SetEarnLoopSegmentSize","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"fundManagerVaultAddress","type":"address"},{"indexed":true,"internalType":"address","name":"executorAddress","type":"address"},{"indexed":false,"internalType":"uint256","name":"index","type":"uint256"},{"indexed":false,"internalType":"address","name":"fundManagerAddress","type":"address"},{"indexed":false,"internalType":"uint24","name":"fundManagerProfitNumerator","type":"uint24"}],"name":"SetFundManagerByIndex","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"strategyContract","type":"address"},{"indexed":true,"internalType":"address","name":"executorAddress","type":"address"},{"indexed":false,"internalType":"uint256","name":"index","type":"uint256"},{"indexed":false,"internalType":"address","name":"fundManagerVaultAddress","type":"address"},{"indexed":false,"internalType":"uint24","name":"fundManagerProfitVaultNumerator","type":"uint24"}],"name":"SetFundManagerVaultByIndex","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"strategyContract","type":"address"},{"indexed":true,"internalType":"address","name":"executorAddress","type":"address"},{"indexed":false,"internalType":"int24","name":"rescaleTickLowerBoundaryOffset","type":"int24"}],"name":"SetRescaleTickLowerBoundaryOffset","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"strategyContract","type":"address"},{"indexed":true,"internalType":"address","name":"executorAddress","type":"address"},{"indexed":false,"internalType":"int24","name":"rescaleTickTolerance","type":"int24"}],"name":"SetRescaleTickTolerance","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"strategyContract","type":"address"},{"indexed":true,"internalType":"address","name":"executorAddress","type":"address"},{"indexed":false,"internalType":"int24","name":"rescaleTickUpperBoundaryOffset","type":"int24"}],"name":"SetRescaleTickUpperBoundaryOffset","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"strategyContract","type":"address"},{"indexed":true,"internalType":"address","name":"executorAddress","type":"address"},{"indexed":false,"internalType":"int24","name":"tickGapLower","type":"int24"}],"name":"SetTickGapLower","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"strategyContract","type":"address"},{"indexed":true,"internalType":"address","name":"executorAddress","type":"address"},{"indexed":false,"internalType":"int24","name":"tickGapUpper","type":"int24"}],"name":"SetTickGapUpper","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"strategyContract","type":"address"},{"indexed":true,"internalType":"address","name":"executorAddress","type":"address"},{"indexed":false,"internalType":"int24","name":"tickLowerBoundaryOffset","type":"int24"}],"name":"SetTickLowerBoundaryOffset","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"strategyContract","type":"address"},{"indexed":true,"internalType":"address","name":"executorAddress","type":"address"},{"indexed":false,"internalType":"int24","name":"tickSpreadLower","type":"int24"}],"name":"SetTickSpreadLower","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"strategyContract","type":"address"},{"indexed":true,"internalType":"address","name":"executorAddress","type":"address"},{"indexed":false,"internalType":"int24","name":"tickSpreadUpper","type":"int24"}],"name":"SetTickSpreadUpper","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"strategyContract","type":"address"},{"indexed":true,"internalType":"address","name":"executorAddress","type":"address"},{"indexed":false,"internalType":"int24","name":"tickUpperBoundaryOffset","type":"int24"}],"name":"SetTickUpperBoundaryOffset","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"strategyContract","type":"address"},{"indexed":true,"internalType":"address","name":"executorAddress","type":"address"},{"indexed":false,"internalType":"uint256","name":"transactionDeadlineDuration","type":"uint256"}],"name":"SetTransactionDeadlineDuration","type":"event"},{"inputs":[],"name":"DEFAULT_ADMIN_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"EXECUTOR_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_fundManagerVaultContract","type":"address"}],"name":"allocate","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_strategyContract","type":"address"}],"name":"collectRewards","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_strategyContract","type":"address"},{"internalType":"bool","name":"_depositDustToken0","type":"bool"}],"name":"depositDustToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_strategyContract","type":"address"}],"name":"earn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_strategyContract","type":"address"},{"internalType":"uint256","name":"_minimumToken0SwapOutAmount","type":"uint256"},{"internalType":"uint256","name":"_minimumToken1SwapOutAmount","type":"uint256"},{"internalType":"uint256","name":"_minimumBuybackSwapOutAmount","type":"uint256"}],"name":"earnPreparation","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_fundManagerVaultContract","type":"address"}],"name":"earnPreparation","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_fundManagerVaultContract","type":"address"}],"name":"getAllFundManagers","outputs":[{"components":[{"internalType":"address","name":"fundManagerAddress","type":"address"},{"internalType":"uint256","name":"fundManagerProfitNumerator","type":"uint256"}],"internalType":"struct IFundManagerVault.FundManager[8]","name":"","type":"tuple[8]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_strategyContract","type":"address"}],"name":"getEarningFlag","outputs":[{"internalType":"bool","name":"isEarningFlag","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_strategyContract","type":"address"}],"name":"getRemainingEarnCountDown","outputs":[{"internalType":"uint256","name":"remainingEarn","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_strategyContract","type":"address"}],"name":"getRescalingFlag","outputs":[{"internalType":"bool","name":"isRescalingFlag","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"getRoleAdmin","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"grantRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"hasRole","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_strategyContract","type":"address"}],"name":"isNftWithinRange","outputs":[{"internalType":"bool","name":"isWithinRange","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"lastRescaleTick","outputs":[{"internalType":"int24","name":"","type":"int24"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"renounceRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_strategyContract","type":"address"},{"internalType":"address","name":"_rescaleTickBoundaryCalculatorContract","type":"address"},{"internalType":"bool","name":"_wasInRange","type":"bool"},{"internalType":"int24","name":"_tickBeforeRescale","type":"int24"}],"name":"rescale","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"rescaleTickLowerBoundaryOffset","outputs":[{"internalType":"int24","name":"","type":"int24"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"rescaleTickTolerance","outputs":[{"internalType":"int24","name":"","type":"int24"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"rescaleTickUpperBoundaryOffset","outputs":[{"internalType":"int24","name":"","type":"int24"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"revokeRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_strategyContract","type":"address"},{"internalType":"uint24","name":"_buyBackNumerator","type":"uint24"}],"name":"setBuyBackNumerator","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_strategyContract","type":"address"},{"internalType":"address","name":"_buyBackToken","type":"address"}],"name":"setBuyBackToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_strategyContract","type":"address"},{"internalType":"uint256","name":"_earnLoopSegmentSize","type":"uint256"}],"name":"setEarnLoopSegmentSize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_fundManagerVaultContract","type":"address"},{"internalType":"uint256","name":"_index","type":"uint256"},{"internalType":"address","name":"_fundManagerAddress","type":"address"},{"internalType":"uint24","name":"_fundManagerProfitNumerator","type":"uint24"}],"name":"setFundManagerByIndex","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_strategyContract","type":"address"},{"internalType":"uint256","name":"_index","type":"uint256"},{"internalType":"address","name":"_fundManagerVaultAddress","type":"address"},{"internalType":"uint24","name":"_fundManagerProfitVaultNumerator","type":"uint24"}],"name":"setFundManagerVaultByIndex","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_strategyContract","type":"address"},{"internalType":"int24","name":"_rescaleTickLowerBoundaryOffset","type":"int24"}],"name":"setRescaleTickLowerBoundaryOffset","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_strategyContract","type":"address"},{"internalType":"int24","name":"_rescaleTickTolerance","type":"int24"}],"name":"setRescaleTickTolerance","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_strategyContract","type":"address"},{"internalType":"int24","name":"_rescaleTickUpperBoundaryOffset","type":"int24"}],"name":"setRescaleTickUpperBoundaryOffset","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_strategyContract","type":"address"},{"internalType":"int24","name":"_tickGapLower","type":"int24"}],"name":"setTickGapLower","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_strategyContract","type":"address"},{"internalType":"int24","name":"_tickGapUpper","type":"int24"}],"name":"setTickGapUpper","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_strategyContract","type":"address"},{"internalType":"int24","name":"_tickLowerBoundaryOffset","type":"int24"}],"name":"setTickLowerBoundaryOffset","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_strategyContract","type":"address"},{"internalType":"int24","name":"_tickSpreadLower","type":"int24"}],"name":"setTickSpreadLower","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_strategyContract","type":"address"},{"internalType":"int24","name":"_tickSpreadUpper","type":"int24"}],"name":"setTickSpreadUpper","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_strategyContract","type":"address"},{"internalType":"int24","name":"_tickUpperBoundaryOffset","type":"int24"}],"name":"setTickUpperBoundaryOffset","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_strategyContract","type":"address"},{"internalType":"uint256","name":"_transactionDeadlineDuration","type":"uint256"}],"name":"setTransactionDeadlineDuration","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"tickGapLower","outputs":[{"internalType":"int24","name":"","type":"int24"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"tickGapUpper","outputs":[{"internalType":"int24","name":"","type":"int24"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"tickLowerBoundaryOffset","outputs":[{"internalType":"int24","name":"","type":"int24"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"tickSpreadLower","outputs":[{"internalType":"int24","name":"","type":"int24"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"tickSpreadUpper","outputs":[{"internalType":"int24","name":"","type":"int24"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"tickUpperBoundaryOffset","outputs":[{"internalType":"int24","name":"","type":"int24"}],"stateMutability":"view","type":"function"}]