DeFi Vectors - ICRC-55

Our DeVeFi R&D is funded by the Neutrinomic Foundation, a core contributor to the Neutrinite DAO.

What is a DeFi Vector?

Any canister that doesn’t require clients to send calls to it to process transactions and provide DeFi services. The canister should know what to do with the tokens when it receives them.

Why?
The current flow services use looks like this:


The frontend plays a major role and when errors occur we have to claim our tokens and restart the process. It uses 6 update calls and waits for their responses.
Most importantly when we attempt to use a DeFi service, we have to know the language it speaks - its interface. There are many types of services, such as order book dexes, AMMs, lending/borrowing, staking, etc. Each has its own language.

If we want to compose with these services to build something like this:


The first possible architecture is - An orchestrating service that knows the interfaces of each service it uses and talks to them using the existing flow.
Problems of that architecture - Everything is most probably in one canister - hard to audit and secure if it changes all the time. Developers have to add new services and that may take years. Interfaces change and it will break the flow. Getting a new service inside the orchestrator is not permissionless. The current flow allows for a lot of exceptions to occur we have to catch and handle.

There is another possible flow that doesn’t require us to know the language of each service to use it. The DeVeFi architecture is built on top of it. Simply it ‘subscribes’ to the ledger backlog and finds out if someone sent tokens to it in one of its subaccounts. These subaccounts are assigned to different vector nodes inside the canister and the service executes a predefined DeFi contract sending them ahead to their destination - another node or a wallet.

Benefits:

The biggest benefit of all is composability. To connect to a new service we have to create a vector node inside and configure it (usually with UI), using its custom interface. Then connect other services to it by setting it as a destination. The service that sends tokens to it doesn’t have to speak all possible service languages. We don’t require an orchestrator (While it’s possible to have one still). Someone creating a new DeFi service will be able to connect it to everything existing and build something more complex right away.

A vector node simply has multiple vectors inside which move tokens from source to destination based on the contract. The controllers of these vector nodes can change contract parameters and call actions while they are running.

Before things get complicated - here is a very simple vector node. One canister - one vector node.
When it receives tokens It will distribute them to multiple accounts.

DeVeFi is currently working and developers can build services/components and connect them using this protocol, but to have a UI builder, we will need to make an ICRC standard that facilitates the discovery, creation & configuration of vectors - ICRC55. There is a draft in the next repo and a node factory:

Advanced vector node factory. One canister - many vector nodes.
When it receives tokens it will periodically send them to a destination.
[devefi/example/basic.mo at main · Neutrinomic/devefi · GitHub]

Neutrinite’s exchange vector factory in production
[GitHub - Neutrinomic/defivectors]
UI here: https://vectors.icpcoins.com
Video demo of how it works: [https://www.youtube.com/watch?v=4rcROMDgDg4]

Mops packages:
devefi (makes connecting to multiple ledgers easier, uses devefi-*-ledgers)
devefi-icrc-ledger
devefi-icp-ledger
rechain - Redux like pattern + ICRC3 logs

DeFi WG repo with ICRC standards: GitHub - Neutrinomic/wg_defi

Discussions: DeFi WG (every tuesday) In Discord ICP Developer Community

Previous post: ICRC-55 DeFi Vectors

13 Likes

You can create test throttle vector from the open-source vector factory example, send NTN tokens to the vector and get them back slowly.

3 Likes

Will this address some of the issues I mentioned in this thread?

1 Like

Yes, it will help with liquidity management. The best way of managing liquidity with it would be to set up your vectors so you don’t have to do any manual swaps multi-routed or not - ever again.

But yes, it can also work for manual swaps where an app creates temporary vectors that swap in 4-5 pools simultaneously.

2 Likes

What part of this would be standardized? I believe there’s not draft for ICRC-55 yet. Wondering what exactly is in scope for it and what isn’t.

2 Likes

Trying to create a draft by working simultaneously on the builder and a framework that produces vectors. devefi/src/ICRC55.mo at main · Neutrinomic/devefi · GitHub
We will create a few vectors, get the builder working and see what’s needed, then iterate over that to improve it.

I was thinking it could also work with other ledger systems, like the HPL or why not Ethereum and Bitcoin. But I think it’s best if ICRC55 is for ICRC ledgers only and if we want to include others, there can be another standard for that. The UI builder can then add these other standards as well.

Ethereum components like Uniswap are definitely interesting. All such components will be canisters on the IC that communicate with other blockchains. Then we could connect a dex on the IC to ckEth Minter to Uniswap and back

1 Like

Actually… scratch ICRC ledgers only. Instead of having the Endpoint
{ ledger : Principal, account: Account }
it could be
{ network: Nat; ledger:Blob; address : Blob }
and it should allow all

New devefi framework release.
We’ve moved a lot of the functionality inside the framework.
Creating vectors, doing refunds, returning tokens on vector deletion, returning tokens in case of sending them to non existing vector etc.
Notice how create_vector has no “await” while accepting payments.

1 Like

A lot of new changes in the framework. It is almost complete, along with the ICRC55 standard.
Mops published.
New blast, old one won’t work: [https://jglts-daaaa-aaaai-qnpma-cai.ic0.app/864.0a89d7091ca4aea28b7838a857d65ed7e804a25ba917d4f92a344da5]
When trying it out, devs should start by copying all files from the /example/ directory, much easier to start from somewhere.

3 Likes

Are you still working on the HPL?

1 Like

This is truly amazing.

1 Like

Thanks for your interest. I was recently asked the same question and so will link to the answer so as not to hi-jack the DeVeFi thread with it: Annoucement: HPL - a ledger for 10k tps - #86 by timo
The answer now is still the same as given there 28 days ago.

1 Like

The DeFi Vectors framework we are making works with the protocol - ICRC-55 (draft) and relies on our middleware to communicate with ledgers. They are abstracting away async ledger calls and instead synchronizing in the background.

Once Bob.fun came around - thousand of canisters happened to come to the subnet we picked for DeFi vectors, to do mini Bitcoin-like mining. And we are happy they picked that subnet! That helped us make the middleware better already.
Our systems are designed to handle that - work during heavy loads and there are 100s of tests and multiple projects and canisters using the middleware.

There was an incident however. The following code didn’t work as we expected:
image

It was supposed to loop forever, except either the call awaited never returned or the setTimer failed when the subnet was under load. The loop stopped, reading ledger backlog and sending transactions stopped. No tokens got lost, since once it resumed the middleware starts from the block it is at and the queue with transactions is in memory.
Either way, we have solved the problem by using Timer.recurringTimer instead and new versions of devefi-icrc-middleware and devefi-icp-middleware are out (1.4.0) And also vectors.icpcoins.com is updated with the same solution.

You can see how the new middleware works like. A pretty delicate piece of machinery and everything is there for a reason. Contributions are welcome, it is MIT licensed.

Reader [devefi_icrc_ledger/src/reader.mo at bf844ed31243775a7599a9aae7bb1e63e801a620 · Neutrinomic/devefi_icrc_ledger · GitHub]

Sender [devefi_icrc_ledger/src/sender.mo at bf844ed31243775a7599a9aae7bb1e63e801a620 · Neutrinomic/devefi_icrc_ledger · GitHub]

We chose to use setTimer instead of recurringTimer because recurringTimer can lead to concurrency issues when calling functions that contain await. To address this, we’re implementing a thread lock with a timeout and adding internal checks to ensure that no older calls are processed after the lock has expired.

Looking forward for the new challenges Bob.fun will bring to the subnet and our systems. Will happily keep our canisters in there to make sure they work in the worst conditions.

3 Likes

Might be worth looking at TimerTool - a robust timer layer for motoko. It handles timers that have an async function and provides a time out. When the time out occurs you receive info about the task that failed and have the option to reschedule it or not. The may be better to make sure that tasks don’t step on each others feet if the recurrence is initiated before the previous task ends.

3 Likes

I think I am getting the hang of it.

Does the vector trade at the market price of ICPswap and other dexs, or does it trade at the LP exchange rate?

Greetings, thanks for the question.

Neutrinite exchange vectors use DEX prices from the Neutrinite DeFi aggregator when it comes to pairs with tokens that are not in CEXes. BTC<->ICP<->USDC use the Exchange Rate Canister (XRC)
The DeFi aggregator usually takes DEX pair prices from ICPSwap. They are visible in icpcoins.com