update add and abi

This commit is contained in:
zhl 2023-06-08 13:54:47 +08:00
parent a0c5f7615f
commit 9d31dc8ce8
9 changed files with 4341 additions and 5922 deletions

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -4,10 +4,7 @@ pragma solidity 0.8.10;
import "@openzeppelin/contracts/token/ERC721/IERC721.sol"; import "@openzeppelin/contracts/token/ERC721/IERC721.sol";
interface IAsset is IERC721 { interface IAsset is IERC721 {
function batchMint( function batchMint(address to, uint256[] memory tokenIds) external;
address to,
uint256[] memory tokenIds
) external returns (uint256[] memory);
function burn(address owner, uint256[] memory ids) external; function burn(address owner, uint256[] memory ids) external;

View File

@ -0,0 +1,96 @@
// SPDX-License-Identifier: MIT
pragma solidity 0.8.10;
import "../core/HasSignature.sol";
import "../utils/TimeChecker.sol";
interface IToken {
function transferFrom(
address from,
address to,
uint256 amount
) external returns (bool);
function signApprove(
address spender,
uint256 amount,
uint256 startTime,
uint256 saltNonce,
bytes calldata signature
) external;
}
contract ExecuteRelay is HasSignature, TimeChecker {
constructor() HasSignature("ExecuteRelay", "1") {}
address public tokenAddress;
event MethodExecuted(
address indexed sender,
address indexed target,
bytes data,
uint256 gasUsed,
uint256 tokenAmount
);
function execute(
address sender,
address target,
uint256 value,
bytes calldata data,
uint256 startTime,
uint256 saltNonce,
bytes calldata signature
) external payable signatureValid(signature) timeValid(startTime) {
bytes32 messageHash = getMessageHash(
target,
value,
data,
startTime,
saltNonce
);
uint256 gasStart = gasleft();
checkSigner712(sender, messageHash, signature);
uint256 gasPrice = tx.gasprice;
_call(target, value, data);
uint256 gasUsed = gasStart - gasleft();
uint256 tokenAmount = gasPrice * gasUsed; // TODO:: calc real token amount
IToken(tokenAddress).signApprove(
sender,
tokenAmount,
startTime,
saltNonce,
signature
);
IToken(tokenAddress).transferFrom(sender, address(this), tokenAmount);
_useSignature(signature);
emit MethodExecuted(sender, target, data, gasUsed, tokenAmount);
}
/**
* @dev Execute an operation's call.
*
* Emits a {CallExecuted} event.
*/
function _call(address target, uint256 value, bytes calldata data) private {
(bool success, ) = target.call{value: value}(data);
require(success, "ExecuteRelay: underlying transaction reverted");
}
function getMessageHash(
address _target,
uint256 _value,
bytes calldata _data,
uint256 _startTime,
uint256 _saltNonce
) public pure returns (bytes32) {
bytes memory encoded = abi.encodePacked(
_target,
_value,
_data,
_startTime,
_saltNonce
);
return keccak256(encoded);
}
}

View File

@ -5,14 +5,12 @@ import "@openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol";
import "@openzeppelin/contracts/security/Pausable.sol"; import "@openzeppelin/contracts/security/Pausable.sol";
import "@openzeppelin/contracts/access/AccessControl.sol"; import "@openzeppelin/contracts/access/AccessControl.sol";
import "../../core/HasSignature.sol"; import "../../core/HasSignature.sol";
import "../../utils/TimeChecker.sol";
contract FTSigner is contract FTSigner is
ERC20, ERC20,
ERC20Burnable, ERC20Burnable,
Pausable, Pausable,
AccessControl, AccessControl,
TimeChecker,
HasSignature HasSignature
{ {
bytes32 public constant PAUSER_ROLE = keccak256("PAUSER_ROLE"); bytes32 public constant PAUSER_ROLE = keccak256("PAUSER_ROLE");
@ -78,31 +76,14 @@ contract FTSigner is
* @dev Approve by signature * @dev Approve by signature
*/ */
function signApprove( function signApprove(
address owner,
address spender, address spender,
uint256 amount, uint256 amount,
uint256 startTime, bytes32 messageHash,
uint256 saltNonce,
bytes calldata signature bytes calldata signature
) external signatureValid(signature) timeValid(startTime) { ) external {
bytes32 messageHash = getMessageHash(spender, amount, startTime, saltNonce);
address owner = _msgSender();
checkSigner712(owner, messageHash, signature); checkSigner712(owner, messageHash, signature);
_approve(owner, spender, amount); _approve(owner, spender, amount);
_useSignature(signature); _useSignature(signature);
} }
function getMessageHash(
address _spender,
uint256 _amount,
uint256 _startTime,
uint256 _saltNonce
) public pure returns (bytes32) {
bytes memory encoded = abi.encodePacked(
_spender,
_amount,
_startTime,
_saltNonce
);
return keccak256(encoded);
}
} }

View File

@ -9,7 +9,6 @@ contract NFT is AccessControl, ERC721Enumerable {
bytes32 public constant MINTER_ROLE = keccak256("MINTER_ROLE"); bytes32 public constant MINTER_ROLE = keccak256("MINTER_ROLE");
bytes32 public constant LOCK_ROLE = keccak256("LOCK_ROLE"); bytes32 public constant LOCK_ROLE = keccak256("LOCK_ROLE");
uint256 public immutable supplyLimit; uint256 public immutable supplyLimit;
uint256 tokenIndex;
event Lock(uint256 indexed tokenId); event Lock(uint256 indexed tokenId);
event UnLock(uint256 indexed tokenId); event UnLock(uint256 indexed tokenId);
@ -45,7 +44,7 @@ contract NFT is AccessControl, ERC721Enumerable {
function batchMint( function batchMint(
address to, address to,
uint256[] memory tokenIds uint256[] memory tokenIds
) external onlyRole(MINTER_ROLE) returns (uint256[] memory) { ) external onlyRole(MINTER_ROLE) {
uint256 count = tokenIds.length; uint256 count = tokenIds.length;
require(count <= 100, "tokenIds too many"); require(count <= 100, "tokenIds too many");
if (supplyLimit > 0) { if (supplyLimit > 0) {
@ -55,13 +54,10 @@ contract NFT is AccessControl, ERC721Enumerable {
); );
} }
for (uint256 i = 0; i < count; i++) { for (uint256 i = 0; i < count; i++) {
tokenIndex += 1; uint256 tokenId = tokenIds[i];
uint256 tokenId = tokenIndex;
_safeMint(to, tokenId); _safeMint(to, tokenId);
tokenIds[i] = tokenId;
} }
emit BatchMint(to, tokenIds); emit BatchMint(to, tokenIds);
return tokenIds;
} }
/** /**

View File

@ -0,0 +1,45 @@
// SPDX-License-Identifier: MIT
pragma solidity 0.8.10;
import "@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/utils/Counters.sol";
contract Soulbound is ERC721Enumerable, Ownable {
using Counters for Counters.Counter;
string private _baseTokenURI = "https://market.cebg.games/api/nft/info/";
uint256 public immutable supplyLimit;
Counters.Counter private _tokenIdCounter;
constructor(
string memory _name,
string memory _symbol,
uint256 _supplyLimt
) ERC721(_name, _symbol) {
supplyLimit = _supplyLimt;
}
function _beforeTokenTransfer(
address from,
address to,
uint256 tokenId
) internal override(ERC721Enumerable) {
require(from == address(0), "Token not transferable");
super._beforeTokenTransfer(from, to, tokenId);
}
function mint() public {
if (supplyLimit > 0) {
require((totalSupply() + 1) <= supplyLimit, "Exceed the total supply");
}
address to = msg.sender;
uint256 tokenId = _tokenIdCounter.current();
_tokenIdCounter.increment();
_safeMint(to, tokenId);
}
function _baseURI() internal view virtual override returns (string memory) {
return _baseTokenURI;
}
}

View File

@ -34,9 +34,9 @@ module.exports = async function main(callback) {
const usdtInstance = await await FT.at( const usdtInstance = await await FT.at(
cfgs.find((c) => c.name === "BEUSDT").address cfgs.find((c) => c.name === "BEUSDT").address
); );
config.market.paymentTokens.push(coinInstance.address); // config.market.paymentTokens.push(coinInstance.address);
config.market.paymentTokens.push(goldInstance.address); // config.market.paymentTokens.push(goldInstance.address);
config.market.paymentTokens.push(usdtInstance.address); // config.market.paymentTokens.push(usdtInstance.address);
// await heroInstance.updateBaseURI(config.token.baseTokenURI); // await heroInstance.updateBaseURI(config.token.baseTokenURI);
// console.log("BEHero baseURI update success."); // console.log("BEHero baseURI update success.");
@ -49,48 +49,48 @@ module.exports = async function main(callback) {
); );
const ROUND = 1000000; const ROUND = 1000000;
const DECIMALS = 1000000000000000000; const DECIMALS = 1000000000000000000;
if (marketInstance) { // if (marketInstance) {
await marketInstance.setFeeToAddress(config.market.feeToAddress); // await marketInstance.setFeeToAddress(config.market.feeToAddress);
console.log( // console.log(
`market receive fee address set to : ${config.market.feeToAddress}` // `market receive fee address set to : ${config.market.feeToAddress}`
); // );
await marketInstance.setTransactionFee((4 * ROUND) / 100); // await marketInstance.setTransactionFee((4 * ROUND) / 100);
await marketInstance.addERC721Support(heroInstance.address); // await marketInstance.addERC721Support(heroInstance.address);
await marketInstance.addERC721Support(equipInstance.address); // await marketInstance.addERC721Support(equipInstance.address);
await marketInstance.addERC721Support(chipInstance.address); // await marketInstance.addERC721Support(chipInstance.address);
const maxPrice = web3.utils.toWei("99990000"); // const maxPrice = web3.utils.toWei("99990000");
const minPrice = web3.utils.toWei("0.01"); // const minPrice = web3.utils.toWei("0.01");
await marketInstance.setNFTPriceMaxLimit(heroInstance.address, maxPrice); // await marketInstance.setNFTPriceMaxLimit(heroInstance.address, maxPrice);
await marketInstance.setNFTPriceMinLimit(heroInstance.address, minPrice); // await marketInstance.setNFTPriceMinLimit(heroInstance.address, minPrice);
await marketInstance.setNFTPriceMaxLimit(equipInstance.address, maxPrice); // await marketInstance.setNFTPriceMaxLimit(equipInstance.address, maxPrice);
await marketInstance.setNFTPriceMinLimit(equipInstance.address, minPrice); // await marketInstance.setNFTPriceMinLimit(equipInstance.address, minPrice);
await marketInstance.setNFTPriceMaxLimit(chipInstance.address, maxPrice); // await marketInstance.setNFTPriceMaxLimit(chipInstance.address, maxPrice);
await marketInstance.setNFTPriceMinLimit(chipInstance.address, minPrice); // await marketInstance.setNFTPriceMinLimit(chipInstance.address, minPrice);
for (let token of config.market.paymentTokens) { // for (let token of config.market.paymentTokens) {
await marketInstance.addERC20Support(token); // await marketInstance.addERC20Support(token);
console.log(`add token for market payment: ${token}`); // console.log(`add token for market payment: ${token}`);
} // }
console.log(`finish update market config`); // console.log(`finish update market config`);
// await heroInstance.grantLockRole(marketInstance.address); // // await heroInstance.grantLockRole(marketInstance.address);
// await heroInstance.setApprovalForAll(marketInstance.address, true); // // await heroInstance.setApprovalForAll(marketInstance.address, true);
// console.log("finish heroInstance.addApprovalWhitelist"); // // console.log("finish heroInstance.addApprovalWhitelist");
// await equipInstance.grantLockRole(marketInstance.address); // // await equipInstance.grantLockRole(marketInstance.address);
// await equipInstance.setApprovalForAll(marketInstance.address, true); // // await equipInstance.setApprovalForAll(marketInstance.address, true);
// console.log("finish equipInstance.addApprovalWhitelist"); // // console.log("finish equipInstance.addApprovalWhitelist");
// await chipInstance.grantLockRole(marketInstance.address); // // await chipInstance.grantLockRole(marketInstance.address);
// await chipInstance.setApprovalForAll(marketInstance.address, true); // // await chipInstance.setApprovalForAll(marketInstance.address, true);
// console.log("finish chipInstance.addApprovalWhitelist"); // // console.log("finish chipInstance.addApprovalWhitelist");
await heroInstance.grantLockRole(config.admins.admin); // await heroInstance.grantLockRole(config.admins.admin);
await equipInstance.grantLockRole(config.admins.admin); // await equipInstance.grantLockRole(config.admins.admin);
await chipInstance.grantLockRole(config.admins.admin); // await chipInstance.grantLockRole(config.admins.admin);
console.log( // console.log(
`Allow operation ${marketInstance.address} to reduce gas fee` // `Allow operation ${marketInstance.address} to reduce gas fee`
); // );
} // }
const factoryInstance = await await UserMinterFactory.at( const factoryInstance = await await UserMinterFactory.at(
cfgs.find((c) => c.name === "UserMinterFactory").address cfgs.find((c) => c.name === "UserMinterFactory").address
@ -106,6 +106,10 @@ module.exports = async function main(callback) {
await equipInstance.setMintRole(factoryInstance.address); await equipInstance.setMintRole(factoryInstance.address);
await chipInstance.setMintRole(factoryInstance.address); await chipInstance.setMintRole(factoryInstance.address);
await factoryInstance.addTokenSupport(heroInstance.address);
await factoryInstance.addTokenSupport(equipInstance.address);
await factoryInstance.addTokenSupport(chipInstance.address);
console.log( console.log(
`Allow factory ${factoryInstance.address} to mint contract \n hero: ${heroInstance.address}, \n equip: ${equipInstance.address}, \n chip: ${chipInstance.address}` `Allow factory ${factoryInstance.address} to mint contract \n hero: ${heroInstance.address}, \n equip: ${equipInstance.address}, \n chip: ${chipInstance.address}`
); );

View File

@ -15,19 +15,19 @@
"name": "HERO", "name": "HERO",
"type": "erc721", "type": "erc721",
"json": "assets/contracts/NFT.json", "json": "assets/contracts/NFT.json",
"address": "0x376076491F4fa4139f6FFec8D4abdE92f186f312" "address": "0xE6A69474E04B93De50dd07F239d62879dB9bF716"
}, },
{ {
"name": "WEAPON", "name": "WEAPON",
"type": "erc721", "type": "erc721",
"json": "assets/contracts/NFT.json", "json": "assets/contracts/NFT.json",
"address": "0xA89327d3ca77c1f3982a426fe5fB06bAEA7E383F" "address": "0x8Ce844402bE22fA1276a375Ff2354DD27aDEF285"
}, },
{ {
"name": "CHIP", "name": "CHIP",
"type": "erc721", "type": "erc721",
"json": "assets/contracts/NFT.json", "json": "assets/contracts/NFT.json",
"address": "0x07Bad070e403a4Bad2Eec3BA3894c4524d3d2674" "address": "0x4678fE0177B15538F441264cB851364d9F3872AA"
}, },
{ {
"name": "BEUSDT", "name": "BEUSDT",
@ -51,6 +51,6 @@
"name": "UserMinterFactory", "name": "UserMinterFactory",
"type": "logic", "type": "logic",
"json": "assets/contracts/UserMinterFactory.json", "json": "assets/contracts/UserMinterFactory.json",
"address": "0x0973C4ecDd44Aad50A7Dbe5fa450e7b6242C3a1d" "address": "0x1A27515c35a92Fb276c2670fa27C85ffAd75D094"
} }
] ]