orderlib uses reverts instead of returned errors; Dexorder.sol
This commit is contained in:
@@ -131,19 +131,15 @@ library OrderLib {
|
||||
}
|
||||
|
||||
function _placeOrder(OrdersInfo storage self, SwapOrder memory order) internal {
|
||||
console2.log('OrderLib._placeOrder()');
|
||||
SwapOrder[] memory orders = new SwapOrder[](1);
|
||||
orders[0] = order;
|
||||
return _placeOrders(self,orders,OcoMode.NO_OCO);
|
||||
}
|
||||
|
||||
function _placeOrders(OrdersInfo storage self, SwapOrder[] memory orders, OcoMode ocoMode) internal {
|
||||
console2.log('_placeOrders A');
|
||||
require(orders.length < type(uint8).max);
|
||||
console2.log('_placeOrders B');
|
||||
uint64 startIndex = uint64(self.orders.length);
|
||||
require(startIndex < type(uint64).max);
|
||||
console2.log('_placeOrders C');
|
||||
uint64 ocoGroup;
|
||||
if( ocoMode == OcoMode.NO_OCO )
|
||||
ocoGroup = NO_OCO_INDEX;
|
||||
@@ -153,11 +149,9 @@ library OrderLib {
|
||||
}
|
||||
else
|
||||
revert('OCOM');
|
||||
console2.log('_placeOrders D');
|
||||
for( uint8 o = 0; o < orders.length; o++ ) {
|
||||
SwapOrder memory order = orders[o];
|
||||
require(order.route.exchange == Exchange.UniswapV3, 'UR');
|
||||
console2.log('_placeOrders E');
|
||||
// todo more order validation
|
||||
// we must explicitly copy into storage because Solidity doesn't implement copying the double-nested
|
||||
// tranches constraints array :(
|
||||
@@ -171,7 +165,6 @@ library OrderLib {
|
||||
status.order.route = order.route;
|
||||
status.order.chainOrder = order.chainOrder;
|
||||
status.order.outputDirectlyToOwner = order.outputDirectlyToOwner;
|
||||
console2.log('_placeOrders F');
|
||||
for( uint t=0; t<order.tranches.length; t++ ) {
|
||||
status.order.tranches.push();
|
||||
OrderLib.Tranche memory ot = order.tranches[t]; // order tranche
|
||||
@@ -179,22 +172,18 @@ library OrderLib {
|
||||
st.fraction = ot.fraction;
|
||||
for( uint c=0; c<ot.constraints.length; c++ )
|
||||
st.constraints.push(ot.constraints[c]);
|
||||
console2.log('_placeOrders G');
|
||||
status.trancheFilledIn.push(0);
|
||||
status.trancheFilledOut.push(0);
|
||||
}
|
||||
status.state = SwapOrderState.Open;
|
||||
status.start = uint32(block.timestamp);
|
||||
status.ocoGroup = ocoGroup;
|
||||
console2.log('_placeOrders H');
|
||||
}
|
||||
emit DexorderSwapPlaced(startIndex,uint8(orders.length));
|
||||
}
|
||||
|
||||
|
||||
// return codes:
|
||||
//
|
||||
// returns the zero-length string '' on success
|
||||
// revert codes:
|
||||
//
|
||||
// NO order is not open
|
||||
// OCO order was implicitly canceled by an OCO
|
||||
@@ -202,12 +191,10 @@ library OrderLib {
|
||||
// TE current time is too early for this tranche
|
||||
// TL current time is too late for this tranche
|
||||
//
|
||||
function execute(OrdersInfo storage self, uint64 orderIndex, uint8 tranche_index, PriceProof memory proof) internal
|
||||
returns (string memory error)
|
||||
{
|
||||
function execute(OrdersInfo storage self, address owner, uint64 orderIndex, uint8 tranche_index, PriceProof memory proof) internal {
|
||||
SwapOrderStatus storage status = self.orders[orderIndex];
|
||||
if (status.state != SwapOrderState.Open)
|
||||
return 'NO'; // Not Open
|
||||
revert('NO'); // Not Open
|
||||
Tranche storage tranche = status.order.tranches[tranche_index];
|
||||
uint160 sqrtPriceX96 = 0;
|
||||
uint160 sqrtPriceLimitX96 = 0;
|
||||
@@ -219,10 +206,10 @@ library OrderLib {
|
||||
TimeConstraint memory tc = abi.decode(constraint.constraint, (TimeConstraint));
|
||||
uint32 time = tc.earliest.mode == TimeMode.Timestamp ? tc.earliest.time : status.start + tc.earliest.time;
|
||||
if (time > block.timestamp)
|
||||
return 'TE'; // time early
|
||||
revert('TE'); // time early
|
||||
time = tc.latest.mode == TimeMode.Timestamp ? tc.latest.time : status.start + tc.latest.time;
|
||||
if (time < block.timestamp)
|
||||
return 'TL'; // time late
|
||||
revert('TL'); // time late
|
||||
}
|
||||
else if (constraint.mode == ConstraintMode.Limit) {
|
||||
if( sqrtPriceX96 == 0 ) {
|
||||
@@ -233,20 +220,19 @@ library OrderLib {
|
||||
if( pc.isRatio )
|
||||
pc.valueSqrtX96 = uint160(price * pc.valueSqrtX96 / 2**96); // todo overflow check!
|
||||
if( pc.isAbove && price < pc.valueSqrtX96 || !pc.isAbove && price > pc.valueSqrtX96 )
|
||||
return 'L';
|
||||
revert('L');
|
||||
}
|
||||
else if (constraint.mode == ConstraintMode.Barrier) {
|
||||
return 'NI'; // not implemented
|
||||
revert('NI'); // not implemented
|
||||
}
|
||||
else if (constraint.mode == ConstraintMode.Trailing) {
|
||||
return 'NI'; // not implemented
|
||||
revert('NI'); // not implemented
|
||||
}
|
||||
else if (constraint.mode == ConstraintMode.Line) {
|
||||
return 'NI'; // not implemented
|
||||
revert('NI'); // not implemented
|
||||
}
|
||||
else
|
||||
return 'NI'; // not implemented
|
||||
// unknown constraint
|
||||
else // unknown constraint
|
||||
revert('NI'); // not implemented
|
||||
}
|
||||
uint256 amount = status.order.amount * tranche.fraction / type(uint16).max // the most this tranche could do
|
||||
- (status.order.amountIsInput ? status.trancheFilledIn[tranche_index] : status.trancheFilledOut[tranche_index]); // minus tranche fills
|
||||
@@ -254,42 +240,39 @@ library OrderLib {
|
||||
uint256 remaining = status.order.amount - (status.order.amountIsInput ? status.filledIn : status.filledOut);
|
||||
if (amount > remaining) // not more than the order's overall remaining amount
|
||||
amount = remaining;
|
||||
address recipient = status.order.outputDirectlyToOwner ? owner : address(this);
|
||||
uint256 amountIn;
|
||||
uint256 amountOut;
|
||||
if( status.order.route.exchange == Exchange.UniswapV3 )
|
||||
(error, amountIn, amountOut) = _do_execute_univ3(status.order, pool, amount, sqrtPriceLimitX96);
|
||||
(amountIn, amountOut) = _do_execute_univ3(recipient, status.order, pool, amount, sqrtPriceLimitX96);
|
||||
// todo other routes
|
||||
else
|
||||
return 'UR'; // unknown route
|
||||
if( bytes(error).length == 0 ) {
|
||||
status.filledIn += amountIn;
|
||||
status.filledOut += amountOut;
|
||||
status.trancheFilledIn[tranche_index] += amountIn;
|
||||
status.trancheFilledOut[tranche_index] += amountOut;
|
||||
emit DexorderSwapFilled(orderIndex, tranche_index, amountIn, amountOut);
|
||||
_checkCompleted(self, orderIndex, status);
|
||||
}
|
||||
return ''; // success is no error, said no one
|
||||
revert('UR'); // unknown route
|
||||
status.filledIn += amountIn;
|
||||
status.filledOut += amountOut;
|
||||
status.trancheFilledIn[tranche_index] += amountIn;
|
||||
status.trancheFilledOut[tranche_index] += amountOut;
|
||||
emit DexorderSwapFilled(orderIndex, tranche_index, amountIn, amountOut);
|
||||
_checkCompleted(self, orderIndex, status);
|
||||
}
|
||||
|
||||
|
||||
function _do_execute_univ3( SwapOrder storage order, address pool, uint256 amount, uint160 sqrtPriceLimitX96) private
|
||||
returns (string memory error, uint256 amountIn, uint256 amountOut)
|
||||
function _do_execute_univ3( address recipient, SwapOrder storage order, address pool, uint256 amount, uint160 sqrtPriceLimitX96) private
|
||||
returns (uint256 amountIn, uint256 amountOut)
|
||||
{
|
||||
// todo refactor this signature to be more low-level, taking only the in/out amounts and limit prices. doesnt need self/status/index
|
||||
if (sqrtPriceLimitX96 == 0)
|
||||
// check pool inversion to see if the price should be high or low
|
||||
sqrtPriceLimitX96 = order.tokenIn < order.tokenOut ? 0 : type(uint160).max;
|
||||
// todo swap direct to owner
|
||||
if (order.amountIsInput) {
|
||||
amountIn = amount;
|
||||
(error, amountOut) = UniswapSwapper.swapExactInput(UniswapSwapper.SwapParams(
|
||||
pool, order.tokenIn, order.tokenOut, order.route.fee, amount, sqrtPriceLimitX96));
|
||||
amountOut = UniswapSwapper.swapExactInput(UniswapSwapper.SwapParams(
|
||||
pool, order.tokenIn, order.tokenOut, recipient, order.route.fee, amount, sqrtPriceLimitX96));
|
||||
}
|
||||
else {
|
||||
amountOut = amount;
|
||||
(error, amountIn) = UniswapSwapper.swapExactOutput(UniswapSwapper.SwapParams(
|
||||
pool, order.tokenIn, order.tokenOut, order.route.fee, amount, sqrtPriceLimitX96));
|
||||
amountIn = UniswapSwapper.swapExactOutput(UniswapSwapper.SwapParams(
|
||||
pool, order.tokenIn, order.tokenOut, recipient, order.route.fee, amount, sqrtPriceLimitX96));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user