Skip to content

Commit

Permalink
New logic for IERCPublicData interface
Browse files Browse the repository at this point in the history
  • Loading branch information
weiqiushi committed Jan 8, 2024
1 parent 481d42b commit e47164b
Show file tree
Hide file tree
Showing 5 changed files with 133 additions and 133 deletions.
6 changes: 5 additions & 1 deletion contracts/dmc.sol
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,12 @@ contract DMCToken is ERC20, Ownable {
_;
}

constructor(uint256 _maxSupply) ERC20("Datamall Chain Token", "DMC") Ownable(msg.sender) {
constructor(uint256 _maxSupply, address[] memory initAddress, uint[] memory initAmount) ERC20("Datamall Chain Token", "DMC") Ownable(msg.sender) {
maxSupply = _maxSupply;

for (uint i = 0; i < initAddress.length; i++) {
_mint(initAddress[i], initAmount[i]);
}
}

function enableMinter(address[] calldata addresses) public onlyOwner {
Expand Down
30 changes: 8 additions & 22 deletions contracts/nft_bridge.sol
Original file line number Diff line number Diff line change
@@ -1,33 +1,19 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/token/ERC721/IERC721.sol";
import "./public_data_storage.sol";

contract NFTBridge is Ownable {
struct NFTInfo {
address nftContract;
uint256 tokenId;
}
mapping (bytes32 => address) initOwnerData;
mapping (bytes32 => NFTInfo) nftInfos;

constructor() Ownable(msg.sender) {
}
contract NFTBridge is IERCPublicDataContract {
mapping (bytes32 => address) ownerData;

function setOwnerData(bytes32 dataMixedHash, address owner) public onlyOwner {
initOwnerData[dataMixedHash] = owner;
constructor() {
}

function setNFTInfo(bytes32 dataMixedHash, address nftContract, uint256 tokenId) public onlyOwner {
nftInfos[dataMixedHash] = NFTInfo(nftContract, tokenId);
function setData(bytes32 dataMixedHash) public {
ownerData[dataMixedHash] = msg.sender;
}

function getOwner(bytes32 dataMixedHash) public view returns (address) {
address owner = initOwnerData[dataMixedHash];
if (owner == address(0)) {
owner = IERC721(nftInfos[dataMixedHash].nftContract).ownerOf(nftInfos[dataMixedHash].tokenId);
}
return owner;
function getDataOwner(bytes32 dataMixedHash) public view returns (address) {
return ownerData[dataMixedHash];
}
}
80 changes: 24 additions & 56 deletions contracts/public_data_storage.sol
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,12 @@ interface IERCPublicDataContract {
//return the owner of the data
function getDataOwner(bytes32 dataHash) external view returns (address);
}

/*
interface IERC721VerifyDataHash{
//return token data hash
function tokenDataHash(uint256 _tokenId) external view returns (bytes32);
}
*/
// Review: 考虑有一些链的出块时间不确定,使用区块间隔要谨慎,可以用区块的时间戳


Expand All @@ -39,13 +40,10 @@ interface IERC721VerifyDataHash{

contract PublicDataStorage is Initializable, UUPSUpgradeable, OwnableUpgradeable {
enum ShowType { Normal, Immediately }
enum BridgeUsage { Force, Perfered, Deny}

struct PublicData {
address owner;
address sponsor;
address nftContract;
uint256 tokenId;
address dataContract;
uint256 maxDeposit;
uint256 dataBalance;
uint64 depositRatio;
Expand All @@ -70,13 +68,13 @@ contract PublicDataStorage is Initializable, UUPSUpgradeable, OwnableUpgradeable

GWTToken public gwtToken;// Gb per Week Token
address public foundationAddress;
NFTBridge public nftBridge;
BridgeUsage public bridgeUsage;

mapping(address => SupplierInfo) _supplierInfos;
mapping(bytes32 => PublicData) _publicDatas;
mapping(uint256 => DataProof) _publicDataProofs;

mapping(address => bool) _allowedPublicDataContract;

struct CycleDataInfo {
address[] lastShowers;
uint64 score;// score = 0表示已经提现过了
Expand Down Expand Up @@ -116,7 +114,7 @@ contract PublicDataStorage is Initializable, UUPSUpgradeable, OwnableUpgradeable
}

SysConfig public sysConfig;
uint256 constant totalRewardScore = 1600;
uint256 public totalRewardScore;

event SupplierBalanceChanged(address supplier, uint256 avalibleBalance, uint256 lockedBalance);
event GWTStacked(address supplier, uint256 amount);
Expand All @@ -131,20 +129,19 @@ contract PublicDataStorage is Initializable, UUPSUpgradeable, OwnableUpgradeable
event ShowDataProof(address supplier, bytes32 dataMixedHash, uint256 nonce_block);
event WithdrawAward(bytes32 mixedHash, uint256 cycle);

function initialize(address _gwtToken, address _Foundation, address _nftBridge) public initializer {
__PublicDataStorageUpgradable_init(_gwtToken, _Foundation, _nftBridge);
function initialize(address _gwtToken, address _Foundation) public initializer {
__PublicDataStorageUpgradable_init(_gwtToken, _Foundation);
}

function __PublicDataStorageUpgradable_init(address _gwtToken, address _Foundation, address _nftBridge) internal onlyInitializing {
function __PublicDataStorageUpgradable_init(address _gwtToken, address _Foundation) internal onlyInitializing {
__UUPSUpgradeable_init();
__Ownable_init(msg.sender);

gwtToken = GWTToken(_gwtToken);
nftBridge = NFTBridge(_nftBridge);
_startBlock = block.number;
_currectCycle = 0;
foundationAddress = _Foundation;
bridgeUsage = BridgeUsage.Force;
totalRewardScore = 1600;

// 设置初始参数
sysConfig.minDepositRatio = 64; // create data时最小为64倍
Expand All @@ -164,8 +161,12 @@ contract PublicDataStorage is Initializable, UUPSUpgradeable, OwnableUpgradeable

}

function setBridgeUsage(BridgeUsage usage) public onlyOwner {
bridgeUsage = usage;
function allowPublicDataContract(address contractAddr) public onlyOwner {
_allowedPublicDataContract[contractAddr] = true;
}

function denyPublicDataContract(address contractAddr) public onlyOwner {
_allowedPublicDataContract[contractAddr] = false;
}

function setSysConfig(SysConfig calldata config) public onlyOwner {
Expand Down Expand Up @@ -233,12 +234,14 @@ contract PublicDataStorage is Initializable, UUPSUpgradeable, OwnableUpgradeable
bytes32 dataMixedHash,
uint64 depositRatio,
uint256 depositAmount,
address publicDataContract,
uint256 tokenId
address publicDataContract
) public {
require(dataMixedHash != bytes32(0), "data hash is empty");
require(_allowedPublicDataContract[publicDataContract], " data contract not allowed");
require(IERCPublicDataContract(publicDataContract).getDataOwner(dataMixedHash) != address(0), "not found in data contract");

// 质押率影响用户SHOW数据所需要冻结的质押
require(depositRatio >= sysConfig.minDepositRatio, "deposit ratio is too small");
require(dataMixedHash != bytes32(0), "data hash is empty");
// minAmount = 数据大小*GWT兑换比例*最小时长*质押率
// get data size from data hash
uint64 dataSize = PublicDataProof.lengthFromMixedHash(dataMixedHash);
Expand All @@ -251,32 +254,9 @@ contract PublicDataStorage is Initializable, UUPSUpgradeable, OwnableUpgradeable
publicDataInfo.depositRatio = depositRatio;
publicDataInfo.maxDeposit = depositAmount;
publicDataInfo.sponsor = msg.sender;
publicDataInfo.dataContract = publicDataContract;
gwtToken.transferFrom(msg.sender, address(this), depositAmount);

address owner = address(0);
if (bridgeUsage != BridgeUsage.Deny) {
owner = nftBridge.getOwner(dataMixedHash);
}

// force模式,从桥合约一定能取到值
if (bridgeUsage == BridgeUsage.Force) {
require(owner != address(0), "data hash not in bridge");
}

// perfered模式,以nftBridge的结果为准
if (owner == address(0)) {
if (publicDataContract == address(0)) {
publicDataInfo.owner = msg.sender;
} else { // 认为publicDataContract是IERC721VerifyDataHash
require(dataMixedHash == IERC721VerifyDataHash(publicDataContract).tokenDataHash(tokenId), "NFT data hash mismatch");
publicDataInfo.nftContract = publicDataContract;
publicDataInfo.tokenId = tokenId;
}
} else {
publicDataInfo.nftContract = address(nftBridge);
// 不需要设置token id;因为nftBridge是以hash做key的
}

uint256 balance_add = (depositAmount * 8) / 10;
publicDataInfo.dataBalance += balance_add;
uint256 system_reward = depositAmount - balance_add;
Expand Down Expand Up @@ -306,11 +286,7 @@ contract PublicDataStorage is Initializable, UUPSUpgradeable, OwnableUpgradeable

function getOwner(bytes32 dataMixedHash) public view returns(address) {
PublicData memory info = _publicDatas[dataMixedHash];
if (info.owner != address(0)) {
return info.owner;
} else {
return IERCPublicDataContract(info.nftContract).getDataOwner(dataMixedHash);
}
return _getDataOwner(dataMixedHash, info);
}

function addDeposit(bytes32 dataMixedHash, uint256 depositAmount) public {
Expand Down Expand Up @@ -558,15 +534,7 @@ contract PublicDataStorage is Initializable, UUPSUpgradeable, OwnableUpgradeable
}

function _getDataOwner(bytes32 dataMixedHash, PublicData memory publicDataInfo) internal view returns(address) {
if (publicDataInfo.nftContract == address(nftBridge)) {
return nftBridge.getOwner(dataMixedHash);
}

if (publicDataInfo.owner != address(0)) {
return publicDataInfo.owner;
} else {
return IERCPublicDataContract(publicDataInfo.nftContract).getDataOwner(dataMixedHash);
}
return IERCPublicDataContract(publicDataInfo.dataContract).getDataOwner(dataMixedHash);
}

// return: 1: sponsor, 2- 6: last shower, 7: owner, 0: no one
Expand Down
84 changes: 50 additions & 34 deletions scripts/deploy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,62 +11,78 @@ async function main() {
let gwtAddress = await gwtContract.getAddress();
console.log("GWT deployed to:", gwtAddress);

let exchange = await (await upgrades.deployProxy(await ethers.getContractFactory("Exchange"),
[dmcAddress, gwtAddress],
{
initializer: "initialize",
kind: "uups",
timeout: 0
})).waitForDeployment() as unknown as Exchange;

const luckyMint = await (await ethers.deployContract("LuckyMint")).waitForDeployment();

let exchange = await (await upgrades.deployProxy(await ethers.getContractFactory("Exchange"),
[dmcAddress, gwtAddress],
{
initializer: "initialize",
kind: "uups",
timeout: 0
})).waitForDeployment() as unknown as Exchange;

let listLibrary = await (await ethers.getContractFactory("SortedScoreList")).deploy();
let proofLibrary = await (await ethers.getContractFactory("PublicDataProof")).deploy();

let foundationAddress = (await ethers.getSigners())[19].address;

const publicDataStorage = await (await ethers.deployContract("PublicDataStorage", [gwtAddress, foundationAddress], {libraries: {
"SortedScoreList": await listLibrary.getAddress(),
"PublicDataProof": await proofLibrary.getAddress()
}})).waitForDeployment();


const publicDataStorage = await (await upgrades.deployProxy(await ethers.getContractFactory("PublicDataStorage", {
libraries: {
"SortedScoreList": await listLibrary.getAddress(),
"PublicDataProof": await proofLibrary.getAddress()
}
}),
[gwtAddress, foundationAddress],
{
initializer: "initialize",
kind: "uups",
timeout: 0,
unsafeAllow: ["external-library-linking"],
})).waitForDeployment();

let publicDataStorageAddress = await publicDataStorage.getAddress();
console.log("PublicDataStorage deployed to:", publicDataStorageAddress);

let bridge = await (await ethers.getContractFactory("NFTBridge")).deploy();

await (await gwtContract.enableMinter([await exchange.getAddress()])).wait();

await(await gwtContract.enableTransfer([publicDataStorageAddress])).wait();
await (await gwtContract.enableTransfer([publicDataStorageAddress])).wait();

let config = await publicDataStorage.sysConfig();
let setConfig: PublicDataStorage.SysConfigStruct = {
minDepositRatio: config.minDepositRatio,
minPublicDataStorageWeeks: config.minPublicDataStorageWeeks,
minLockWeeks: config.minLockWeeks,
blocksPerCycle: config.blocksPerCycle,
topRewards: config.topRewards,
lockAfterShow: config.lockAfterShow,
showTimeout: config.showTimeout,
maxNonceBlockDistance: config.maxNonceBlockDistance,
minRankingScore: config.minRankingScore,
minDataSize: config.minDataSize
};
setConfig.showTimeout = 720n;
setConfig.lockAfterShow = 720n;
setConfig.minRankingScore = 1n;
await (await publicDataStorage.setSysConfig(setConfig)).wait();
let setConfig: PublicDataStorage.SysConfigStruct = {
minDepositRatio: config.minDepositRatio,
minPublicDataStorageWeeks: config.minPublicDataStorageWeeks,
minLockWeeks: config.minLockWeeks,
blocksPerCycle: config.blocksPerCycle,
topRewards: config.topRewards,
lockAfterShow: config.lockAfterShow,
showTimeout: config.showTimeout,
maxNonceBlockDistance: config.maxNonceBlockDistance,
minRankingScore: config.minRankingScore,
minDataSize: config.minDataSize,
createDepositRatio: config.createDepositRatio,
};
setConfig.showTimeout = 720n;
setConfig.lockAfterShow = 720n;
setConfig.minRankingScore = 1n;
await (await publicDataStorage.setSysConfig(setConfig)).wait();
await (await publicDataStorage.allowPublicDataContract(await bridge.getAddress())).wait()

if (network.name !== "hardhat") {
fs.writeFileSync(`${network.name}-deployed.json`, JSON.stringify({
DMCToken: dmcAddress,
GWTToken: gwtAddress,
exchange: await exchange.getAddress(),
PublicDataStore: publicDataStorageAddress
PublicDataStore: publicDataStorageAddress,
LuckyMint: await luckyMint.getAddress(),
}));
}
}

// We recommend this pattern to be able to use async/await everywhere
// and properly handle errors.
main().catch((error) => {
console.error(error);
process.exitCode = 1;
console.error(error);
process.exitCode = 1;
});
Loading

0 comments on commit e47164b

Please sign in to comment.