src/main/java/cc/mrbird/febs/common/contants/AppContants.java | ●●●●● patch | view | raw | blame | history | |
src/main/java/cc/mrbird/febs/dapp/controller/ApiCommonController.java | ●●●●● patch | view | raw | blame | history | |
src/main/java/cc/mrbird/febs/dapp/controller/ApiDappMemberController.java | ●●●●● patch | view | raw | blame | history | |
src/main/java/cc/mrbird/febs/dapp/service/impl/BscCoinContractEvent.java | ●●●●● patch | view | raw | blame | history | |
src/main/java/cc/mrbird/febs/dapp/service/impl/DappSystemServiceImpl.java | ●●●●● patch | view | raw | blame | history | |
src/main/java/cc/mrbird/febs/dapp/vo/RedisTransferPoolVo.java | ●●●●● patch | view | raw | blame | history | |
src/main/java/cc/mrbird/febs/job/SystemTradeJob.java | ●●●●● patch | view | raw | blame | history | |
src/test/java/cc/mrbird/febs/ChainTest.java | ●●●●● 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(); } }