# General Design ## Vault Creating a separate contract for each user address allows users to deposit coins into their "account" using standard ERC20 sends without extra approvals. Withdrawals require a contract call, but again no approval step. Furthermore, this clarifies the no-custody nature of the setup, since DexOrder never has any claim to ownership of the user's contract. Of course this costs extra gas up front to create the contract for the user, but on L2's it should be minimal. What about ETH? Hmmm... The alternative is to have a single contract which keeps an accounting of everyone's everything. Deposits would require approvals and a contract call. Using separate vaults will be an easier, more secure experience for frequent traders who are more likely to be our users rather than casual, occasional traders. ## Orders Orders are defined using an in-token, an out-token, a route/pool, and an amount of either input or output currency. Each order may have many tranches, and each tranch may have its own price/time constraints. Each tranche tracks its own filled amount in addition to incrementing the global filled counter. OCO support. Conditional orders (stoploss) are implemented as a separate order which starts with amount 0 but receives any filled amounts from orders that reference it. ## Reorg Resilience Blockchain reorganizations happen, so we need a system that can revert recent activity, restore to a previous state, and replay a new set of truths. We need to track the current set of open orders with their computable pool dependencies, and we need to ensure that sent/mined transactions are not lost after a reorg but retried or safely discarded. We run a single synchronous process which generates a batch of all the transactions and event logs, tagged with the block height, hash, and parent, plus a dexorder global sequence number. All subsequent processing is done within that block context, reading the state from the parent block and writing the state for the new block. State is kept entirely in-memory as a base state from an old block plus diffs organized in a tree of blockchain branches. All getters of a state object return the base value plus any diffs found by walking the current worker context's blockchain path up through its parent block. All setters write update requests to the current block hash, including its global seq. After all layers of jobs have provably completed, the actions are executed in seq order, and thte block may be marked as completed. As blocks age out, orphans/uncles are simply dropped from memory while old main-chain blocks become new root blocks for the in-memory diff tree. Active orders with an opportunity to trade are poked whenever they appear on any fork. Transactions generated by jobs carry their original block context. If a sent tx has an origin block that gets too old, the tx will be retried if the origin block is main chain but not if the origin block was a reorged fork. Whenever we get a transaction receipt, the receipt is added to the order. As the order ages out, transaction receipts are re-checked for validity