update add and abi
This commit is contained in:
parent
a0c5f7615f
commit
9d31dc8ce8
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -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;
|
||||||
|
|
||||||
|
96
contracts/logic/ExecuteRelay.sol
Normal file
96
contracts/logic/ExecuteRelay.sol
Normal 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);
|
||||||
|
}
|
||||||
|
}
|
@ -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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
45
contracts/tokens/erc721/NFTSbt.sol
Normal file
45
contracts/tokens/erc721/NFTSbt.sol
Normal 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;
|
||||||
|
}
|
||||||
|
}
|
@ -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}`
|
||||||
);
|
);
|
||||||
|
@ -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"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
Loading…
x
Reference in New Issue
Block a user