At Part 1, I wrote about Flow Open World Builder(OWB) program I have been participating. In the 2nd part of this series, I will go into a dit deeper into the code by explaining the UniSwap clone I made for their capstone project.
My code is a port of “The Minimum Viable Exchange” blog post by Austin Griffith so I will use his Solidity code to compare. I highly recommend you read his blog post before diving into this blog post.
AMM(Automated Market Maker) is a decentralised exchange without counterparty. Users can instantly exchange tokens based on the price calculated by the smart contract. Each AMM (Uniswap, Bancor, Curve, etc) have a different formula, but Uniswap uses the simplest formula called
In the nutshell, the
k is called an invariant because it doesn’t change during trades. (The
k only changes as liquidity are added.) The curve shows the intuition that the bigger amount one token is sold over the other, the bigger price fluctuation occurs(aka “slippage”).
In Austin’s Solidity code, it shows like this.
And here is my Cadence code
Apart from a minor difference of how I name the variable, it’s almost identical. The big difference is that Cadence allows floating-point whereas Solidity doesn’t. This may feel a trivial difference but let’s not forget that the demise of YAM protocol occurred by forgetting to divide after multiply to work around the lack of floating-point.
Trading between pairs in Solidity is as follows.
It’s not difficult but a bit harder to read the flow of the money transfer. This is because
eth is an internal currency of solidity expressed with
msg.value whereas Token transfer is defined by ERC20 standard so the interface is completely different. You need to be constantly aware that people can just send ETH and you have to explicitly reject it if you don’t want that to happen. I didn’t take that into consideration so I hit a minor bug when I integrated DAI into Kickback and ended up redeploying the contract code (wasted around $30 worth of gas which doesn’t seem a lot now due to the yield farming craze now but that was a lot back in 2019).
[BUG] ETH can be stack on DAI party · Issue #35 · wearekickback/contracts
Summary GIVEN a user has 10DAI on their wallet AND the user has 10ETH on their wallet AND the user manually do…
And this is the equivalent Cadence code.
I am still uncertain about their internal currency Flow because I don’t own any and you can still deploy it without paying gas to its flow emulator. According to their Fungible Token tutorial, Flow token acts exactly the same as any other tokens, making the code more straight forward.
One unfamiliar syntax is
<- . In Cadence, there is a notion of so-called “Resource” which you define as follows.
Instead of assigning these values using
= , you always have to use
<- to express that the resource is transferred from one place to another. If you don’t either explicitly destroy, return or save into storage space (Unlike Ethereum, in Cadence all smart-contract and its data are stored into each user’s account), the VS code shows
loss of resourceerror.
Sorry, I didn’t implement it.
I literally copied and pasted the curve graph. As our contract interface was pretty much the same, it did work with minimum changes.
As a newly developed language, tooling is definitely still lacking. The third-party company such as TryCrypto has been developing “Select and Generate” style easy boiler plating toolset similar to Truffle.
For our capstone project, I wanted to experience the metal of the language so I decided to use their Go SDK and
go-flow-tooling the library developed by 0xAlchemist who is also participating in the OWB program (yes, some people are developing tools as they learn!).
I am not sure about your deployment contract, but my ENS deployment and test seeding contract are massive (nearly 1000 lines).
As explained in Part1, this can be massively simplified on Flow as you can write the interaction of smart-contract using Transaction. Here is one example.
I don’t explain every single detail but you may see something like
This is because every time you deploy a new contract, you save it under the storage of your account. When you use contracts stored in either yours or someone else’s, you have to explicitly define which capability is accessible to the public (and which is kept private), and have to provide a link so that you can later borrow the capability,
TBH, this notion of handling resource and capability is still something I can’t get my head around. It is frustrating to prototype something when I don’t care so much about the security but I am guessing this is the trade-off of making a secure contract.
I’m glad that you read this far. My source code is at https://github.com/makoto/alley-oop. TBH, I am sure that there are many things I am doing it wrong so not the code to use as a reference. Instead, I suggest you go through their series of tutorials which is really good!