fix
Helius
2022-05-30 2ccbfa3ef257c53f9fbc80ab7e7459b09bbfa3d3
fix
6 files modified
2 files added
225 ■■■■■ changed files
src/main/java/cc/mrbird/febs/common/contants/AppContants.java 4 ●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/dapp/controller/ApiCommonController.java 9 ●●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/dapp/controller/ApiDappMemberController.java 12 ●●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/dapp/service/impl/BscCoinContractEvent.java 13 ●●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/dapp/service/impl/DappSystemServiceImpl.java 40 ●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/dapp/vo/RedisTransferPoolVo.java 21 ●●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/job/SystemTradeJob.java 110 ●●●●● patch | view | raw | blame | history
src/test/java/cc/mrbird/febs/ChainTest.java 16 ●●●●● patch | view | raw | blame | history
src/main/java/cc/mrbird/febs/common/contants/AppContants.java
@@ -104,4 +104,8 @@
    public static final String REDIS_KEY_SIGN = "LOGIN_SIGN";
    public static final String SYSTEM_START_FLAG = "SYSTEM_START_FLAG";
    public static final String REDIS_KEY_TRANSFER_POOL_VOL = "TRANSFER_POOL_VOL";
    public static final String REDIS_KEY_TRANSFER_POOL_VOL_REMAIN = "TRANSFER_POOL_VOL_REMAIN";
    public static final String REDIS_KEY_USDT_OUT_LIMIT = "SOURCE_POOL_USDT_OUT_LIMIT";
    public static final String REDIS_KEY_USDT_OUT_LIMIT_REMAIN = "SOURCE_POOL_USDT_OUT_LIMIT_REMAIN";
}
src/main/java/cc/mrbird/febs/dapp/controller/ApiCommonController.java
@@ -57,13 +57,4 @@
    public FebsResponse totalIncome() {
        return new FebsResponse().success().data(dappSystemService.findTotalInComeAndList());
    }
    @ApiOperation(value = "系统参数", notes = "系统参数")
    @ApiResponses({
            @ApiResponse(code = 200, message = "success", response = SystemDto.class)
    })
    @GetMapping(value = "/system")
    public FebsResponse system() {
        return new FebsResponse().success().data(dappSystemService.system());
    }
}
src/main/java/cc/mrbird/febs/dapp/controller/ApiDappMemberController.java
@@ -2,8 +2,10 @@
import cc.mrbird.febs.common.entity.FebsResponse;
import cc.mrbird.febs.dapp.dto.RecordInPageDto;
import cc.mrbird.febs.dapp.dto.SystemDto;
import cc.mrbird.febs.dapp.dto.TransferDto;
import cc.mrbird.febs.dapp.dto.WalletOperateDto;
import cc.mrbird.febs.dapp.service.DappSystemService;
import cc.mrbird.febs.dapp.service.DappWalletService;
import cc.mrbird.febs.dapp.vo.WalletInfoVo;
import io.swagger.annotations.Api;
@@ -27,6 +29,7 @@
public class ApiDappMemberController {
    private final DappWalletService dappWalletService;
    private final DappSystemService dappSystemService;
    @ApiOperation(value = "获取账户信息接口", notes = "获取账号信息接口")
    @ApiResponses({
@@ -70,4 +73,13 @@
    public FebsResponse calPrice() {
        return new FebsResponse().success().data(dappWalletService.calPrice());
    }
    @ApiOperation(value = "系统参数", notes = "系统参数")
    @ApiResponses({
            @ApiResponse(code = 200, message = "success", response = SystemDto.class)
    })
    @GetMapping(value = "/system")
    public FebsResponse system() {
        return new FebsResponse().success().data(dappSystemService.system());
    }
}
src/main/java/cc/mrbird/febs/dapp/service/impl/BscCoinContractEvent.java
@@ -40,13 +40,19 @@
    public void compile(EthUsdtContract.TransferEventResponse e) {
        int decimals = ChainService.getInstance(ChainEnum.BSC_TFC.name()).decimals();
        if (e.to != null) {
            // 合约创建时,同时创建地址
            if ("0x0000000000000000000000000000000000000000".equals(e.from)) {
                DappMemberEntity toMember = dappMemberDao.selectByAddress(e.to, null);
                if (toMember == null) {
                    toMember = dappMemberService.insertMember(e.to, "0");
                }
                return;
            }
            DappMemberEntity fromMember = dappMemberService.findByAddress(e.from, null);
            if (fromMember == null) {
                fromMember = dappMemberService.insertMember(e.from, null);
                DappMemberEntity sourceAddress = dappMemberDao.selectByAddress(ChainEnum.BSC_TFC.getAddress(), null);
                fromMember = dappMemberService.insertMember(e.from, sourceAddress.getInviteId());
            }
            // 如果转账对象地址不为源池地址,则创建用户
@@ -63,11 +69,8 @@
                BigDecimal amount = BigDecimal.valueOf(tokens.intValue()).divide(BigDecimal.TEN.pow(decimals), decimals, RoundingMode.HALF_DOWN);
                DappFundFlowEntity fundFlow = dappFundFlowDao.selectByFromHash(e.log.getTransactionHash(), 1);
                // TODO price
                BigDecimal newPrice = BigDecimal.valueOf(1);
                BigDecimal newPrice = fundFlow.getNewestPrice();
                BigDecimal transferAmount = amount.multiply(newPrice);
                fundFlow.setNewestPrice(newPrice);
                // 更改状态为已同步
                fundFlow.setStatus(2);
                fundFlow.setTargetAmount(transferAmount);
src/main/java/cc/mrbird/febs/dapp/service/impl/DappSystemServiceImpl.java
@@ -1,13 +1,18 @@
package cc.mrbird.febs.dapp.service.impl;
import cc.mrbird.febs.common.contants.AppContants;
import cc.mrbird.febs.common.utils.LoginUserUtil;
import cc.mrbird.febs.common.utils.RedisUtils;
import cc.mrbird.febs.dapp.chain.ChainEnum;
import cc.mrbird.febs.dapp.chain.ChainService;
import cc.mrbird.febs.dapp.dto.SystemDto;
import cc.mrbird.febs.dapp.entity.DappMemberEntity;
import cc.mrbird.febs.dapp.entity.DappMineDataEntity;
import cc.mrbird.febs.dapp.entity.DappReturnRatioEntity;
import cc.mrbird.febs.dapp.mapper.DappReturnRatioDao;
import cc.mrbird.febs.dapp.mapper.DappSystemDao;
import cc.mrbird.febs.dapp.service.DappSystemService;
import cc.mrbird.febs.dapp.vo.RedisTransferPoolVo;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import lombok.RequiredArgsConstructor;
@@ -62,13 +67,36 @@
    @Override
    public SystemDto system() {
        DappMemberEntity member = LoginUserUtil.getAppUser();
        SystemDto system = new SystemDto();
        system.setBuyTotal(BigDecimal.valueOf(10000));
        system.setBuyRemain(BigDecimal.valueOf(100));
        system.setSaleTotal(BigDecimal.valueOf(10000));
        system.setSaleRemain(BigDecimal.valueOf(1000));
        system.setUsdtTotal(BigDecimal.valueOf(32000));
        system.setUsdtRemain(BigDecimal.valueOf(12000));
        RedisTransferPoolVo transferPool = (RedisTransferPoolVo) redisUtils.get(AppContants.REDIS_KEY_TRANSFER_POOL_VOL);
        BigDecimal poolRemain = (BigDecimal) redisUtils.get(AppContants.REDIS_KEY_TRANSFER_POOL_VOL_REMAIN);
        // 买币数量
        system.setBuyTotal(transferPool.getTodayVol());
        system.setBuyRemain(poolRemain);
        BigDecimal balance = ChainService.getInstance(ChainEnum.BSC_TFC.name()).balanceOf(member.getAddress());
        Object o = redisUtils.get(AppContants.REDIS_KEY_USDT_OUT_LIMIT_REMAIN);
        BigDecimal remain;
        if (o == null) {
            remain = balance.multiply(BigDecimal.valueOf(0.3));
            redisUtils.set(AppContants.REDIS_KEY_USDT_OUT_LIMIT_REMAIN, remain);
        } else {
            remain = (BigDecimal) o;
        }
        // 卖币数量
        system.setSaleTotal(balance.multiply(BigDecimal.valueOf(0.3)));
        system.setSaleRemain(remain);
        BigDecimal usdtRemain = (BigDecimal) redisUtils.get(AppContants.REDIS_KEY_USDT_OUT_LIMIT_REMAIN);
        BigDecimal usdtTotal = (BigDecimal) redisUtils.get(AppContants.REDIS_KEY_USDT_OUT_LIMIT);
        // usdt数量
        system.setUsdtTotal(usdtTotal);
        system.setUsdtRemain(usdtRemain);
        system.setFeeRatio(BigDecimal.TEN);
        return system;
    }
src/main/java/cc/mrbird/febs/dapp/vo/RedisTransferPoolVo.java
New file
@@ -0,0 +1,21 @@
package cc.mrbird.febs.dapp.vo;
import lombok.Data;
import java.math.BigDecimal;
/**
 * @author wzy
 * @date 2022-05-30
 **/
@Data
public class RedisTransferPoolVo {
    private BigDecimal todayVol;
    private BigDecimal todayProp;
    private int finishCnt;
    private int unFinishCnt;
}
src/main/java/cc/mrbird/febs/job/SystemTradeJob.java
New file
@@ -0,0 +1,110 @@
package cc.mrbird.febs.job;
import cc.mrbird.febs.common.contants.AppContants;
import cc.mrbird.febs.common.utils.RedisUtils;
import cc.mrbird.febs.dapp.chain.ChainEnum;
import cc.mrbird.febs.dapp.chain.ChainService;
import cc.mrbird.febs.dapp.vo.RedisTransferPoolVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import java.math.BigDecimal;
import java.math.RoundingMode;
/**
 * @author wzy
 * @date 2022-05-30
 **/
@Slf4j
@Component
public class SystemTradeJob {
    @Autowired
    private RedisUtils redisUtils;
    // 最低容量(百分比)
    private final BigDecimal volProp = new BigDecimal("0.5");
    private final BigDecimal basic_vol = BigDecimal.valueOf(1200000);
    /**
     * 中转池容量计算
     *
     * 源池出币量最低为0.5%每天基础量,作为可s交易量
     * 按当天交易完成量的百分比,第二天出币补齐已成交部分
     * 按每天的基础量,同一阶段累计完成5次100%交易量后增加0.5%基础出币量比例出币,无上限……
     * 当一个阶段的当日量72小时未100%交易完成,中转池回到上一阶段阶容量。
     * 例:当进入一个新阶段为每天出币量为3%时,此笔出量累计72小时未完全成交,源池出币量回到上一阶段每天出币2.5%,需重计5倍量,……以此类推增加或递减
     */
    @Scheduled(cron = "0 0 0 * * ?")
    public void transferPoolVol() {
        log.info("中转池容量");
        Object o = redisUtils.get(AppContants.REDIS_KEY_TRANSFER_POOL_VOL);
        if (o == null) {
            RedisTransferPoolVo transferPool= new RedisTransferPoolVo();
            BigDecimal total = basic_vol.multiply(volProp.divide(BigDecimal.valueOf(100), 4, RoundingMode.HALF_UP));
            transferPool.setTodayVol(total);
            transferPool.setTodayProp(volProp);
            transferPool.setFinishCnt(0);
            transferPool.setFinishCnt(0);
            redisUtils.set(AppContants.REDIS_KEY_TRANSFER_POOL_VOL, transferPool);
            redisUtils.set(AppContants.REDIS_KEY_TRANSFER_POOL_VOL_REMAIN, total);
            return;
        }
        RedisTransferPoolVo transferPool = (RedisTransferPoolVo) o;
        BigDecimal remain = (BigDecimal) redisUtils.get(AppContants.REDIS_KEY_TRANSFER_POOL_VOL_REMAIN);
        // 全卖了
        if (remain.compareTo(BigDecimal.ZERO) == 0) {
            int finishCnt = transferPool.getFinishCnt() + 1;
            BigDecimal targetProp = transferPool.getTodayProp();
            if (finishCnt == 5) {
                targetProp = transferPool.getTodayVol().add(volProp);
                transferPool.setTodayProp(targetProp);
                transferPool.setFinishCnt(0);
            } else {
                transferPool.setFinishCnt(finishCnt);
            }
            BigDecimal total = basic_vol.multiply(targetProp.divide(BigDecimal.valueOf(100), 4, RoundingMode.HALF_UP));
            transferPool.setTodayVol(total);
            transferPool.setUnFinishCnt(0);
            redisUtils.set(AppContants.REDIS_KEY_TRANSFER_POOL_VOL_REMAIN, total);
        } else {
            int unFinishCnt = transferPool.getUnFinishCnt() + 1;
            BigDecimal targetProp = transferPool.getTodayProp();
            if (unFinishCnt >= 3) {
                targetProp = transferPool.getTodayProp().compareTo(volProp) == 0 ? volProp : transferPool.getTodayProp().subtract(volProp);
                transferPool.setTodayProp(targetProp);
                transferPool.setUnFinishCnt(0);
            } else {
                transferPool.setUnFinishCnt(unFinishCnt);
            }
            BigDecimal aa = targetProp.divide(BigDecimal.valueOf(100), 4, RoundingMode.HALF_UP);
            BigDecimal total = basic_vol.multiply(aa);
            transferPool.setTodayVol(total);
            redisUtils.set(AppContants.REDIS_KEY_TRANSFER_POOL_VOL_REMAIN, total);
        }
        redisUtils.set(AppContants.REDIS_KEY_TRANSFER_POOL_VOL, transferPool);
    }
    /**
     * 源池每日出U限制
     *
     * 源池每天可交易量为源池总USDT数量的10%,以上一天00:00时读取源池实时USDT数量为参考,作为当天可交易USDT数量。
     */
    @Scheduled(cron = "0 0 0 * * ?")
    public void sourcePoolUsdtOutLimit() {
        log.info("源池每日出U限制");
        BigDecimal sourceBalance = ChainService.getInstance(ChainEnum.BSC_USDT.name()).balanceOf(ChainEnum.BSC_USDT_SOURCE.getAddress());
        BigDecimal total = sourceBalance.multiply(BigDecimal.valueOf(0.1));
        redisUtils.set(AppContants.REDIS_KEY_USDT_OUT_LIMIT, total);
        redisUtils.set(AppContants.REDIS_KEY_USDT_OUT_LIMIT_REMAIN, total);
    }
}
src/test/java/cc/mrbird/febs/ChainTest.java
@@ -3,7 +3,9 @@
import cc.mrbird.febs.dapp.chain.ChainEnum;
import cc.mrbird.febs.dapp.chain.ChainService;
import cc.mrbird.febs.dapp.chain.ContractChainService;
import cc.mrbird.febs.job.SystemTradeJob;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
/**
@@ -19,4 +21,18 @@
        System.out.println(instance.balanceOf("0x4ebdca102623b46a47042d580dddade2a53d057f"));
    }
    @Autowired
    private SystemTradeJob systemTradeJob;
    @Test
    public void transferPoolTest() {
        systemTradeJob.transferPoolVol();
    }
    @Test
    public void sourceUsdtTest() {
        systemTradeJob.sourcePoolUsdtOutLimit();
    }
}