def _cash(self, cdtbalance, cdtsupply, cdtamount):
        # check overflow and change unit
        cdtbalance = math.uint256(cdtbalance)
        cdtsupply = math.uint256(cdtsupply)
        cdtamount = math.uint256(cdtamount)
        cdtbalance = math.ethertofloat(cdtbalance)
        cdtsupply = math.ethertofloat(cdtsupply)
        cdtamount = math.ethertofloat(cdtamount)

        # Approximate calculation for it is always less than actual amount
        cdtprice = math.div(
            cdtbalance,
            math.mul(cdtsupply,
                     math.decimaltofloat(self.CDT_CRR * self.decimal)))
        ethamount = math.mul(cdtamount, cdtprice)
        assert ethamount < cdtbalance
        cashfee = math.mul(
            ethamount, math.decimaltofloat(self.CDT_CASHFEE * self.decimal))
        ethamount = math.sub(ethamount, cashfee)
        cdtbalance = math.sub(cdtbalance, ethamount)
        cdtprice = math.div(
            cdtbalance,
            math.mul(cdtsupply,
                     math.decimaltofloat(self.CDT_CRR * self.decimal)))
        return math.floattoether(ethamount), math.floattodecimal(cdtprice)
    def _withdraw(self, dptbalance, dptcirculation, dptamount):
        # check overflow and change unit
        dptbalance = math.uint256(dptbalance)
        dptcirculation = math.uint256(dptcirculation)
        dptamount = math.uint256(dptamount)

        dptbalance = math.ethertofloat(dptbalance)
        dptcirculation = math.ethertofloat(dptcirculation)
        dptamount = math.ethertofloat(dptamount)

        dptprice = math.div(
            dptbalance, math.mul(dptcirculation,
                                 self._get_crr(dptcirculation)))
        # Calculate the maximum ether should be returned to user
        ethamount = math.mul(dptamount, dptprice)

        # Calculate the maximum CRR after withdraw
        max_crr = self._get_crr(math.sub(dptcirculation, dptamount))
        # Calculate the minimum price after withdraw
        dptprice = math.div(math.sub(dptbalance, ethamount),
                            math.mul(dptcirculation, max_crr))
        # the actual withdraw price of DPT is equal to the minimum possible price after withdraw, ether=DPT*P
        actual_ether = math.mul(dptamount, dptprice)
        return math.floattoether(actual_ether), math.floattodecimal(
            max_crr), math.floattodecimal(dptprice)
 def _get_loan_plan(self, supply, circulation):
     #  check over flow and change unit
     high = math.decimaltofloat(self.high * self.decimal)
     low = math.decimaltofloat(self.low * self.decimal)
     supply = math.uint256(supply)
     circulation = math.uint256(circulation)
     supply = math.ethertofloat(supply)
     circulation = math.ethertofloat(circulation)
     assert 0 < supply
     assert 0 < circulation
     return math.floattodecimal(
         _sigmoid(high - low, low, math.div(supply, math.float(2)),
                  math.div(supply, math.float(8)), circulation)
     ), self.loandays * 24 * 3600, self.exemptdays * 24 * 3600
    def _to_discredit_token(self, cdtbalance, supply, sctamount):
        # check overflow and change unit
        cdtbalance = math.uint256(cdtbalance)
        supply = math.uint256(supply)
        sctamount = math.uint256(sctamount)

        cdtbalance = math.ethertofloat(cdtbalance)
        supply = math.ethertofloat(supply)
        sctamount = math.ethertofloat(sctamount)

        cdtprice = math.div(
            cdtbalance,
            math.mul(supply, math.decimaltofloat(self.CDT_CRR * self.decimal)))
        return math.floattoether(
            math.mul(sctamount, math.decimaltofloat(
                0.8 * self.decimal))), math.floattodecimal(cdtprice)
    def _loan(self, cdtamount, interestrate, crr):
        # check overflow and change unit
        cdtamount = math.uint256(cdtamount)
        interestrate = math.uint256(interestrate)
        crr = math.uint256(crr)
        cdtamount = math.ethertofloat(cdtamount)
        interestrate = math.decimaltofloat(interestrate)
        crr = math.decimaltofloat(crr)

        # loaned ether
        ethamount = math.mul(cdtamount,
                             math.decimaltofloat(self.CDTL * self.decimal))
        # calculate the interest
        earn = math.mul(ethamount, interestrate)
        cdtreserve = math.mul(
            earn, math.decimaltofloat(self.CDT_RESERVE * self.decimal))
        interest = math.sub(earn, cdtreserve)
        issuecdtamount = math.div(
            math.mul(earn, crr),
            math.decimaltofloat(self.CDTIP * self.decimal))
        # calculate the new issue CDT to prize loaned user using the interest
        ethamount = math.sub(ethamount, earn)
        sctamount = cdtamount
        return math.floattoether(ethamount), math.floattoether(
            interest), math.floattoether(issuecdtamount), math.floattoether(
                sctamount)
    def _deposit(self, dptbalance, dptsupply, dptcirculation, ethamount):
        # check overflow and change unit
        dptbalance = math.uint256(dptbalance)
        dptsupply = math.uint256(dptsupply)
        dptcirculation = math.uint256(dptcirculation)
        ethamount = math.uint256(ethamount)

        dptbalance = math.ethertofloat(dptbalance)
        dptsupply = math.ethertofloat(dptsupply)
        dptcirculation = math.ethertofloat(dptcirculation)
        ethamount = math.ethertofloat(ethamount)

        # Calculate current CRR and price of DPT
        crr = self._get_crr(dptcirculation)
        dptprice = math.div(dptbalance, math.mul(dptcirculation, crr))
        # Calculate the maximum DPT should be gave to user
        token = math.div(ethamount, dptprice)
        # Calculate the maximum balance of DPT contract
        max_balance = math.add(dptbalance, ethamount)
        # Calculate the minimum CRR of DPT
        crr = self._get_crr(math.add(dptcirculation, token))
        # Calculate the maximum price of DPT
        dptprice = math.div(max_balance, math.mul(dptcirculation, crr))
        # Actual price is equal to maximum price of DPT, for exchanging as less DPT to user as possible.
        token = math.div(ethamount, dptprice)
        # There could be less DPT remained in the DPT contract than supposed DPT, so contract need to issue new DPT
        # the first situation is there is enough DPT
        if math.sub(dptsupply, dptcirculation) >= token.real:
            crr = self._get_crr(math.add(dptcirculation, token))
            dptprice = math.div(max_balance,
                                math.mul(math.add(dptcirculation, token), crr))
            return math.floattoether(token), 0, math.floattodecimal(
                crr), math.floattodecimal(dptprice)
        # the second situation is there is insufficient DPT in the contract
        else:
            # the maximum supposed token transfer from contract to user is determined by the remaining DPT in the contract.
            # the issue price of token is
            token = math.sub(dptsupply, dptcirculation)
            # the minimum CRR after the deposit
            crr = self._get_crr(math.add(dptcirculation, token))
            # the maximum price after the deposit
            dptprice = math.div(max_balance, math.mul(dptcirculation, crr))
            return math.floattoether(token), math.floattoether(
                math.sub(ethamount,
                         math.mul(token, dptprice))), math.floattodecimal(
                             crr), math.floattodecimal(dptprice)
Beispiel #7
0
 def _issue(self, circulation, ethamount):
     #  check over flow and change unit
     circulation = math.uint256(circulation)
     ethamount = math.uint256(ethamount)
     circulation = math.ethertofloat(circulation)
     ethamount = math.ethertofloat(ethamount)
     crr = self._get_crr(circulation)
     ethdpt = math.mul(ethamount, crr)
     dpt = math.div(ethdpt, math.decimaltofloat(self.DPTIP * self.decimal))
     cdt = math.div(math.mul(math.sub(math.float(1), crr), ethamount),
                    math.decimaltofloat(self.CDTIP * self.decimal))
     crr = self._get_crr(circulation)
     # Split the new issued tokens to User and Founder
     udpt = math.mul(dpt, math.decimaltofloat(self.U * self.decimal))
     ucdt = math.mul(cdt, math.decimaltofloat(self.U * self.decimal))
     fdpt = math.mul(dpt, math.decimaltofloat(self.F * self.decimal))
     fcdt = math.mul(cdt, math.decimaltofloat(self.F * self.decimal))
     return math.floattoether(udpt), math.floattoether(
         ucdt), math.floattoether(fdpt), math.floattoether(
             fcdt), math.floattoether(ethdpt), math.floattodecimal(crr)
    def _to_credit_token(self, repayethamount, dctamount):
        # check over float and change unit
        repayethamount = math.uint256(repayethamount)
        dctamount = math.uint256(dctamount)

        repayethamount = math.ethertofloat(repayethamount)
        dctamount = math.ethertofloat(dctamount)
        ethamount = math.mul(dctamount,
                             math.decimaltofloat(self.CDTL * self.decimal))
        if repayethamount < ethamount:
            ethamount = repayethamount
            cdtamount = math.div(ethamount,
                                 math.decimaltofloat(self.CDTL * self.decimal))
            refunddctamount = math.sub(dctamount, cdtamount)
            return 0, math.floattoether(cdtamount), math.floattoether(
                refunddctamount)
        else:
            cdtamount = math.div(ethamount,
                                 math.decimaltofloat(self.CDTL * self.decimal))
            refundethamount = math.sub(repayethamount, ethamount)
            return math.floattoether(refundethamount), math.floattoether(
                cdtamount), 0
    def _repay(self, repayethamount, sctamount):
        # check overflow and change unit
        repayethamount = math.uint256(repayethamount)
        sctamount = math.uint256(sctamount)
        repayethamount = math.ethertofloat(repayethamount)
        sctamount = math.ethertofloat(sctamount)

        ethamount = math.mul(sctamount,
                             math.decimaltofloat(self.CDTL * self.decimal))
        if repayethamount < ethamount:
            ethamount = repayethamount
            cdtamount = math.div(ethamount,
                                 math.decimaltofloat(self.CDTL * self.decimal))
            refundsctamount = math.sub(sctamount, cdtamount)
            return 0, math.floattoether(cdtamount), math.floattoether(
                refundsctamount)
        else:
            cdtamount = math.div(ethamount,
                                 math.decimaltofloat(self.CDTL * self.decimal))
            refundethamount = math.sub(repayethamount, ethamount)
            return math.floattoether(refundethamount), math.floattoether(
                cdtamount), 0
Beispiel #10
0
from solidity.python.dabformula import EasyDABFormula as Formula
from solidity.python.dabformula import _sigmoid as _sigmoid
from solidity.python.dabformula import sigmoid as sigmoid
import solidity.python.solmath as math
import cmath
formula = Formula()
# udpt_expect, ucdt_expect, fdpt_expect, fcdt_expect, crr_expect = formula._issue(30000000000000000570425344,30000000000000000000)
# print(crr_expect)

acc_float = 1 / math.float(1)

for i in range(17):
    try:
        s1 = sigmoid(0.6, 0.2, 100000, 100000 / 4, 10000 + acc_float * 10**i)
        s2 = _sigmoid(
            math.ethertofloat(0.6 * formula.ether),
            math.ethertofloat(0.2 * formula.ether), math.float(100000),
            math.float(100000) / 4,
            math.ethertofloat(10000 * formula.ether +
                              acc_float * 10**i * formula.ether))
        print(s1.real,
              math.floattoether(s2) / formula.ether, 'accuracy of _sigmoid',
              s1.real - math.floattoether(s2) / formula.ether, i)
    except AssertionError as err:
        continue

for i in range(5000):
    try:
        s1 = sigmoid(0.6, 0.2, 100000, 100000 / 4, 1000 * i)
        s2 = _sigmoid(math.ethertofloat(0.6 * formula.ether),
                      math.ethertofloat(0.2 * formula.ether),