-
Notifications
You must be signed in to change notification settings - Fork 98
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Packing overrides and filler #221
Changes from 7 commits
24cde90
d63c7d4
1a475e2
e63b15d
2d2760c
cf4e70b
26ead0d
ccf5b4a
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1 @@ | ||
188845 | ||
187839 |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1 @@ | ||
210669 | ||
208628 |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1 @@ | ||
221076 | ||
218396 |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1 @@ | ||
275385 | ||
272068 |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1 @@ | ||
204195 | ||
202154 |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1 @@ | ||
155052 | ||
154046 |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1 @@ | ||
140619 | ||
139613 |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1 @@ | ||
164362 | ||
163357 |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,96 @@ | ||
// SPDX-License-Identifier: GPL-2.0-or-later | ||
pragma solidity ^0.8.0; | ||
|
||
struct CosignerData { | ||
// The time at which the DutchOutputs start decaying | ||
uint256 decayStartTime; | ||
// The time at which price becomes static | ||
uint256 decayEndTime; | ||
// Encoded exclusiveFiller, inputOverride, and outputOverrides, where needed | ||
// First byte: fff0 0000 where f is a flag signalling inclusion of the 3 variables | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. and the last 5 bits are the length of outputs array? |
||
// exclusiveFiller: The address who has exclusive rights to the order until decayStartTime | ||
// inputOverride: The number of tokens that the swapper will provide when settling the order | ||
// outputOverrides: The tokens that must be received to satisfy the order | ||
bytes extraData; | ||
} | ||
|
||
library CosignerExtraDataLib { | ||
bytes32 constant EXCL_FILLER_FLAG_MASK = 0x8000000000000000000000000000000000000000000000000000000000000000; | ||
bytes32 constant INPUT_OVERRIDE_FLAG_MASK = 0x4000000000000000000000000000000000000000000000000000000000000000; | ||
bytes32 constant OUTPUT_OVERRIDE_FLAG_MASK = 0x2000000000000000000000000000000000000000000000000000000000000000; | ||
bytes32 constant OUTPUTS_LENGTH_FLAG_MASK = 0x1F00000000000000000000000000000000000000000000000000000000000000; | ||
|
||
// "True" first bit of byte 1 signals that there is an exclusive filler | ||
function hasExclusiveFiller(bytes memory extraData) internal pure returns (bool flag) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. would it be even cheaper to just take a There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. oh yeah good point i'll try that |
||
if (extraData.length == 0) return false; | ||
assembly { | ||
flag := and(mload(add(extraData, 32)), EXCL_FILLER_FLAG_MASK) | ||
} | ||
} | ||
|
||
// "True" second bit of byte 1 signals that there is an input override | ||
function hasInputOverride(bytes memory extraData) internal pure returns (bool flag) { | ||
if (extraData.length == 0) return false; | ||
assembly { | ||
flag := and(mload(add(extraData, 32)), INPUT_OVERRIDE_FLAG_MASK) | ||
} | ||
} | ||
|
||
// "True" third bit of byte 1 signals that there is an output override | ||
function hasOutputOverrides(bytes memory extraData) internal pure returns (bool flag) { | ||
if (extraData.length == 0) return false; | ||
assembly { | ||
flag := and(mload(add(extraData, 32)), OUTPUT_OVERRIDE_FLAG_MASK) | ||
} | ||
} | ||
|
||
function decodeExtraParameters(bytes memory extraData) | ||
internal | ||
pure | ||
returns (address filler, uint256 inputOverride, uint256[] memory outputOverrides) | ||
{ | ||
if (extraData.length == 0) return (filler, inputOverride, outputOverrides); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. can just do empty return right? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. also in what case would we ever have 0 length? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. length==0 when there is no exclusive filler, no inputOverrides, and no outputoverrides... so i guess an open order where someone fills the exact amount in the order itself |
||
// The first 32 bytes are length | ||
// The first byte (index 0) only contains flags of whether each field is included in the bytes | ||
// So we can start from index 1 (after 32) to start decoding each field | ||
uint256 bytesOffset = 33; | ||
|
||
if (hasExclusiveFiller(extraData)) { | ||
// + 20 bytes for address, - 32 bytes for the length offset | ||
require(extraData.length >= bytesOffset - 12); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. can we do a nicer custom err here? |
||
assembly { | ||
// it loads a full 32 bytes, shift right 96 bits so only the address remains | ||
filler := shr(96, mload(add(extraData, bytesOffset))) | ||
} | ||
bytesOffset += 20; | ||
} | ||
|
||
if (hasInputOverride(extraData)) { | ||
// + 32 bytes for uint256, - 32 bytes for the length offset | ||
require(extraData.length >= bytesOffset); | ||
assembly { | ||
inputOverride := mload(add(extraData, bytesOffset)) | ||
} | ||
bytesOffset += 32; | ||
} | ||
|
||
if (hasOutputOverrides(extraData)) { | ||
uint256 length; | ||
assembly { | ||
length := shr(248, and(mload(add(extraData, 32)), OUTPUTS_LENGTH_FLAG_MASK)) | ||
} | ||
|
||
// each element of the array is 32 bytes, - 32 bytes for the length offset | ||
require(extraData.length == bytesOffset + (length - 1) * 32); | ||
outputOverrides = new uint256[](length); | ||
|
||
uint256 outputOverride; | ||
for (uint256 i = 0; i < length; i++) { | ||
assembly { | ||
outputOverride := mload(add(extraData, add(bytesOffset, mul(i, 32)))) | ||
} | ||
outputOverrides[i] = outputOverride; | ||
} | ||
} | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
any benefit to including these in extraData as well and having them be only uint32s? that may also allow slightly cleaner reading as you could just have
parseInputOverrides(bytes encodedCosignerData) -> CosignerData
or something