Defillama is now tracking @rainprotocol on @base, @LineaBuild, @0xPolygon, @BNBCHAIN, @arbitrum & @FlareNetworks
Links:
Defillama is now tracking @rainprotocol on @base, @LineaBuild, @0xPolygon, @BNBCHAIN, @arbitrum & @FlareNetworks
Links:
Efficient market making is crucial for providing liquidity and stabilizing token prices. Raindex offers a powerful toolset for deploying bespoke market making strategies that can dynamically respond to market conditions.
These strategies are:
One such strategy is the Recharging Grid Strategy, which ensures continuous liquidity and effective price discovery through an innovative recharging mechanism.
The Recharging Grid Strategy involves setting firm prices for batches of tokens, known as "tranches." These tranches form a stepped price curve, which can be used to manage buy and sell orders programmatically. The strategy stands out due to its ability to "recharge" tranches, meaning that as each tranche clears, more tokens become available at predefined prices. This recharging mechanism allows the strategy to adapt to market movements and maintain liquidity over time.
Key features of the Recharging Grid Strategy include:
For a detailed explanation of how the Recharging Grid Strategy works, including its parameters and configuration options, you can refer to the strategy documentation.
In this blog post, we will guide you through the process of deploying a market making strategy using Raindex, specifically focusing on the Recharging Grid Strategy. Whether you are a trader looking to capitalize on market volatility, a market maker aiming to provide continuous liquidity, or a token issuer managing your treasury, this strategy could be for you.
Use the recharging grid strategy.
In this strategy I sell wFLR when it is greater than $0.03 and buy when it is less than $0.03 and I can set increasing sell/buy sizes as the price diverges from the starting point.
This is a great treasury management or token management strategy for believers in Flare.
The strategy works well while the token price is initially ranging around $0.03 and I've got capital to deploy or tokens to liquidate as it diverges significantly.
First I go to Raindex pubstrats and fork the tranche grid strategy.
Then I enter the network details, in this case Flare. I label each parameter so these don't conflict with my app settings.
networks:
flare-tranche:
rpc: https://rpc.ankr.com/flare
chain-id: 14
network-id: 14
currency: FLR
subgraphs:
flare-tranche: https://subgraphs.h20liquidity.tech/subgraphs/name/flare-0xb06202aA
orderbooks:
flare-tranche:
address: 0xb06202aA3Fe7d85171fB7aA5f17011d17E63f382
network: flare-tranche
subgraph: flare-tranche
deployers:
flare-tranche:
address: 0x550878091b2B1506069F61ae59e3A5484Bca9166
network: flare-tranche
tokens:
flare-wflr:
network: flare-tranche
address: 0x1D80c49BbBCd1C0911346656B529DF9E5c2F783d
flare-eusdt:
network: flare-tranche
address: 0x96B41289D90444B8adD57e6F265DB5aE8651DF29
Then I enter tokens I want to trade. In this case it's wFLR and eUSDT. I get the contract address either from the Raindex pubstrats or from Flarescan. Note I can have a basket of tokens not just a pair.
tokens:
flare-wflr:
network: flare-tranche
address: 0x1D80c49BbBCd1C0911346656B529DF9E5c2F783d
flare-eusdt:
network: flare-tranche
address: 0x96B41289D90444B8adD57e6F265DB5aE8651DF29
I put up my buy and sells with the relevant orderbook and my vaults. I can deposit and withdraw tokens into this vault after my order is deployed.
orders:
# vault-id generated with `openssl rand -hex 32`
flare-tranche-buy:
orderbook: flare-tranche
inputs:
- token: flare-wflr
vault-id: 0x562bd75e19e548420f9f3da43a7d7d67c6344580256b952c9214192c445d6043
outputs:
- token: flare-eusdt
vault-id: 0x562bd75e19e548420f9f3da43a7d7d67c6344580256b952c9214192c445d6043
flare-tranche-sell:
orderbook: flare-tranche
inputs:
- token: flare-eusdt
vault-id: 0x562bd75e19e548420f9f3da43a7d7d67c6344580256b952c9214192c445d6043
outputs:
- token: flare-wflr
vault-id: 0x562bd75e19e548420f9f3da43a7d7d67c6344580256b952c9214192c445d6043
I set up the parameters that are consistent across both buy and sell scenarios (to learn more about these read the reference). These include:
scenarios:
flare-tranche-tranches:
network: flare-tranche
deployer: flare-tranche
orderbook: flare-tranche
bindings:
uniswap-words: 0xb1d6D10561D4e1792A7c6B336b0529e4bFb5Ea8F
orderbook-subparser: 0xF836f2746B407136a5bCB515495949B1edB75184
tranche-space-per-second: 11574074074074
tranche-space-recharge-delay: 300
tranche-space-shyness: 9e17
min-tranche-space-diff: 1e17
tranche-space-snap-threshold: 1e16
io-ratio-multiplier: '''io-ratio-multiplier-identity'
Specific scenarios for buying wFLR including base price, growth rates for tranche prices, tranche amounts and growth rates. Here we also define the simulations and later the chart details.
scenarios:
buy:
bindings:
amount-is-output: 1
io-ratio-expr: '''linear-growth'
io-ratio-base: 33e18
io-ratio-growth: 3e18
tranche-size-expr: '''linear-growth'
tranche-size-base: 10e18
tranche-size-growth: 1e18
scenarios:
initialized:
bindings:
initial-tranche-space: 0
scenarios:
prod:
bindings:
get-last-tranche: '''get-last-tranche-prod'
set-last-tranche: '''set-last-tranche-prod'
plottables: '''plottables-prod'
test:
runs: 100
bindings:
get-last-tranche: '''get-last-tranche-test-init'
set-last-tranche: '''set-last-tranche-test'
plottables: '''plottables-test'
test-last-update-time: 0
test-now: 0
test:
runs: 10000
bindings:
get-last-tranche: '''get-last-tranche-test'
set-last-tranche: '''set-last-tranche-test'
plottables: '''plottables-test'
max-test-tranche-space: 20e18
test-last-update-time: 0
test-now: 0
The first chart section tells us viusally what our strategy is doing. Here it is showing me that:
This aligns with my expectations which means I can move forward.
The second chart section tells us visually what our strategy is doing based on running simulations on my device. We fork the blockchain and then simulate according to the parameters in the strategy. Here we can see we've selected 10,000 simulations with a max tranche space of 20, so we only simulate 20 tranches.
The first chart shows us that we purchase 330 FLR in the first tranche, and then that we increase the amount of FLR per tranche, purchasing approx 2,500 FLR at tranche 20.
The second chart (io-ratio) shows the number of FLR purchased per USD spent, which also increases in a stepwise fashion as designed.
The third chart shows that we spend an increasing amount of USD per tranche, which makes sense as we want to buy more FLR as the market drops.
The fourth chart shows the price we are paying for 1 FLR in USD, which shows a decrease in price per FLR as our tranches increase.
The fifth chart shows our starting tranche:
Specific scenarios for selling wFLR including base price, growth rates for tranche prices, tranche amounts and growth rates. Here we also define the simulations and later the chart details.
sell:
bindings:
amount-is-output: 0
io-ratio-expr: '''linear-growth'
io-ratio-base: 3e16
io-ratio-growth: 1e16
tranche-size-expr: '''linear-growth'
tranche-size-base: 10e18
tranche-size-growth: 1e14
scenarios:
initialized:
bindings:
initial-tranche-space: 1e18
scenarios:
prod:
bindings:
get-last-tranche: '''get-last-tranche-prod'
set-last-tranche: '''set-last-tranche-prod'
plottables: '''plottables-prod'
test:
runs: 100
bindings:
get-last-tranche: '''get-last-tranche-test-init'
set-last-tranche: '''set-last-tranche-test'
plottables: '''plottables-test'
test-last-update-time: 0
test-now: 0
test:
runs: 10000
bindings:
get-last-tranche: '''get-last-tranche-test'
set-last-tranche: '''set-last-tranche-test'
plottables: '''plottables-test'
max-test-tranche-space: 20e18
test-last-update-time: 0
test-now: 0
The first chart section tells us viusally what our strategy is doing. Here it is showing me that:
Again this lines up with my expectations.
The sell chart simulation is the same as the buy chart simulation, except that it covers selling, not buying wFLR.
The first chart shows our starting tranche.
The second chart (io-ratio) shows the number of FLR sold per USD spent which also increases in a stepwise fashion as designed. Here we are selling more FLR per USD as the FLR price increases.
The third chart shows that we spend the same USD per tranche. We may also consider a strategy where we sell more USD per tranche as tranches increase either linearly or exponentially.
The fourth chart is the same as io-ratio, and shows our effective price per tranche.
The fifth chart shows the number of FLR we sell per tranche.
Using Raindex I added the orders and then funded the vault.
You can see the orders:
0x5259dd5154f7d8478cb395cd5b7c2e574384ded28872712a185336e2e2f84915 0x8f5fd9e9ea6015d9939818828184ee9811ca10035cf28e71d64b17a79022102c
Decimals are now the default type of number in Rainlang.
What does this mean?
Until now there was no default type of number. We were totally agnostic to whether some number was an integer or a decimal.
We put the responsibility of deciding and tracking when to use what in their code back on rainlang authors.
As you might expect, this was easier to implement in the language, and made writing Rainlang more difficult.
Philosophically, that's the opposite of what we want in a language that is supposed to be easy to understand and use. So now Rainlang is opinionated and treats everything as a decimal by default.
All Rainlang in the wild that contains math will include some combination of math functions like:
decimal18-mul(2e18 5e17)
=> translates to 2 * 0.5
as decimal values
int-mul(2 5)
=> translates to 2 * 5
as integer values
This is confusing and error prone for several reasons:
block-timestamp()
provide integer values, but you'll
most likely want to do decimal math with them in practiseIn the latest version of Rainlang, almost all math words look like:
mul(2 0.5)
=> equivalent to the old decimal18-mul(2e18 5e17)
.
For anyone who really wants the old integer math behaviour, there are some words
available as uint256-*
such as uint256-mul
but their use is discouraged
generally. Where you would have previously raised something 18 decimals to work
with decimal math, you now scale something by -18 decimals to work with integer
math.
For example:
uint256-mul(2e-18 5e-18)
=> equivalent to the old int-mul(2 5)
.
To achieve the above there are 3 key changes that all compatible language contracts need to respect:
1
and 1.5
are scaled by 18 orders of magnitude to
their internal representation in the EVM. E.g. 1
literal is 1e18
onchain.decimal18-*
prefixed words no longer have any prefix and so are treated
as the default way to handle all numeric values.block-timestamp()
and
chain-id()
are now scaled up 18 orders of magnitude to return compatible
decimal values.The overall impact is that beginner and intermediate Rainlang authors will probably never even be aware of the mismatch between high level Rainlang decimals and low level EVM integers.
These changes also need to extend to the context grid, such as the one provided by Raindex. Older versions of Raindex will continue to be compatible with the current version of Rainlang, but for the smoothest experience all vault balances will be pre-scaled to decimal values in the near future, with some opinionated rounding behaviours.
If you want to understand why there are decimal and integer values in the first place, you need to understand what a number is onchain.
The EVM (Ethereum Virtual Machine) almost exclusively deals with data in 32 byte chunks. When you save, load, multiply, add, etc. any data, it's usually 32 bytes at a time. This makes gas calculations much simpler, there can be a flat cost for each thing you might want to do, per 32 bytes.
So every number is 32 bytes, which is 256 individual 1's and 0's in binary.
The default of the EVM for all the native blockchain words, is to treat these numbers as unsigned integers. This means no negative numbers, and no decimal numbers.
If you wanted to get the current block number for block 1
it would give you
0x0000000000000000000000000000000000000000000000000000000000000001
.
Very early on in Ethereum's history developers realised this is not good enough for things like tokens.
Say you had $1 and you wanted to send $0.5 to someone. Well this is impossible
if 1
is 0x0000000000000000000000000000000000000000000000000000000000000001
.
There is simply nowhere to put a number smaller than 1
in this representation.
In practise what happens is that all math rounds down to the closest integer, so
sending $0.5 would send $0, which is not a satisfying outcome.
To make matters worse, everything onchain costs gas, so if some more complex approach was going to be proposed then it would literally cost more gas the more complex the idea. Complex math is not very popular when the network is highly congested and people are spending $10-100+ per transaction.
The most common solution is to simply treat 1e18
(that is, 1 with 18 zeros)
as "one" by convention and then create onchain math libraries that figure out
all the implications of that. Rainlang uses the prb-math
library under the hood for this.
This means that if you want to send 0.5 DAI to someone, you are sending them
5e17
DAI. This costs a bit more gas to do the more complex decimal calculations
but means that people can send $0.5, so overall it's worth it.
But now we have a social layer problem. This 18 decimal fixed point
representation of numbers is only a convention. It isn't even a convention that
tokens follow consistently. The ERC20 specification allows for any fixed point
representation of a token, for example Tether treats 1e6
as "one" instead of
1e18
. The specification also explicitly states that it is optional for tokens
to even self report what their own convention is, making it impossible to
implement a reliable generalized onchain conversion.
decimals Returns the number of decimals the token uses - e.g. 8, means to divide the token amount by 100000000 to get its user representation. OPTIONAL - This method can be used to improve usability, but interfaces and other contracts MUST NOT expect these values to be present.
So the summary is that Rainlang is forced to exist in a world where beginners
will write in 1
into a text editor and expect it to equally mean "one second",
"one DAI" or "one USDT", while the reality is all three things are totally
different onchain. That's the problem that we're attempting to solve here.
As with all Rainlang versions, there are no admin keys or DAOs, so everyone has to upgrade for themselves if/when they want to.
Pragmatically in the Raindex app this means configuring a new deployer in their settings.
At the time of writing we haven't yet fully deployed the changes to every network and sub parser, but it will be rolled out and announced in all the usual channels as we go.
🚨 The competition closes 4 June at midnight UTC - submit your entry here 🚨
To celebrate the release of the Raindex app and deployment on Flare, we’re launching a trading strategy competition with $12,000 worth of FLR in prizes.
Whether you’re new to decentralized finance or a seasoned strategist, this competition is a platform to innovate, impact, and get inspired.
Rainlang is a new, onchain language that is the native language of DeFi. It’s designed to be far easier to write than Solidity - if you can write spreadsheet formulas you can probably learn Rainlang.
Why is this important? Raindex gives you the flexibility and power usually associated with CEX trading or running bots, whilst retaining the attributes we’re all here for - it’s trustless, permissionless and decentralised. It empowers users to craft and execute trading strategies without intermediaries. It’s also completely onchain, which means users don’t need to put their funds in someone else’s hands or put their hot wallet private keys in a bot connected to the internet.
Why Flare? Flare offers a unique trust model for the oracles on their network as the data availability and integrity is provided by the validators themselves. Raindex exposes these oracles directly to traders, without needing devs. The Flare Time Series Oracles (FTSOs) words are available in Raindex, to use in your strategies.
To enter the competition you simply need to create your strategy then deploy it on the Flare network. Entries should focus on robustness of the strategy and market adaptability to stand out in the competition.
There will also be a prize specifically for technical writing, judged by Rareskills, the leading web3 educators. Submitting for this prize will also put you in the running for a full-time technical writing job with Rareskills.
Support will be given to all entrants to learn Rainlang and get their questions answered. Best of all, you get to participate in a community dedicated to pushing the boundaries of DeFi.
1st prize - $5000
2nd prize - $2000
Best use of Flare Time Series Oracles (FTSOs) - $2500
Best technical writing - $2500
First and second prizes will be judged on overall quality, keeping in mind the following criteria:
The FTSOs are decentalized oracles secured by the Flare validators. You can pull FTSO prices into your strategy by using the FTSO words in Rainlang. This prize will be awarded to the strategy with the best use of the FTSOs.
RareSkills is the leading resource for advanced blockchain education. Rainlang is a new language, so there isn’t much documentation yet. This is where you come in! The best written technical article for a strategy will win this prize, the winner will also be eligible for a writing job with RareSkills. Suggestions on how to make your writing stand out are given here: https://www.rareskills.io/post/technical-writing-checklist
David is an experienced developer, long time trader and inventor of Rainlang.
Thanos, a DeFi analyst, leverages his extensive experience trading on-chain primitives to fortify the decentralized finance ecosystem on Flare.
Jeffrey is the founder of Rareskills, has a passion for education and is an experienced developer in his own right. The RareSkills blog has significantly influenced major projects in the web3 space.
Rainlang is a pioneering project that has created a new programming language for DeFi and a new DEX, RainDEX.
We're looking for experienced developers who share our passion for decentralization and innovation, and want the experience of being part of the early team working on one of the most unique things in DeFi.
Rainlang is defi’s native language, it’s an onchain language, parsed and interpreted by smart contracts. It’s compatible with any EVM and permissionlessly extensible.
Raindex is a standalone desktop app built with Tauri, that allows anyone to write, deploy and manage token trading strategies, written in Rainlang.
Our team is spread across the world, from the US to India. We are founded by three Australians who are now based in the UK and Tbilisi:
Our ideal candidates are deeply ingrained in the culture and technology of decentralized finance. This is not just a job; it’s a call to those who want to be at the forefront of financial technology innovation.
We look for the following attributes:
Our approach is centered around creating secure, reliable, and efficient software for decentralized finance. Here's how we ensure our standards and practices meet the challenges of the industry:
Location: Remote Job type: Full time
We are looking for experienced Rust developers who want to help create Rainlang tooling and applications.
You'll have experience working with concurrency in Rust as a lot of what we are doing is fairly compute intensive but parallelisable. Bonus points if you have worked with Foundry, as we are using it as a crate for various tasks such as forking blockchains locally for fuzzing/simulations in the DEX.
Location: Remote Job type: Full time
We are looking for front end developers who have good experience with Typescript and front end frameworks, ideally Svelte.
You'll have experience with front end web3 frameworks like wagmi, as well as the idiosyncrasies of dealing with DeFi front ends (transaction updates, decimals handling for token amounts, etc).
Send your resume to josh@rainlang.xyz
Today we’re excited to share the first release of our open source desktop app for our Rainlang powered DEX protocol, imaginatively named Raindex.
Raindex allows anyone to write, deploy and manage perpetual token trading strategies, written in Rainlang, on any EVM network.
We’ve also created an extension to Rainlang, available only on the Flare network, that allows any strategy writer to use the Flare Time Series Oracles (FTSOs) directly within their strategies.
The culmination of three years of dedicated development, the Raindex app gives you the flexibility and power usually associated with CEX trading or running bots, whilst retaining the attributes we’re all here for - it’s trustless, permissionless and decentralised. It empowers users to craft and execute Rainlang strategies without intermediaries, blending the best of both worlds.
How does this look in practice?
This is a totally new kind of DEX, where traders can move past "one size fits all" AMM curves and be given total freedom in how they express their trades. It’s also completely onchain, which means users don’t need to put their funds in someone else’s hands or put their hot wallet private keys in a bot connected to the internet.
This is a community launch, so for now the contracts are unaudited. Use at your own risk and as always, please DYOR.
What can you do with the app?
As of today you can use the app to:
There’s a few layers of the stack that have come together to make this happen:
We see Rainlang and Raindex going far and wide, but it’s early days and therefore our first users are early adopters. For now, what does a Raindex user look like?
Rainlang is the native language of DeFi. If you can write an Excel formula, we think you can learn to write Rainlang.
Rainlang is:
using-words-from flare-sub-parser
/* ensure that the cooldown time has elapsed since the last trade */
:ensure(
greater-than-or-equal-to(
block-timestamp()
int-add(get("last-traded") 43200) /* 12 hrs in seconds */
)
),
/* getting a quote from the Flare FTSO */
max-output: 100e18,
price: ftso-current-price-pair(‘USD’ ‘WFLR’ 3600),
:set("last-traded" block-timestamp());
The above Raindex order buys $100 worth of WFLR every 12 hours, at the current price returned by the Flare Time Series Oracle (FTSO). If you don’t think you could’ve written it yourself, at the very least you can probably understand it and maybe even tweak it to suit your purposes.
What other kinds of strategies can you run? Pretty much anything you can imagine… That said, we have a few ideas:
As you may have noticed in the example above, we’re using the Flare FTSOs to make sure our order is always offering the up-to-date market price for FLR. This is a subparser available only on Flare and an example of new words can be added to Rainlang, totally permissionlessly. We’ll be further extending this subparser with new words for EMAs, bringing even more power to those writing strategies with Raindex.
Why is this cool? Flare offers a unique trust model for the oracles on their network as the data availability and integrity is provided by the validators themselves. Raindex exposes these oracles directly to traders, without needing devs.
The Flare FTSO words are not only available in Raindex, but anywhere Rainlang is being used. Anybody building DeFi products with Rainlang can use these words.
If you’d like to get started, check out our first videos, where you can learn how to deploy your first strategy.
If you need support or have any questions, @thedavidmeister, @dcatki or @highonhopium are always in the community Telegram group.