Skip to content

[PT1-785] Feature/anchored minimal - #229

Open
ifelsedeveloper wants to merge 6 commits into
masterfrom
feature/anchored-minimal
Open

[PT1-785] Feature/anchored minimal#229
ifelsedeveloper wants to merge 6 commits into
masterfrom
feature/anchored-minimal

Conversation

@ifelsedeveloper

Copy link
Copy Markdown
Contributor

Change Summary

What does this PR change?
Add anchored based order via order registrator and timestamp flag

@ifelsedeveloper ifelsedeveloper changed the title Feature/anchored minimal [PT1-785] Feature/anchored minimal Aug 14, 2026
Comment thread package.json
"dependencies": {
"@1inch/delegating": "1.1.0",
"@1inch/limit-order-protocol-contract": "4.3.3",
"@1inch/limit-order-protocol-contract": "1inch/limit-order-protocol#c4970e319d309fb605185b65b36162f5ece3abd6",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need to publish the npm package with the new version.

function _anchoredTime(uint256 flaggedTime, bytes32 orderHash) private view returns (uint256) {
uint256 announcedTime = _ORDER_REGISTRATOR.announcedAt(orderHash);
if (announcedTime == 0) revert OrderNotAnnounced();
return Math.max(flaggedTime & _ANCHOR_TIMESTAMP_MASK, announcedTime);

@SteMak SteMak Sep 8, 2026

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did not get it. Which role has the flaggedTime here, why using Math.max?

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As synced, flaggedTime is not needed; here use return announcedTime;
It would be good if this will not produce one more if, to drop 3 redundant bytes though: calldata is uint32 ts with high bit not set or bytes1 of value 0x80

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use order registrator for 0x80000000 timestamp

Comment thread hardhat.config.js
const LOP_COMPILER_SETTINGS = JSON.parse(JSON.stringify(DEFAULT_COMPILER_SETTINGS));
LOP_COMPILER_SETTINGS.version = '0.8.30';

const LOW_OPTIMIZER_COMPILER_SETTINGS = JSON.parse(JSON.stringify(LOP_COMPILER_SETTINGS));

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Won't it compile without this changes?

Comment thread README.md
```

Parameters are read from a `.env` file as `OPS_*` variables. `OPS_NETWORK` and `OPS_CHAIN_ID` are always required; each target validates its own additions, so `deploy-settlement`, for example, also needs `OPS_ROUTER_V6_ADDRESS`, `OPS_ACCESS_TOKEN_ADDRESS`, `OPS_WETH_ADDRESS` and `OPS_SETTLEMENT_OWNER_ADDRESS`. Contracts are deployed through a CREATE3 deployer so that the same address is used on every chain, which needs `OPS_CREATE3_DEPLOYER_ADDRESS` and a salt; zkSync Era does not support CREATE3 and falls back to a plain deployment.
Parameters are read from a `.env` file as `OPS_*` variables. `OPS_NETWORK` and `OPS_CHAIN_ID` are always required; each target validates its own additions, so `deploy-settlement`, for example, also needs `OPS_ROUTER_V6_ADDRESS`, `OPS_ACCESS_TOKEN_ADDRESS`, `OPS_WETH_ADDRESS`, `OPS_SETTLEMENT_OWNER_ADDRESS` and `OPS_ORDER_REGISTRATOR_ADDRESS`. The OrderRegistrator must implement the `announcedAt(bytes32)` getter introduced in Limit Order Protocol 4.3.5. Contracts are deployed through a CREATE3 deployer so that the same address is used on every chain, which needs `OPS_CREATE3_DEPLOYER_ADDRESS` and a salt; zkSync Era does not support CREATE3 and falls back to a plain deployment.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The OrderRegistrator must implement the announcedAt(bytes32) getter introduced in Limit Order Protocol 4.3.5

Does it make sense to add the text here?

Comment thread test/MeasureGas.js
await weth.connect(alice).deposit({ value: ether('1') });

const settlementExtension = await deployContract('Settlement', [lopv4, accessToken, weth, owner]);
const settlementExtension = await deployContract('Settlement', [lopv4, accessToken, weth, owner, ethers.ZeroAddress]);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Feels like Gas measurements are not properly updated

});
orderRegistratorInterface.decodeFunctionResult('announcedAt', result);
} catch (error) {
throw new Error(`OrderRegistrator at ${orderRegistratorAddress} does not implement announcedAt(bytes32)`, {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The other deploy parameters does not have same-level validations. Is it meaningful to execute such checks for OrderRegistrator?

* bytes3 gasBumpEstimate;
* bytes4 gasPriceEstimate;
* bytes4 auctionStartTime;
* bytes4 auctionStartTime; // top bit is the anchor flag, see `_ANCHOR_FLAG_MASK`

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comment inside of comment. Declare outside or remove or rename field to be self-explaining

error InvalidResult(uint256 actual, uint256 expected);

constructor(IERC20 accessToken, address weth, address owner) SimpleSettlement(address(this), accessToken, weth, owner) {}
constructor(IERC20 accessToken, address weth, address owner) SimpleSettlement(address(this), accessToken, weth, owner, IOrderRegistrator(address(0))) {}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why hardcoding zero-address instead of meaningful value?

Comment thread contracts/Settlement.sol
import { IOrderMixin } from "@1inch/limit-order-protocol-contract/contracts/interfaces/IOrderMixin.sol";

import { IOrderRegistrator } from "@1inch/limit-order-protocol-contract/contracts/interfaces/IOrderRegistrator.sol";
import { SimpleSettlement } from "./SimpleSettlement.sol";

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Broken style: there was a whitespace between module and local imports

using Math for uint256;

/// @dev Top bit of a uint32 timestamp (auction start time / whitelist allowed time) opts the order
/// into anchoring: effective time = max(timestamp without the flag, OrderRegistrator.announcedAt(orderHash)).

@SteMak SteMak Sep 8, 2026

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why documenting protocol behavior in natspec of random constant?

error InvalidEstimatedTakingAmount();
error OrderNotAnnounced();

IOrderRegistrator private immutable _ORDER_REGISTRATOR;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why constants - errors - immutables layout? The errors - constants - immutables would be more consistent

* @param whitelistData Whitelist data is a tightly packed struct of the following format:
* ```
* 4 bytes - allowed time
* 4 bytes - allowed time (top bit is the anchor flag, see `_ANCHOR_FLAG_MASK`)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comments referring to another comments in another file part is hard to read

uint80 maskedTakerAddress = uint80(uint160(taker));
uint256 allowedTime = uint32(bytes4(whitelistData));
if (allowedTime & _ANCHOR_FLAG_MASK != 0) {
allowedTime = _anchoredTime(allowedTime, orderHash);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The _anchoredTime reassigns 2 different timestamps: whitelist start timestamp and auction start timestamp which potentially are different. Is it intended? If so, that should be explicit

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants