Skip to content

Commit

Permalink
feat: added testToInt
Browse files Browse the repository at this point in the history
  • Loading branch information
robertleifke committed Oct 25, 2024
1 parent eae6060 commit 1280008
Show file tree
Hide file tree
Showing 6 changed files with 174 additions and 44 deletions.
1 change: 1 addition & 0 deletions .env_example
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
PRIVATE_KEY=<your_private_key>
19 changes: 0 additions & 19 deletions script/Counter.s.sol

This file was deleted.

21 changes: 21 additions & 0 deletions script/deployRootFinder.s.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// SPDX-License-Identifier: GPL-3.0-or-later
pragma solidity ^0.8.13;

import "forge-std/Script.sol";
import "../src/RootFinder.sol";

contract DeployRootFinder is Script {
function run() external {
// Begin broadcasting transactions
vm.startBroadcast();

// Deploy the RootFinder contract
RootFinder rootFinder = new RootFinder();

// Log the address of the deployed contract
console.log("RootFinder deployed at:", address(rootFinder));

// Stop broadcasting transactions
vm.stopBroadcast();
}
}
34 changes: 33 additions & 1 deletion src/rootFinder.sol
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,17 @@ import { ERC20 } from "lib/solmate/src/tokens/ERC20.sol";
using FixedPointMathLib for uint256;
using FixedPointMathLib for int256;

/// @title RootFinder
/// @notice A contract for finding roots using numerical methods
/// @dev Uses Newton's method for root finding
contract RootFinder {
uint256 private constant MAX_ITERATIONS = 20;
uint256 private constant TOLERANCE = 10;

/// @notice Finds the root of a function using Newton's method
/// @param args Encoded arguments for the function
/// @param initialGuess Initial guess for the root
/// @return reserveX_ The found root
function findRootNewX(bytes memory args, uint256 initialGuess) public pure returns (uint256 reserveX_) {
reserveX_ = initialGuess;
int256 reserveX_next;
Expand All @@ -36,20 +43,36 @@ contract RootFinder {
}
}

/// @notice Computes the derivative of the trading function with respect to reserveX
/// @param args Encoded arguments for the function
/// @param rX Current value of reserveX
/// @return The computed derivative
function computeTfDReserveX(bytes memory args, uint256 rX) internal pure returns (int256) {
(, uint256 L,,,) = abi.decode(args, (uint256, uint256, uint256, uint256, uint256));
int256 a = Gaussian.ppf(toInt(rX * 1e18 / L));
int256 pdf_a = Gaussian.pdf(a);
return 1e36 / (int256(L) * pdf_a / 1e18);
}

/// @notice Finds the value of X in the trading function
/// @param data Encoded arguments for the function
/// @param x Current value of X
/// @return The computed value of the trading function
function findX(bytes memory data, uint256 x) internal pure returns (int256) {
(uint256 reserveY_, uint256 liquidity, uint256 strike_, uint256 sigma_, uint256 tau_) =
abi.decode(data, (uint256, uint256, uint256, uint256, uint256));

return computeTradingFunction(x, reserveY_, liquidity, strike_, sigma_, tau_);
}

/// @notice Computes the trading function
/// @param reserveX_ Reserve X
/// @param reserveY_ Reserve Y
/// @param liquidity Liquidity
/// @param strike_ Strike price
/// @param sigma_ Volatility
/// @param tau_ Time to expiration
/// @return The computed value of the trading function
function computeTradingFunction(
uint256 reserveX_,
uint256 reserveY_,
Expand All @@ -67,18 +90,27 @@ contract RootFinder {
return a + b + c;
}

/// @notice Computes sigma * sqrt(tau)
/// @param sigma_ Volatility
/// @param tau_ Time to expiration
/// @return The computed value of sigma * sqrt(tau)
function computeSigmaSqrtTau(uint256 sigma_, uint256 tau_) internal pure returns (uint256) {
uint256 sqrtTau = FixedPointMathLib.sqrt(tau_) * 1e9;
return sigma_.mulWadUp(sqrtTau);
}

/// @notice Converts a uint256 to an int256
/// @param x The uint256 value to convert
/// @return The converted int256 value
function toInt(uint256 x) internal pure returns (int256) {
require(x <= uint256(type(int256).max), "ToIntOverflow");
return int256(x);
}

/// @notice Computes the absolute value of an int256
/// @param x The int256 value
/// @return The absolute value of x
function abs(int256 x) internal pure returns (int256) {
return x < 0 ? -x : x;
}
}

24 changes: 0 additions & 24 deletions test/Counter.t.sol

This file was deleted.

119 changes: 119 additions & 0 deletions test/rootFinder.t.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
// SPDX-License-Identifier: GPL-3.0-or-later
pragma solidity ^0.8.13;

import "forge-std/Test.sol";
import "../src/RootFinder.sol";

contract RootFinderTest is Test {
RootFinder rootFinder;

// Initialize the RootFinder contract before each test
function setUp() public {
rootFinder = new RootFinder();
}

// Test findRootNewX to ensure it converges on the expected result
// for a given set of input parameters
function testFindRootNewX() public {
// Define inputs for findRootNewX
uint256 reserveY_ = 1000 ether;
uint256 liquidity = 5000 ether;
uint256 strike_ = 1500 ether;
uint256 sigma_ = 1e18; // 100% volatility
uint256 tau_ = 365 days; // 1-year duration

bytes memory args = abi.encode(reserveY_, liquidity, strike_, sigma_, tau_);

uint256 initialGuess = 1500 ether;
uint256 result = rootFinder.findRootNewX(args, initialGuess);

// Assert result within 1 ether tolerance
uint256 expectedValue = 1500 ether; // TODO: Replace with actual expected value
assertApproxEqAbs(result, expectedValue, 1 ether, "Root did not converge to expected value within tolerance");
}

// Test computeTfDReserveX to verify the accuracy of the derivative computation
function testComputeTfDReserveX() public {
// Define inputs for derivative computation
uint256 reserveY_ = 1000 ether;
uint256 liquidity = 5000 ether;
uint256 strike_ = 1500 ether;
uint256 sigma_ = 1e18; // 100% volatility
uint256 tau_ = 365 days; // 1-year duration

bytes memory args = abi.encode(reserveY_, liquidity, strike_, sigma_, tau_);
uint256 rX = 1200 ether;

int256 derivative = rootFinder.computeTfDReserveX(args, rX);
int256 expectedDerivative = -1e18; // TODO: Replace with actual expected derivative

assertApproxEqAbs(derivative, expectedDerivative, 1e16, "Computed derivative does not match expected value within tolerance");
}

// Test findX function to ensure it returns the expected value for given inputs
function testFindX() public {
// Test data for findX
uint256 reserveY_ = 1000 ether;
uint256 liquidity = 5000 ether;
uint256 strike_ = 1500 ether;
uint256 sigma_ = 1e18; // 100% volatility
uint256 tau_ = 365 days; // 1-year duration

bytes memory data = abi.encode(reserveY_, liquidity, strike_, sigma_, tau_);
uint256 x = 1200 ether;

int256 result = rootFinder.findX(data, x);

int256 expectedValue = 0; // TODO: Replace with actual expected outcome
assertApproxEqAbs(result, expectedValue, 1e16, "findX returned unexpected value");
}

// Test computeTradingFunction with known parameters to verify correct calculation
function testComputeTradingFunction() public {
uint256 reserveX_ = 2000 ether;
uint256 reserveY_ = 3000 ether;
uint256 liquidity = 10000 ether;
uint256 strike_ = 1500 ether;
uint256 sigma_ = 1e18; // 100% volatility
uint256 tau_ = 365 days; // 1-year duration

int256 result = rootFinder.computeTradingFunction(reserveX_, reserveY_, liquidity, strike_, sigma_, tau_);

int256 expectedValue = 1000; // TODO: Replace with actual expected result
assertApproxEqAbs(result, expectedValue, 1e16, "computeTradingFunction result does not match expected value");
}

// Test computeSigmaSqrtTau to ensure correct calculation of sigma * sqrt(tau)
function testComputeSigmaSqrtTau() public {
uint256 sigma_ = 1e18; // 100% volatility
uint256 tau_ = 365 days; // 1-year duration

uint256 result = rootFinder.computeSigmaSqrtTau(sigma_, tau_);

uint256 expectedValue = 1e18; // TODO: Replace with actual expected sigma * sqrt(tau) result
assertApproxEqAbs(result, expectedValue, 1e16, "computeSigmaSqrtTau result does not match expected value");
}

// Test toInt function for correct uint256 to int256 conversion and overflow handling
function testToInt() public {
uint256 largeNumber = type(uint256).max;

// Expect revert for input larger than max int256
vm.expectRevert(bytes("ToIntOverflow"));
rootFinder.toInt(largeNumber);

uint256 validNumber = uint256(type(int256).max);
int256 result = rootFinder.toInt(validNumber);

assertEq(result, int256(validNumber), "toInt did not convert uint256 to int256 correctly");
}

// Test abs function to ensure correct absolute value calculation for positive and negative inputs
function testAbs() public {
int256 positiveValue = 1e18;
int256 negativeValue = -1e18;

assertEq(rootFinder.abs(positiveValue), 1e18, "abs failed to return correct value for positive input");
assertEq(rootFinder.abs(negativeValue), 1e18, "abs failed to return correct value for negative input");
}
}

0 comments on commit 1280008

Please sign in to comment.