Skip to content

Commit

Permalink
Add BlockNumberish and tests
Browse files Browse the repository at this point in the history
  • Loading branch information
zhongeric committed Oct 2, 2024
1 parent bc9ddd9 commit 83d7da1
Show file tree
Hide file tree
Showing 31 changed files with 374 additions and 117 deletions.
Original file line number Diff line number Diff line change
@@ -1 +1 @@
198780
198870
2 changes: 1 addition & 1 deletion .forge-snapshots/Base-V3DutchOrder-ExecuteBatch.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
231116
231296
Original file line number Diff line number Diff line change
@@ -1 +1 @@
244626
244817
Original file line number Diff line number Diff line change
@@ -1 +1 @@
302041
302243
Original file line number Diff line number Diff line change
@@ -1 +1 @@
224642
224822
2 changes: 1 addition & 1 deletion .forge-snapshots/Base-V3DutchOrder-ExecuteSingle.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
165165
165255
Original file line number Diff line number Diff line change
@@ -1 +1 @@
150727
150817
Original file line number Diff line number Diff line change
@@ -1 +1 @@
174481
174571
2 changes: 1 addition & 1 deletion .forge-snapshots/Base-V3DutchOrder-RevertInvalidNonce.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
43785
43875
2 changes: 1 addition & 1 deletion .forge-snapshots/Base-V3DutchOrder-V3-ExclusiveFiller.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
169089
169179
2 changes: 1 addition & 1 deletion .forge-snapshots/Base-V3DutchOrder-V3-InputOverride.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
169170
169260
2 changes: 1 addition & 1 deletion .forge-snapshots/Base-V3DutchOrder-V3-OutputOverride.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
169113
169203
2 changes: 1 addition & 1 deletion .forge-snapshots/V3-DutchDecay.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
13179
13351
2 changes: 1 addition & 1 deletion .forge-snapshots/V3-DutchDecayBounded.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
1199
1247
2 changes: 1 addition & 1 deletion .forge-snapshots/V3-DutchDecayFullyDecayed.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
6677
6755
2 changes: 1 addition & 1 deletion .forge-snapshots/V3-DutchDecayFullyDecayedNegative.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
6365
6443
2 changes: 1 addition & 1 deletion .forge-snapshots/V3-DutchDecayNegative.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
1271
1309
2 changes: 1 addition & 1 deletion .forge-snapshots/V3-DutchDecayNoDecay.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
5899
5975
2 changes: 1 addition & 1 deletion .forge-snapshots/V3-DutchDecayNoDecayYet.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
4703
4779
2 changes: 1 addition & 1 deletion .forge-snapshots/V3-DutchDecayNoDecayYetNegative.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
4703
4779
2 changes: 1 addition & 1 deletion .forge-snapshots/V3-DutchDecayRange.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
1271
1309
2 changes: 1 addition & 1 deletion .forge-snapshots/V3-ExtendedMultiPointDutchDecay.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
88354
89192
2 changes: 1 addition & 1 deletion .forge-snapshots/V3-MultiPointDutchDecay.snap
Original file line number Diff line number Diff line change
@@ -1 +1 @@
26242
26608
31 changes: 31 additions & 0 deletions src/base/BlockNumberish.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import {IArbSys} from "../interfaces/IArbSys.sol";

/// @title BlockNumberish
/// A helper contract to get the current block number on different chains
contract BlockNumberish {
// Declare an immutable function type variable for the _getTstorish function
// based on chain support for tstore at time of deployment.
function() view returns (uint256) internal immutable _getBlockNumberish;

constructor() {
// Set the function to use based on chainid
if (block.chainid == 42161) {
_getBlockNumberish = _getBlockNumberSyscall;
} else {
_getBlockNumberish = _getBlockNumber;
}
}

/// @dev Private function to get the block number on arbitrum
function _getBlockNumberSyscall() private view returns (uint256) {
return IArbSys(0x0000000000000000000000000000000000000064).arbBlockNumber();
}

/// @dev Private function to get the block number using the opcode
function _getBlockNumber() private view returns (uint256) {
return block.number;
}
}
10 changes: 3 additions & 7 deletions src/lib/ExclusivityLib.sol
Original file line number Diff line number Diff line change
Expand Up @@ -41,14 +41,10 @@ library ExclusivityLib {
ResolvedOrder memory order,
address exclusive,
uint256 exclusivityEnd,
uint256 exclusivityOverrideBps
uint256 exclusivityOverrideBps,
uint256 blockNumberish
) internal view {
uint256 blockNumber = block.number;
// Arbitrum specific block numbers must be fetched from their system contracts
if (block.chainid == 42161) {
blockNumber = IArbSys(address(100)).arbBlockNumber();
}
_handleExclusiveOverride(order, exclusive, exclusivityEnd, exclusivityOverrideBps, blockNumber);
_handleExclusiveOverride(order, exclusive, exclusivityEnd, exclusivityOverrideBps, blockNumberish);
}

/// @notice Applies exclusivity override to the resolved order if necessary
Expand Down
30 changes: 15 additions & 15 deletions src/lib/NonlinearDutchDecayLib.sol
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ library NonlinearDutchDecayLib {
NonlinearDutchDecay memory curve,
uint256 startAmount,
uint256 decayStartBlock,
uint256 blockNumberish,
uint256 minAmount,
uint256 maxAmount
) internal view returns (uint256 decayedAmount) {
Expand All @@ -37,18 +38,12 @@ library NonlinearDutchDecayLib {
revert InvalidDecayCurve();
}

uint256 blockNumber = block.number;
// Arbitrum specific block numbers must be fetched from their system contracts
if (block.chainid == 42161) {
blockNumber = IArbSys(address(100)).arbBlockNumber();
}

// handle current block before decay or no decay
if (decayStartBlock >= blockNumber || curve.relativeAmounts.length == 0) {
if (decayStartBlock >= blockNumberish || curve.relativeAmounts.length == 0) {
return startAmount.bound(minAmount, maxAmount);
}

uint16 blockDelta = uint16(blockNumber - decayStartBlock);
uint16 blockDelta = uint16(blockNumberish - decayStartBlock);
(uint16 startPoint, uint16 endPoint, int256 relStartAmount, int256 relEndAmount) =
locateCurvePosition(curve, blockDelta);
// get decay of only the relative amounts
Expand Down Expand Up @@ -97,43 +92,48 @@ library NonlinearDutchDecayLib {
/// @notice returns a decayed output using the given dutch spec and blocks
/// @param output The output to decay
/// @param decayStartBlock The block to start decaying
/// @param blockNumberish The block number to decay to
/// @return result a decayed output
function decay(V3DutchOutput memory output, uint256 decayStartBlock)
function decay(V3DutchOutput memory output, uint256 decayStartBlock, uint256 blockNumberish)
internal
view
returns (OutputToken memory result)
{
uint256 decayedOutput =
decay(output.curve, output.startAmount, decayStartBlock, output.minAmount, type(uint256).max);
uint256 decayedOutput = decay(
output.curve, output.startAmount, decayStartBlock, blockNumberish, output.minAmount, type(uint256).max
);
result = OutputToken(output.token, decayedOutput, output.recipient);
}

/// @notice returns a decayed output array using the given dutch spec and blocks
/// @param outputs The output array to decay
/// @param decayStartBlock The block to start decaying
/// @param blockNumberish The block number to decay to
/// @return result a decayed output array
function decay(V3DutchOutput[] memory outputs, uint256 decayStartBlock)
function decay(V3DutchOutput[] memory outputs, uint256 decayStartBlock, uint256 blockNumberish)
internal
view
returns (OutputToken[] memory result)
{
uint256 outputLength = outputs.length;
result = new OutputToken[](outputLength);
for (uint256 i = 0; i < outputLength; i++) {
result[i] = decay(outputs[i], decayStartBlock);
result[i] = decay(outputs[i], decayStartBlock, blockNumberish);
}
}

/// @notice returns a decayed input using the given dutch spec and times
/// @param input The input to decay
/// @param decayStartBlock The block to start decaying
/// @param blockNumberish The block number to decay to
/// @return result a decayed input
function decay(V3DutchInput memory input, uint256 decayStartBlock)
function decay(V3DutchInput memory input, uint256 decayStartBlock, uint256 blockNumberish)
internal
view
returns (InputToken memory result)
{
uint256 decayedInput = decay(input.curve, input.startAmount, decayStartBlock, 0, input.maxAmount);
uint256 decayedInput =
decay(input.curve, input.startAmount, decayStartBlock, blockNumberish, 0, input.maxAmount);
result = InputToken(input.token, decayedInput, input.maxAmount);
}
}
17 changes: 12 additions & 5 deletions src/reactors/V3DutchOrderReactor.sol
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {ExclusivityLib} from "../lib/ExclusivityLib.sol";
import {NonlinearDutchDecayLib} from "../lib/NonlinearDutchDecayLib.sol";
import {V3DutchOrderLib, V3DutchOrder, CosignerData, V3DutchOutput, V3DutchInput} from "../lib/V3DutchOrderLib.sol";
import {SignedOrder, ResolvedOrder} from "../base/ReactorStructs.sol";
import {BlockNumberish} from "../base/BlockNumberish.sol";
import {FixedPointMathLib} from "solmate/src/utils/FixedPointMathLib.sol";
import {MathExt} from "../lib/MathExt.sol";
import {Math} from "openzeppelin-contracts/utils/math/Math.sol";
Expand All @@ -22,7 +23,7 @@ import {CosignerLib} from "../lib/CosignerLib.sol";
/// - For each outputAmount:
/// - If amount is 0, then use baseOutput
/// - If amount is nonzero, then ensure it is greater than specified baseOutput and replace startAmount
contract V3DutchOrderReactor is BaseReactor {
contract V3DutchOrderReactor is BaseReactor, BlockNumberish {
using Permit2Lib for ResolvedOrder;
using V3DutchOrderLib for V3DutchOrder;
using NonlinearDutchDecayLib for V3DutchOutput[];
Expand All @@ -40,7 +41,10 @@ contract V3DutchOrderReactor is BaseReactor {
/// @notice thrown when an order's cosigner output is less than the specified
error InvalidCosignerOutput();

constructor(IPermit2 _permit2, address _protocolFeeOwner) BaseReactor(_permit2, _protocolFeeOwner) {}
constructor(IPermit2 _permit2, address _protocolFeeOwner)
BaseReactor(_permit2, _protocolFeeOwner)
BlockNumberish()
{}

/// @inheritdoc BaseReactor
function _resolve(SignedOrder calldata signedOrder)
Expand All @@ -58,17 +62,20 @@ contract V3DutchOrderReactor is BaseReactor {
_updateWithCosignerAmounts(order);
_updateWithGasAdjustment(order);

uint256 blockNumberish = _getBlockNumberish();

resolvedOrder = ResolvedOrder({
info: order.info,
input: order.baseInput.decay(order.cosignerData.decayStartBlock),
outputs: order.baseOutputs.decay(order.cosignerData.decayStartBlock),
input: order.baseInput.decay(order.cosignerData.decayStartBlock, blockNumberish),
outputs: order.baseOutputs.decay(order.cosignerData.decayStartBlock, blockNumberish),
sig: signedOrder.sig,
hash: orderHash
});
resolvedOrder.handleExclusiveOverrideBlock(
order.cosignerData.exclusiveFiller,
order.cosignerData.decayStartBlock,
order.cosignerData.exclusivityOverrideBps
order.cosignerData.exclusivityOverrideBps,
blockNumberish
);
}

Expand Down
52 changes: 52 additions & 0 deletions test/base/BlockNumberish.t.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
// SPDX-License-Identifier: GPL-2.0-or-later
pragma solidity ^0.8.0;

import {Test} from "forge-std/Test.sol";
import {BlockNumberish} from "../../src/base/BlockNumberish.sol";

/// Mock Arbitrum syscall contract
contract MockArbSys {
uint256 _blockNumber;

/// @dev helper function to set the block number
function setBlockNumber(uint256 blockNumber) external {
_blockNumber = blockNumber;
}

/// @notice returns the block number
function arbBlockNumber() external view returns (uint256) {
return _blockNumber;
}
}

contract MockBlockNumberish is BlockNumberish {
function getBlockNumberish() external view returns (uint256) {
return _getBlockNumberish();
}
}

contract BlockNumberishTest is Test {
MockArbSys arbSys;
MockBlockNumberish blockNumberish;

function setUp() public {
// etch MockArbSys to address(100)
vm.etch(address(100), address(new MockArbSys()).code);
arbSys = MockArbSys(address(100));
}

function test_getBlockNumber() public {
blockNumberish = new MockBlockNumberish();

vm.roll(100);
assertEq(blockNumberish.getBlockNumberish(), 100);
}

function test_getBlockNumberSyscall() public {
vm.chainId(42161);
blockNumberish = new MockBlockNumberish();

arbSys.setBlockNumber(1);
assertEq(blockNumberish.getBlockNumberish(), 1);
}
}
Loading

0 comments on commit 83d7da1

Please sign in to comment.