Skip to content

Proposal: Making liquidity provision a first class citizen in the smart contracts #744

@josojo

Description

@josojo

Liquidity provision seems to be so important for a number of use-cases. It's a shame that it is soo gas expensive and so cumbersome and that we can't build pools on the current protocol.

Imagine the liquidity provision could be done with one account instead of 1 account per bracket. That would make withdraws and deposits so much cheaper and the order placement as well.

The following proposal describes a technical solution for this scenario:

In this scenario, users should place the same orders, currently placed by our brackets-strategy, in one validFromOrders tx plus a bool flag indicating that this account is in the bracket-strategy mode.
All orders from these accounts must be sorted so that the orders at index 0,1 would be the same as the bracket trading at the lowest price, and the orders at index n-1, n would be the same as the bracket trading at the highest price, if n orders are placed from one particular account.

Then the smart contract could calculate automatically during the solution submission, minimal balances of sellTokens, that the account would need to have in order to allow the i-th order to be touched, just as shown in this sheet:
https://docs.google.com/spreadsheets/d/10Et3GeH97ovyAyVaus04YLUFXI1uzimQCD16EkmyHLM/edit?usp=sharing

An example is: if the bracket with the index 1 - bracket -9 - is touched by selling DAI for ETH, then after the sell is complete, at least 1005 DAI still needs to be in the account. If this would not be the case, then this order should not be touched. This prevents that the same order is touched several times unless the account balance was refilled with trade selling the opposite token.

On the other hand, if we are selling ETH for DAI, we are checking that enough ETH is still in the account after the i-th order is processed.

This logic could be checked in the smart contract very easily during the solution submission like that:

// Perform all subtractions after additions to avoid negative values
        for (uint256 i = 0; i < owners.length; i++) {
            Order memory order = orders[owners[i]][orderIds[i]];
            (, uint128 executedSellAmount) = getTradedAmounts(buyVolumes[i], order);
            subtractBalance(owners[i], tokenIdToAddressMap(order.sellToken), executedSellAmount);
            if(isBracketAccount(owners[i])){ <-- here starts the new code
               unit totalValueInSellToken=calculateSellTokenValueOfAccountWithCurrentAuctionPrice(...)
                require(balanceOfOwner(owners[i], sellToken)>=orderIds[i]/lengthOfOrders(owner[i])*totalValueInSellToken, "bracket order was not allowed to be touched")
             }. <-- here ends the new code
        }

Probably, there are much smarter ways to do it. But maybe it is worth thinking in this direction...
I think this feature is a hard requirement for implementing pools, as currently deposit transactions for 20 brackets cost 6 m gas.


Update:
instead of placing the orders directly by the account, we could also allow users to only specify the highestLimitPrice, lowestLimitPrice and number of simulated orders, and then we can calculate the actual order price during the solution submission.

order_limit_price = lowestLimitPrice + (highestLimitPrice- lowestLimitPrice) * index/#orders

This would allow us to place with one transaction 1000 order for a pool, and hence a rediculous low spread. If we pool enough funds into one pool, then even a higher amount of orders might even become economically viable.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Version2Proposals for the version 2 contract

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions