Browse Source

添加安全计算

master
mac 6 months ago
parent
commit
6fa62278be
  1. 1323
      .openzeppelin/bsc-testnet.json
  2. 284
      contracts/Pledge.sol
  3. 55
      contracts/SafeMath.sol
  4. 65
      package-lock.json
  5. 3
      package.json
  6. 10
      scripts/deployProxy.ts
  7. 4
      sync.block.js
  8. 35
      test/Pledge.ts

1323
.openzeppelin/bsc-testnet.json
File diff suppressed because it is too large
View File

284
contracts/Pledge.sol

@ -6,66 +6,80 @@ import "./NFT.sol";
import "./Pool.sol"; import "./Pool.sol";
import "./PledgeType.sol"; import "./PledgeType.sol";
import "./Utils.sol"; import "./Utils.sol";
import "./SafeMath.sol";
contract Pledge is Initializable { contract Pledge is Initializable {
using SafeMath for uint256;
NFT nftContract; NFT nftContract;
Pool poolContract; Pool poolContract;
ProductInfo[] public productInfo; ProductInfo[] public productInfo;
mapping(uint256 => PledgeType) pledges;
mapping(address => PledgeType[]) public pledgeRecords;
mapping(uint256 => PledgeType) public invitationPledges;
mapping(uint256 => PledgeType) pledges;
mapping(address => PledgeType[]) public pledgeRecords;
mapping(uint256 => PledgeType) public invitationPledges;
mapping(address => RecommendObjType) public recommendObj; mapping(address => RecommendObjType) public recommendObj;
mapping(address => uint256[]) public invitationTokens;
mapping(address => address[]) public invitationAddress;
mapping(address => uint256[]) public invitationTokens;
mapping(address => address[]) public invitationAddress;
mapping(address => PledgeWithdrawRecordType[]) public pledgeWithdrawRecord; mapping(address => PledgeWithdrawRecordType[]) public pledgeWithdrawRecord;
mapping(address => InvitationWithdrawRecordType[]) public invitationWithdrawRecord;
address[] public blackList;
mapping(address => InvitationWithdrawRecordType[])
public invitationWithdrawRecord;
address[] public blackList;
address[] public whiteList; address[] public whiteList;
mapping(address => PledgeType[]) public pledgeDestoryRecords; mapping(address => PledgeType[]) public pledgeDestoryRecords;
uint256 public invitationRate;
uint256 public invitationRate;
uint256 public nextTokenId; uint256 public nextTokenId;
bool public pledgeStatus; bool public pledgeStatus;
uint256 public dayTime; uint256 public dayTime;
function initialize(address nftAddress, address poolAddress) public initializer {
function initialize(
address nftAddress,
address poolAddress
) public initializer {
nftContract = NFT(nftAddress); nftContract = NFT(nftAddress);
poolContract = Pool(poolAddress); poolContract = Pool(poolAddress);
nextTokenId = 1; nextTokenId = 1;
invitationRate = 1;
invitationRate = 100;
pledgeStatus = false; pledgeStatus = false;
dayTime = 1 days; dayTime = 1 days;
productInfo.push(ProductInfo(180, 14));
productInfo.push(ProductInfo(270, 15));
productInfo.push(ProductInfo(360, 16));
productInfo.push(ProductInfo(180, 1408));
productInfo.push(ProductInfo(270, 1521));
productInfo.push(ProductInfo(360, 1623));
} }
modifier onlyAdmin (){
modifier onlyAdmin() {
address[] memory _admins = nftContract.getAdmin(); address[] memory _admins = nftContract.getAdmin();
bool _isAdmin = Utils.isAdmin(_admins, msg.sender); bool _isAdmin = Utils.isAdmin(_admins, msg.sender);
require(_isAdmin == true,"For administrators only");
require(_isAdmin == true, "For administrators only");
_; _;
} }
modifier onlyBlacks (){
modifier onlyBlacks() {
bool _isBlack = Utils.isAdmin(blackList, msg.sender); bool _isBlack = Utils.isAdmin(blackList, msg.sender);
require(_isBlack == false,"You've been blacklisted.");
require(_isBlack == false, "You've been blacklisted.");
_; _;
} }
function getPledgeRecords(address _owner) public view returns(PledgeType[] memory){
function getPledgeRecords(
address _owner
) public view returns (PledgeType[] memory) {
return pledgeRecords[_owner]; return pledgeRecords[_owner];
} }
function getPledgeWithdrawRecord(address _owner) public view returns(PledgeWithdrawRecordType[] memory){
function getPledgeWithdrawRecord(
address _owner
) public view returns (PledgeWithdrawRecordType[] memory) {
return pledgeWithdrawRecord[_owner]; return pledgeWithdrawRecord[_owner];
} }
function getInvitationWithdrawRecord(address _owner) public view returns(InvitationWithdrawRecordType[] memory){
function getInvitationWithdrawRecord(
address _owner
) public view returns (InvitationWithdrawRecordType[] memory) {
return invitationWithdrawRecord[_owner]; return invitationWithdrawRecord[_owner];
} }
function getPledgeDestoryRecords(address _owner) public view returns(PledgeType[] memory){
function getPledgeDestoryRecords(
address _owner
) public view returns (PledgeType[] memory) {
return pledgeDestoryRecords[_owner]; return pledgeDestoryRecords[_owner];
} }
@ -73,7 +87,9 @@ contract Pledge is Initializable {
return productInfo; return productInfo;
} }
function getOwnerAllPledgeInfo( address _ownerAddress ) public view returns (PledgeType[] memory result) {
function getOwnerAllPledgeInfo(
address _ownerAddress
) public view returns (PledgeType[] memory result) {
uint256[] memory tokens = getOwnerAllTokens(_ownerAddress); uint256[] memory tokens = getOwnerAllTokens(_ownerAddress);
result = new PledgeType[](tokens.length); result = new PledgeType[](tokens.length);
for (uint256 i = 0; i < tokens.length; i++) { for (uint256 i = 0; i < tokens.length; i++) {
@ -83,9 +99,15 @@ contract Pledge is Initializable {
} }
function bindRecommend(address _referrer) internal { function bindRecommend(address _referrer) internal {
require(recommendObj[msg.sender].key == address(0),"Already have recommenders");
require(msg.sender != _referrer ,"You can't recommend yourself.");
require(recommendObj[_referrer].referrer != msg.sender,"Can't recommend each other");
require(
recommendObj[msg.sender].key == address(0),
"Already have recommenders"
);
require(msg.sender != _referrer, "You can't recommend yourself.");
require(
recommendObj[_referrer].referrer != msg.sender,
"Can't recommend each other"
);
recommendObj[msg.sender] = RecommendObjType( recommendObj[msg.sender] = RecommendObjType(
msg.sender, msg.sender,
_referrer, _referrer,
@ -94,7 +116,7 @@ contract Pledge is Initializable {
); );
invitationAddress[_referrer].push(msg.sender); invitationAddress[_referrer].push(msg.sender);
} }
function setInvitationIncomes(PledgeType memory _pledge) internal { function setInvitationIncomes(PledgeType memory _pledge) internal {
address recommendAddr = recommendObj[msg.sender].referrer; address recommendAddr = recommendObj[msg.sender].referrer;
PledgeType memory _invitationPledge = _pledge; PledgeType memory _invitationPledge = _pledge;
@ -103,9 +125,11 @@ contract Pledge is Initializable {
uint256 rate = _invitationPledge.rate; uint256 rate = _invitationPledge.rate;
uint256 day = _invitationPledge.pledgeDay; uint256 day = _invitationPledge.pledgeDay;
uint256 tokenId = _invitationPledge.tokenId; uint256 tokenId = _invitationPledge.tokenId;
uint256 contribute = (((amount * rate) / 365) * day) / 100;
recommendObj[msg.sender].contribute += contribute;
// uint256 contribute = (((amount * rate) / 365) * day) / 100;
uint256 contribute = amount.mul(rate).div(365).mul(day).div(10000);
recommendObj[msg.sender].contribute = contribute.add(recommendObj[msg.sender].contribute);
if (invitationTokens[recommendAddr].length == 0) { if (invitationTokens[recommendAddr].length == 0) {
invitationTokens[recommendAddr] = new uint256[](0); invitationTokens[recommendAddr] = new uint256[](0);
} }
@ -116,10 +140,14 @@ contract Pledge is Initializable {
invitationPledges[tokenId] = _invitationPledge; invitationPledges[tokenId] = _invitationPledge;
} }
function pledge(uint256 amount, uint256 index, address _referrer) external onlyBlacks {
function pledge(
uint256 amount,
uint256 index,
address _referrer
) external onlyBlacks {
bool _isWhite = Utils.isAdmin(whiteList, msg.sender); bool _isWhite = Utils.isAdmin(whiteList, msg.sender);
if(!_isWhite){
require(pledgeStatus == false,"The pledge is closed.");
if (!_isWhite) {
require(pledgeStatus == false, "The pledge is closed.");
} }
require(amount >= 1, "Minimum pledge 1FIL"); require(amount >= 1, "Minimum pledge 1FIL");
require(index < productInfo.length, "Product does not exist"); require(index < productInfo.length, "Product does not exist");
@ -133,16 +161,27 @@ contract Pledge is Initializable {
uint256 startTime = block.timestamp; uint256 startTime = block.timestamp;
uint256 endTime = block.timestamp + (item.day * dayTime); uint256 endTime = block.timestamp + (item.day * dayTime);
nftContract.mint(msg.sender, tokenId); nftContract.mint(msg.sender, tokenId);
PledgeType memory _pledge = PledgeType(tokenId,startTime,endTime,startTime,amount,item.rate,item.day,msg.sender,false);
PledgeType memory _pledge = PledgeType(
tokenId,
startTime,
endTime,
startTime,
amount,
item.rate,
item.day,
msg.sender,
false
);
pledges[tokenId] = _pledge; pledges[tokenId] = _pledge;
pledgeRecords[msg.sender].push(_pledge); pledgeRecords[msg.sender].push(_pledge);
if (recommendObj[msg.sender].key != address(0)) { if (recommendObj[msg.sender].key != address(0)) {
setInvitationIncomes(_pledge); setInvitationIncomes(_pledge);
} }
} }
function getOwnerAllTokens( address _ownerAddress ) public view returns (uint256[] memory) {
function getOwnerAllTokens(
address _ownerAddress
) public view returns (uint256[] memory) {
uint256 nftAmount = nftContract.balanceOf(_ownerAddress); uint256 nftAmount = nftContract.balanceOf(_ownerAddress);
uint256[] memory tokens = new uint256[](nftAmount); uint256[] memory tokens = new uint256[](nftAmount);
for (uint256 i = 0; i < nftAmount; i++) { for (uint256 i = 0; i < nftAmount; i++) {
@ -151,20 +190,24 @@ contract Pledge is Initializable {
return tokens; return tokens;
} }
function calculateInterest( PledgeType memory _pledge ) public view returns (uint256) {
function calculateInterest(
PledgeType memory _pledge
) public view returns (uint256) {
uint256 total_amount = _pledge.pledgeAmount; uint256 total_amount = _pledge.pledgeAmount;
uint256 currentTime = block.timestamp; uint256 currentTime = block.timestamp;
uint256 withdrawTime = _pledge.withdrawTime; uint256 withdrawTime = _pledge.withdrawTime;
uint256 rate = _pledge.rate; uint256 rate = _pledge.rate;
if(_pledge.endTime < currentTime){
if (_pledge.endTime < currentTime) {
currentTime = _pledge.endTime; currentTime = _pledge.endTime;
} }
uint256 daysPassed = (currentTime - withdrawTime) / dayTime; uint256 daysPassed = (currentTime - withdrawTime) / dayTime;
uint256 dailyShare = (((total_amount * rate) / 365) * daysPassed) / 100;
uint256 dailyShare = total_amount.mul(rate).div(365).mul(daysPassed).div(10000);
return dailyShare; return dailyShare;
} }
function getWithdrawbleAmount( address _owner ) public view returns (uint256) {
function getWithdrawbleAmount(
address _owner
) public view returns (uint256) {
uint256[] memory tokens = getOwnerAllTokens(_owner); uint256[] memory tokens = getOwnerAllTokens(_owner);
if (tokens.length <= 0) return 0; if (tokens.length <= 0) return 0;
uint256 _total_interest = 0; uint256 _total_interest = 0;
@ -178,39 +221,59 @@ contract Pledge is Initializable {
function withdraAllInterest() external onlyBlacks { function withdraAllInterest() external onlyBlacks {
uint256 _total_interest = getWithdrawbleAmount(msg.sender); uint256 _total_interest = getWithdrawbleAmount(msg.sender);
require(_total_interest > 0, "Withdrawal amount must be greater than 0");
require(
_total_interest > 0,
"Withdrawal amount must be greater than 0"
);
uint256[] memory tokens = getOwnerAllTokens(msg.sender); uint256[] memory tokens = getOwnerAllTokens(msg.sender);
for(uint256 i=0;i<tokens.length;i++){
for (uint256 i = 0; i < tokens.length; i++) {
uint256 _withdrawTime = block.timestamp; uint256 _withdrawTime = block.timestamp;
uint256 _tokenId = tokens[i]; uint256 _tokenId = tokens[i];
require(!pledges[_tokenId].isBlack,"Unable to withdraw, the NFT Tokend is blacklisted.");
if(pledges[_tokenId].endTime < _withdrawTime){
require(
!pledges[_tokenId].isBlack,
"Unable to withdraw, the NFT Tokend is blacklisted."
);
if (pledges[_tokenId].endTime < _withdrawTime) {
_withdrawTime = pledges[_tokenId].endTime; _withdrawTime = pledges[_tokenId].endTime;
} }
pledges[_tokenId].withdrawTime = _withdrawTime; pledges[_tokenId].withdrawTime = _withdrawTime;
} }
poolContract.withdraw(msg.sender, _total_interest); poolContract.withdraw(msg.sender, _total_interest);
pledgeWithdrawRecord[msg.sender].push(PledgeWithdrawRecordType(_total_interest,block.timestamp,0,0,2));
pledgeWithdrawRecord[msg.sender].push(
PledgeWithdrawRecordType(_total_interest, block.timestamp, 0, 0, 2)
);
} }
function withdrawInterest(uint256 tokenId) external onlyBlacks { function withdrawInterest(uint256 tokenId) external onlyBlacks {
address _owner = nftContract.ownerOf(tokenId); address _owner = nftContract.ownerOf(tokenId);
require(_owner == msg.sender,"It's not a contract.");
require(_owner == msg.sender, "It's not a contract.");
PledgeType memory data = pledges[tokenId]; PledgeType memory data = pledges[tokenId];
require(!data.isBlack,"Unable to withdraw,the NFT Tokend is blacklisted.");
require(
!data.isBlack,
"Unable to withdraw,the NFT Tokend is blacklisted."
);
uint256 _interest = calculateInterest(data); uint256 _interest = calculateInterest(data);
require(_interest > 0, "Withdrawal amount must be greater than 0"); require(_interest > 0, "Withdrawal amount must be greater than 0");
uint256 _withdrawTime = block.timestamp; uint256 _withdrawTime = block.timestamp;
if(data.endTime < _withdrawTime){
if (data.endTime < _withdrawTime) {
_withdrawTime = data.endTime; _withdrawTime = data.endTime;
} }
poolContract.withdraw(msg.sender, _interest); poolContract.withdraw(msg.sender, _interest);
pledges[tokenId].withdrawTime = _withdrawTime; pledges[tokenId].withdrawTime = _withdrawTime;
pledgeWithdrawRecord[msg.sender].push(PledgeWithdrawRecordType(_interest,block.timestamp,data.tokenId,data.pledgeDay,1));
pledgeWithdrawRecord[msg.sender].push(
PledgeWithdrawRecordType(
_interest,
block.timestamp,
data.tokenId,
data.pledgeDay,
1
)
);
} }
function getOwnerInvitationPledges( address addr ) public view returns (PledgeType[] memory result) {
function getOwnerInvitationPledges(
address addr
) public view returns (PledgeType[] memory result) {
uint256[] memory _tokens = invitationTokens[addr]; uint256[] memory _tokens = invitationTokens[addr];
result = new PledgeType[](_tokens.length); result = new PledgeType[](_tokens.length);
for (uint256 i = 0; i < _tokens.length; i++) { for (uint256 i = 0; i < _tokens.length; i++) {
@ -220,84 +283,97 @@ contract Pledge is Initializable {
return result; return result;
} }
function getOwnerAllInvitationWithdrawAmout(address owner) public view returns(uint256){
function getOwnerAllInvitationWithdrawAmout(
address owner
) public view returns (uint256) {
uint256 _income = 0; uint256 _income = 0;
PledgeType[] memory _pledges = getOwnerInvitationPledges(owner); PledgeType[] memory _pledges = getOwnerInvitationPledges(owner);
for(uint256 i=0;i<_pledges.length;i++){
for (uint256 i = 0; i < _pledges.length; i++) {
PledgeType memory data = _pledges[i]; PledgeType memory data = _pledges[i];
_income += calculateInterest(data); _income += calculateInterest(data);
} }
return _income; return _income;
} }
function withdraInvitationAllInterest() external onlyBlacks {
uint256 _total_interest = getOwnerAllInvitationWithdrawAmout(msg.sender);
require(_total_interest > 0, "Withdrawal amount must be greater than 0");
function withdraInvitationAllInterest() external onlyBlacks {
uint256 _total_interest = getOwnerAllInvitationWithdrawAmout(
msg.sender
);
require(
_total_interest > 0,
"Withdrawal amount must be greater than 0"
);
uint256[] memory tokens = invitationTokens[msg.sender]; uint256[] memory tokens = invitationTokens[msg.sender];
for(uint256 i=0;i<tokens.length;i++){
for (uint256 i = 0; i < tokens.length; i++) {
uint256 _withdrawTime = block.timestamp; uint256 _withdrawTime = block.timestamp;
uint256 _tokenId = tokens[i]; uint256 _tokenId = tokens[i];
if(invitationPledges[_tokenId].endTime < _withdrawTime){
if (invitationPledges[_tokenId].endTime < _withdrawTime) {
_withdrawTime = invitationPledges[_tokenId].endTime; _withdrawTime = invitationPledges[_tokenId].endTime;
} }
invitationPledges[_tokenId].withdrawTime = _withdrawTime; invitationPledges[_tokenId].withdrawTime = _withdrawTime;
} }
uint256 currentTime = block.timestamp; uint256 currentTime = block.timestamp;
poolContract.withdraw(msg.sender, _total_interest); poolContract.withdraw(msg.sender, _total_interest);
invitationWithdrawRecord[msg.sender].push(InvitationWithdrawRecordType(_total_interest,currentTime));
invitationWithdrawRecord[msg.sender].push(
InvitationWithdrawRecordType(_total_interest, currentTime)
);
} }
function withdrawInvitationInterest(uint256 tokenId) external onlyBlacks { function withdrawInvitationInterest(uint256 tokenId) external onlyBlacks {
uint256[] memory _tokens = invitationTokens[msg.sender]; uint256[] memory _tokens = invitationTokens[msg.sender];
bool _owner = false; bool _owner = false;
for(uint256 i=0;i<_tokens.length;i++){
for (uint256 i = 0; i < _tokens.length; i++) {
uint256 _tokenId = _tokens[i]; uint256 _tokenId = _tokens[i];
if(_tokenId == tokenId){
if (_tokenId == tokenId) {
_owner = true; _owner = true;
break; break;
} }
} }
require(_owner == true,"It's not a contract.");
require(_owner == true, "It's not a contract.");
PledgeType memory data = invitationPledges[tokenId]; PledgeType memory data = invitationPledges[tokenId];
uint256 _interest = calculateInterest(data); uint256 _interest = calculateInterest(data);
require(_interest > 0, "Withdrawal amount must be greater than 0"); require(_interest > 0, "Withdrawal amount must be greater than 0");
uint256 _withdrawTime = block.timestamp; uint256 _withdrawTime = block.timestamp;
if(data.endTime < _withdrawTime){
if (data.endTime < _withdrawTime) {
_withdrawTime = data.endTime; _withdrawTime = data.endTime;
} }
poolContract.withdraw(msg.sender, _interest); poolContract.withdraw(msg.sender, _interest);
uint256 currentTime = block.timestamp; uint256 currentTime = block.timestamp;
invitationPledges[tokenId].withdrawTime = _withdrawTime; invitationPledges[tokenId].withdrawTime = _withdrawTime;
invitationWithdrawRecord[msg.sender].push(InvitationWithdrawRecordType(_interest,currentTime));
invitationWithdrawRecord[msg.sender].push(
InvitationWithdrawRecordType(_interest, currentTime)
);
} }
function getAllInvitationMember( address addr ) public view returns (RecommendObjType[] memory result) {
function getAllInvitationMember(
address addr
) public view returns (RecommendObjType[] memory result) {
address[] memory _addresss = invitationAddress[addr]; address[] memory _addresss = invitationAddress[addr];
result = new RecommendObjType[](_addresss.length); result = new RecommendObjType[](_addresss.length);
for (uint256 i = 0; i < _addresss.length; i++) { for (uint256 i = 0; i < _addresss.length; i++) {
result[i] = recommendObj[_addresss[i]]; result[i] = recommendObj[_addresss[i]];
} }
return result; return result;
}
}
function getCurrentTime() public view returns (uint256){
function getCurrentTime() public view returns (uint256) {
uint256 currentTime = block.timestamp; uint256 currentTime = block.timestamp;
return currentTime; return currentTime;
} }
function destroyPledge(uint256 tokenId) external onlyBlacks{
function destroyPledge(uint256 tokenId) external onlyBlacks {
address _owner = nftContract.ownerOf(tokenId); address _owner = nftContract.ownerOf(tokenId);
require(_owner == msg.sender,"You're not a contract owner.");
require(_owner == msg.sender, "You're not a contract owner.");
uint256 currentTime = block.timestamp; uint256 currentTime = block.timestamp;
PledgeType memory data = pledges[tokenId]; PledgeType memory data = pledges[tokenId];
require(data.endTime < currentTime,"Unexpired Pledge Agreement");
nftContract.transferFrom(msg.sender,address(this), tokenId);
require(data.endTime < currentTime, "Unexpired Pledge Agreement");
nftContract.transferFrom(msg.sender, address(this), tokenId);
poolContract.withdraw(msg.sender, data.pledgeAmount); poolContract.withdraw(msg.sender, data.pledgeAmount);
data.withdrawTime = currentTime; data.withdrawTime = currentTime;
pledgeDestoryRecords[msg.sender].push(data); pledgeDestoryRecords[msg.sender].push(data);
}
}
function setInvitationRate(uint256 _rate) external onlyAdmin{
function setInvitationRate(uint256 _rate) external onlyAdmin {
invitationRate = _rate; invitationRate = _rate;
} }
@ -305,67 +381,85 @@ contract Pledge is Initializable {
pledgeStatus = _status; pledgeStatus = _status;
} }
function addBlackOrWhiteList(address[] memory _blacks,uint256 _type) external onlyAdmin {
require(_blacks.length>0,"Enter at least one address");
if(_type == 1){
function addBlackOrWhiteList(
address[] memory _blacks,
uint256 _type
) external onlyAdmin {
require(_blacks.length > 0, "Enter at least one address");
if (_type == 1) {
address[] memory blacks = Utils.addAdmin(blackList, _blacks); address[] memory blacks = Utils.addAdmin(blackList, _blacks);
blackList = blacks;
blackList = blacks;
} }
if(_type == 2){
if (_type == 2) {
address[] memory whites = Utils.addAdmin(whiteList, _blacks); address[] memory whites = Utils.addAdmin(whiteList, _blacks);
whiteList = whites;
whiteList = whites;
} }
} }
function delBlackOrWhiteList(address[] memory _blacks,uint256 _type) external onlyAdmin{
require(_blacks.length>0,"Enter at least one address");
if(_type == 1){
function delBlackOrWhiteList(
address[] memory _blacks,
uint256 _type
) external onlyAdmin {
require(_blacks.length > 0, "Enter at least one address");
if (_type == 1) {
address[] memory blacks = Utils.deleteAdmin(blackList, _blacks); address[] memory blacks = Utils.deleteAdmin(blackList, _blacks);
blackList = blacks; blackList = blacks;
} }
if(_type == 2){
if (_type == 2) {
address[] memory whites = Utils.deleteAdmin(whiteList, _blacks); address[] memory whites = Utils.deleteAdmin(whiteList, _blacks);
whiteList = whites;
whiteList = whites;
} }
} }
function getBlackOrWhiteList(uint256 _type) public view returns (address[] memory) {
function getBlackOrWhiteList(
uint256 _type
) public view returns (address[] memory) {
return _type == 1 ? blackList : whiteList; return _type == 1 ? blackList : whiteList;
} }
function setProductInfo(uint256[] memory _days,uint256[] memory _rates) external onlyAdmin {
function setProductInfo(
uint256[] memory _days,
uint256[] memory _rates
) external onlyAdmin {
delete productInfo; delete productInfo;
for(uint256 i=0;i<3;i++){
productInfo.push(ProductInfo(_days[i],_rates[i]));
for (uint256 i = 0; i < 3; i++) {
productInfo.push(ProductInfo(_days[i], _rates[i]));
} }
} }
function getDetails(uint256 tokenId,uint256 _type) public view returns(PledgeType memory){
if(_type == 1){
function getDetails(
uint256 tokenId,
uint256 _type
) public view returns (PledgeType memory) {
if (_type == 1) {
return pledges[tokenId]; return pledges[tokenId];
} }
return invitationPledges[tokenId]; return invitationPledges[tokenId];
} }
function addNftBalcks(uint256[] memory _tokenIds) external onlyAdmin { function addNftBalcks(uint256[] memory _tokenIds) external onlyAdmin {
require(_tokenIds.length > 0,"Parameter is empty");
require(_tokenIds.length > 0, "Parameter is empty");
nftContract.addBlacks(_tokenIds); nftContract.addBlacks(_tokenIds);
for(uint256 i=0;i<_tokenIds.length;i++){
for (uint256 i = 0; i < _tokenIds.length; i++) {
uint256 _id = _tokenIds[i]; uint256 _id = _tokenIds[i];
require(pledges[_id].sender != address(0), "NFT ID does not exist"); require(pledges[_id].sender != address(0), "NFT ID does not exist");
require(!pledges[_id].isBlack,"NFT ID already exists");
require(!pledges[_id].isBlack, "NFT ID already exists");
pledges[_id].isBlack = true; pledges[_id].isBlack = true;
} }
} }
function deleteNftBlacks(uint256[] memory _ids) external onlyAdmin { function deleteNftBlacks(uint256[] memory _ids) external onlyAdmin {
require(_ids.length > 0,"Parameter is empty");
require(_ids.length > 0, "Parameter is empty");
nftContract.delBlacks(_ids); nftContract.delBlacks(_ids);
for(uint256 i=0;i<_ids.length;i++){
for (uint256 i = 0; i < _ids.length; i++) {
uint256 _id = _ids[i]; uint256 _id = _ids[i];
require(pledges[_id].sender != address(0), "NFT ID does not exist"); require(pledges[_id].sender != address(0), "NFT ID does not exist");
pledges[_id].isBlack = false; pledges[_id].isBlack = false;
} }
} }
}
function setDayTime(uint256 time) external onlyAdmin {
dayTime = time;
}
}

55
contracts/SafeMath.sol

@ -0,0 +1,55 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;
// TODO(zx): Replace all instances of SafeMath with OZ implementation
library SafeMath {
function add(uint256 a, uint256 b) internal pure returns (uint256) {
uint256 c = a + b;
require(c >= a, "SafeMath: addition overflow");
return c;
}
function sub(uint256 a, uint256 b) internal pure returns (uint256) {
return sub(a, b, "SafeMath: subtraction overflow");
}
function sub(
uint256 a,
uint256 b,
string memory errorMessage
) internal pure returns (uint256) {
require(b <= a, errorMessage);
uint256 c = a - b;
return c;
}
function mul(uint256 a, uint256 b) internal pure returns (uint256) {
if (a == 0) {
return 0;
}
uint256 c = a * b;
require(c / a == b, "SafeMath: multiplication overflow");
return c;
}
function div(uint256 a, uint256 b) internal pure returns (uint256) {
return div(a, b, "SafeMath: division by zero");
}
function div(
uint256 a,
uint256 b,
string memory errorMessage
) internal pure returns (uint256) {
require(b > 0, errorMessage);
uint256 c = a / b;
assert(a == b * c + (a % b)); // There is no case in which this doesn't hold
return c;
}
}

65
package-lock.json

@ -5,6 +5,9 @@
"packages": { "packages": {
"": { "": {
"name": "hardhat-project", "name": "hardhat-project",
"dependencies": {
"@nomicfoundation/edr-darwin-arm64": "^0.3.8"
},
"devDependencies": { "devDependencies": {
"@nomicfoundation/hardhat-chai-matchers": "^2.0.6", "@nomicfoundation/hardhat-chai-matchers": "^2.0.6",
"@nomicfoundation/hardhat-ethers": "^3.0.5", "@nomicfoundation/hardhat-ethers": "^3.0.5",
@ -1084,17 +1087,9 @@
} }
}, },
"node_modules/@nomicfoundation/edr-darwin-arm64": { "node_modules/@nomicfoundation/edr-darwin-arm64": {
"version": "0.3.3",
"resolved": "https://registry.npmjs.org/@nomicfoundation/edr-darwin-arm64/-/edr-darwin-arm64-0.3.3.tgz",
"integrity": "sha512-E9VGsUD+1Ga4mn/5ooHsMi8JEfhZbKP6CXN/BhJ8kXbIC10NqTD1RuhCKGRtYq4vqH/3Nfq25Xg8E8RWOF4KBQ==",
"cpu": [
"arm64"
],
"dev": true,
"optional": true,
"os": [
"darwin"
],
"version": "0.3.8",
"resolved": "https://registry.npmjs.org/@nomicfoundation/edr-darwin-arm64/-/edr-darwin-arm64-0.3.8.tgz",
"integrity": "sha512-eB0leCexS8sQEmfyD72cdvLj9djkBzQGP4wSQw6SNf2I4Sw4Cnzb3d45caG2FqFFjbvfqL0t+badUUIceqQuMw==",
"engines": { "engines": {
"node": ">= 18" "node": ">= 18"
} }
@ -1227,6 +1222,22 @@
"node": ">= 18" "node": ">= 18"
} }
}, },
"node_modules/@nomicfoundation/edr/node_modules/@nomicfoundation/edr-darwin-arm64": {
"version": "0.3.3",
"resolved": "https://registry.npmjs.org/@nomicfoundation/edr-darwin-arm64/-/edr-darwin-arm64-0.3.3.tgz",
"integrity": "sha512-E9VGsUD+1Ga4mn/5ooHsMi8JEfhZbKP6CXN/BhJ8kXbIC10NqTD1RuhCKGRtYq4vqH/3Nfq25Xg8E8RWOF4KBQ==",
"cpu": [
"arm64"
],
"dev": true,
"optional": true,
"os": [
"darwin"
],
"engines": {
"node": ">= 18"
}
},
"node_modules/@nomicfoundation/ethereumjs-common": { "node_modules/@nomicfoundation/ethereumjs-common": {
"version": "4.0.4", "version": "4.0.4",
"resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-common/-/ethereumjs-common-4.0.4.tgz", "resolved": "https://registry.npmjs.org/@nomicfoundation/ethereumjs-common/-/ethereumjs-common-4.0.4.tgz",
@ -8901,14 +8912,21 @@
"@nomicfoundation/edr-win32-arm64-msvc": "0.3.3", "@nomicfoundation/edr-win32-arm64-msvc": "0.3.3",
"@nomicfoundation/edr-win32-ia32-msvc": "0.3.3", "@nomicfoundation/edr-win32-ia32-msvc": "0.3.3",
"@nomicfoundation/edr-win32-x64-msvc": "0.3.3" "@nomicfoundation/edr-win32-x64-msvc": "0.3.3"
},
"dependencies": {
"@nomicfoundation/edr-darwin-arm64": {
"version": "0.3.3",
"resolved": "https://registry.npmjs.org/@nomicfoundation/edr-darwin-arm64/-/edr-darwin-arm64-0.3.3.tgz",
"integrity": "sha512-E9VGsUD+1Ga4mn/5ooHsMi8JEfhZbKP6CXN/BhJ8kXbIC10NqTD1RuhCKGRtYq4vqH/3Nfq25Xg8E8RWOF4KBQ==",
"dev": true,
"optional": true
}
} }
}, },
"@nomicfoundation/edr-darwin-arm64": { "@nomicfoundation/edr-darwin-arm64": {
"version": "0.3.3",
"resolved": "https://registry.npmjs.org/@nomicfoundation/edr-darwin-arm64/-/edr-darwin-arm64-0.3.3.tgz",
"integrity": "sha512-E9VGsUD+1Ga4mn/5ooHsMi8JEfhZbKP6CXN/BhJ8kXbIC10NqTD1RuhCKGRtYq4vqH/3Nfq25Xg8E8RWOF4KBQ==",
"dev": true,
"optional": true
"version": "0.3.8",
"resolved": "https://registry.npmjs.org/@nomicfoundation/edr-darwin-arm64/-/edr-darwin-arm64-0.3.8.tgz",
"integrity": "sha512-eB0leCexS8sQEmfyD72cdvLj9djkBzQGP4wSQw6SNf2I4Sw4Cnzb3d45caG2FqFFjbvfqL0t+badUUIceqQuMw=="
}, },
"@nomicfoundation/edr-darwin-x64": { "@nomicfoundation/edr-darwin-x64": {
"version": "0.3.3", "version": "0.3.3",
@ -9038,7 +9056,8 @@
"version": "4.0.0", "version": "4.0.0",
"resolved": "https://registry.npmjs.org/@nomicfoundation/hardhat-toolbox/-/hardhat-toolbox-4.0.0.tgz", "resolved": "https://registry.npmjs.org/@nomicfoundation/hardhat-toolbox/-/hardhat-toolbox-4.0.0.tgz",
"integrity": "sha512-jhcWHp0aHaL0aDYj8IJl80v4SZXWMS1A2XxXa1CA6pBiFfJKuZinCkO6wb+POAt0LIfXB3gA3AgdcOccrcwBwA==", "integrity": "sha512-jhcWHp0aHaL0aDYj8IJl80v4SZXWMS1A2XxXa1CA6pBiFfJKuZinCkO6wb+POAt0LIfXB3gA3AgdcOccrcwBwA==",
"dev": true
"dev": true,
"requires": {}
}, },
"@nomicfoundation/hardhat-verify": { "@nomicfoundation/hardhat-verify": {
"version": "2.0.5", "version": "2.0.5",
@ -9155,7 +9174,8 @@
"version": "5.0.2", "version": "5.0.2",
"resolved": "https://registry.npmjs.org/@openzeppelin/contracts-upgradeable/-/contracts-upgradeable-5.0.2.tgz", "resolved": "https://registry.npmjs.org/@openzeppelin/contracts-upgradeable/-/contracts-upgradeable-5.0.2.tgz",
"integrity": "sha512-0MmkHSHiW2NRFiT9/r5Lu4eJq5UJ4/tzlOgYXNAIj/ONkQTVnz22pLxDvp4C4uZ9he7ZFvGn3Driptn1/iU7tQ==", "integrity": "sha512-0MmkHSHiW2NRFiT9/r5Lu4eJq5UJ4/tzlOgYXNAIj/ONkQTVnz22pLxDvp4C4uZ9he7ZFvGn3Driptn1/iU7tQ==",
"dev": true
"dev": true,
"requires": {}
}, },
"@openzeppelin/defender-admin-client": { "@openzeppelin/defender-admin-client": {
"version": "1.54.1", "version": "1.54.1",
@ -11121,7 +11141,8 @@
"version": "8.5.0", "version": "8.5.0",
"resolved": "https://registry.npmjs.org/ws/-/ws-8.5.0.tgz", "resolved": "https://registry.npmjs.org/ws/-/ws-8.5.0.tgz",
"integrity": "sha512-BWX0SWVgLPzYwF8lTzEy1egjhS4S4OEAHfsO8o65WOVsrnSRGaSiUaa9e0ggGlkMTtBlmOpEXiie9RUcBO86qg==", "integrity": "sha512-BWX0SWVgLPzYwF8lTzEy1egjhS4S4OEAHfsO8o65WOVsrnSRGaSiUaa9e0ggGlkMTtBlmOpEXiie9RUcBO86qg==",
"dev": true
"dev": true,
"requires": {}
} }
} }
}, },
@ -13678,7 +13699,8 @@
"version": "7.0.3", "version": "7.0.3",
"resolved": "https://registry.npmjs.org/ts-essentials/-/ts-essentials-7.0.3.tgz", "resolved": "https://registry.npmjs.org/ts-essentials/-/ts-essentials-7.0.3.tgz",
"integrity": "sha512-8+gr5+lqO3G84KdiTSMRLtuyJ+nTBVRKuCrK4lidMPdVeEp0uqC875uE5NMcaA7YYMN7XsNiFQuMvasF8HT/xQ==", "integrity": "sha512-8+gr5+lqO3G84KdiTSMRLtuyJ+nTBVRKuCrK4lidMPdVeEp0uqC875uE5NMcaA7YYMN7XsNiFQuMvasF8HT/xQ==",
"dev": true
"dev": true,
"requires": {}
}, },
"ts-node": { "ts-node": {
"version": "10.9.2", "version": "10.9.2",
@ -14158,7 +14180,8 @@
"version": "7.4.6", "version": "7.4.6",
"resolved": "https://registry.npmjs.org/ws/-/ws-7.4.6.tgz", "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.6.tgz",
"integrity": "sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A==", "integrity": "sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A==",
"dev": true
"dev": true,
"requires": {}
}, },
"y18n": { "y18n": {
"version": "5.0.8", "version": "5.0.8",

3
package.json

@ -28,5 +28,8 @@
"deploy:dev": "npx hardhat run --network bscTest scripts/deployProxy.ts", "deploy:dev": "npx hardhat run --network bscTest scripts/deployProxy.ts",
"deploy:local": "npx hardhat run --network local scripts/deployProxy.ts", "deploy:local": "npx hardhat run --network local scripts/deployProxy.ts",
"deploy:prod": "npx hardhat run --network bscMain scripts/deployProxy.ts" "deploy:prod": "npx hardhat run --network bscMain scripts/deployProxy.ts"
},
"dependencies": {
"@nomicfoundation/edr-darwin-arm64": "^0.3.8"
} }
} }

10
scripts/deployProxy.ts

@ -1,3 +1,4 @@
import { toBigInt } from "ethers";
import { ethers, upgrades } from "hardhat"; import { ethers, upgrades } from "hardhat";
async function main() { async function main() {
@ -8,11 +9,11 @@ async function main() {
const FIL_ADDRESS = process.env.FIL_ADDRESS const FIL_ADDRESS = process.env.FIL_ADDRESS
// const FIL_ADDRESS = fil.target // const FIL_ADDRESS = fil.target
console.log('fil地址:',FIL_ADDRESS);
console.log('fil地址:', FIL_ADDRESS);
console.log("開始部署NFT合約"); console.log("開始部署NFT合約");
const NFT = await ethers.getContractFactory("NFT"); const NFT = await ethers.getContractFactory("NFT");
const baseURI = "ipfs://QmQpgq4FvXNHZfoytpiwk617Nozmeu7iMiyiSzthVg1ZV7/metadata.json"
const baseURI = "ipfs://QmXrE6iMBSHKe6jcLJnXtC9RtnUyjdJx9sBFbvLUTMunQv/metadata.json"
const nft = await NFT.deploy("SOFIL NFT", "SFSC", baseURI); const nft = await NFT.deploy("SOFIL NFT", "SFSC", baseURI);
console.log("NFT合約", nft.target); console.log("NFT合約", nft.target);
@ -35,11 +36,16 @@ async function main() {
await tx.wait() await tx.wait()
const tx1 = await pool.setPledgeContractAddress(pledge.target); const tx1 = await pool.setPledgeContractAddress(pledge.target);
await tx1.wait() await tx1.wait()
// 主网删除
const tx2 = await pledge.setDayTime(toBigInt(60))
await tx2.wait()
// 測試使用 // 測試使用
console.log('設置成功'); console.log('設置成功');
console.log('NFT的質押合約地址', await nft.pledgeAddress()); console.log('NFT的質押合約地址', await nft.pledgeAddress());
console.log('Pool的質押合約地址', await pool._pledgeContractAddress()); console.log('Pool的質押合約地址', await pool._pledgeContractAddress());
console.log('质押时间', await pledge.dayTime()); console.log('质押时间', await pledge.dayTime());
} }

4
sync.block.js

@ -1122,7 +1122,7 @@ const _abi = [
] ]
const private = '0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80' const private = '0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80'
const provider = new ethers.JsonRpcProvider("http://127.0.0.1:8545") const provider = new ethers.JsonRpcProvider("http://127.0.0.1:8545")
const contractAddress = "0x5eb3Bc0a489C5A8288765d2336659EbCA68FCd00";
const contractAddress = "0xA51c1fc2f0D1a1b8494Ed1FE312d7C3a78Ed91C0";
const wallet = new ethers.Wallet(private, provider); const wallet = new ethers.Wallet(private, provider);
const contract = new ethers.Contract(contractAddress, _abi, wallet) const contract = new ethers.Contract(contractAddress, _abi, wallet)
@ -1132,7 +1132,7 @@ async function sync() {
const res = await contract.setDayTime(ethers.toBigInt(1)) const res = await contract.setDayTime(ethers.toBigInt(1))
a++ a++
} }
// 0x2ADDed672bacEfe857a408B577CB7DF1f6687c07
setInterval(() => { setInterval(() => {
sync() sync()
}, 5000) }, 5000)

35
test/Pledge.ts

@ -10,7 +10,7 @@ describe("NFT", function () {
const fil = await FIL.deploy(); const fil = await FIL.deploy();
const NFT = await ethers.getContractFactory("NFT"); const NFT = await ethers.getContractFactory("NFT");
const nft = await NFT.deploy("MyNFT", "MNFT");
const nft = await NFT.deploy("MyNFT", "MNFT", "123");
const Pool = await ethers.getContractFactory("Pool"); const Pool = await ethers.getContractFactory("Pool");
const pool = await upgrades.deployProxy(Pool, [fil.target, nft.target]); const pool = await upgrades.deployProxy(Pool, [fil.target, nft.target]);
@ -21,9 +21,9 @@ describe("NFT", function () {
pool.target, pool.target,
]); ]);
await nft.setPledgeAddress(pledge.target);
await pool.setPledgeContractAddress(pledge.target);
await pledge.setDayTime(ethers.toBigInt(1));
// await nft.setPledgeAddress(pledge.target);
// await pool.setPledgeContractAddress(pledge.target);
// await pledge.setDayTime(ethers.toBigInt(1));
return { nft, owner, otherAccount, pool, pledge, fil }; return { nft, owner, otherAccount, pool, pledge, fil };
} }
@ -53,16 +53,23 @@ describe("NFT", function () {
// }); // });
describe("Test Contract", async function () { describe("Test Contract", async function () {
it("测试NFT黑名单", async () => {
const { pledge,fil,pool,otherAccount,owner,nft } = await loadFixture(deployOneYearLockFixture);
await fil.approve(pool.target, ethers.parseEther("1000"));
await pledge.pledge(ethers.parseEther("1000"), "0x2",otherAccount.address);
// console.log(await pledge.getOwnerAllPledgeInfo(owner.address));
await pledge.addNftBalcks(["0x1"])
await nft.setApprovalForAll(pledge.target,true)
await pledge.destroyPledge("0x1")
});
// it("测试NFT黑名单", async () => {
// const { pledge, fil, pool, otherAccount, owner, nft } = await loadFixture(deployOneYearLockFixture);
// await fil.approve(pool.target, ethers.parseEther("1000"));
// await pledge.pledge(ethers.parseEther("1000"), "0x2", otherAccount.address);
// // console.log(await pledge.getOwnerAllPledgeInfo(owner.address));
// await pledge.addNftBalcks(["0x1"])
// await nft.setApprovalForAll(pledge.target, true)
// await pledge.destroyPledge("0x1")
// });
it("测试安全计算", async function () {
const { pool, owner, pledge, fil } = await loadFixture(deployOneYearLockFixture);
console.log(await pledge.safeAdd(ethers.parseEther("10000000000000000000000000000"), ethers.parseEther("10000000000000000")));
})
// it("测试质押销毁",async ()=>{ // it("测试质押销毁",async ()=>{

Loading…
Cancel
Save