Skip to content

Commit

Permalink
wip lower contract size
Browse files Browse the repository at this point in the history
  • Loading branch information
kinrezC committed Jul 15, 2024
1 parent 6f0b802 commit c5984f7
Show file tree
Hide file tree
Showing 11 changed files with 141 additions and 242 deletions.
22 changes: 19 additions & 3 deletions src/LiquidityManager.sol
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,8 @@ import {IStandardizedYield} from "pendle/interfaces/IStandardizedYield.sol";
import {PYIndexLib, PYIndex} from "pendle/core/StandardizedYield/PYIndex.sol";
import {FixedPointMathLib} from "solmate/utils/FixedPointMathLib.sol";
import {SafeTransferLib, ERC20} from "solmate/utils/SafeTransferLib.sol";
import {console} from "forge-std/console.sol";

import {RMM, IPYieldToken} from "./RMM.sol";
import {RMM, IPYieldToken, Gaussian, computeTradingFunction} from "./RMM.sol";
import {InvalidTokenIn, InsufficientSYMinted} from "./lib/RmmErrors.sol";

contract LiquidityManager {
Expand Down Expand Up @@ -115,7 +114,6 @@ contract LiquidityManager {

// swap ptToSwap for sy
(uint256 syOut,) = rmm.swapExactPtForSy(ptToSwap, args.minOut, address(this));
console.log("syOut", syOut);

sy.approve(address(rmm), type(uint256).max);
liquidity = rmm.allocate(false, pt.balanceOf(address(this)), args.minLiquidityDelta, msg.sender);
Expand Down Expand Up @@ -180,4 +178,22 @@ contract LiquidityManager {
function isAApproxB(uint256 a, uint256 b, uint256 eps) internal pure returns (bool) {
return b.mulWadDown(1 ether - eps) <= a && a <= b.mulWadDown(1 ether + eps);
}

function calcMaxPtOut(
uint256 reserveX_,
uint256 reserveY_,
uint256 totalLiquidity_,
uint256 strike_,
uint256 sigma_,
uint256 tau_
) internal pure returns (uint256) {
int256 currentTF = computeTradingFunction(reserveX_, reserveY_, totalLiquidity_, strike_, sigma_, tau_);

uint256 maxProportion = uint256(int256(1e18) - currentTF) * 1e18 / (2 * 1e18);

uint256 maxPtOut = reserveY_ * maxProportion / 1e18;

return (maxPtOut * 999) / 1000;
}

}
112 changes: 13 additions & 99 deletions src/RMM.sol
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import {PYIndexLib, PYIndex} from "pendle/core/StandardizedYield/PYIndex.sol";
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 "./lib/RmmLib.sol";
import "./lib/RmmErrors.sol";
Expand All @@ -22,19 +21,16 @@ contract RMM is ERC20 {

using SafeTransferLib for ERC20;

uint256 public constant IMPLIED_RATE_TIME = 365 * 86400;
uint256 public constant BURNT_LIQUIDITY = 1000;
IPPrincipalToken public PT;
IStandardizedYield public SY;
IPYieldToken public YT;

IPPrincipalToken public immutable PT;
IStandardizedYield public immutable SY;
IPYieldToken public immutable YT;
uint256 public SY_scalar;
uint256 public PT_scalar;

uint256 public immutable SY_scalar;
uint256 public immutable PT_scalar;

uint256 public immutable sigma;
uint256 public immutable fee;
uint256 public immutable maturity;
uint256 public sigma;
uint256 public fee;
uint256 public maturity;

uint256 public reserveX;
uint256 public reserveY;
Expand Down Expand Up @@ -93,14 +89,13 @@ contract RMM is ERC20 {
lock
returns (uint256 totalLiquidity_, uint256 amountY)
{
if (strike != 0) revert AlreadyInitialized();
if (strike_ <= 1e18) revert InvalidStrike();
if (strike_ <= 1e18 || strike_ != 0) revert InvalidStrikeChange();

PYIndex index = YT.newIndex();
(totalLiquidity_, amountY) = prepareInit(priceX, amountX, strike_, sigma, index);

_mint(msg.sender, totalLiquidity_ - BURNT_LIQUIDITY);
_mint(address(0), BURNT_LIQUIDITY);
_mint(msg.sender, totalLiquidity_ - 1000);
_mint(address(0), 1000);
_adjust(toInt(amountX), toInt(amountY), toInt(totalLiquidity_), strike_, index);
_debit(address(SY), reserveX);
_debit(address(PT), reserveY);
Expand Down Expand Up @@ -392,7 +387,7 @@ contract RMM is ERC20 {
int256 timeToExpiry = int256(maturity) - int256(block.timestamp);

lastImpliedPrice = timeToExpiry > 0
? uint256(int256(approxSpotPrice(index.syToAsset(reserveX))).lnWad() * int256(IMPLIED_RATE_TIME) / timeToExpiry)
? uint256(int256(computeSpotPrice(index.syToAsset(reserveX), totalLiquidity, strike, sigma, lastTau())).lnWad() * int256(365 * 86400) / timeToExpiry)
: 1 ether;
}

Expand Down Expand Up @@ -437,19 +432,13 @@ contract RMM is ERC20 {
return computeTradingFunction(totalAsset, reserveY, totalLiquidity, strike, sigma, lastTau());
}

/// @notice Uses state to approximate the spot price of the X token in terms of the Y token.
/// @dev Do not rely on this for onchain calculations.
function approxSpotPrice(uint256 totalAsset) public view returns (uint256) {
return computeSpotPrice(totalAsset, totalLiquidity, strike, sigma, lastTau());
}

function computeKGivenLastPrice(uint256 reserveX_, uint256 liquidity, uint256 sigma_, uint256 tau_)
public
view
returns (uint256)
{
int256 timeToExpiry = int256(maturity - block.timestamp);
int256 rt = int256(lastImpliedPrice) * int256(timeToExpiry) / int256(IMPLIED_RATE_TIME);
int256 rt = int256(lastImpliedPrice) * int256(timeToExpiry) / int256(365 * 86400);
int256 lastPrice = rt.expWad();

uint256 a = sigma_.mulWadDown(sigma_).mulWadDown(tau_).mulWadDown(0.5 ether);
Expand Down Expand Up @@ -502,77 +491,6 @@ contract RMM is ERC20 {
}
}

function calcMaxPtOut(
uint256 reserveX_,
uint256 reserveY_,
uint256 totalLiquidity_,
uint256 strike_,
uint256 sigma_,
uint256 tau_
) internal pure returns (uint256) {
int256 currentTF = computeTradingFunction(reserveX_, reserveY_, totalLiquidity_, strike_, sigma_, tau_);

uint256 maxProportion = uint256(int256(1e18) - currentTF) * 1e18 / (2 * 1e18);

uint256 maxPtOut = reserveY_ * maxProportion / 1e18;

return (maxPtOut * 999) / 1000;
}

function calcMaxPtIn(
uint256 reserveX_,
uint256 reserveY_,
uint256 totalLiquidity_,
uint256 strike_
) internal pure returns (uint256) {
uint256 low = 0;
uint256 high = reserveY_ - 1;

while (low != high) {
uint256 mid = (low + high + 1) / 2;
if (calcSlope(reserveX_, reserveY_, totalLiquidity_, strike_, int256(mid)) < 0) {
high = mid - 1;
} else {
low = mid;
}
}

return low;
}



function calcSlope(
uint256 reserveX_,
uint256 reserveY_,
uint256 totalLiquidity_,
uint256 strike_,
int256 ptToMarket
) internal pure returns (int256) {
uint256 newReserveY = reserveY_ + uint256(ptToMarket);
uint256 b_i = newReserveY * 1e36 / (strike_ * totalLiquidity_);

if (b_i > 1e18) {
return -1;
}

int256 b = Gaussian.ppf(toInt(b_i));
int256 pdf_b = Gaussian.pdf(b);

int256 slope = (int256(strike_ * totalLiquidity_) * pdf_b / 1e36);

int256 dxdy = computedXdY(reserveX_, newReserveY);

return slope + dxdy;
}

function computedXdY(
uint256 reserveX_,
uint256 reserveY_
) internal pure returns (int256) {
return -int256(reserveX_) * 1e18 / int256(reserveY_);
}

//prepare calls
function prepareInit(uint256 priceX, uint256 amountX, uint256 strike_, uint256 sigma_, PYIndex index)
public
Expand Down Expand Up @@ -749,10 +667,6 @@ contract RMM is ERC20 {
}

function redeemPy(uint256 amount, address to) internal returns (uint256 amountOut) {
console2.log("PT balance", PT.balanceOf(address(this)));
console2.log("YT balance", YT.balanceOf(address(this)));
console2.log("SY balance", SY.balanceOf(address(YT)));
console2.log("SY address", address(SY));
PT.transfer(address(YT), amount);
YT.transfer(address(YT), amount);
amountOut = YT.redeemPY(to);
Expand Down
73 changes: 0 additions & 73 deletions src/lib/BisectionLib.sol

This file was deleted.

28 changes: 1 addition & 27 deletions src/lib/LiquidityLib.sol
Original file line number Diff line number Diff line change
Expand Up @@ -6,24 +6,6 @@ import {FixedPointMathLib} from "solmate/utils/FixedPointMathLib.sol";
using FixedPointMathLib for uint256;
using FixedPointMathLib for int256;

function computeAllocationGivenX(bool add, uint256 amountX, uint256 rx, uint256 L)
pure
returns (uint256 nextRx, uint256 nextL)
{
uint256 deltaL = amountX.mulDivDown(L, rx);
nextRx = add ? rx + amountX : rx - amountX;
nextL = add ? L + deltaL : L - deltaL;
}

function computeAllocationGivenY(bool add, uint256 amountY, uint256 ry, uint256 L)
pure
returns (uint256 nextRy, uint256 nextL)
{
uint256 deltaL = amountY.mulDivDown(L, ry);
nextRy = add ? ry + amountY : ry - amountY;
nextL = add ? L + deltaL : L - deltaL;
}

function computeDeltaLGivenDeltaX(uint256 deltaX, uint256 liquidity, uint256 reserveX) pure returns (uint256 deltaL) {
return liquidity.mulDivDown(deltaX, reserveX);
}
Expand Down Expand Up @@ -62,12 +44,4 @@ function computeAllocationGivenDeltaY(uint256 deltaY, uint256 reserveX, uint256
{
deltaX = computeDeltaXGivenDeltaY(deltaY, reserveX, reserveY);
deltaL = computeDeltaLGivenDeltaY(deltaY, liquidity, reserveY);
}

function computeAllocationGivenDeltaL(uint256 deltaL, uint256 reserveX, uint256 reserveY, uint256 liquidity)
pure
returns (uint256 deltaX, uint256 deltaY)
{
deltaX = computeDeltaXGivenDeltaL(deltaL, reserveX, liquidity);
deltaY = computeDeltaYGivenDeltaL(deltaL, reserveY, liquidity);
}
}
6 changes: 5 additions & 1 deletion src/lib/RmmErrors.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@
pragma solidity ^0.8.13;

/// @dev Thrown if trying to initialize a pool with an invalid strike price (strike < 1e18).
error InvalidStrike();
/// @dev Thrown if trying to change the strike price of an already initialized pool.
error InvalidStrikeChange();
/// @dev Thrown if trying to initialize an already initialized pool.
error AlreadyInitialized();
/// @dev Thrown when a `balanceOf` call fails or returns unexpected data.
Expand Down Expand Up @@ -31,3 +32,6 @@ error InvalidTokenIn(address tokenIn);
error Reentrancy();

error MaturityReached();

error ToIntOverflow();
error ToUintOverflow();
Loading

0 comments on commit c5984f7

Please sign in to comment.