Skip to content

Commit a98789a

Browse files
author
Sachin
authored
Add delta-neutral basis trading strategy extension contract (#27)
* Add IUniswapV3Quoter interface * Add WIP basis trading strategy contract * Add WIP strategy contract unit tests * Fix bugs in existing contracts and tests * Refactor setter functions; Add unit tests for setter functions * Fix getCurrentEtherIncentive; Add tests for withdrawEtherBalance and getCurrentEtherIncentive * Refactor shouldRebalance; Add tests for shouldRebalance and shouldRebalanceWithBounds * Refactor getChunkRebalanceNotional; Add tests for getChunkRebalanceNotional * Fix disengage; Add unit tests for disengage * Add unit tests for ripcord * Fix reinvest; Add unit tests for reinvest * Remove console logs from contract; Fix comments * Rebase to master * Add javadocs and missing test cases * Fix reinvest; Add appropriate revert logic * Fix coverage; Remove unncessary if block * Fix compilation * Fix imports and failing tests * Fix bug: Update reinvest to onlyAllowedCaller from onlyOperator * Updated version to 0.0.7-basis.0 * Add suggested changes * Remove pending todos * Fix to support all leverages <1, =1, >1; Refactor tests * Add logic to return reinvest only when reinvestable amount > 0; Add unit tests * Fix failing tests; Fix unit calculation * Updated version to 0.0.7-basis.1 * Refactor reinvest * Verify bytes parameters set in exchange settings * Update package to 0.0.7-basis.2 * Update version to 0.0.8; Pull latest set-protocol-v2 * Add check for booleans in exchange params * Add suggested changes * Deposit unused USDC to Perp after rebalance; Add unit tests for all flows * Add check for exchange name * Fix failing tests
1 parent f4e1292 commit a98789a

13 files changed

+5986
-135
lines changed

contracts/extensions/DeltaNeutralBasisTradingStrategyExtension.sol

Lines changed: 1554 additions & 0 deletions
Large diffs are not rendered by default.

contracts/extensions/PerpV2LeverageStrategyExtension.sol

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ import { SafeMath } from "@openzeppelin/contracts/math/SafeMath.sol";
2727
import { SignedSafeMath } from "@openzeppelin/contracts/math/SignedSafeMath.sol";
2828

2929
import { IAccountBalance } from "@setprotocol/set-protocol-v2/contracts/interfaces/external/perp-v2/IAccountBalance.sol";
30-
import { IPerpV2LeverageModule } from "@setprotocol/set-protocol-v2/contracts/interfaces/IPerpV2LeverageModule.sol";
30+
import { IPerpV2LeverageModuleV2 } from "@setprotocol/set-protocol-v2/contracts/interfaces/IPerpV2LeverageModuleV2.sol";
3131
import { ISetToken } from "@setprotocol/set-protocol-v2/contracts/interfaces/ISetToken.sol";
3232
import { IVault } from "@setprotocol/set-protocol-v2/contracts/interfaces/external/perp-v2/IVault.sol";
3333
import { PreciseUnitMath } from "@setprotocol/set-protocol-v2/contracts/lib/PreciseUnitMath.sol";
@@ -71,7 +71,7 @@ contract PerpV2LeverageStrategyExtension is BaseExtension {
7171
struct ActionInfo {
7272
int256 baseBalance; // Balance of virtual base asset from Perp in precise units (10e18). E.g. vWBTC = 10e18
7373
int256 quoteBalance; // Balance of virtual quote asset from Perp in precise units (10e18). E.g. vUSD = 10e18
74-
IPerpV2LeverageModule.AccountInfo accountInfo; // Info on perpetual account including, collateral balance, owedRealizedPnl and pendingFunding
74+
IPerpV2LeverageModuleV2.AccountInfo accountInfo; // Info on perpetual account including, collateral balance, owedRealizedPnl and pendingFunding
7575
int256 basePositionValue; // Valuation in USD adjusted for decimals in precise units (10e18)
7676
int256 quoteValue; // Valuation in USD adjusted for decimals in precise units (10e18)
7777
int256 basePrice; // Price of base asset in precise units (10e18) from PerpV2 Oracle
@@ -88,7 +88,7 @@ contract PerpV2LeverageStrategyExtension is BaseExtension {
8888

8989
struct ContractSettings {
9090
ISetToken setToken; // Instance of leverage token
91-
IPerpV2LeverageModule perpV2LeverageModule; // Instance of Perp V2 leverage module
91+
IPerpV2LeverageModuleV2 perpV2LeverageModule; // Instance of Perp V2 leverage module
9292
IAccountBalance perpV2AccountBalance; // Instance of Perp V2 AccountBalance contract used to fetch position balances
9393
IPriceFeed baseUSDPriceOracle; // PerpV2 oracle that returns TWAP price for base asset in USD. IPriceFeed is a PerpV2 specific interface
9494
// to interact with differnt oracle providers, e.g. Band Protocol and Chainlink, for different assets
@@ -399,7 +399,7 @@ contract PerpV2LeverageStrategyExtension is BaseExtension {
399399
*/
400400
function deposit(uint256 _collateralUnits) external onlyOperator {
401401
bytes memory depositCalldata = abi.encodeWithSelector(
402-
IPerpV2LeverageModule.deposit.selector,
402+
IPerpV2LeverageModuleV2.deposit.selector,
403403
address(strategy.setToken),
404404
_collateralUnits
405405
);
@@ -414,7 +414,7 @@ contract PerpV2LeverageStrategyExtension is BaseExtension {
414414
*/
415415
function withdraw(uint256 _collateralUnits) external onlyOperator {
416416
bytes memory withdrawCalldata = abi.encodeWithSelector(
417-
IPerpV2LeverageModule.withdraw.selector,
417+
IPerpV2LeverageModuleV2.withdraw.selector,
418418
address(strategy.setToken),
419419
_collateralUnits
420420
);
@@ -599,7 +599,7 @@ contract PerpV2LeverageStrategyExtension is BaseExtension {
599599
function getCurrentEtherIncentive() external view returns(uint256) {
600600
int256 currentLeverageRatio = getCurrentLeverageRatio();
601601

602-
if (currentLeverageRatio >= incentive.incentivizedLeverageRatio) {
602+
if (currentLeverageRatio.abs() >= incentive.incentivizedLeverageRatio.abs()) {
603603
// If ETH reward is below the balance on this contract, then return ETH balance on contract instead
604604
return incentive.etherReward < address(this).balance ? incentive.etherReward : address(this).balance;
605605
} else {
@@ -673,7 +673,7 @@ contract PerpV2LeverageStrategyExtension is BaseExtension {
673673
uint256 oppositeBoundUnits = _calculateOppositeBoundUnits(baseRebalanceUnits, _leverageInfo.action, _leverageInfo.slippageTolerance);
674674

675675
bytes memory tradeCallData = abi.encodeWithSelector(
676-
IPerpV2LeverageModule.trade.selector,
676+
IPerpV2LeverageModuleV2.trade.selector,
677677
address(strategy.setToken),
678678
strategy.virtualBaseAddress,
679679
baseRebalanceUnits,
@@ -754,7 +754,6 @@ contract PerpV2LeverageStrategyExtension is BaseExtension {
754754

755755
// Fetch base token prices from PerpV2 oracles and adjust them to 18 decimal places.
756756
int256 rawBasePrice = strategy.baseUSDPriceOracle.getPrice(strategy.twapInterval).toInt256();
757-
uint256 decimals = strategy.baseUSDPriceOracle.decimals();
758757
rebalanceInfo.basePrice = rawBasePrice.mul((10 ** strategy.basePriceDecimalAdjustment).toInt256());
759758

760759
// vUSD price is fixed to 1$
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
// SPDX-License-Identifier: GPL-2.0-or-later
2+
pragma solidity 0.6.10;
3+
pragma experimental ABIEncoderV2;
4+
5+
/// @title Quoter Interface
6+
/// @notice Supports quoting the calculated amounts from exact input or exact output swaps
7+
/// @dev These functions are not marked view because they rely on calling non-view functions and reverting
8+
/// to compute the result. They are also not gas efficient and should not be called on-chain.
9+
interface IUniswapV3Quoter {
10+
/// @notice Returns the amount out received for a given exact input swap without executing the swap
11+
/// @param path The path of the swap, i.e. each token pair and the pool fee
12+
/// @param amountIn The amount of the first token to swap
13+
/// @return amountOut The amount of the last token that would be received
14+
function quoteExactInput(bytes memory path, uint256 amountIn) external returns (uint256 amountOut);
15+
16+
/// @notice Returns the amount out received for a given exact input but for a swap of a single pool
17+
/// @param tokenIn The token being swapped in
18+
/// @param tokenOut The token being swapped out
19+
/// @param fee The fee of the token pool to consider for the pair
20+
/// @param amountIn The desired input amount
21+
/// @param sqrtPriceLimitX96 The price limit of the pool that cannot be exceeded by the swap
22+
/// @return amountOut The amount of `tokenOut` that would be received
23+
function quoteExactInputSingle(
24+
address tokenIn,
25+
address tokenOut,
26+
uint24 fee,
27+
uint256 amountIn,
28+
uint160 sqrtPriceLimitX96
29+
) external returns (uint256 amountOut);
30+
31+
/// @notice Returns the amount in required for a given exact output swap without executing the swap
32+
/// @param path The path of the swap, i.e. each token pair and the pool fee. Path must be provided in reverse order
33+
/// @param amountOut The amount of the last token to receive
34+
/// @return amountIn The amount of first token required to be paid
35+
function quoteExactOutput(bytes memory path, uint256 amountOut) external returns (uint256 amountIn);
36+
37+
/// @notice Returns the amount in required to receive the given exact output amount but for a swap of a single pool
38+
/// @param tokenIn The token being swapped in
39+
/// @param tokenOut The token being swapped out
40+
/// @param fee The fee of the token pool to consider for the pair
41+
/// @param amountOut The desired output amount
42+
/// @param sqrtPriceLimitX96 The price limit of the pool that cannot be exceeded by the swap
43+
/// @return amountIn The amount required as the input for the swap in order to receive `amountOut`
44+
function quoteExactOutputSingle(
45+
address tokenIn,
46+
address tokenOut,
47+
uint24 fee,
48+
uint256 amountOut,
49+
uint160 sqrtPriceLimitX96
50+
) external returns (uint256 amountIn);
51+
}

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@setprotocol/set-v2-strategies",
3-
"version": "0.0.7",
3+
"version": "0.0.8",
44
"description": "",
55
"main": "dist",
66
"types": "dist/types",
@@ -90,7 +90,7 @@
9090
"web3": "^1.2.9"
9191
},
9292
"dependencies": {
93-
"@setprotocol/set-protocol-v2": "^0.4.0-hhat.1",
93+
"@setprotocol/set-protocol-v2": "0.10.0-hhat.1",
9494
"@uniswap/v3-sdk": "^3.5.1",
9595
"ethers": "5.5.2",
9696
"fs-extra": "^5.0.0",

0 commit comments

Comments
 (0)