Skip to content

Complex Orders #175

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

Open
wants to merge 102 commits into
base: development
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
102 commits
Select commit Hold shift + click to select a range
02c39c9
dex selector with curve and univ3 implementations
Drypto13 Nov 3, 2021
cbfb1e0
Implementation fixes
Drypto13 Nov 14, 2021
03739d9
Init commit
Drypto13 Dec 9, 2021
54dcb26
passed tests
Drypto13 Dec 9, 2021
d830a61
Merge branch 'development' into dex-selection
Drypto13 Dec 9, 2021
040e8bc
Formatting
Drypto13 Dec 27, 2021
a7af5e0
Test Case
Drypto13 Dec 27, 2021
fdd5fc8
standardized inputs
Drypto13 Dec 28, 2021
d3f0f24
further cleanup
Drypto13 Dec 28, 2021
9ef3570
Formatting Specification
Drypto13 Dec 28, 2021
9f26413
edge case handling
Drypto13 Dec 28, 2021
6398bdf
resolve conflicts
Drypto13 Dec 29, 2021
ac8ad8f
cleanup
Drypto13 Dec 29, 2021
fd45c17
Update IBZx.sol
Drypto13 Dec 29, 2021
ee5bb2d
Update IToken.sol
Drypto13 Dec 29, 2021
dc3f347
Merge branch 'interest-model-redesign' into dex-selection
Drypto13 Dec 29, 2021
ce89686
Update LoanTokenLogicStandard.sol
Drypto13 Dec 30, 2021
9e765fb
Update IToken.sol
Drypto13 Dec 30, 2021
717cb79
Update SwapsExternal.sol
Drypto13 Dec 30, 2021
0551ad2
Update LoanTokenLogicStandard.sol
Drypto13 Dec 30, 2021
835f00d
Update IToken.sol
Drypto13 Dec 30, 2021
5cfc9aa
Merge branch 'development' into dex-selection
Drypto13 Jan 8, 2022
fcd9ccf
Flags
Drypto13 Jan 9, 2022
204237e
Update Flags.sol
Drypto13 Jan 9, 2022
ea2ee32
Merge branch 'development' into dex-selection
RomanHiden Jan 9, 2022
4f3a50f
Merge branch 'interest-model-redesign' into dex-selection
RomanHiden Jan 9, 2022
f8a0d44
formated Flags
RomanHiden Jan 9, 2022
34f7dec
formated loan opening l115
RomanHiden Jan 9, 2022
78478fe
formated loan opening l124
RomanHiden Jan 9, 2022
436fc66
formated swap external
RomanHiden Jan 9, 2022
ef25f84
Merge branch 'interest-model-redesign' into dex-selection
RomanHiden Jan 9, 2022
1c8bf9d
minor var rename
RomanHiden Jan 9, 2022
a8d2a7d
optimized deployment cost
RomanHiden Jan 9, 2022
4b9ad1f
moar optimizations
RomanHiden Jan 9, 2022
e1e27b7
revert changes
Drypto13 Jan 9, 2022
0424099
name changes
Drypto13 Jan 10, 2022
80939fc
Major refactor and partial re-design
Drypto13 Jan 12, 2022
1e97bf3
interface version changes
Drypto13 Jan 12, 2022
260689e
Merge branch 'dex-selection' into complex-orders
Drypto13 Jan 12, 2022
321b422
Format Compliant Calls
Drypto13 Jan 13, 2022
787d043
Update DexRecords.sol
Drypto13 Jan 13, 2022
8f60b2c
Update SwapsExternal.sol
Drypto13 Jan 13, 2022
929999e
Update SwapsUser.sol
Drypto13 Jan 13, 2022
c6dc85e
Formatting
Drypto13 Jan 13, 2022
f07ec3f
Merge branch 'dex-selection' into complex-orders
Drypto13 Jan 13, 2022
dfff2b6
Re-design on order storage
Drypto13 Jan 24, 2022
7b9feac
Merge branch 'interest-model-redesign' into complex-orders
Drypto13 Mar 11, 2022
ee6af34
Delete BytesLib.sol
Drypto13 Mar 11, 2022
709025a
cleanup
Drypto13 Mar 11, 2022
11c618f
optimizations
Drypto13 Mar 13, 2022
9e28dfa
minor fixes and limited test case
Drypto13 Mar 13, 2022
4355ece
edge case handling and minor improvements
Drypto13 Mar 14, 2022
b00403c
pausable guardian for orderbook contracts
Drypto13 Mar 14, 2022
4fbab92
Merge branch 'interest-model-redesign' into complex-orders
Drypto13 Mar 14, 2022
57229db
delegated manager upgrade with test cases
Drypto13 Mar 14, 2022
415ccab
minor improvements
Drypto13 Mar 15, 2022
dd6e3ed
some more optimizations
Drypto13 Mar 16, 2022
d32e767
bug fix
Drypto13 Mar 17, 2022
3d174b2
polygon test deployment
Drypto13 Mar 27, 2022
f8931ed
Merge branch 'interest-model-redesign' into complex-orders
Drypto13 Mar 27, 2022
d66921b
minor re-design for price execution
Drypto13 Apr 8, 2022
b10e127
minor fixes and interface update
Drypto13 Apr 9, 2022
55d0ad1
updated env
Drypto13 Apr 9, 2022
39c8647
partial re-structure for chainlink keeper contracts
Drypto13 Apr 10, 2022
f982b3b
full comments on interface
Drypto13 Apr 10, 2022
1ce6760
updated test case
Drypto13 Apr 10, 2022
ff496b1
keeper fix
Drypto13 Apr 11, 2022
962551e
min order size includes leverage
Drypto13 Apr 11, 2022
03095c9
minor fix on order sizing
Drypto13 Apr 11, 2022
46d77cb
changes
Drypto13 Apr 19, 2022
b1d5b85
Update LoanOpenings.sol
Drypto13 Apr 19, 2022
e1bf5db
Update IDexRecords.sol
Drypto13 Apr 19, 2022
a0a27d1
Merge branch 'interest-model-redesign' into complex-orders
Drypto13 Apr 19, 2022
6c18d32
Delete OrderBookEvents.sol
Drypto13 Apr 20, 2022
3239004
upgraded logic and keeper deployments
Drypto13 Apr 21, 2022
399f953
new deployment
Drypto13 Apr 23, 2022
e789bf8
user pays gas costs
Drypto13 Apr 28, 2022
bd6ce1a
remove minimum
Drypto13 Apr 28, 2022
1620d57
add checks and min trade size
Drypto13 Apr 28, 2022
ea95788
minor updates
Drypto13 May 6, 2022
7ff5634
Merge branch 'interest-model-redesign' into complex-orders
Drypto13 May 7, 2022
aeee948
passed tests and fixes for issues
Drypto13 May 8, 2022
ef8e6e2
fix(set-matic): case issue in script
May 24, 2022
bced548
interface update
Drypto13 May 27, 2022
af58be1
Merge branch 'development' into complex-orders
Drypto13 May 27, 2022
fd738b9
Merge branch 'development' into complex-orders
Drypto13 May 29, 2022
c82d33a
function name changes
Drypto13 Jun 23, 2022
610dc8a
avoid revert due to failure
Drypto13 Jun 24, 2022
3184123
use updated getSwapExpectedReturn
Drypto13 Jun 28, 2022
fa899da
minor fix
Drypto13 Jun 28, 2022
da33a86
minor bug fixes
Drypto13 Jun 29, 2022
f597cbd
min amount received on stop orders
Drypto13 Jun 29, 2022
aee96fa
Update OrderBook.sol
Drypto13 Jun 29, 2022
e0a0249
test cases
Drypto13 Jul 10, 2022
02174a5
Update IOrderBook.sol
Drypto13 Jul 10, 2022
db36955
Merge branch 'development' into complex-orders
Drypto13 Jul 11, 2022
e58a301
Merge branch 'development' into complex-orders
Drypto13 Aug 26, 2022
0d109ee
Merge branch 'development' into complex-orders
Drypto13 Jan 5, 2023
ee955af
OpenZeppelin version adjustment
Drypto13 Jan 5, 2023
bc99756
gas price fix
Drypto13 Jan 5, 2023
ab62376
Remove approve requirement for gas fee
Drypto13 Mar 16, 2023
3eceeba
Merge branch 'development' into complex-orders
0xosama May 3, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion contracts/governance/PausableGuardian_0_8.sol
Original file line number Diff line number Diff line change
Expand Up @@ -59,4 +59,4 @@ contract PausableGuardian_0_8 is Ownable {
guardian := sload(Pausable_GuardianAddress)
}
}
}
}
2 changes: 1 addition & 1 deletion contracts/interfaces/IWeth.sol
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
* Licensed under the Apache License, Version 2.0.
*/

pragma solidity >=0.5.0 <0.6.0;
pragma solidity >=0.5.0 <0.9.0;


interface IWeth {
Expand Down
23 changes: 23 additions & 0 deletions contracts/orderbook/Events/OrderBookEvents.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
pragma solidity ^0.8.0;
import "../IOrderBook.sol";

contract OrderBookEvents {
event OrderCancelled(address indexed trader, bytes32 orderID);
event OrderPlaced(
address indexed trader,
IOrderBook.OrderType indexed OrderType,
uint256 indexed execPrice,
bytes32 orderID,
address collateralTokenAddress,
address loanTokenAddress
);
event OrderExecuted(address indexed trader, bytes32 orderID);
event OrderAmended(
address indexed trader,
IOrderBook.OrderType indexed OrderType,
uint256 indexed execPrice,
bytes32 orderID,
address collateralTokenAddress,
address loanTokenAddress
);
}
228 changes: 228 additions & 0 deletions contracts/orderbook/IOrderBook.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,228 @@
pragma solidity ^0.8.0;

interface IOrderBook {
enum OrderType {
LIMIT_OPEN,
LIMIT_CLOSE,
MARKET_STOP
}

enum OrderStatus {
ACTIVE,
CANCELLED,
EXECUTED
}

/*
Used values for different order types:
LIMIT_OPEN:
loanID
orderID
amountReceived
leverage
loanTokenAmount
collateralTokenAmount
trader
iToken
loanTokenAddress
base
orderType
status
timeTillExpiration
loanDataBytes
LIMIT_CLOSE and MARKET_STOP:
loanID
orderID
amountReceived
loanTokenAmount
collateralTokenAmount
trader
iToken
loanTokenAddress
base
orderType
status
timeTillExpiration
loanDataBytes
*/
struct Order {
bytes32 loanID; //ID of the loan on OOKI protocol
bytes32 orderID; //order ID
uint256 amountReceived; //amount received from the trade executing. Denominated in base for limit open and loanTokenAddress for limit close and market stop
uint256 leverage; //leverage amount
uint256 loanTokenAmount; //loan token amount denominated in loanTokenAddress
uint256 collateralTokenAmount; //collateral token amount denominated in base
address trader; //trader placing order
address iToken; //iToken being interacted with
address loanTokenAddress; //loan token
address base; //collateral token
OrderType orderType; //order type
OrderStatus status; //order status
uint64 timeTillExpiration; //Time till expiration. Useful for GTD and time-based cancellation
bytes loanDataBytes; //data passed for margin trades
}

/// Returns proxy owner
/// @return owner Contract owner
function owner() external view returns(address owner);

/// Returns guardian
/// @return guardian Protocol guardian address
function getGuardian() external view returns(address guardian);

/// Returns Deposits contract address
/// @return vault Deposits Contract
function VAULT() external view returns(address vault);

/// Returns Protocol contract address
/// @return protocol ooki protocol contract
function PROTOCOL() external view returns(address protocol);

/// Returns minimum trade size in USDC
/// @return size USDC amount
function MIN_AMOUNT_IN_USDC() external view returns(uint256 size);

/// Places new Order
/// @param order Order Struct
function placeOrder(Order calldata order) external;

/// Amends Order
/// @param order Order Struct
function amendOrder(Order calldata order) external;

/// Cancels Order
/// @param orderID ID of order to be canceled
function cancelOrder(bytes32 orderID) external;

/// Cancels Order
/// @param orderID ID of order to be canceled
function cancelOrderProtocol(bytes32 orderID) external returns (uint256);

/// Force cancels order
/// @param orderID ID of order to be canceled
function cancelOrderGuardian(bytes32 orderID) external;

/// Changes stop type between index and dex price
/// @param stopType true = index, false = dex price
function changeStopType(bool stopType) external;

/// Set price feed contract address
/// @param newFeed new price feed contract
function setPriceFeed(address newFeed) external;

/// Set gas price to be used for incentives (if price feed does not already contain it)
/// @param gasPrice gas price in gwei
function setGasPrice(uint256 gasPrice) external;

/// Return price feed contract address
/// @return priceFeed Price Feed Contract Address
function priceFeed() external view returns (address priceFeed);

/// Returns gas price used for incentive calculations
/// @return gasPrice gas price in gwei
function getGasPrice() external view returns (uint256 gasPrice);

/// Deposit Gas Token to pay out incentives for orders to be executed
/// @param amount when depositing wrapped token, this is amount to be deposited (leave as 0 if sending native token)
function depositGasFeeToken(uint256 amount) external payable;

/// Withdraw Gas Token (received as native token)
/// @param amount amount to be withdrawn
function withdrawGasFeeToken(uint256 amount) external;

/// Return amount received through a specified swap
/// @param srcToken source token address
/// @param destToken destination token address
/// @param payload loanDataBytes passed for margin trades
/// @param amountIn amount in for the swap
function getDexRate(address srcToken, address destToken, bytes calldata payload, uint256 amountIn) external returns(uint256);

/// Checks if order is able to be cleared from books due to failing to meet all requirements
/// @param orderID order ID
function clearOrder(bytes32 orderID) external view returns (bool);

/// Returns list of orders that are up to be cleared. Used for Chainlink Keepers
/// @param start starting index
/// @param end ending index
/// @return hasOrders true if the payload contains any orders
/// @return payload bytes32[] encoded with the order IDs up for clearing from books
function getClearOrderList(uint start, uint end) external view returns (bool hasOrders, bytes memory payload);

/// Returns an order ID available for execution. Used for Chainlink Keepers
/// @param start starting index
/// @param end ending index
/// @return ID order ID up for execution. If equal to 0 there is no order ID up for execution in the specified index range
function getExecuteOrder(uint start, uint end) external returns (bytes32 ID);

/// Checks if order meets requirements for execution
/// @param orderID order ID of order being checked
function prelimCheck(bytes32 orderID) external returns (bool);

/// Returns oracle rate for a swap
/// @param srcToken source token address
/// @param destToken destination token address
/// @param amount swap amount
function queryRateReturn(address srcToken, address destToken, uint256 amount) external view returns(uint256);

/// Checks if dex rate is within acceptable bounds from oracle rate
/// @param srcToken source token address
/// @param destToken destination token address
/// @param payload loanDataBytes used for margin trade
function priceCheck(address srcToken, address destToken, bytes calldata payload) external returns(bool);

/// Executes Order
/// @param orderID order ID
/// @return incentiveAmountReceived amount received in gas token from exeuction of order
function executeOrder(bytes32 orderID) external returns(uint256 incentiveAmountReceived);

/// sets token allowances
/// @param spenders addresses that will be given allowance
/// @param tokens token addresses
function adjustAllowance(address[] calldata spenders, address[] calldata tokens) external;

/// revokes token allowances
/// @param spenders addresses that will have allowance revoked
/// @param tokens token addresses
function revokeAllowance(address[] calldata spenders, address[] calldata tokens) external;

/// Retrieves active orders for a trader
/// @param trader address of trader
function getUserOrders(address trader) external view returns (Order[] memory);

/// Retrieves active orders for a trader
/// @param trader address of trader
/// @param start starting index
/// @param end ending index
function getUserOrdersLimited(address trader, uint256 start, uint256 end) external view returns (Order[] memory);

/// Retrieves order corresponding to an order ID
/// @param orderID order ID
function getOrderByOrderID(bytes32 orderID) external view returns (Order memory);

/// Retrieves active order IDs for a trader
/// @param trader address of trader
function getUserOrderIDs(address trader) external view returns (bytes32[] memory);

/// Returns total active orders count for a trader
/// @param trader address of trader
function getUserOrdersCount(address trader) external view returns (uint256);

/// Returns total active orders count
function getGlobalOrdersCount() external view returns (uint256);

/// Returns total active order IDs
function getGlobalOrderIDs() external view returns (bytes32[] memory);

/// Returns total active orders
function getGlobalOrders() external view returns (Order[] memory);

/// Returns active order IDs
/// @param start starting index
/// @param end ending index
function getGlobalOrderIDsLimited(uint256 start, uint256 end) external view returns (bytes32[] memory);

/// Returns active orders
/// @param start starting index
/// @param end ending index
function getGlobalOrdersLimited(uint256 start, uint256 end) external view returns (Order[] memory);
}
43 changes: 43 additions & 0 deletions contracts/orderbook/Keepers/OrderKeeper.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
pragma solidity ^0.8.0;
import "../IOrderBook.sol";
import "@openzeppelin-4.7.0/token/ERC20/extensions/IERC20Metadata.sol";
import "../../governance/PausableGuardian_0_8.sol";

contract OrderKeeper is PausableGuardian_0_8 {
address public implementation;
IERC20Metadata public constant WRAPPED_TOKEN = IERC20Metadata(0x0d500B1d8E8eF31E21C99d1Db9A6444d3ADf1270);
IOrderBook public orderBook;

function checkUpkeep(bytes calldata checkData)
external
returns (bool upkeepNeeded, bytes memory performData)
{
(uint256 start, uint256 end) = abi.decode(checkData, (uint256, uint256));
uint256 orderIDLength = orderBook.getGlobalOrdersCount();
if (start > orderIDLength) {
return (upkeepNeeded, performData);
}
if(end > orderIDLength) {
end = orderIDLength;
}
bytes32 orderIDForExec = orderBook
.getExecuteOrder(start, end);
return (orderIDForExec != 0, abi.encode(orderIDForExec));
}

function performUpkeep(bytes calldata performData) external pausable {
bytes32 orderId = abi.decode(performData, (bytes32));
//emit OrderExecuted(trader,orderId);
try orderBook.executeOrder(orderId) {

} catch(bytes memory){} catch Error (string memory) {}
}

function setOrderBook(IOrderBook contractAddress) external onlyOwner {
orderBook = contractAddress;
}

function withdrawIncentivesReceived(address receiver) external onlyOwner {
WRAPPED_TOKEN.transfer(receiver, WRAPPED_TOKEN.balanceOf(address(this)));
}
}
47 changes: 47 additions & 0 deletions contracts/orderbook/Keepers/OrderKeeperClear.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
pragma solidity ^0.8.0;
import "../IOrderBook.sol";
import "@openzeppelin-4.7.0/token/ERC20/extensions/IERC20Metadata.sol";
import "../../governance/PausableGuardian_0_8.sol";

contract OrderKeeperClear is PausableGuardian_0_8 {
address public implementation;
IERC20Metadata public constant WRAPPED_TOKEN = IERC20Metadata(0x0d500B1d8E8eF31E21C99d1Db9A6444d3ADf1270);
IOrderBook public orderBook;

function checkUpkeep(bytes calldata checkData)
Copy link
Contributor

Choose a reason for hiding this comment

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

so probably you will need multiple upkeep jobs in case that check does not fit into single blcok. thats why checkData
needs to be https://github.com/bZxNetwork/liquidation_helper/blob/main/contracts/BzxLiquidateV2Polygon.sol#L234

external
view
returns (bool upkeepNeeded, bytes memory performData)
{
(uint256 start, uint256 end) = abi.decode(checkData, (uint256, uint256));
uint256 orderIDLength = orderBook.getGlobalOrdersCount();
if (start > orderIDLength) {
return (upkeepNeeded, performData);
}
if(end > orderIDLength) {
end = orderIDLength;
}
return orderBook.getClearOrderList(start, end);
}

function performUpkeep(bytes calldata performData) external pausable {
bytes32[] memory orderId = abi.decode(performData, (bytes32[]));
//emit OrderExecuted(trader,orderId);
for (uint i;i<orderId.length;) {
if(orderId[i]==0) {
unchecked { ++i; }
continue;
}
orderBook.cancelOrderProtocol(orderId[i]);
unchecked { ++i; }
}
}

function setOrderBook(IOrderBook contractAddress) external onlyOwner {
orderBook = contractAddress;
}

function withdrawIncentivesReceived(address receiver) external onlyOwner {
WRAPPED_TOKEN.transfer(receiver, WRAPPED_TOKEN.balanceOf(address(this)));
}
}
Loading