Merge remote-tracking branch 'origin/master'
This commit is contained in:
@@ -11,7 +11,13 @@ library OrderLib {
|
|||||||
// todo safe math and/or bounds checking
|
// todo safe math and/or bounds checking
|
||||||
|
|
||||||
uint64 internal constant NO_CHAIN = type(uint64).max;
|
uint64 internal constant NO_CHAIN = type(uint64).max;
|
||||||
uint64 internal constant NO_OCO = type(uint64).max;
|
uint64 internal constant NO_OCO_INDEX = type(uint64).max;
|
||||||
|
|
||||||
|
struct OrdersInfo {
|
||||||
|
bool _ignored; // workaround for Solidity bug where a public struct member cannot start with an array of uncertain size
|
||||||
|
SwapOrderStatus[] orders;
|
||||||
|
OcoGroup[] ocoGroups;
|
||||||
|
}
|
||||||
|
|
||||||
event DexorderSwapPlaced (uint64 startOrderIndex, uint8 numOrders);
|
event DexorderSwapPlaced (uint64 startOrderIndex, uint8 numOrders);
|
||||||
|
|
||||||
@@ -51,8 +57,10 @@ library OrderLib {
|
|||||||
SwapOrderState state;
|
SwapOrderState state;
|
||||||
uint32 start;
|
uint32 start;
|
||||||
uint64 ocoGroup;
|
uint64 ocoGroup;
|
||||||
uint256 filledIn;
|
uint256 filledIn; // total
|
||||||
uint256 filledOut;
|
uint256 filledOut; // total
|
||||||
|
uint256[] trancheFilledIn; // sum(tranchFilledIn) == filledIn
|
||||||
|
uint256[] trancheFilledOut; // sum(tranchFilledOut) == filledOut
|
||||||
}
|
}
|
||||||
|
|
||||||
enum ConstraintMode {
|
enum ConstraintMode {
|
||||||
@@ -64,8 +72,8 @@ library OrderLib {
|
|||||||
}
|
}
|
||||||
|
|
||||||
struct Constraint {
|
struct Constraint {
|
||||||
ConstraintMode mode;
|
ConstraintMode mode; // type information
|
||||||
bytes constraint; // abi-encoded constraint struct
|
bytes constraint; // abi packed-encoded constraint struct: decode according to mode
|
||||||
}
|
}
|
||||||
|
|
||||||
struct PriceConstraint {
|
struct PriceConstraint {
|
||||||
@@ -122,12 +130,6 @@ library OrderLib {
|
|||||||
uint8 num; // number of orders in the group
|
uint8 num; // number of orders in the group
|
||||||
}
|
}
|
||||||
|
|
||||||
struct OrdersInfo {
|
|
||||||
bool _ignored; // workaround for Solidity bug where a public struct member cannot start with an array of uncertain size
|
|
||||||
SwapOrderStatus[] orders;
|
|
||||||
OcoGroup[] ocoGroups; // each indexed OCO group is an array of orderIndexes of orders in the oco group.
|
|
||||||
}
|
|
||||||
|
|
||||||
function _placeOrder(OrdersInfo storage self, SwapOrder memory order) internal {
|
function _placeOrder(OrdersInfo storage self, SwapOrder memory order) internal {
|
||||||
SwapOrder[] memory orders = new SwapOrder[](1);
|
SwapOrder[] memory orders = new SwapOrder[](1);
|
||||||
orders[0] = order;
|
orders[0] = order;
|
||||||
@@ -140,7 +142,7 @@ library OrderLib {
|
|||||||
require(startIndex < type(uint64).max);
|
require(startIndex < type(uint64).max);
|
||||||
uint64 ocoGroup;
|
uint64 ocoGroup;
|
||||||
if( ocoMode == OcoMode.NO_OCO )
|
if( ocoMode == OcoMode.NO_OCO )
|
||||||
ocoGroup = NO_OCO;
|
ocoGroup = NO_OCO_INDEX;
|
||||||
else if ( ocoMode == OcoMode.CANCEL_ON_PARTIAL_FILL || ocoMode == OcoMode.CANCEL_ON_COMPLETION ){
|
else if ( ocoMode == OcoMode.CANCEL_ON_PARTIAL_FILL || ocoMode == OcoMode.CANCEL_ON_COMPLETION ){
|
||||||
ocoGroup = uint64(self.ocoGroups.length);
|
ocoGroup = uint64(self.ocoGroups.length);
|
||||||
self.ocoGroups.push(OcoGroup(ocoMode, startIndex, uint8(orders.length)));
|
self.ocoGroups.push(OcoGroup(ocoMode, startIndex, uint8(orders.length)));
|
||||||
@@ -170,6 +172,8 @@ library OrderLib {
|
|||||||
st.fraction = ot.fraction;
|
st.fraction = ot.fraction;
|
||||||
for( uint c=0; c<ot.constraints.length; c++ )
|
for( uint c=0; c<ot.constraints.length; c++ )
|
||||||
st.constraints.push(ot.constraints[c]);
|
st.constraints.push(ot.constraints[c]);
|
||||||
|
status.trancheFilledIn.push(0);
|
||||||
|
status.trancheFilledOut.push(0);
|
||||||
}
|
}
|
||||||
status.state = SwapOrderState.Open;
|
status.state = SwapOrderState.Open;
|
||||||
status.start = uint32(block.timestamp);
|
status.start = uint32(block.timestamp);
|
||||||
@@ -206,10 +210,10 @@ library OrderLib {
|
|||||||
TimeConstraint memory tc = abi.decode(constraint.constraint, (TimeConstraint));
|
TimeConstraint memory tc = abi.decode(constraint.constraint, (TimeConstraint));
|
||||||
uint32 time = tc.earliest.mode == TimeMode.Timestamp ? tc.earliest.time : status.start + tc.earliest.time;
|
uint32 time = tc.earliest.mode == TimeMode.Timestamp ? tc.earliest.time : status.start + tc.earliest.time;
|
||||||
if (time > block.timestamp)
|
if (time > block.timestamp)
|
||||||
return 'TE';
|
return 'TE'; // time early
|
||||||
time = tc.latest.mode == TimeMode.Timestamp ? tc.latest.time : status.start + tc.latest.time;
|
time = tc.latest.mode == TimeMode.Timestamp ? tc.latest.time : status.start + tc.latest.time;
|
||||||
if (time < block.timestamp)
|
if (time < block.timestamp)
|
||||||
return 'TL';
|
return 'TL'; // time late
|
||||||
}
|
}
|
||||||
else if (constraint.mode == ConstraintMode.Limit) {
|
else if (constraint.mode == ConstraintMode.Limit) {
|
||||||
if( sqrtPriceX96 == 0 ) {
|
if( sqrtPriceX96 == 0 ) {
|
||||||
@@ -223,21 +227,23 @@ library OrderLib {
|
|||||||
return 'L';
|
return 'L';
|
||||||
}
|
}
|
||||||
else if (constraint.mode == ConstraintMode.Barrier) {
|
else if (constraint.mode == ConstraintMode.Barrier) {
|
||||||
return 'NI';
|
return 'NI'; // not implemented
|
||||||
}
|
}
|
||||||
else if (constraint.mode == ConstraintMode.Trailing) {
|
else if (constraint.mode == ConstraintMode.Trailing) {
|
||||||
return 'NI';
|
return 'NI'; // not implemented
|
||||||
}
|
}
|
||||||
else if (constraint.mode == ConstraintMode.Line) {
|
else if (constraint.mode == ConstraintMode.Line) {
|
||||||
return 'NI';
|
return 'NI'; // not implemented
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
return 'NI';
|
return 'NI'; // not implemented
|
||||||
// unknown constraint
|
// unknown constraint
|
||||||
}
|
}
|
||||||
uint256 amount = status.order.amount * tranche.fraction / 10 ** 18;
|
uint256 amount = status.order.amount * tranche.fraction / 10 ** 18 // the most this tranche could do
|
||||||
|
- (status.order.amountIsInput ? status.trancheFilledIn[tranche_index] : status.trancheFilledOut[tranche_index]); // minus tranche fills
|
||||||
|
// order amount remaining
|
||||||
uint256 remaining = status.order.amount - (status.order.amountIsInput ? status.filledIn : status.filledOut);
|
uint256 remaining = status.order.amount - (status.order.amountIsInput ? status.filledIn : status.filledOut);
|
||||||
if (amount > remaining)
|
if (amount > remaining) // not more than the order's overall remaining amount
|
||||||
amount = remaining;
|
amount = remaining;
|
||||||
uint256 amountIn;
|
uint256 amountIn;
|
||||||
uint256 amountOut;
|
uint256 amountOut;
|
||||||
@@ -245,13 +251,16 @@ library OrderLib {
|
|||||||
(error, amountIn, amountOut) = _do_execute_univ3(status.order, pool, amount, sqrtPriceLimitX96);
|
(error, amountIn, amountOut) = _do_execute_univ3(status.order, pool, amount, sqrtPriceLimitX96);
|
||||||
// todo other routes
|
// todo other routes
|
||||||
else
|
else
|
||||||
error = 'UR'; // unknown route
|
return 'UR'; // unknown route
|
||||||
if( bytes(error).length == 0 ) {
|
if( bytes(error).length == 0 ) {
|
||||||
status.filledIn += amountIn;
|
status.filledIn += amountIn;
|
||||||
status.filledOut += amountOut;
|
status.filledOut += amountOut;
|
||||||
|
status.trancheFilledIn[tranche_index] += amountIn;
|
||||||
|
status.trancheFilledOut[tranche_index] += amountOut;
|
||||||
emit DexorderSwapFilled(orderIndex, tranche_index, amountIn, amountOut);
|
emit DexorderSwapFilled(orderIndex, tranche_index, amountIn, amountOut);
|
||||||
_checkCompleted(self, orderIndex, status);
|
_checkCompleted(self, orderIndex, status);
|
||||||
}
|
}
|
||||||
|
return ''; // success is no error, said no one
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -280,10 +289,10 @@ library OrderLib {
|
|||||||
if( remaining == 0 ) { // todo dust leeway?
|
if( remaining == 0 ) { // todo dust leeway?
|
||||||
status.state = SwapOrderState.Filled;
|
status.state = SwapOrderState.Filled;
|
||||||
emit DexorderSwapCompleted(orderIndex);
|
emit DexorderSwapCompleted(orderIndex);
|
||||||
if( status.ocoGroup != NO_OCO )
|
if( status.ocoGroup != NO_OCO_INDEX)
|
||||||
_cancelOco(self, status.ocoGroup);
|
_cancelOco(self, status.ocoGroup);
|
||||||
}
|
}
|
||||||
else if( status.ocoGroup != NO_OCO && self.ocoGroups[status.ocoGroup].mode == OcoMode.CANCEL_ON_PARTIAL_FILL )
|
else if( status.ocoGroup != NO_OCO_INDEX && self.ocoGroups[status.ocoGroup].mode == OcoMode.CANCEL_ON_PARTIAL_FILL )
|
||||||
_cancelOco(self, status.ocoGroup);
|
_cancelOco(self, status.ocoGroup);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user