oceanprotocol-archive / bounties

🎣 Bounties for Ocean Protocol
Apache License 2.0
11 stars 0 forks source link

Bounty : Bonding Curves UX #3

Closed innopreneur closed 5 years ago

innopreneur commented 5 years ago

Bonding Curves UX bounty

How can you help?

We are looking for some help to create a React-based UX for Bonding Curves. Main aim is create a reusable React component named BondingCurve.js which can be plugged to any react application in Ocean Protocol Ecosystem. This component will interact with Ethereum Smart Contract (to read data) and will plot graphs/charts based on the data read from the Smart Contract.

What needs to be done?

Create a React standalone application (preferably using Create-React-App v2 starter kit) that has one reusable component - BondingCurve.js (apart from bootstrapped App.js).

Specifications about BondingCurve.js :

sample bonding curve

Implementation Details

Note - All the smart contracts needed to query prices and supply, are already present in this repo. And this is the same repo where the PR for the finished work should be submitted. You can use Ganache as your local blockchain network to deploy smart contracts and test UX.

1. plotting BC as "price vs. supply"

Take a look at this test -


contract('BondingCurve', (accounts) => {
    describe('Test User stories', () => {
        it('Should query the price of drops at different supply', async () => {
            const token = await Token.deployed()
            const market = await BondingCurve.deployed()
            const scale = 1e18

            const assetId = 1
            const assetPrice = 100 * scale
            // 1. register dataset
            await market.register(assetId, assetPrice, { from: accounts[0] })
            // get initial fund and approve withdraw
            await market.requestTokens(10000 * scale, { from: accounts[0] })
            await token.approve(market.address, 10000 * scale, { from: accounts[0] })

            let i
            let supply
            let receipt
            // each time buy drops with 0.1 Ocean token up to 5000 Ocean Token
            // list price history along the amount of drops
            const drops_supply_range = 10000
            for (i = 0; i < 100000; i++) {
                receipt = await market.buyDrops(assetId, 50 * scale, { from: accounts[0] })
                supply = await market.dropsSupply(assetId, { from: accounts[0] })
                //console.log(  '[' + i + '] drops supply :=' + supply.toNumber() + ' drops :=' + receipt.logs[0].args._drops.toNumber()  + ' with ocn cost :=' + receipt.logs[0].args._ocn.toNumber() / scale )
                console.log( '[' + i + '] drops supply :=' + supply.toNumber() + ' with price :=' + receipt.logs[0].args._price.toNumber() / scale + ' Ocean token per drop')
                if ( supply > drops_supply_range){
                  break;
                }
            }

            const drops = await market.dropsBalance(assetId, { from: accounts[0] })
            await market.sellDrops(assetId, drops.valueOf(), { from: accounts[0] })
        })

The key part is following for-loop, which sweep the supply from 0 to limit (i.e., 10000). It will keep buying bonded tokens with 50 Ocean tokens each time. Then, query the current supply amount and print it out. You can keep them into two arrays for plotting.

const drops_supply_range = 10000
for (i = 0; i < 100000; i++) {
      receipt = await market.buyDrops(assetId, 50 * scale, { from: accounts[0] })
     supply = await market.dropsSupply(assetId, { from: accounts[0] })
      console.log( '[' + i + '] drops supply :=' + supply.toNumber() + ' with price :=' + receipt.logs[0].args._price.toNumber() / scale + ' Ocean token per drop')
      if ( supply > drops_supply_range){
            break;
      }
}

2. plot BC as "price vs. time"


        it('Should walk through typical user story', async () => {
            // const marketPlace = await Market.deployed();
            const token = await Token.deployed()
            const market = await BondingCurve.deployed()
            const scale = 1e18

            const assetId = 1
            const assetPrice = 100 * scale
            // 1. register dataset
            await market.register(assetId, assetPrice, { from: accounts[0] })

            // 2. provider request initial tokens 2000
            await market.requestTokens(2000 * scale, { from: accounts[0] })
            const bal1 = await token.balanceOf.call(accounts[0])
            // assert.equal(bal1.toNumber(), 2000,"User should have 2000 OCN tokens now.");
            console.log(`User has ${bal1.toNumber() /scale} Ocean tokens now.`)

            // 3. provider transfer OCN tokens into Market and buy drops
            // here the number of Ocean tokens needs to scale down by 1e18
            const ntokens = 10 * scale
            // calculate number of OCN tokens required for tx
            await token.approve(market.address, 2000 * scale, { from: accounts[0] })

            let tx = await market.buyDrops(assetId, ntokens, { from: accounts[0] })
            console.log('user[0] buy drops at effective price :=' + tx.logs[0].args._price.toNumber() / scale + ' Ocean token per drop')
            const bal2 = await token.balanceOf.call(accounts[0])
            console.log(`provider has balance of OCN := ${bal2.valueOf() / scale }`)
            // assert.equal(bal2.toNumber(), 2000 - ntokens,"User should have 1875 OCN tokens now.");
            const drops1 = await market.dropsBalance(assetId, { from: accounts[0] })
            console.log(`User [0] should have ${drops1.toNumber()} drops now.`)

            // another use purchase drops
            await market.requestTokens(2000 * scale, { from: accounts[1] })
            await token.approve(market.address, ntokens, { from: accounts[1] })
            // transfer 100 OCN tokens to market and buy drops
            tx = await market.buyDrops(assetId, ntokens, { from: accounts[1] })
            console.log('user[1] buy drops at effective price :=' + tx.logs[0].args._price.toNumber() / scale + ' Ocean token per drop')
            const drops2 = await market.dropsBalance(assetId, { from: accounts[1] })
            console.log(`User [1] should have ${drops2.toNumber()} drops now.`)

            // 7. provider sell Drops for Ocean TOKENS
            tx = await market.sellDrops(assetId, drops1.valueOf(), { from: accounts[0] })
            console.log('user[0] sell drops at effective price :=' + tx.logs[0].args._price.toNumber() / scale + ' Ocean token per drop')
            // user get his Ocean tokens after withdraw
            await market.withdraw({ from: accounts[0] })
            const tokenBalance1 = await token.balanceOf.call(accounts[0])
            console.log(`user[0] balance of Ocean tokens := ${tokenBalance1.toNumber() / scale} (5 Ocean tokens as profit)`)
        })

In this case, you only need to listen to the event of "buyDrops" and "sellDrops" and log the price at each time of the transaction. Then plot them out in the graph with corresponding timestamp.

let tx = await market.buyDrops(assetId, ntokens, { from: accounts[0] })
console.log('user[0] buy drops at effective price :=' + tx.logs[0].args._price.toNumber() / scale + ' Ocean token per drop')

tx = await market.sellDrops(assetId, drops1.valueOf(), { from: accounts[0] })
console.log('user[0] sell drops at effective price :=' + tx.logs[0].args._price.toNumber() / scale + ' Ocean token per drop')

Tech stack should include following -

The Pull Requests must be sent to this repository: https://github.com/oceanprotocol/bondingCurvesUX

We are expecting submitted code to go in this subrepo - https://github.com/oceanprotocol/bondingCurvesUX/tree/master/client

We are very happy when

When all below changes are merged with master branch

Seen this problem before?

Any help solving this is welcome. Feel free to leave any comments and help someone else to solve it. We might airdrop tokens to someone even if not directly completing bounty.

Questions & Reviews

Pull requests will be reviewed by one of the maintainers or long-term contributors. In case of any additional questions feel free to ask in this thread and we will do our best to add the missing info :)

Reward

This bounty is valued at 5000 PROCN tokens. Once the project was reviewed and merged in the master branch, you will receive the reward. PROCN is a proto-Ocean token. Bounty hunters that earn PROCN will be able to convert them 1:1 to Ocean tokens on network launch (currently Ocean Token is valued at 0.20 EUR). Network launch is expected to happen by Mar 31, 2019. Until then PROCN will be locked and non-transferrable in the ETH wallet to which it is delivered to.

gitcoinbot commented 5 years ago

Issue Status: 1. Open 2. Started 3. Submitted 4. Done


This issue now has a funding of 5000.0 PROCN attached to it as part of the Ocean Protocol fund.

gitcoinbot commented 5 years ago

Issue Status: 1. Open 2. Started 3. Submitted 4. Done


Workers have applied to start work.

These users each claimed they can complete the work by 2 months, 4 weeks from now. Please review their action plans below:

1) Superjo149 has applied to start work _(Funders only: approve worker | reject worker)_.

Action plan:

Questions:

Learn more on the Gitcoin Issue Details page.

gitcoinbot commented 5 years ago

Issue Status: 1. Open 2. Started 3. Submitted 4. Done


Work has been started.

These users each claimed they can complete the work by 1 month, 3 weeks ago. Please review their action plans below:

1) superjo149 has been approved to start work.

Action plan:

Questions:

Learn more on the Gitcoin Issue Details page.

2) proy24 has been approved to start work.

I propose to use Amcharts library for implementing this project. Amcharts is used to create beatiful and dynamic graphs and is free under a linkware license. https://www.amcharts.com/javascript-charts/

I propose a 7 day timeline from the date of getting confirmed. Timeline-- Build a prototype with basic functionality. i,e, render the data for bonding-curves. Add advanced querying mechanism . Filter day, month, year etc. Create unit tests for functionality. Create final version.

Questions-- Does this project expect state management via Redux, Is it ok to use a library like react-drizzle for web3 integration?

Learn more on the Gitcoin Issue Details page.

chalidbdb commented 5 years ago

@Superjo149, welcome! Happy to have you on board! Please have a look to this tweet. There might be a code base that you could utilize or learn from. https://twitter.com/oceanprotocol/status/1052209922933436416

innopreneur commented 5 years ago

Hey @Superjo149, Welcome Onboard! To answer your questions -

Any specific date format for the charts?

image

Ideally we are looking for something like this. Minimal requirement is "max" period timeline (user can see data for the entire lifetime of particular asset.). Also, "3 months" timeline would be nice to have because initially we don't want to wait till whole year to plot data. And as you see on hover, user can also see data for a particular day.

Does the timeline chart need to have both buy and sell drop events data?

No timeline should have price -> timeline (timeline could be hours, day, months, year etc depending on time period we plot. For (e.g.) in above image, for "max" timeline, we plot price -> year.) plotting. Its explained in the bounty description above how to get price for a given time (independent of buy and sell operations). Think of this like a chart of price of google shares at any given time. In that users are not concerned about what is buy/sell price, they just see the price of google shares at any given point in time.

Is the price shown using calculation "price / scale" or the raw value? If so, is scale a fixed value.

What do you mean by scale? Scale of the chart (zoomed in or zoomed out) or did you mean supply.

And feel free to ask many more questions. I will be your contact person. And to reduce latencyh in question-answer cycle, please join our Gitter channel. Its meant for technical discussions. And you will have access to many more developers (incl. me) to help you with your queries.

gitcoinbot commented 5 years ago

Issue Status: 1. Open 2. Started 3. Submitted 4. Done


Work for 5000.0 PROCN has been submitted by:

  1. @Superjo149

@chalidbdb please take a look at the submitted work:


innopreneur commented 5 years ago

Closing this bounty as it is completed.

gitcoinbot commented 5 years ago

⚡️ A tip worth 5000.00000 PROCN has been granted to @Superjo149 for this issue from @chalidbdb. ⚡️

Nice work @Superjo149! Your tip has automatically been deposited in the ETH address we have on file.

gitcoinbot commented 5 years ago

Issue Status: 1. Open 2. Started 3. Submitted 4. Done


The funding of 5000.0 PROCN attached to this issue has been approved & issued.