Skip to content

Commit

Permalink
fix SY swap tests
Browse files Browse the repository at this point in the history
  • Loading branch information
kinrezC committed Apr 26, 2024
1 parent 7012a90 commit 8d00880
Show file tree
Hide file tree
Showing 4 changed files with 65 additions and 25 deletions.
28 changes: 13 additions & 15 deletions src/SYCoveredCall/SYCoveredCall.sol
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,15 @@ import { Pool } from "src/interfaces/IDFMM.sol";
import { PairStrategy, IStrategy } from "src/PairStrategy.sol";
import { IDFMM } from "src/interfaces/IDFMM.sol";
import { DynamicParamLib, DynamicParam } from "src/lib/DynamicParamLib.sol";
import { SignedWadMathLib } from "src/lib/SignedWadMath.sol";
import { FixedPointMathLib } from "solmate/utils/FixedPointMathLib.sol";
import {
computeTradingFunction,
computeDeltaGivenDeltaLRoundUp,
computeDeltaGivenDeltaLRoundDown,
computeDeltaLXIn,
computeDeltaLYIn,
computeTau,
computePriceGivenX,
computeKGivenLastPrice
} from "src/SYCoveredCall/SYCoveredCallMath.sol";
import {
Expand All @@ -24,6 +25,7 @@ import { IPPrincipalToken } from "pendle/interfaces/IPPrincipalToken.sol";
import { IStandardizedYield } from "pendle/interfaces/IStandardizedYield.sol";
import { IPYieldToken } from "pendle/interfaces/IPYieldToken.sol";
import "forge-std/console2.sol";
import { Gaussian } from "solstat/Gaussian.sol";

enum UpdateCode {
Invalid,
Expand Down Expand Up @@ -120,19 +122,11 @@ contract SYCoveredCall is PairStrategy {
(reserves, totalLiquidity, params) =
abi.decode(data, (uint256[], uint256, SYCoveredCallParams));

IStandardizedYield SY = IStandardizedYield(pool.tokens[0]);
IPPrincipalToken PT = IPPrincipalToken(pool.tokens[1]);
params.lastTimestamp = block.timestamp;

int256 tau = int256(computeTau(params));

console2.log("got here1");
console2.log("pt.sy", params.PT.SY());
console2.log("sy", address(params.SY));
if (params.PT.SY() != address(params.SY)) {
revert InvalidPair();
}
console2.log("got here2");

if (params.PT.expiry() <= block.timestamp) {
revert InvalidMaturity();
Expand All @@ -155,6 +149,7 @@ contract SYCoveredCall is PairStrategy {
internalParams[poolId].width = params.width;
internalParams[poolId].swapFee = params.swapFee;
internalParams[poolId].controller = params.controller;
internalParams[poolId].lastTimestamp = block.timestamp;

invariant =
tradingFunction(reserves, totalLiquidity, abi.encode(params));
Expand Down Expand Up @@ -222,7 +217,6 @@ contract SYCoveredCall is PairStrategy {
params = getPoolParams(poolId);
SYCoveredCallParams memory ccParams =
abi.decode(params, (SYCoveredCallParams));
console2.log("got here");

uint256 computedL;
uint256 swapTimestamp;
Expand All @@ -236,7 +230,9 @@ contract SYCoveredCall is PairStrategy {
) = abi.decode(
data, (uint256, uint256, uint256, uint256, uint256, uint256)
);
console2.log("got here2");

console2.log("swapTimestamp", swapTimestamp);
console2.log("block.timestamp", block.timestamp);

if (
swapTimestamp < internalParams[poolId].lastTimestamp
Expand All @@ -249,31 +245,33 @@ contract SYCoveredCall is PairStrategy {
// if timestamp is valid, append it to the poolParams for validation check
ccParams.lastTimestamp = swapTimestamp;

// compute new K
ccParams.mean =
computeKGivenLastPrice(pool.reserves[0], computedL, ccParams);

int256 computedInvariant =
tradingFunction(pool.reserves, computedL, abi.encode(params));
tradingFunction(pool.reserves, computedL, abi.encode(ccParams));
console2.log("got here");

if (computedInvariant < 0 || computedInvariant > EPSILON) {
revert InvalidComputedLiquidity(computedInvariant);
}

console2.log("now we compute dl");
deltaLiquidity = _computeSwapDeltaLiquidity(
pool,
abi.encode(params),
abi.encode(ccParams),
tokenInIndex,
tokenOutIndex,
amountIn,
amountOut
);
console2.log("deltaLiquidity", deltaLiquidity);

pool.reserves[tokenInIndex] += amountIn;
pool.reserves[tokenOutIndex] -= amountOut;

invariant = tradingFunction(
pool.reserves, computedL + deltaLiquidity, abi.encode(params)
pool.reserves, computedL + deltaLiquidity, abi.encode(ccParams)
);

params = abi.encode(ccParams);
Expand Down
25 changes: 21 additions & 4 deletions src/SYCoveredCall/SYCoveredCallSolver.sol
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,7 @@ contract SYCoveredCallSolver {
uint256 amountOut;
uint256 deltaLiquidity;
uint256 fees;
uint256 timestamp;
}

function simulateSwap(
Expand All @@ -230,6 +231,10 @@ contract SYCoveredCallSolver {
getPoolParamsCustomTimestamp(poolId, timestamp);

SimulateSwapState memory state;
state.timestamp = timestamp;
console2.log("preTotalLiquidity", preTotalLiquidity);
console2.log("preReserves[0]", preReserves[0]);
console2.log("preReserves[1]", preReserves[1]);

uint256 startComputedL = getNextLiquidity(
poolId, preReserves[0], preReserves[1], preTotalLiquidity
Expand Down Expand Up @@ -298,11 +303,23 @@ contract SYCoveredCallSolver {
bytes memory swapData;

if (swapXToY) {
swapData =
abi.encode(0, 1, swapAmountIn, state.amountOut, startComputedL);
swapData = abi.encode(
0,
1,
swapAmountIn,
state.amountOut,
startComputedL,
state.timestamp
);
} else {
swapData =
abi.encode(1, 0, swapAmountIn, state.amountOut, startComputedL);
swapData = abi.encode(
1,
0,
swapAmountIn,
state.amountOut,
startComputedL,
state.timestamp
);
}

(bool valid,,,,,,,) = IStrategy(strategy).validateSwap(
Expand Down
5 changes: 2 additions & 3 deletions test/SYCoveredCall/unit/SetUp.sol
Original file line number Diff line number Diff line change
Expand Up @@ -89,8 +89,6 @@ contract SYCoveredCallSetUp is SetUp {
}

modifier init() {
vm.warp(0);

address[] memory tokens = new address[](2);
tokens[0] = address(tokenX);
tokens[1] = address(tokenY);
Expand All @@ -99,7 +97,7 @@ contract SYCoveredCallSetUp is SetUp {
mean: uint256(pendleRateAnchor),
width: 0.1 ether,
maturity: PT.expiry(),
swapFee: TEST_SWAP_FEE,
swapFee: 0.0005 ether,
lastTimestamp: block.timestamp,
controller: address(this),
SY: SY,
Expand All @@ -120,6 +118,7 @@ contract SYCoveredCallSetUp is SetUp {
feeCollector: address(0),
controllerFee: 0
});
console2.log("timestamp", block.timestamp);

(POOL_ID,,) = dfmm.init(defaultInitParams);

Expand Down
32 changes: 29 additions & 3 deletions test/SYCoveredCall/unit/Swap.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -34,15 +34,16 @@ contract SYCoveredCallSwapTest is SYCoveredCallSetUp {
);
}

function test_SYCoveredCall_swap_SwapsXforY_WarpToMaturity() public init {
vm.warp(370 days);
function test_SYCoveredCall_swap_SwapsXforY_Warp2Days() public init {
vm.warp(block.timestamp + 2 days);

uint256 preDfmmBalanceX = tokenX.balanceOf(address(dfmm));
uint256 preDfmmBalanceY = tokenY.balanceOf(address(dfmm));

uint256 preUserBalanceX = tokenX.balanceOf(address(this));
uint256 preUserBalanceY = tokenY.balanceOf(address(this));

uint256 amountIn = 99.9999999 ether;
uint256 amountIn = 0.1 ether;
bool swapXForY = true;

(bool valid, uint256 amountOut,, bytes memory payload) =
Expand Down Expand Up @@ -126,4 +127,29 @@ contract SYCoveredCallSwapTest is SYCoveredCallSetUp {
vm.expectRevert();
dfmm.swap(POOL_ID, address(this), payload, "");
}

function _computeDeltaLXIn(
uint256 amountIn,
uint256 rx,
uint256 ry,
uint256 L,
SYCoveredCallParams memory params
) external view returns (uint256 deltaL) {
uint256 fees = params.swapFee.mulWadUp(amountIn);
uint256 px = computePriceGivenX(rx, L, params);
deltaL =
px.mulWadUp(L).mulWadUp(fees).divWadDown(px.mulWadDown(rx) + ry);
}

function _computeDeltaLYIn(
uint256 amountIn,
uint256 rx,
uint256 ry,
uint256 L,
SYCoveredCallParams memory params
) external returns (uint256 deltaL) {
uint256 fees = params.swapFee.mulWadUp(amountIn);
uint256 px = computePriceGivenX(rx, L, params);
deltaL = L.mulWadUp(fees).divWadDown(px.mulWadDown(rx) + ry);
}
}

0 comments on commit 8d00880

Please sign in to comment.