Skip to content

Instantly share code, notes, and snippets.

@Dexaran
Last active October 6, 2025 21:18
Show Gist options
  • Select an option

  • Save Dexaran/108b78e597fccb4ec9947dcd4df7ac95 to your computer and use it in GitHub Desktop.

Select an option

Save Dexaran/108b78e597fccb4ec9947dcd4df7ac95 to your computer and use it in GitHub Desktop.

Dex223 development report (June - July 2025)

This article is a development report for the Dex223 decentralized exchange.

We’re building an exchange to speed up the adoption of the ERC-223 token standard. ERC-223 was created to address a security problem in the older ERC-20 standard. The security issue in ERC-20 has caused over $100M in losses on Ethereum in 2023. Take a look at other Dex223 development reports.

Browse other Dex223 development reports here.

Dex223 Core platform

The implementation of the core platform is completed. The final version of the core contracts can be found here: https://github.com/EthereumCommonwealth/Dex223-contracts/tree/d99da952dfb472762e4c28f62a80202549e46ea8/contracts/dex-core

The core contracts include: Factory, Pools, Auto-Listing registry and Auto-listing contracts.

This version of the contracts is deployed on Ethereum mainnet, verified and is ready for production use:

Name Address
WETH9 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2
TOKEN_CONVERTER 0xe7E969012557f25bECddB717A3aa2f4789ba9f9a
POOL_LIBRARY 0xfA5930D2Ef1b6231e220aeDda88E28C4E8F0F3a0
FACTORY 0x8dae173016f65F61e90631Ee5f28C9E47b1ebc06
SWAP_ROUTER 0xbeBAB9Ab58f8099fbFEb15E14b663615D19304Fa
POSITION_MANAGER 0xFd4cE11db9db9433286734304049526E9336139E
POOL_INIT_CODE_HASH 0xa5fa1f34aae4b83ab2690d3f3df6f78e99959a1f2eb8aa4c11ba10586677338d
POOL_USDC_WETH 0x82Cc735b39a3992be7b47bEb9AE7519aC92ed562
CORE_AUTOLISTING 0x029f10E06Dc7d6264f9432ACA3F52572543c48e0
FREE_AUTOLISTING 0xa7089d8cbcc47543388a346dd6ebf0b05106a477
AUTOLISTINGS_REGISTRY 0x105F43A70aFCEd0493545D04C1d5687DF4b3f48f

The UI of the core platform is also finalized at this point, we've added the last fixes, finalized tooltip texts and it must be fully operational.

All these changes to the core platform were completed in the first days of June. We are currently waiting for the quality analysis team (mostly composed of former EOS Support department) to approve the platform for the coordinated launch.

We consider the platform to be technically complete and ready for production use since June.

Margin module development

The bulk of the development this month was done in the margin module domain. In June we had a working prototype of the module which was audited internally (mostly by myself) and tested.

The testing indicated no issues in the math of the margin module or its workflow but we detected a huge quantity of problems related to Oracles and potential vulnerabilities that could allow order owners to intentionally design their margin orders in such a way that would allow them to pull funds from the borrowers.

Margin module: Oracles

Oracles passed a huge number of update iterations (which can be tracked by commits history here and here and I'll not cover every potential problem that was fixed in this report). This is just the first "default" Oracle that governs prices for the Dex223 margin module. We are planning to have at least two different Oracles at the launch of this module: (1) "default" Oracle would pull prices from the actual liquidity reserves in Dex223 pools and (2) LINK Oracle would be an alternative version which uses prices provided by ChainLINK Oracles as the mark price for liquidations.

The "default" oracle we are currently working with has an intrinsic problem related to in-contract computations. Uniswap and Dex223 store "price" in a Q64.96 format.

For example 1:1 price in a USDT-USDC pool look like this 79237389755455049773827871756. In order to calculate the actual price we would need to divide this number by 2**96 and then the result needs to be squared. In EVM there are no fixed-point numbers so if the price in the pool is less than 2**96 then the result of all these computations will inevitably become zero. In order to bypass this computational limitation of EVM we are raising the price to the power of 2 first then dividing it by 2**192, however we hit another limitation of EVM such that if any of the results of this computations would overflow uint256 (which can potentially happen) - it would cause the Oracle to return an invalid price for a completely functional pair of tokens and a functional Pool with existing liquidity.

Another problem with this price and automated price reading is that the "price" is only valid for one token swap, if we have token1 and token2 then the "price" in the pool is the amount of token2 that we would receive for 1 token1. If we would need to swap token1 for token2 then the price needs to be actually reverted and we need to make sure that nothing will overflow or slash out extra digits once again thanks to EVM not being able to process the most basic math.

Therefore the decision was made to simplify the computations and simply slash the price to the first 6 digits within Oracle. This would guarantee the safety of auto-computations but in return it negatively impacts precision.

We are aware of a number of potential problems with the current implementation of the default Oracle:

  • If one token is significantly more expensive than the other (1 token1 > 1,000,000 token2) then the slashing method of Oracle's safe computations is ruining the price precision to the point where it becomes unusable.
  • If the Oracle under any circumstances would fail to return any actual price then it would completely freeze the workflow of the position that holds these tokens. This means - the owner of the position will not be able to close it, make any trades, withdraw the funds. This position can not be liquidated either so the funds will be effectively frozen there in the contract. We need to make sure that this will not happen but we can not guarantee that this will not happen because a user can assign a custom Oracle to their Orders. We certainly need a built-in backup price source that would be triggered in case we fail to get the price from the Oracle specified by the owner of the funds held in the position.
  • Given how flexible the system is i.e. users can set up custom Oracles, allow tokens to be traded by token-lists and set up any deadlines for positions - we will most certainly have Orders with messed settings at some point. In order to make sure that the funds are not being lost due to this problems we will need to implement a method of manual control over the margin module at the beginning which would allow the developers to extract funds from these orders and positions.

Margin module: UI integration

Even though the margin module was completed quite some time ago it was highly unoptimized and when the contract-UI integration started we had to re-implement a lot of functions in a way that would allow making multiple actions in one transaction.

It would have taken 5 transactions just to set up an Order at first (create an order template, tell the Order which tokens are allowed for trading, tell the Order which tokens are allowed to be a collateral, deposit funds to the Order which can be borrowed, enable Order).

In the current implementation we managed to reduce the number of transactions where its possible to just approval + action, however when setting up the Order we couldn't separate the step where funds are being deposited to the Order from the initial Order setup.

Also, we've built the monitoring system that will pull data from the contracts (by tracking their state on-chain) and feed it onto UI. The Orders need to be tracked and displayed, positions also need to be tracked as well as their status and liquidation risks. This data needs to be displayed here: https://test-app.dex223.io/en/margin-trading

The backend part of the Orders/Positions state displaying is completed. The current prototype deployed on test-app is unreliable but positions will be properly tracked in the next update.

Margin module: debugging

The margin module is especially hard-to-debug system as its workflow is not straightforward but requires a set of conditions to be met every time a particular scenario is being executed. Each Pool it interacts with must have a specific amount of liquidity, the Oracle must pull the price and respond correctly, transactions must be executed at a specific time because everything is time-sensitive in margin module since it calculates interest based on the timestamp of each last block.

In order to simplify the testing of the contract and allow UI developers to execute particular scenarios in a fixed environment a special contract that simulates a "trader" was introduced:

https://github.com/EthereumCommonwealth/Dex223-contracts/blob/d99da952dfb472762e4c28f62a80202549e46ea8/contracts/dex-core/Dex223MarginModule.sol#L214-L756

That contract does two things:

  1. It sets up a pair of tokens
  2. It makes orders, takes loans, trades and takes profit or liquidates itself depending on what the tester wants from it

Anyone can interact with the "trader contract". The contract is deployed on Sepolia here: https://sepolia.etherscan.io/address/0xBca81278ff25E0BA088fcdFd3E2D798CDC3D2358

It can set up a new Oracle but this one is the most up-to-date one we have at the moment: https://sepolia.etherscan.io/address/0xc569D09E6de44679A2a7f1a31CC82eEB5feA0dC3

Functions called x0_MakeTokens(..), x1_MakePool10000(), x2_Liquidity() set up tokens.

Functions called step1_, step2_, step3_ etc. execute actions.

The default scenario involves:

  1. Make a tokenlist for an Order
  2. Create an Order
  3. Deposit tokens in the Order that was just created
  4. Take a loan from the Order
  5. Make a test margin swap (optional and can be skipped)
  6. Make a normal swap (directly via the Pool, not using the margin module) to slightly alter the price (optional and can be skipped)
  7. Make a swap with significant amount of tokens that pushes the price in the chosen direction - either makes the last opened position profitable or prone to liquidation
  8. Position liquidation or position closing depending on the chosen scenario
  9. Confirmation of the liquidation or withdrawal of the funds

Steps 7-8-9 from different scenarios conflict with each other.

For any early testers we strongly recommend using the Utility contract for setting up your tokens (with functions x0-x2) and making an Order (functions step1-step3). Anyone would be able to take loans from this Orders but in case we will need to investigate a reported problem - we will at least know that the amount of liquidity and Order settings were correct at the beginning.

Margin module: known problems

  • Order creation and funds depositing can't be performed in one transaction.
  • Lender can't specify a "liquidation tax" which would be allocated to cover the price difference in case liquidation does not precisely happen at liquidation price. This feature was planned from the beginning as we expect the lack of precision, especially at low-liquidity pairs.
  • Oracles are far from being reliable. The method of reading data from Pools is heavily affected by the limitations of EVM that we have to combat.
  • Perpetual positions are not yet supported.
  • UI is not completed, most of the tooltips and status handlers are not set yet.

Revenue Contracts

Revenue contracts were built but we don't have a UI that would allow a smooth interaction with them yet. The implementation of the UI will only begin once the margin module UI is ready.

The contract source codes are published here: https://gist.github.com/Dexaran/9601c5369000f20069bb0b54fe7c9357

This version is not properly tested.

UI updates

Most of the UI updates were also related to the margin module implementation.

  • Design system was updated (affects the displayed interactive elements like buttons, dropdowns etc.).

  • The margin module contracts differed from the version we planned at the beginning as we were solving arising problems therefore UI needed to be updated.

  • Particularly Margin Swap UI was updated to display positions that the user is swapping from.

  • Token importing was significantly simplified.

  • Core UI was finalized, missing tooltips and minor bugs were fixed. Now it is production ready: app.dex223.io

  • A new page "Liquidation risks" was added.

  • Remove liquidity and Borrow Market UI templates were updated to account for the latest contracts/Oracles change.

  • Margin swap directly from an Order was added (more on this one in the next report as we are currently working on this feature).

  • Position and Order management was reworked.

  • "Position health status" was implemented as we investigated the design of our competitors and found out that most of the users must be familiar with this term and this method of information displaying.

  • Manual liquidation through UI was created.

The latest Figma templates can be found here: https://www.figma.com/design/8ogeGWWFTcmjUBDWXLlIMU/%F0%9F%94%84-DEX223-Exchange---All-mockups---Current-version--Copy-?node-id=2460-62488&t=uPJgy4R8eJIXHMq7-1

Margin module has its own Figma: https://www.figma.com/design/dcgcSLN3cQKtq3umsEsK0C/Margin-module--Copy-?node-id=0-1&t=BJiFJOPtSyIULLHT-1

ERC-20 Vulnerability state

In 2021 OWASP introduced a new category of vulnerabilities that ERC-20 flaw perfectly fits in - insecure by design.

In 2017 when the ERC-20 flaw was discovered there was no such category and advocating for adding ERC-20 to any common vulnerabilities lists was difficult since the flaw was not actually an "exploitable vulnerability that could lead someone into hacking a contract and directly causing damage" but rather "a way for users to damage themselves when using this system in a common way".

With this new addition we gained a strong argument to advocate for ERC-20 flaw being classified as an actual vulnerability.

The success of the project depends on our ability to make the problem of ERC-20 standard known and recognized. Therefore we will focus on giving this one some exposure outside of crypto-related resources this time.

At the other hand the severity of ERC-20 problems was highlighted in the official Ethereum documentation as the moderators finally approved the pull request into one of the ethereum.org releases ethereum/ethereum-org-website#13218 (comment)

It took about a year of bureaucratic fight to make this happen but finally this is happening.

Once we will have a working prototype of the DEX we are planning to launch a campaign of warning existing projects that use ERC-20 standard (well, almost all projects in the Ethereum ecosystem that should be) about the problems associated with it and the possibility of using ERC-7417 Converter to mitigate them.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment