feat: register a polling schedule#123
Conversation
f47098d to
f62db1a
Compare
8fdcbe1 to
4e308b0
Compare
f62db1a to
6b6c223
Compare
4e308b0 to
6966303
Compare
6b6c223 to
6e29a31
Compare
04c1bde to
bf350d1
Compare
kaze-cow
left a comment
There was a problem hiding this comment.
there is probably some shady security issue with simply not including the staticInput in the schedule ID, but I need to see the rest of the code put together before I will comment further.
appears there are currently merge conflicts that need fixing
| /// @dev A schedule is uniquely identified by its funder, handler, owner, and salt. | ||
| struct Schedule { | ||
| IConditionalOrderGenerator handler; // the conditional-order handler to poll (e.g. the TWAP type) | ||
| address funder; // source of funds; the only registrant |
There was a problem hiding this comment.
based solely on this comment, its unclear: in the case of polling for a TWAP order using CoW Shed and an EOA, is the funder the EOA, or the CoWShed?
There was a problem hiding this comment.
IIUC, funder can be anyone that approves the Poller contract
| struct Schedule { | ||
| IConditionalOrderGenerator handler; // the conditional-order handler to poll (e.g. the TWAP type) | ||
| address funder; // source of funds; the only registrant | ||
| address owner; // order owner; the pull destination |
There was a problem hiding this comment.
from this comment I assume it is the CoWShed. I would rename this field to orderOwner and clarify in the comment that this is the CoW Settlement order, as opposed to any other kind of order that may become relevant.
There was a problem hiding this comment.
I don't think this brings any value. owner can be anyone that will receive funds in the end
| bytes32 salt; // the conditional order's salt | ||
| bytes staticInput; // the order's staticInput |
There was a problem hiding this comment.
comments are kind of redundant. maybe
| bytes32 salt; // the conditional order's salt | |
| bytes staticInput; // the order's staticInput | |
| /// Used to set a new poller schedule instance with the same parameters | |
| bytes32 salt; | |
| /// The `staticInput` parameter used for `getTradableOrder` when calling `handler` | |
| bytes staticInput; |
| contract ComposableCowPoller { | ||
| /// @notice Parameters for a JIT funding schedule. | ||
| /// @dev A schedule is uniquely identified by its funder, handler, owner, and salt. | ||
| struct Schedule { |
There was a problem hiding this comment.
all of the fields in this struct comments could be docstrings (/// before the field)
| /// @notice Computes the deterministic, appData-independent schedule key. | ||
| /// @dev `staticInput` is excluded because its appData can depend on this key. | ||
| /// Use a different salt for concurrent schedules with the same funder, handler, and owner. | ||
| /// @param funder The token source. | ||
| /// @param handler The conditional-order generator. | ||
| /// @param owner The conditional-order owner. | ||
| /// @param salt The conditional-order salt. | ||
| /// @return The schedule key. | ||
| function scheduleId(address funder, IConditionalOrderGenerator handler, address owner, bytes32 salt) | ||
| public | ||
| pure | ||
| returns (bytes32) | ||
| { | ||
| return keccak256(abi.encode(funder, handler, owner, salt)); | ||
| } |
There was a problem hiding this comment.
Even though staticInput isnt used in the schedule ID, it still would make the most sense here to simply take in the Schedule struct to make it simpler for the front end. Also, its wierd that the order of address funder and IConditionalOrderGenerator handler have been flipped from the original structure, and this could be problematic on the frontend because the type is ultimately address in both cases.
| /// @param schedule The schedule to store. | ||
| /// @return id The deterministic key of the stored schedule. | ||
| function register(Schedule calldata schedule) external returns (bytes32 id) { | ||
| if (msg.sender != schedule.funder) revert OnlyFunder(); |
There was a problem hiding this comment.
its now possible to do
| if (msg.sender != schedule.funder) revert OnlyFunder(); | |
| require(msg.sender == schedule.funder, OnlyFunder()); |
There was a problem hiding this comment.
While I prefer this style of reverts, this is not a standard adopted in any CoW repo IIRC.
| /// @param id The deterministic key of the schedule. | ||
| /// @param owner The conditional-order owner and pull destination. | ||
| /// @param funder The token source that registered the schedule. | ||
| event ScheduleRegistered(bytes32 indexed id, address indexed owner, address indexed funder); |
There was a problem hiding this comment.
for completeness it would be good to include all fields of Schedule in the log
There was a problem hiding this comment.
The current fields are the most important ones, and adding more could just spike up gas costs at not much additional benefits (e.g. staticInput, handler etc)
| /// added in follow-up PRs. | ||
| /// @notice Exercises registering a schedule for a composable TWAP created via `createWithContext`. | ||
| contract ComposableCowPollerTest is BaseComposableCoWTest { | ||
| uint256 constant PART = 100e18; |
There was a problem hiding this comment.
this is the amount to trade on each TWAP trade, right? The constant (or at least the naming) actually makes it harder to understand what is going on, so it seems like it would be best to rename this to something like TWAP_PART_AMOUNT, or perhaps remove it entirely.
| /// @notice Exercises registering a schedule for a composable TWAP created via `createWithContext`. | ||
| contract ComposableCowPollerTest is BaseComposableCoWTest { | ||
| uint256 constant PART = 100e18; | ||
| uint256 constant LIMIT = 1e18; |
There was a problem hiding this comment.
this value is only used in the _bundle function so low value in having it as a constant here.
There was a problem hiding this comment.
Hardcoded magic values are really hard to understand, so I'd keep it as-is
Clarify schedule roles, accept Schedule in scheduleId, and improve TWAP test naming.
21fe323 to
45755b8
Compare
Part of #121. Follow uo #116
The polling requires a pre-authorization from the funding account (the registration).
This pre-authorization is done by registering a polling schedule
What
Adds the struct of the register.
The registrations are done using a
scheduleId(bytes32). The PR provides apurefunction that generates this id deterministically based on the funder, handler, owner and salt.This pre-register is what will allow in a follow up PR to implement the constraints in the function that does the actual poll.
Test plan
forge test --match-contract ComposableCowPollerTest -vvTest pass