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 _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 _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 get_loan_plan(self, supply, circulation):
        #  check over flow and change unit
        supply = math.uint256(supply)
        circulation = math.uint256(circulation)

        supply /= self.ether
        circulation /= self.ether

        assert 0 < supply
        assert 0 < circulation
        return sigmoid(
            self.high - self.low, self.low, supply / 2.0, supply / 8.0,
            circulation
        ).real * self.decimal, 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 _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)
Exemple #8
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