Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

EIP-30 Dexy stablecoin #62

Open
wants to merge 8 commits into
base: master
Choose a base branch
from
Open

EIP-30 Dexy stablecoin #62

wants to merge 8 commits into from

Conversation

scalahub
Copy link
Contributor

No description provided.

@scalahub scalahub requested review from code-for-uss and kushti April 19, 2022 20:50
@scalahub scalahub added the S-wip Status: Work in progress label Apr 19, 2022
eip-0030.md Outdated
// tokens(0): emissionNFT identifying the box
// tokens(1): dexyUSD tokens to be emitted

val selfOutIndex = getVar[Int](0).get
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not a constant?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Makes it more flexible due to possible AOTC issues with hard-wiring (box can be spent in two different transactions: top-up and mint)

eip-0030.md Outdated

val validOP = oraclePoolBox.tokens(0)._1 == oraclePoolNFT

val oraclePoolRate = oraclePoolBox.R4[Long].get // can assume always > 0 (ref oracle pool contracts) NanoErgs per USD
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

per USD or USD cent?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes its USD-cent if we consider v1 oracle

eip-0030.md Outdated

val selfOut = OUTPUTS(selfOutIndex)

val validSelfOut = selfOut.tokens(0) == SELF.tokens(0) && // emissionNFT and quantity preserved
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"and quantity" could be missed

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

agreed, we can remove "and quantity"

eip-0030.md Outdated
val validSelfOut = selfOut.tokens(0) == SELF.tokens(0) && // emissionNFT and quantity preserved
selfOut.propositionBytes == SELF.propositionBytes && // script preserved
selfOut.tokens(1)._1 == SELF.tokens(1)._1 && // dexyUSD tokenId preserved
selfOut.value > SELF.value // can only purchase dexyUSD, not sell it
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"can only purchase dexyUSD, not sell it" => "can only sell dexyUSD, not purchase it", so
selfOut.value < SELF.value

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe the comment is misinterpreted. The full comment should read "users can only purchase dexyUSD".

Maybe we can also write it as "box can only sell dexyUSD"?

Also since the contract sells dexyUSD, shouldn't selfOut.value be more than SELF.value? (i.e., shouldn't Ergs increase?)

{
// Notation:
//
// X is the primary token
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

X is the primary token (ERG)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think better to keep X as nanoErgs

//
// X is the primary token
// Y is the secondary token
// When using Erg-USD oracle v1, X is NanoErg and Y is USD
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Y is USD cent ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes comment is incorrect. It should be USD cent with oracle v1

eip-0030.md Outdated
val oraclePoolRateXY = oraclePoolBox.R4[Long].get
val lpRateXY0 = reservesX0 / reservesY0 // we can assume that reservesY0 > 0 (since at least one token must exist)
val lpRateXY1 = reservesX1 / reservesY1 // we can assume that reservesY1 > 0 (since at least one token must exist)
val isCrossing = (lpRateXY0 - oraclePoolRateXY) * (lpRateXY1 - oraclePoolRateXY) < 0 // if (and only if) oracle pool rate falls in between, then this will be negative
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why to check this in LP contract?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This variable captures whether the oracle pool rate falls in between the rates at input and output LP box in a swap transaction. Each time this happens, a counter is incremented in R5. This is done in every swap, independent of the top-up requirement

eip-0030.md Outdated
val crossCounterIn = SELF.R5[Int].get
val crossCounterOut = successor.R5[Int].get

val validCrossCounter = crossCounterOut == {if (isCrossing) crossCounterIn + 1 else crossCounterIn}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why to check this in LP contract?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just to keep track of how many times its crossed (see above comment). Note that the requirement we are trying to capture is that between a top-up initiation and top-up completion, the LP rate should not have crossed the oracle pool rate. If it does, then the top-up becomes invalid and we need to start afresh.

eip-0030.md Outdated
```scala
{
// Tracking box
// R4: Crossing Counter of LP box
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do we need for the counter? I guess it would be enough to write down in register height when price condition violated (within certain margin), and then a special action can nullify the register if price is okay again. On receiver side (in the bank contract), we check that HEIGHT - trackingBox.R4 > threshold

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, there can be other ways to achieve the goal stated in previous comment. So in the LP, we would need to store two values. One contains boolean when condition is violated and another height at which violated.

We can consider this approach as well. That way we can skip "initiation" and "completion" of top-up and just have a single step.

eip-0030.md Outdated
}
```

## Swapping Contract
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Description of the contract is needed.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Going to add in next commit

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
S-wip Status: Work in progress
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants