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 _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 _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 _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
     F = math.div(math.sub(math.float(1), crr), math.float(2))
     U = math.sub(math.float(1), F)
     udpt = math.mul(dpt, U)
     ucdt = math.mul(cdt, U)
     fdpt = math.mul(dpt, F)
     fcdt = math.mul(cdt, F)
     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
 def _get_crr(self, circulation):
     return _sigmoid(math.decimaltofloat(self.a * self.decimal),
                     math.decimaltofloat(self.b * self.decimal),
                     math.decimaltofloat(self.l * self.decimal),
                     math.decimaltofloat(self.d * self.decimal),
                     circulation)