文件 1 的 1:InvestContract.sol
pragma solidity 0.8.19;
interface IERC20 {
function decimals() external view returns (uint8);
function symbol() external view returns (string memory);
function name() external view returns (string memory);
function totalSupply() external view returns (uint256);
function balanceOf(address account) external view returns (uint256);
function transfer(address recipient, uint256 amount) external returns (bool);
function allowance(address owner, address spender) external view returns (uint256);
function approve(address spender, uint256 amount) external returns (bool);
function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);
event Transfer(address indexed from, address indexed to, uint256 value);
event Approval(address indexed owner, address indexed spender, uint256 value);
}
interface IARC{
function getInviteList(address _us) external view returns(address[] memory);
function getLine(address _us) external view returns(address[] memory);
}
interface Itransfer{
function transferToken(address token, address sender, address to, uint256 amount) external;
}
interface IPrice{
function getArbPrice(uint256 _arbAmt) external view returns(uint256,uint256);
}
interface IPair{
function sync() external;
function mint(address to) external returns (uint liquidity);
function burn(address to) external returns (uint amount0, uint amount1);
}
interface ISwapRouter {
function factory() external pure returns (address);
function swapExactTokensForTokensSupportingFeeOnTransferTokens(
uint amountIn,
uint amountOutMin,
address[] calldata path,
address to,
uint deadline
) external;
}
interface IoldInvest{
struct UserInfo{
uint256 investArb;
uint256 investPrice;
uint256 investValue;
uint256 maxClaimValue;
uint256 claimdValue;
uint256 inviteRwds;
uint256 teamRwds;
uint256 dayRate;
uint256 inviteRate;
uint256 teamValue;
uint256 teamAmount;
uint256 lastTime;
}
function getUserInfo(address _user)external view returns(UserInfo memory);
function getUserInfos(address _user)external view returns(uint256,bool,uint256,uint256);
function getUserLine(address _user) external view returns(address[] memory);
function getGlobal()external view returns(uint256,uint256,uint256,uint256,uint256);
}
contract InvestContract{
address private dead = 0x000000000000000000000000000000000000dEaD;
address private arc = 0xbdCA2E08bC10Dc500D82736D2Da423CaC4E98aF8;
address private arb = 0x912CE59144191C1204E64559FE8253a0e49E6548;
address private pair = 0xDa82b877DB91Cc9C36df61F8C8dc7Ded1a35D262;
address private router = 0x4752ba5DBc23f44D87826276BF6Fd6b1C372aD24;
address private claimFeeFunder = 0x48A3fEb6e776085b3EdCA0965038005038c560ab;
address private investFeeFunder = 0xAD11d8804B9fB44D4E7bB13A0b195E89fD368832;
address private transferContract = 0x394A8273A52d2D8EA25034e3A21281FCd517A882;
address private priceContract = 0xa52A96F527b9F60d9305F0E40C5b4e394F5859d5;
address private oldContract = 0xC1bA54fAeCE039Ce287687557c431b71446CA06e;
struct UserInfo{
uint256 investArb;
uint256 investPrice;
uint256 investValue;
uint256 maxClaimValue;
uint256 claimdValue;
uint256 inviteRwds;
uint256 teamRwds;
uint256 dayRate;
uint256 inviteRate;
uint256 teamValue;
uint256 teamAmount;
uint256 lastTime;
}
mapping(address=>uint256) private userTotalArb;
mapping(address=>uint256) private userTotalValue;
mapping(address=>UserInfo) private userInfo;
mapping(address=>bool) private projectManage;
mapping(address=>bool) private blackUser;
mapping(address=>uint256) private userId;
mapping(uint256=>address) public idToUser;
mapping(address=>address[]) private userLine;
uint256 private constant MAX = ~uint256(0);
uint256 private totalInvestUser;
uint256 private totalInvestArb;
uint256 private totalInvestValue;
uint256 private totalMintLp;
uint256 private totalClaimLp;
uint256 private totalCliamValue;
uint256 private totalInvestTimes;
bool private investState;
bool private claimState;
uint256[] private investLimits = [10000 ether,5000 ether,2000 ether,500 ether];
uint256[] private dayRates = [200,150,120,100];
uint256 private totalDatRate = 10000;
uint256 private minLimit = 500 ether;
uint256 private maxLimit = 5000 ether;
uint256 private investFee = 200;
uint256[] private shareRateList = [20,10,5,2,2,2,2,2,2,2];
bool private isBigRwd;
constructor(){
projectManage[msg.sender] = true;
}
function _addInvestRate(address _top) private{
UserInfo storage tInfo = userInfo[_top];
tInfo.inviteRate ++;
}
function _addTeamValues(address[] memory _uLine,uint256 _value,bool _isFirstTeam) private{
for(uint256 i = 0; i < _uLine.length; i++){
UserInfo storage _tInfo = userInfo[_uLine[i]];
_tInfo.teamValue +=_value;
if(_isFirstTeam){
_tInfo.teamAmount++;
}
}
}
function _invest(address _user,uint256 _arbAmt,uint256 _price,uint256 _value,uint256 _dayRate,address[] memory _uLine) private{
UserInfo storage uInfo = userInfo[_user];
require(uInfo.investArb == 0,'Wait End');
uInfo.investArb = _arbAmt;
uInfo.investValue = _value;
uInfo.investPrice = _price;
uInfo.maxClaimValue = _value*2;
uInfo.dayRate = _dayRate;
uInfo.lastTime = block.timestamp;
userTotalArb[_user] +=_arbAmt;
userTotalValue[_user] +=_value;
uint256 _userId = userId[_user];
bool isFirstTeam;
if(_userId ==0){
totalInvestUser++;
userId[_user] = totalInvestUser;
idToUser[totalInvestUser] = _user;
userLine[_user] = _uLine;
_addInvestRate(_uLine[0]);
isFirstTeam = true;
}
_addTeamValues(_uLine,_value,isFirstTeam);
totalInvestArb +=_arbAmt;
totalInvestValue +=_value;
totalInvestTimes++;
}
function _calcDayRate(uint256 _arbAmt) private view returns(uint256){
for(uint256 i=0;i<investLimits.length;i++){
if(_arbAmt >=investLimits[i]){
return dayRates[i];
}
}
return dayRates[dayRates.length-1];
}
function addLp(uint256 _arbAmt) private returns(uint256){
uint256 _buyAmt = _arbAmt/2;
address[] memory buyPath = new address[](2);
buyPath[0]=arb;
buyPath[1]=arc;
uint256 _startBal = IERC20(arc).balanceOf(address(this));
ISwapRouter(router).swapExactTokensForTokensSupportingFeeOnTransferTokens(_buyAmt, 0, buyPath, address(this), block.timestamp+3000);
uint256 _endBal = IERC20(arc).balanceOf(address(this));
uint256 _arcBal = _endBal - _startBal;
uint256 _addAmt = _arbAmt - _buyAmt;
IERC20(arb).transfer(pair, _addAmt);
IERC20(arc).transfer(pair, _arcBal);
uint256 _lpAmt = IPair(pair).mint(address(this));
IPair(pair).sync();
require(_lpAmt>0,'Mint Error');
return _lpAmt;
}
function buyLp(uint256 _arbAmt) external {
require(investState,'Wait Open BuyLp');
require(_arbAmt>=minLimit,'Min Limit');
require(maxLimit>_arbAmt,'max Limit');
address _user = msg.sender;
require(_user == tx.origin,'BOT');
address[] memory _uLine = IARC(arc).getLine(_user);
require(_uLine.length>0,'Bind');
(uint256 _price,uint256 _value) = IPrice(priceContract).getArbPrice(_arbAmt);
uint256 _dayRate = _calcDayRate(_arbAmt);
_tokenTransferFrom(arb, _user, address(this), _arbAmt);
_invest(_user,_arbAmt,_price,_value,_dayRate,_uLine);
uint256 _fee = _arbAmt*investFee/10000;
if(_fee>0){
IERC20(arb).transfer(investFeeFunder, _fee);
}
uint256 _addLpAmt = _arbAmt - _fee;
uint256 _lpAmt = addLp(_addLpAmt);
totalMintLp +=_lpAmt;
}
function sendRwds(address _user,uint256 _value) private returns(uint256){
uint256 _pariArbAmt = IERC20(arb).balanceOf(pair);
uint256 _pairSupply = IERC20(pair).totalSupply();
(,uint256 _pairValue) = IPrice(priceContract).getArbPrice(_pariArbAmt);
uint256 _pairValues = _pairValue *2;
uint256 _lpAmt = _value * _pairSupply / _pairValues;
uint256 _feeAmt = _lpAmt * 5/100;
uint256 _rwdAmt = _lpAmt - _feeAmt;
IERC20(pair).transfer(claimFeeFunder, _feeAmt);
IERC20(pair).transfer(_user, _rwdAmt);
return _lpAmt;
}
function checkSendRwds(uint256 _value) external view returns(uint256,uint256,uint256){
uint256 _pariArbAmt = IERC20(arb).balanceOf(pair);
uint256 _pairSupply = IERC20(pair).totalSupply();
(,uint256 _pairValue) = IPrice(priceContract).getArbPrice(_pariArbAmt);
uint256 _pairValues = _pairValue *2;
uint256 _lpAmt = _value * _pairSupply / _pairValues;
uint256 _feeAmt = _lpAmt * 5/100;
uint256 _rwdAmt = _lpAmt - _feeAmt;
return(_lpAmt,_feeAmt,_rwdAmt);
}
function sendInviteRwds(address[] memory _line,uint256 _values) private{
if(_values==0){
return;
}
uint256 _len = _line.length>=10?10:_line.length;
for(uint256 i=0;i<_len;i++){
UserInfo storage uInfo = userInfo[_line[i]];
bool canRwds = (uInfo.investArb>0) && (uInfo.inviteRate>=(i+1));
if(canRwds){
uint256 shareRewars = (_values * shareRateList[i]) / 100;
uInfo.inviteRwds +=shareRewars;
}
}
return;
}
function sendTeamRwds(address[] memory _line,uint256 _values) private{
if(_values==0){
return;
}
uint256 maxTeamFee = 45;
uint256 useTeamFee;
uint256 bsAmt = _values;
bool isFirstBig;
uint256 indexFirstBig;
uint256 bigValue;
uint256 bigUser;
for(uint256 i=0;i<_line.length;i++){
UserInfo storage linfo = userInfo[_line[i]];
uint256 _teamValue = linfo.teamValue;
if(_teamValue >= 10000000 ether){
if(maxTeamFee>useTeamFee){
uint256 _rwds = ((bsAmt * (maxTeamFee - useTeamFee)) / 100);
linfo.teamRwds += _rwds;
useTeamFee = 45;
if(!isFirstBig){
isFirstBig = true;
indexFirstBig = i;
bigValue = _rwds*11/100;
}
}
bigUser++;
}
if(_teamValue >= 5000000 ether && _teamValue< 10000000 ether && useTeamFee<40){
linfo.teamRwds += ((bsAmt * (40 - useTeamFee)) / 100);
useTeamFee = 40;
}
if(_teamValue >= 2000000 ether && _teamValue< 5000000 ether && useTeamFee<35){
linfo.teamRwds += ((bsAmt * (35 - useTeamFee)) / 100);
useTeamFee = 35;
}
if(_teamValue >= 1000000 ether && _teamValue< 2000000 ether && useTeamFee<30){
linfo.teamRwds += ((bsAmt * (30 - useTeamFee)) / 100);
useTeamFee = 30;
}
if(_teamValue >= 500000 ether && _teamValue< 1000000 ether && useTeamFee<25){
linfo.teamRwds += ((bsAmt * (25 - useTeamFee)) / 100);
useTeamFee = 25;
}
if(_teamValue >= 200000 ether && _teamValue< 500000 ether && useTeamFee<20){
linfo.teamRwds += ((bsAmt * (20 - useTeamFee)) / 100);
useTeamFee = 20;
}
if(_teamValue >= 100000 ether && _teamValue< 200000 ether && useTeamFee<15){
linfo.teamRwds += ((bsAmt * (15 - useTeamFee)) / 100);
useTeamFee = 15;
}
if(_teamValue >= 50000 ether && _teamValue< 100000 ether && useTeamFee<10){
linfo.teamRwds += ((bsAmt * (10 - useTeamFee)) / 100);
useTeamFee = 10;
}
if(_teamValue >= 30000 ether && _teamValue< 50000 ether && useTeamFee<5){
linfo.teamRwds += ((bsAmt * (5 - useTeamFee)) / 100);
useTeamFee = 5;
}
}
if(isBigRwd && bigUser>1 && bigValue>0 && !isFirstBig && (_line.length>=(indexFirstBig+1))){
uint256 _perBigAmt = bigValue/(bigUser-1);
for(uint256 i=indexFirstBig+1;i<_line.length;i++){
UserInfo storage _linfo = userInfo[_line[i]];
uint256 _teamValue_ = _linfo.teamValue;
if(_teamValue_ >= 10000000 ether){
_linfo.teamRwds += _perBigAmt;
}
}
}
}
function _claimRewards(address _user,address[] memory _line) private{
UserInfo storage uInfo = userInfo[_user];
require(uInfo.investArb>0,'Not Invest');
require(block.timestamp >=(uInfo.lastTime+86400),'Wait Time');
uint256 pendingDays= (block.timestamp - uInfo.lastTime)/86400;
uint256 pendingRwds =uInfo.investValue * pendingDays * uInfo.dayRate /totalDatRate;
uint256 _canClaimRwds =uInfo.maxClaimValue>=uInfo.claimdValue? uInfo.maxClaimValue - uInfo.claimdValue:0;
if(pendingRwds>=_canClaimRwds){
pendingRwds = _canClaimRwds;
}
sendInviteRwds(_line,pendingRwds);
sendTeamRwds(_line,pendingRwds);
uint256 allRwds = pendingRwds + uInfo.inviteRwds + uInfo.teamRwds;
bool isOut;
if(allRwds>=_canClaimRwds){
allRwds = _canClaimRwds;
isOut = true;
}
totalCliamValue +=allRwds;
uint256 sendLpAmt = sendRwds(_user,allRwds);
totalClaimLp += sendLpAmt;
if(isOut){
uInfo.investArb=0;
uInfo.investPrice=0;
uInfo.investValue=0;
uInfo.maxClaimValue=0;
uInfo.claimdValue=0;
uInfo.inviteRwds=0;
uInfo.teamRwds=0;
uInfo.dayRate=0;
uInfo.lastTime=0;
}else{
uInfo.claimdValue += allRwds;
uInfo.inviteRwds=0;
uInfo.teamRwds=0;
uInfo.lastTime=block.timestamp;
}
}
function claimRewards()external{
require(claimState,'Wait Open Claim');
address _user = msg.sender;
require(_user == tx.origin,'BOT');
require(!blackUser[_user],'Black');
address[] memory _uLine = IARC(arc).getLine(_user);
require(_uLine.length>0,'Bind');
_claimRewards(_user,_uLine);
return;
}
function _tokenTransferFrom(address token, address sender, address to, uint256 amount) private{
Itransfer(transferContract).transferToken(token, sender, to, amount);
}
function setProjectManage(address _addr,bool _state) external {
require(_addr != msg.sender,'SAME');
require(projectManage[msg.sender],'M');
projectManage[_addr] = _state;
}
function renounceManage()external{
require(projectManage[msg.sender],'M');
projectManage[msg.sender] = false;
}
function setFunderAddr(address _investFeeFunder,address _claimFeeFunder)external {
require(projectManage[msg.sender],'M');
investFeeFunder = _investFeeFunder;
claimFeeFunder = _claimFeeFunder;
}
function setContarctAddr(address _transferContract,address _priceContract)external {
require(projectManage[msg.sender],'M');
transferContract = _transferContract;
priceContract = _priceContract;
}
function setBlackList(address[] memory _blackList,bool _state)external {
require(projectManage[msg.sender],'M');
for(uint256 i=0;i<_blackList.length;i++){
blackUser[_blackList[i]] = _state;
}
}
function setStates(uint256 _type,bool _state)external{
require(projectManage[msg.sender],'M');
if(_type ==1){
investState = _state;
}
if(_type ==2){
claimState = _state;
}
}
function setDayRates(uint256[] memory _investLimits,uint256[] memory _dayRates,uint256 _totalDatRate) external{
require(projectManage[msg.sender],'M');
investLimits = _investLimits;
dayRates = _dayRates;
totalDatRate = _totalDatRate;
}
function setLimitAndFee(uint256 _minLimit,uint256 _maxLimit,uint256 _investFee) external{
require(projectManage[msg.sender],'M');
minLimit=_minLimit;
maxLimit=_maxLimit;
investFee=_investFee;
}
function setInviteRate(uint256[] memory _shareRateList)external{
require(projectManage[msg.sender],'M');
shareRateList = _shareRateList;
}
function setIsBigRwd(bool _state) external{
require(projectManage[msg.sender],'M');
isBigRwd = _state;
}
function claimToken(address token, uint256 amount,address _to) external {
if (projectManage[msg.sender]) {
IERC20(token).transfer(_to, amount);
}
}
function addApprove()external{
IERC20(arb).approve(router, MAX);
IERC20(arc).approve(router, MAX);
IERC20(pair).approve(router, MAX);
}
function _getUserTeamMaxMin(
address _user
) external view returns(address, uint256, uint256) {
address[] memory userInviteList = IARC(arc).getInviteList(_user);
uint256 len = userInviteList.length;
if (len > 1) {
uint256 maxLV = 0;
address maxLaddr;
for (uint256 i = 0; i < len; i++) {
UserInfo memory iinfo = userInfo[userInviteList[i]];
uint256 ztT = iinfo.teamValue;
uint256 ztS = userTotalValue[userInviteList[i]];
uint256 ztV = ztT+ztS;
if (ztV > maxLV) {
maxLV = ztV;
maxLaddr = userInviteList[i];
}
}
uint256 uV = userInfo[_user].teamValue;
uint256 minV = (uV >= maxLV) ? (uV - maxLV) : 0;
return (maxLaddr, maxLV, minV);
} else {
return (address(0), 0, 0);
}
}
function getAddr()external view returns(address,address){
return(transferContract,priceContract);
}
function getUserInfo(address _user)external view returns(UserInfo memory){
UserInfo memory uInfo = userInfo[_user];
return uInfo;
}
function getUserInfos(address _user)external view returns(uint256,bool,uint256,uint256){
return (userId[_user],blackUser[_user],userTotalArb[_user],userTotalValue[_user]);
}
function getUserLine(address _user) external view returns(address[] memory){
return userLine[_user];
}
function getGlobal()external view returns(uint256,uint256,uint256,uint256,uint256,uint256){
return(totalInvestUser,totalInvestArb,totalMintLp,totalClaimLp,totalInvestTimes,totalCliamValue);
}
function getState()external view returns(bool,bool,bool){
return(investState,claimState,isBigRwd);
}
function getRates()external view returns(uint256[] memory,uint256[] memory,uint256[] memory,uint256,uint256,uint256,uint256){
return(investLimits,dayRates,shareRateList,totalDatRate,minLimit,maxLimit,investFee);
}
function getPendingRwds(address _user) external view returns(uint256){
UserInfo memory uinfo = userInfo[_user];
if(uinfo.investArb==0){
return 0;
}
if(uinfo.lastTime+86400 > block.timestamp){
return 0;
}
uint256 _days = (block.timestamp - uinfo.lastTime)/86400;
uint256 staticPending = uinfo.investValue * _days * uinfo.dayRate / totalDatRate;
uint256 _canClaimd = uinfo.maxClaimValue >uinfo.claimdValue?uinfo.maxClaimValue - uinfo.claimdValue:0;
if(staticPending>=_canClaimd){
staticPending = _canClaimd;
}
return staticPending;
}
function syncUser(address user)external{
require(projectManage[msg.sender],'M');
address _user = user;
IoldInvest.UserInfo memory oInfo = IoldInvest(oldContract).getUserInfo(_user);
require(oInfo.investArb>0,'No Invest');
UserInfo storage uInfo = userInfo[_user];
require(uInfo.investArb == 0,'SYNC');
uInfo.investArb = oInfo.investArb;
uInfo.investPrice = oInfo.investPrice;
uInfo.investValue = oInfo.investValue;
uInfo.maxClaimValue = oInfo.maxClaimValue;
uInfo.claimdValue = oInfo.claimdValue;
uInfo.inviteRwds = oInfo.inviteRwds;
uInfo.teamRwds = oInfo.teamRwds;
uInfo.dayRate = oInfo.dayRate;
uInfo.inviteRate = oInfo.inviteRate;
uInfo.teamValue = oInfo.teamValue;
uInfo.teamAmount = oInfo.teamAmount;
uInfo.lastTime = oInfo.lastTime;
(uint256 _uid,,uint256 _userTotalArb,uint256 _userTotalValue) = IoldInvest(oldContract).getUserInfos(_user);
userId[_user] = _uid;
idToUser[_uid] = _user;
userTotalArb[_user] = _userTotalArb;
userTotalValue[_user] = _userTotalValue;
address[] memory _uline = IoldInvest(oldContract).getUserLine(_user);
userLine[_user] = _uline;
totalInvestValue +=_userTotalValue;
}
function syncGlobal()external{
require(projectManage[msg.sender],'M');
require(totalInvestUser==0,'SYNC');
(uint256 _totalInvestUser,uint256 _totalInvestArb,uint256 _totalMintLp,uint256 _totalClaimLp,uint256 _totalInvestTimes) = IoldInvest(oldContract).getGlobal();
totalInvestUser=_totalInvestUser;
totalInvestArb = _totalInvestArb;
totalMintLp = _totalMintLp;
totalClaimLp=_totalClaimLp;
totalInvestTimes = _totalInvestTimes;
}
}