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

Apply equation changes and some comments. #7

Merged
merged 2 commits into from
Jan 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,8 @@
val _fissionedErg: Long = IN_GLUONW_BOX.value - _MinFee
val RErg: BigInt = _fissionedErg.toBigInt
// Price of Gold
// Gold Oracle data input value has units of: nanoErg / kg
// We want units of: nanoErg / g
val Pt: BigInt = CONTEXT.dataInputs(0).R4[Long].get.toBigInt / 1000

// We're using 1,000,000,000 because the precision is based on nanoErgs
Expand Down Expand Up @@ -447,10 +449,8 @@
val ProtonsActualValue: BigInt = (OUT_GLUONW_PROTONS_TOKEN._2 - IN_GLUONW_PROTONS_TOKEN._2).toBigInt
val ErgsActualValue: BigInt = (IN_GLUONW_BOX.value - OUT_GLUONW_BOX.value).toBigInt

// M(1 - phiFusion) = Ergs
// therefore, M = Ergs / (1 - phiFusion)
val M: BigInt = ErgsActualValue * (precision / (precision - PhiFusion))

// M = Ergs
val M: BigInt = ErgsActualValue

val inProtonsNumerator: BigInt = M * SProtons * precision
val inNeutronsNumerator: BigInt = M * SNeutrons * precision
Expand All @@ -459,7 +459,7 @@
val NeutronsExpectedValue: BigInt = inNeutronsNumerator / denominator
val ProtonsExpectedValue: BigInt = inProtonsNumerator / denominator
// This will make the outErgsValueValid condition tautological. We could take this and the condition off, but we will keep it for the sake of completeness.
val ErgsExpectedValue: BigInt = ErgsActualValue
val ErgsExpectedValue: BigInt = M

// ### The 2 conditions to ensure that the values out is right ### //
val __inNeutronsValueValid: Boolean = NeutronsActualValue == NeutronsExpectedValue
Expand Down Expand Up @@ -598,7 +598,7 @@
val Phi0 = precision / 100
val Phi1 = precision / 2

val VarPhiBeta: BigInt = Phi0 + Phi1 * volume / RErg
val VarPhiBeta: BigInt = Phi0 + ((Phi1 * volume) / RErg)

// Due to some issues with moving towards the next block. We should give it a margin of error of +-3 blocks
// There is a tricky situation where if the lastblock is within a day, and if it is always updated,
Expand All @@ -614,17 +614,15 @@
// ** Fusion Ratio **
// min(q*, (SNeutrons * Pt / R))
// where q* is a constant, Pt is the price of gold in Ergs.
val oneMinusPhiBeta: BigInt = precision - VarPhiBeta
val oneMinusFusionRatio: BigInt = precision - fusionRatio
val minusesMultiplied: BigInt =
oneMinusPhiBeta * oneMinusFusionRatio / precision
val outNeutronsAmount: BigInt =
(((M * minusesMultiplied) / fusionRatio) * SNeutrons) / SProtons

val outProtonsAmount: BigInt = M.toBigInt
// The steps of multiplication and division done below are to avoid overflow errors.
val oneMinusPhiBeta: BigInt = (precision - VarPhiBeta)
val oneMinusFusionRatio: BigInt = (precision - fusionRatio)
val ratio1: BigInt = (M.toBigInt * oneMinusPhiBeta) / SProtons
val ratio2: BigInt = (oneMinusFusionRatio * SNeutrons) / precision
val outNeutronsAmount: BigInt = (ratio1 * ratio2) / fusionRatio

val NeutronsExpectedValue: BigInt = outNeutronsAmount
val ProtonsExpectedValue: BigInt = outProtonsAmount
val ProtonsExpectedValue: BigInt = M.toBigInt
val ErgsExpectedValue: BigInt = (IN_GLUONW_BOX.value).toBigInt

// ### The 2 conditions to ensure that the values out is right ### //
Expand All @@ -642,9 +640,7 @@
__outVolumePlusValidated,
__lastBlockPreserved
)))
}
else if (isBetaDecayMinusTx)
{
} else if (isBetaDecayMinusTx) {
// ===== BetaDecayMinus Tx ===== //
//Equation: M [Neutrons] = M * (1 - PhiBeta(T)) * ((q(R, S neutron)) / 1 - q(R, S neutron)) * (S protons / S neutrons) [Protons]
val M: Long = (OUT_GLUONW_NEUTRONS_TOKEN._2 - IN_GLUONW_NEUTRONS_TOKEN._2)
Expand Down Expand Up @@ -758,15 +754,14 @@
// ** Fusion Ratio **
// min(q*, (SNeutrons * Pt / R))
// where q* is a constant, Pt is the price of gold in Ergs.
// The steps of multiplication and division done below are to avoid overflow errors.
Copy link
Contributor

Choose a reason for hiding this comment

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

you say its to avoid overflow, are there tests that can test this in the off-chain code? Just to make sure we cover some edge cases

Copy link
Contributor Author

Choose a reason for hiding this comment

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

No, I did not make tests for it. I did a math calculation by hand assuming worst case scenario (i.e. largest possible values given the chosen protocol paramters) to determine how to do the divisions. I guess it would be good to do tests for that though.

Copy link
Contributor

Choose a reason for hiding this comment

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

can you write one quick test for it. Dont need to be extensive. Just something so that we have reference for what the worst case scenario would be. After that its good to merge

val oneMinusPhiBeta: BigInt = precision - VarPhiBeta
val oneMinusFusionRatio: BigInt = precision - fusionRatio
val neutronsToDecayMultiplyOneMinusPhiBeta: BigInt =
M.toBigInt * oneMinusPhiBeta / precision
val outProtonsAmount: BigInt =
((neutronsToDecayMultiplyOneMinusPhiBeta * SProtons / SNeutrons) * fusionRatio) / oneMinusFusionRatio
val outNeutronsAmount: BigInt = M.toBigInt
val ratio1: BigInt = (M.toBigInt * oneMinusPhiBeta) / SNeutrons
val ratio2: BigInt = (fusionRatio * SProtons) / precision
val outProtonsAmount: BigInt = (ratio1 * ratio2) / oneMinusFusionRatio

val NeutronsExpectedValue: BigInt = outNeutronsAmount
val NeutronsExpectedValue: BigInt = M.toBigInt
val ProtonsExpectedValue: BigInt = outProtonsAmount
val ErgsExpectedValue: BigInt = (IN_GLUONW_BOX.value).toBigInt

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -244,10 +244,9 @@ case class GluonWCalculator(
)
val oneMinusFusionRatio: BigInt =
BigInt(gluonWConstants.precision) - fusionRatio
val minusesMultiplied: BigInt =
oneMinusPhiBeta * oneMinusFusionRatio / gluonWConstants.precision
val outNeutronsAmount: Long =
((((BigInt(protonsToDecay) * minusesMultiplied) / fusionRatio) * sNeutrons) / sProtons).toLong
val ratio1: BigInt = (BigInt(protonsToDecay) * oneMinusPhiBeta) / BigInt(sProtons)
val ratio2: BigInt = (oneMinusFusionRatio * BigInt(sNeutrons)) / BigInt(gluonWConstants.precision)
val outNeutronsAmount: BigInt = (ratio1 * ratio2) / fusionRatio

GluonWBoxOutputAssetAmount(
ergAmount = 0,
Expand Down Expand Up @@ -275,15 +274,14 @@ case class GluonWCalculator(
)
val oneMinusFusionRatio: BigInt =
BigInt(gluonWConstants.precision) - fusionRatio
val neutronsToDecayMultiplyOneMinusPhiBeta: BigInt =
BigInt(neutronsToDecay) * oneMinusPhiBeta / gluonWConstants.precision
val outProtonsAmount: Long =
(((neutronsToDecayMultiplyOneMinusPhiBeta * sProtons / sNeutrons) * fusionRatio) / oneMinusFusionRatio).toLong
val ratio1: BigInt = (BigInt(neutronsToDecay) * oneMinusPhiBeta) / BigInt(sNeutrons)
val ratio2: BigInt = (fusionRatio * BigInt(sProtons)) / BigInt(gluonWConstants.precision)
val outProtonsAmount: BigInt = (ratio1 * ratio2) / oneMinusFusionRatio

GluonWBoxOutputAssetAmount(
ergAmount = 0,
neutronsAmount = -neutronsToDecay,
protonsAmount = outProtonsAmount
protonsAmount = outProtonsAmount.toLong
)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -169,8 +169,8 @@ trait GluonWBase extends UnitSpec {

def genesisGluonWBox(
ergAmount: Double = 200_000L,
neutronAmount: Double = 1_000L,
protonAmount: Double = 1_000L
neutronAmount: Double = 1_000_000L,
protonAmount: Double = 1_000_000L
kii-dot marked this conversation as resolved.
Show resolved Hide resolved
): GluonWBox = GluonWBox.create(
protonAmount =
GluonWBoxConstants.PROTONS_TOTAL_CIRCULATING_SUPPLY - (protonAmount * GluonWBoxConstants.PRECISION).toLong,
Expand Down