An Actual Sigmoid Function in Solidity
Breaking past theories and creating an actual implementation in a smart contract
Token bonding curves have been a topic of interest lately within the crypto space, especially with the growth in DeFi & NFTs. With more and more projects implementing some sort of price curve for Automated Market Makers (AMM) or ICOs, people are becoming more creative in the way they choose to price their tokens.
We’ve all heard about linear curves, power functions and inverse graphs, which some of the famous protocols like Uniswap and Bancor use. However, an interesting type of curve has also been discussed, the Sigmoid function. Although it has appeared in a few articles discussing its use case and practical applications, I have yet to discover any smart contract actually implementing it.
What is a Sigmoid Function?
For those who are unaware, a Sigmoid function has a characteristic of an “S”-shaped curve, as shown above. The most common implementation uses a logistic function, which looks like this:
However, I chose to go for the algebraic function, for a number of reasons:
Where:
a = the height of the curve (or maximumPrice/2)
b = the token supply at the inflection point happens (aka midway point)
c = the steepness of the curve
The Benefits of an Algebraic Sigmoid Function
First, this function is highly customizable. We can manipulate the values a, b and c to shape our Sigmoid function as we like. You can view an interactive example here! I am by no means a Math god, and this function was actually thanks to an article that I found, so all credit goes to Slava for the materials!
Besides that, this function is easier to perform integration on, which will be handy in the future if anyone attempts to do so. However, I must note that I was only interested in using the point on the curve as the price function, and not the area.
The Challenges
Everything in life has its pros and cons. As some might realize by looking at the function above, we have a square root. Square root in Solidity is rather challenging to compute. This is due to the fact that Solidity does not handle floating point numbers. To overcome this issue, I had to implement an arbitrary fixed point decimal system in the contract. In simple terms:
We can have an arbitrary fixed point decimal system that takes 5 decimal points. This basically means: DECIMAL POINT GOES HERE
|
v
123456789 = 1234.56789
1234567 = 12.34567
Hopefully the example above is clear enough to help you guys understand. Thankfully, as I was developing this system, I landed across a library called FixidityLib that coincidentally a friend of mine @obernardovieira helped create! 🤯
FixedMath.sol
I drew some inspiration from FixidityLib and developed a library of mine called FixedMath.sol. It is by no means a fully complete library for fixed point math in Solidity, however, I’ve implemented a square root function which works pretty well using the Babylonian method. (Now I’m starting to think I should call my library another name 😂)
The Babylonian method is rather simple. Start by approximating a number (X₀) which will be used to derive the next approximate number. Then, the process is repeated using the new approximate number each time until you reach a point where the new approximate number is the same as the old one. It is honestly a rather genius solution if I might say so myself. You can read more about it here if you’re interested. That basically sums up the challenge of implementing a Sigmoid function in Solidity!
Application
I probably should have started the article about why I chose to embark on this challenge, but I figured that more importantly, most people would want to know how this was done. Anyways, here we are now with why I started this. Why specifically a Sigmoid function?
I’m working on a project called Decentramall that started during the HackFS hackathon. The idea of the project was to allow people to buy a SPACE token which gives the owner the right to open a store on our platform, or rent it out to earn some returns. We decided to have a hard cap of 1200 SPACE tokens, which if the price was based on a quadratic curve, would look and behave very oddly. We thought that a Sigmoid function would be way more rewarding for early adopters as the price will increase rapidly after a certain point, but still benefit late comers as they won’t be paying some absurd price for it. Furthermore, when I first learnt about the algebraic Sigmoid function that was shown above, I really liked how customizable it was, allowing us to mess around with the values to shape our curve as we like. Also, I just wanted to challenge myself to see what I can create with Solidity.
I’ll be writing an article on the project rather soon, and will link it here when its ready! For now, you can view the code and contracts on GitHub! If you’ve seen any projects that use a Sigmoid function, please do share it with me! I’ll be interested to learn what I can improve on and optimize in the future versions! 😄 Overall, it was a great experience messing around with decimal numbers and square root functions in Solidity. 💪