-
Notifications
You must be signed in to change notification settings - Fork 36
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
base: master
Are you sure you want to change the base?
Conversation
eip-0030.md
Outdated
// tokens(0): emissionNFT identifying the box | ||
// tokens(1): dexyUSD tokens to be emitted | ||
|
||
val selfOutIndex = getVar[Int](0).get |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why not a constant?
There was a problem hiding this comment.
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 |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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 |
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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 |
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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 |
There was a problem hiding this comment.
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)
There was a problem hiding this comment.
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 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Y is USD cent ?
There was a problem hiding this comment.
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 |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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} |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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 |
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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 |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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
No description provided.