Put In the Time
Learning the Agoric platform takes time but it's worth it. You should be up for the challenge that comes with new software that's still itself under development. Some features were works-in-progress when I was learning it, as was some of the documentation, but the tools are improving regularly — and I learned a lot in the process. A great thing about Agoric’s bounties is that they are all open source smart contracts: anyone can run the contracts and use them in their own dapp.
I’ve worked on four Agoric bounties thus far, the most interesting of which was the Osmosis-Agoric Arbitrage Bot:
NFT Auction (Modify dapp card store so that the application sells cards in a first price auction, vs at a fixed price as it currently does).
Arbitrage Bot (Build a bot which is able to arbitrage prices between a pool on Osmosis and a pool on the Agoric AMM).
My favorite bounty so far was the arbitrage bot. For that, we created a smart contract to monitor two pools. This meant connecting the Osmosis and the Agoric chain together in a way that supports the bounty specifications.
To accomplish this, we procured coins on one side and then sold coins on the other side for an equal amount. This project had some built-in complexities. For example, precision on Osmosis is 18 decimal digits, but on Agoric it is only 6. I needed the Agoric bot to have the same (higher) precision as Osmosis, because otherwise the bot might fail to make a profit.
After some initial attempts, I decided to borrow the BigInteger implementation from Keplr Wallet. I updated it for the hardened JS environment, and added some functionalities related to nthRoot.
That, however, only solved half of the problem. I also had to use calculus to find the optimal trade amount. It’s all math, and to make the code easy to follow, I had put all the math in the comments to convince myself:
// start code-block /** * buy side B * cIn = (c * sOut) / (s - sOut) * (With fee fB) * cIn = (cB * sOut) / (sB - sOut) * (1 + fB) * * sell side S * cOut = (c * sIn) / (s + sIn) * (With fee fS) * cOut = (cS * sIn) / (sS + sIn) * (1 - fS) * * P = cOut - cIn with note that (sOut = sIn = x) * P(x) = (cS * x)(1 - fS)/(sS + x) - (cB * x)(1 + fB)/(sB - x) **/ // end code-block
That way the code could be straightforward and easy to follow. A lot of math evolved, so to make sure my code is correct, I had to add some debugging utilities, to compare “optimal” profit to its left and right values. It turned out great. In this snippet, after finding the optimal value x, we compare profit(x) with profit(x±1) to be sure:
// start code-block // x is the “optimal” value from above equation const leftX = x.add(oneDec); const rightX = x.sub(oneDec);
const leftProfit = m .mul(leftX) .quo(c.add(leftX)) .sub(k.mul(leftX).quo(f.sub(leftX)));
const rightProfit = m .mul(rightX) .quo(c.add(rightX)) .sub(k.mul(rightX).quo(f.sub(rightX)));
// assert left value, right value smaller than the “optimal one” assert( profit.gt(leftProfit) && profit.gt(rightProfit), 'Something wrong with optimal value', ) // end code-block
For this to work in real life, though, is another story, requiring a much more complicated strategy, but this naive little bot is really interesting demo showing what we can achieve.
I’ve completed these bounties to date, and I would love to do more to learn and to sharpen my skills. Agoric is a great SDK for building smart contracts because of its flexibility and potential. The only limitations are the ones we impose on ourselves.