Skip to content

Commit

Permalink
merge main
Browse files Browse the repository at this point in the history
  • Loading branch information
hensha256 committed Oct 17, 2024
2 parents de4d1bf + dd76ef0 commit 1157d37
Show file tree
Hide file tree
Showing 8 changed files with 87 additions and 6 deletions.
2 changes: 1 addition & 1 deletion src/V4Router.sol
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import {PoolKey} from "@uniswap/v4-core/src/types/PoolKey.sol";
import {Currency} from "@uniswap/v4-core/src/types/Currency.sol";
import {TickMath} from "@uniswap/v4-core/src/libraries/TickMath.sol";
import {SafeCast} from "@uniswap/v4-core/src/libraries/SafeCast.sol";
import {BipsLibrary} from "@uniswap/v4-core/src/libraries/BipsLibrary.sol";

import {PathKey, PathKeyLibrary} from "./libraries/PathKey.sol";
import {CalldataDecoder} from "./libraries/CalldataDecoder.sol";
Expand All @@ -16,6 +15,7 @@ import {BaseActionsRouter} from "./base/BaseActionsRouter.sol";
import {DeltaResolver} from "./base/DeltaResolver.sol";
import {Actions} from "./libraries/Actions.sol";
import {ActionConstants} from "./libraries/ActionConstants.sol";
import {BipsLibrary} from "./libraries/BipsLibrary.sol";

/// @title UniswapV4Router
/// @notice Abstract contract that contains all internal logic needed for routing through Uniswap v4 pools
Expand Down
5 changes: 3 additions & 2 deletions src/base/ImmutableState.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,12 @@
pragma solidity ^0.8.0;

import {IPoolManager} from "@uniswap/v4-core/src/interfaces/IPoolManager.sol";
import {IImmutableState} from "../interfaces/IImmutableState.sol";

/// @title Immutable State
/// @notice A collection of immutable state variables, commonly used across multiple contracts
contract ImmutableState {
/// @notice The Uniswap v4 PoolManager contract
contract ImmutableState is IImmutableState {
/// @inheritdoc IImmutableState
IPoolManager public immutable poolManager;

constructor(IPoolManager _poolManager) {
Expand Down
10 changes: 10 additions & 0 deletions src/interfaces/IImmutableState.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.0;

import {IPoolManager} from "@uniswap/v4-core/src/interfaces/IPoolManager.sol";

/// @title Interface for ImmutableState
interface IImmutableState {
/// @notice The Uniswap v4 PoolManager contract
function poolManager() external view returns (IPoolManager);
}
3 changes: 2 additions & 1 deletion src/interfaces/IPositionManager.sol
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,11 @@ import {PoolKey} from "@uniswap/v4-core/src/types/PoolKey.sol";
import {PositionInfo} from "../libraries/PositionInfoLibrary.sol";

import {INotifier} from "./INotifier.sol";
import {IImmutableState} from "./IImmutableState.sol";

/// @title IPositionManager
/// @notice Interface for the PositionManager contract
interface IPositionManager is INotifier {
interface IPositionManager is INotifier, IImmutableState {
/// @notice Thrown when the caller is not approved to modify a position
error NotApproved(address caller);
/// @notice Thrown when the block.timestamp exceeds the user-provided deadline
Expand Down
3 changes: 2 additions & 1 deletion src/interfaces/IV4Router.sol
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,11 @@ pragma solidity ^0.8.0;
import {PoolKey} from "@uniswap/v4-core/src/types/PoolKey.sol";
import {Currency} from "@uniswap/v4-core/src/types/Currency.sol";
import {PathKey} from "../libraries/PathKey.sol";
import {IImmutableState} from "./IImmutableState.sol";

/// @title IV4Router
/// @notice Interface containing all the structs and errors for different v4 swap types
interface IV4Router {
interface IV4Router is IImmutableState {
/// @notice Emitted when an exactInput swap does not receive its minAmountOut
error V4TooLittleReceived(uint256 minAmountOutReceived, uint256 amountReceived);
/// @notice Emitted when an exactOutput is asked for more than its maxAmountIn
Expand Down
17 changes: 17 additions & 0 deletions src/libraries/BipsLibrary.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// SPDX-License-Identifier: GPL-2.0-or-later
pragma solidity ^0.8.0;

/// @title For calculating a percentage of an amount, using bips
library BipsLibrary {
uint256 internal constant BPS_DENOMINATOR = 10_000;

/// @notice emitted when an invalid percentage is provided
error InvalidBips();

/// @param amount The total amount to calculate a percentage of
/// @param bips The percentage to calculate, in bips
function calculatePortion(uint256 amount, uint256 bips) internal pure returns (uint256) {
if (bips > BPS_DENOMINATOR) revert InvalidBips();
return (amount * bips) / BPS_DENOMINATOR;
}
}
51 changes: 51 additions & 0 deletions test/libraries/BipsLibrary.t.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;

import "forge-std/Test.sol";
import {BipsLibrary} from "../../src/libraries/BipsLibrary.sol";

contract BipsLibraryTest is Test {
using BipsLibrary for uint256;

// The block gas limit set in foundry config is 300_000_000 (300M) for testing purposes
uint256 BLOCK_GAS_LIMIT;

function setUp() public {
BLOCK_GAS_LIMIT = block.gaslimit;
}

function test_fuzz_calculatePortion(uint256 amount, uint256 bips) public {
amount = bound(amount, 0, uint256(type(uint128).max));
if (bips > BipsLibrary.BPS_DENOMINATOR) {
vm.expectRevert(BipsLibrary.InvalidBips.selector);
amount.calculatePortion(bips);
} else {
assertEq(amount.calculatePortion(bips), amount * bips / BipsLibrary.BPS_DENOMINATOR);
}
}

function test_fuzz_gasLimit(uint256 bips) public {
if (bips > BipsLibrary.BPS_DENOMINATOR) {
vm.expectRevert(BipsLibrary.InvalidBips.selector);
block.gaslimit.calculatePortion(bips);
} else {
assertEq(block.gaslimit.calculatePortion(bips), BLOCK_GAS_LIMIT * bips / BipsLibrary.BPS_DENOMINATOR);
}
}

function test_gasLimit_100_percent() public view {
assertEq(block.gaslimit, block.gaslimit.calculatePortion(10_000));
}

function test_gasLimit_1_percent() public view {
// 100 bps = 1%
// 1% of 30M is 300K
assertEq(BLOCK_GAS_LIMIT / 100, block.gaslimit.calculatePortion(100));
}

function test_gasLimit_1BP() public view {
// 1bp is 0.01%
// 0.01% of 30M is 300
assertEq(BLOCK_GAS_LIMIT / 10000, block.gaslimit.calculatePortion(1));
}
}
2 changes: 1 addition & 1 deletion test/router/Payments.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,13 @@ pragma solidity ^0.8.19;

import {GasSnapshot} from "forge-gas-snapshot/GasSnapshot.sol";
import {Currency, CurrencyLibrary} from "@uniswap/v4-core/src/types/Currency.sol";
import {BipsLibrary} from "@uniswap/v4-core/src/libraries/BipsLibrary.sol";

import {IV4Router} from "../../src/interfaces/IV4Router.sol";
import {RoutingTestHelpers} from "../shared/RoutingTestHelpers.sol";
import {Plan, Planner} from "../shared/Planner.sol";
import {Actions} from "../../src/libraries/Actions.sol";
import {ActionConstants} from "../../src/libraries/ActionConstants.sol";
import {BipsLibrary} from "../../src/libraries/BipsLibrary.sol";

contract PaymentsTests is RoutingTestHelpers, GasSnapshot {
using CurrencyLibrary for Currency;
Expand Down

0 comments on commit 1157d37

Please sign in to comment.