mirror of
https://github.com/c9s/bbgo.git
synced 2024-11-26 08:45:16 +00:00
Merge pull request #440 from zenixls2/main
Solidity contract: add missing files on bbgo contract folder
This commit is contained in:
commit
83129a4927
17
contracts/.eslintrc.js
Normal file
17
contracts/.eslintrc.js
Normal file
|
@ -0,0 +1,17 @@
|
|||
module.exports = {
|
||||
parser: 'babel-eslint',
|
||||
extends: 'standard',
|
||||
env: {
|
||||
node: true,
|
||||
es6: true,
|
||||
mocha: true
|
||||
},
|
||||
rules: {
|
||||
'space-before-function-paren': ['error', 'never']
|
||||
},
|
||||
globals: {
|
||||
contract: true,
|
||||
web3: true,
|
||||
assert: true
|
||||
}
|
||||
}
|
8
contracts/.solhint.json
Normal file
8
contracts/.solhint.json
Normal file
|
@ -0,0 +1,8 @@
|
|||
{
|
||||
"extends": "solhint:recommended",
|
||||
"plugins": [],
|
||||
"rules": {
|
||||
"compiler-version": ["error", ">=0.6.6"],
|
||||
"reason-string": ["warn", {"maxLength": 64}]
|
||||
}
|
||||
}
|
|
@ -1,7 +1,51 @@
|
|||
# BBG Contracts
|
||||
------------
|
||||
|
||||
### 1. Before Start
|
||||
|
||||
truffle migrate --network polygon
|
||||
Create and modify the following files in this directory, the secret key inside the files are dummy ones from truffle dev server:
|
||||
- development-secret.json
|
||||
- polygon-secret.json
|
||||
- bsc-secret.json
|
||||
|
||||
### 2. Prepare the dependencies
|
||||
|
||||
```bash
|
||||
npm i
|
||||
# if you want to develope in localhost, try to run npm run devserver separately
|
||||
# ex: npm run devserver
|
||||
# it will give you a set of secrets and account addresses
|
||||
```
|
||||
|
||||
### 3. Deploy
|
||||
|
||||
Migrate:
|
||||
```bash
|
||||
npm run migrate:dev
|
||||
# npm run migrate:polygon
|
||||
# npm run migrate:polygon-test
|
||||
# npm run migrate:bsc
|
||||
# npm run migrate:bsc-test
|
||||
```
|
||||
|
||||
Lint:
|
||||
```bash
|
||||
npm run lint
|
||||
# # fix solidity issue
|
||||
# npm run lint:sol:fix
|
||||
# # fix js issue
|
||||
# npm run lint:js:fix
|
||||
```
|
||||
|
||||
Test:
|
||||
```bash
|
||||
npm run test
|
||||
```
|
||||
|
||||
```bash
|
||||
truffle run verify ChildMintableERC20 --network polygon
|
||||
```
|
||||
|
||||
```bash
|
||||
truffle run verify ChildMintableERC20@0x3Afe98235d680e8d7A52e1458a59D60f45F935C0 --network polygon
|
||||
```
|
||||
|
|
4
contracts/bsc-secret.json
Normal file
4
contracts/bsc-secret.json
Normal file
|
@ -0,0 +1,4 @@
|
|||
{
|
||||
"privateKey": "3899a918953e01bfe218116cdfeccbed579e26275c4a89abcbc70d2cb9e9bbb8",
|
||||
"etherScanApiKey": ""
|
||||
}
|
|
@ -1,6 +1,7 @@
|
|||
// SPDX-License-Identifier: MIT
|
||||
pragma solidity >=0.4.22 <0.9.0;
|
||||
|
||||
|
||||
contract Migrations {
|
||||
address public owner = msg.sender;
|
||||
uint public last_completed_migration;
|
||||
|
|
79
contracts/contracts/child/ChildToken/ChildMintableERC20.sol
Normal file
79
contracts/contracts/child/ChildToken/ChildMintableERC20.sol
Normal file
|
@ -0,0 +1,79 @@
|
|||
pragma solidity 0.6.6;
|
||||
|
||||
import {ERC20} from "@openzeppelin/contracts/token/ERC20/ERC20.sol";
|
||||
import {AccessControlMixin} from "../../common/AccessControlMixin.sol";
|
||||
import {IChildToken} from "./IChildToken.sol";
|
||||
import {NativeMetaTransaction} from "../../common/NativeMetaTransaction.sol";
|
||||
import {ContextMixin} from "../../common/ContextMixin.sol";
|
||||
|
||||
|
||||
contract ChildMintableERC20 is
|
||||
ERC20,
|
||||
IChildToken,
|
||||
AccessControlMixin,
|
||||
NativeMetaTransaction,
|
||||
ContextMixin
|
||||
{
|
||||
bytes32 public constant DEPOSITOR_ROLE = keccak256("DEPOSITOR_ROLE");
|
||||
|
||||
constructor(
|
||||
string memory name_,
|
||||
string memory symbol_,
|
||||
uint8 decimals_,
|
||||
address childChainManager
|
||||
) public ERC20(name_, symbol_) {
|
||||
_setupContractId("ChildMintableERC20");
|
||||
_setupDecimals(decimals_);
|
||||
_setupRole(DEFAULT_ADMIN_ROLE, _msgSender());
|
||||
_setupRole(DEPOSITOR_ROLE, childChainManager);
|
||||
_initializeEIP712(name_);
|
||||
}
|
||||
|
||||
// This is to support Native meta transactions
|
||||
// never use msg.sender directly, use _msgSender() instead
|
||||
function _msgSender()
|
||||
internal
|
||||
override
|
||||
view
|
||||
returns (address payable sender)
|
||||
{
|
||||
return ContextMixin.msgSender();
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice called when token is deposited on root chain
|
||||
* @dev Should be callable only by ChildChainManager
|
||||
* Should handle deposit by minting the required amount for user
|
||||
* Make sure minting is done only by this function
|
||||
* @param user user address for whom deposit is being done
|
||||
* @param depositData abi encoded amount
|
||||
*/
|
||||
function deposit(address user, bytes calldata depositData)
|
||||
external
|
||||
override
|
||||
only(DEPOSITOR_ROLE)
|
||||
{
|
||||
uint256 amount = abi.decode(depositData, (uint256));
|
||||
_mint(user, amount);
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice called when user wants to withdraw tokens back to root chain
|
||||
* @dev Should burn user's tokens. This transaction will be verified when exiting on root chain
|
||||
* @param amount amount of tokens to withdraw
|
||||
*/
|
||||
function withdraw(uint256 amount) external {
|
||||
_burn(_msgSender(), amount);
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice Example function to handle minting tokens on matic chain
|
||||
* @dev Minting can be done as per requirement,
|
||||
* This implementation allows only admin to mint tokens but it can be changed as per requirement
|
||||
* @param user user for whom tokens are being minted
|
||||
* @param amount amount of token to mint
|
||||
*/
|
||||
function mint(address user, uint256 amount) public only(DEFAULT_ADMIN_ROLE) {
|
||||
_mint(user, amount);
|
||||
}
|
||||
}
|
5
contracts/contracts/child/ChildToken/IChildToken.sol
Normal file
5
contracts/contracts/child/ChildToken/IChildToken.sol
Normal file
|
@ -0,0 +1,5 @@
|
|||
pragma solidity 0.6.6;
|
||||
|
||||
interface IChildToken {
|
||||
function deposit(address user, bytes calldata depositData) external;
|
||||
}
|
19
contracts/contracts/common/AccessControlMixin.sol
Normal file
19
contracts/contracts/common/AccessControlMixin.sol
Normal file
|
@ -0,0 +1,19 @@
|
|||
pragma solidity 0.6.6;
|
||||
|
||||
import {AccessControl} from "@openzeppelin/contracts/access/AccessControl.sol";
|
||||
|
||||
|
||||
contract AccessControlMixin is AccessControl {
|
||||
string private _revertMsg;
|
||||
function _setupContractId(string memory contractId) internal {
|
||||
_revertMsg = string(abi.encodePacked(contractId, ": INSUFFICIENT_PERMISSIONS"));
|
||||
}
|
||||
|
||||
modifier only(bytes32 role) {
|
||||
require(
|
||||
hasRole(role, _msgSender()),
|
||||
_revertMsg
|
||||
);
|
||||
_;
|
||||
}
|
||||
}
|
25
contracts/contracts/common/ContextMixin.sol
Normal file
25
contracts/contracts/common/ContextMixin.sol
Normal file
|
@ -0,0 +1,25 @@
|
|||
pragma solidity 0.6.6;
|
||||
|
||||
abstract contract ContextMixin {
|
||||
function msgSender()
|
||||
internal
|
||||
view
|
||||
returns (address payable sender)
|
||||
{
|
||||
if (msg.sender == address(this)) {
|
||||
bytes memory array = msg.data;
|
||||
uint256 index = msg.data.length;
|
||||
/* solhint-disable no-inline-assembly */
|
||||
assembly {
|
||||
// Load the 32 bytes word from memory with the address on the lower 20 bytes, and mask those.
|
||||
sender := and(
|
||||
mload(add(array, index)),
|
||||
0xffffffffffffffffffffffffffffffffffffffff
|
||||
)
|
||||
}
|
||||
} else {
|
||||
sender = msg.sender;
|
||||
}
|
||||
return sender;
|
||||
}
|
||||
}
|
77
contracts/contracts/common/EIP712Base.sol
Normal file
77
contracts/contracts/common/EIP712Base.sol
Normal file
|
@ -0,0 +1,77 @@
|
|||
pragma solidity 0.6.6;
|
||||
|
||||
import {Initializable} from "./Initializable.sol";
|
||||
|
||||
|
||||
contract EIP712Base is Initializable {
|
||||
struct EIP712Domain {
|
||||
string name;
|
||||
string version;
|
||||
address verifyingContract;
|
||||
bytes32 salt;
|
||||
}
|
||||
|
||||
string constant public ERC712_VERSION = "1";
|
||||
|
||||
bytes32 internal constant EIP712_DOMAIN_TYPEHASH = keccak256(
|
||||
bytes(
|
||||
"EIP712Domain(string name,string version,address verifyingContract,bytes32 salt)"
|
||||
)
|
||||
);
|
||||
bytes32 internal domainSeperator;
|
||||
|
||||
// supposed to be called once while initializing.
|
||||
// one of the contractsa that inherits this contract follows proxy pattern
|
||||
// so it is not possible to do this in a constructor
|
||||
function _initializeEIP712(
|
||||
string memory name
|
||||
)
|
||||
internal
|
||||
initializer
|
||||
{
|
||||
_setDomainSeperator(name);
|
||||
}
|
||||
|
||||
function _setDomainSeperator(string memory name) internal {
|
||||
domainSeperator = keccak256(
|
||||
abi.encode(
|
||||
EIP712_DOMAIN_TYPEHASH,
|
||||
keccak256(bytes(name)),
|
||||
keccak256(bytes(ERC712_VERSION)),
|
||||
address(this),
|
||||
bytes32(getChainId())
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
function getDomainSeperator() public view returns (bytes32) {
|
||||
return domainSeperator;
|
||||
}
|
||||
|
||||
function getChainId() public pure returns (uint256) {
|
||||
uint256 id;
|
||||
/* solhint-disable no-inline-assembly */
|
||||
assembly {
|
||||
id := chainid()
|
||||
}
|
||||
return id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accept message hash and returns hash message in EIP712 compatible form
|
||||
* So that it can be used to recover signer from signature signed using EIP712 formatted data
|
||||
* https://eips.ethereum.org/EIPS/eip-712
|
||||
* "\\x19" makes the encoding deterministic
|
||||
* "\\x01" is the version byte to make it compatible to EIP-191
|
||||
*/
|
||||
function toTypedMessageHash(bytes32 messageHash)
|
||||
internal
|
||||
view
|
||||
returns (bytes32)
|
||||
{
|
||||
return
|
||||
keccak256(
|
||||
abi.encodePacked("\x19\x01", getDomainSeperator(), messageHash)
|
||||
);
|
||||
}
|
||||
}
|
12
contracts/contracts/common/Initializable.sol
Normal file
12
contracts/contracts/common/Initializable.sol
Normal file
|
@ -0,0 +1,12 @@
|
|||
pragma solidity 0.6.6;
|
||||
|
||||
|
||||
contract Initializable {
|
||||
bool public inited = false;
|
||||
|
||||
modifier initializer() {
|
||||
require(!inited, "already inited");
|
||||
_;
|
||||
inited = true;
|
||||
}
|
||||
}
|
106
contracts/contracts/common/NativeMetaTransaction.sol
Normal file
106
contracts/contracts/common/NativeMetaTransaction.sol
Normal file
|
@ -0,0 +1,106 @@
|
|||
pragma solidity 0.6.6;
|
||||
|
||||
import {SafeMath} from "@openzeppelin/contracts/math/SafeMath.sol";
|
||||
import {EIP712Base} from "./EIP712Base.sol";
|
||||
|
||||
|
||||
contract NativeMetaTransaction is EIP712Base {
|
||||
using SafeMath for uint256;
|
||||
bytes32 private constant META_TRANSACTION_TYPEHASH = keccak256(
|
||||
bytes(
|
||||
"MetaTransaction(uint256 nonce,address from,bytes functionSignature)"
|
||||
)
|
||||
);
|
||||
event MetaTransactionExecuted(
|
||||
address userAddress,
|
||||
address payable relayerAddress,
|
||||
bytes functionSignature
|
||||
);
|
||||
mapping(address => uint256) public nonces;
|
||||
|
||||
/*
|
||||
* Meta transaction structure.
|
||||
* No point of including value field here as if user is doing value transfer then he has the funds to pay for gas
|
||||
* He should call the desired function directly in that case.
|
||||
*/
|
||||
struct MetaTransaction {
|
||||
uint256 nonce;
|
||||
address from;
|
||||
bytes functionSignature;
|
||||
}
|
||||
|
||||
function executeMetaTransaction(
|
||||
address userAddress,
|
||||
bytes memory functionSignature,
|
||||
bytes32 sigR,
|
||||
bytes32 sigS,
|
||||
uint8 sigV
|
||||
) public payable returns (bytes memory) {
|
||||
MetaTransaction memory metaTx = MetaTransaction({
|
||||
nonce: nonces[userAddress],
|
||||
from: userAddress,
|
||||
functionSignature: functionSignature
|
||||
});
|
||||
|
||||
require(
|
||||
verify(userAddress, metaTx, sigR, sigS, sigV),
|
||||
"Signer and signature do not match"
|
||||
);
|
||||
|
||||
// increase nonce for user (to avoid re-use)
|
||||
nonces[userAddress] = nonces[userAddress].add(1);
|
||||
|
||||
emit MetaTransactionExecuted(
|
||||
userAddress,
|
||||
msg.sender,
|
||||
functionSignature
|
||||
);
|
||||
|
||||
// Append userAddress and relayer address at the end to extract it from calling context
|
||||
/* solhint-disable avoid-low-level-calls */
|
||||
(bool success, bytes memory returnData) = address(this).call(
|
||||
abi.encodePacked(functionSignature, userAddress)
|
||||
);
|
||||
require(success, "Function call not successful");
|
||||
|
||||
return returnData;
|
||||
}
|
||||
|
||||
function hashMetaTransaction(MetaTransaction memory metaTx)
|
||||
internal
|
||||
pure
|
||||
returns (bytes32)
|
||||
{
|
||||
return
|
||||
keccak256(
|
||||
abi.encode(
|
||||
META_TRANSACTION_TYPEHASH,
|
||||
metaTx.nonce,
|
||||
metaTx.from,
|
||||
keccak256(metaTx.functionSignature)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
function getNonce(address user) public view returns (uint256 nonce) {
|
||||
nonce = nonces[user];
|
||||
}
|
||||
|
||||
function verify(
|
||||
address signer,
|
||||
MetaTransaction memory metaTx,
|
||||
bytes32 sigR,
|
||||
bytes32 sigS,
|
||||
uint8 sigV
|
||||
) internal view returns (bool) {
|
||||
require(signer != address(0), "NativeMetaTransaction: INVALID_SIGNER");
|
||||
return
|
||||
signer ==
|
||||
ecrecover(
|
||||
toTypedMessageHash(hashMetaTransaction(metaTx)),
|
||||
sigV,
|
||||
sigR,
|
||||
sigS
|
||||
);
|
||||
}
|
||||
}
|
7
contracts/contracts/common/Proxy/IERCProxy.sol
Normal file
7
contracts/contracts/common/Proxy/IERCProxy.sol
Normal file
|
@ -0,0 +1,7 @@
|
|||
pragma solidity 0.6.6;
|
||||
|
||||
interface IERCProxy {
|
||||
function proxyType() external pure returns (uint256 proxyTypeId);
|
||||
|
||||
function implementation() external view returns (address codeAddr);
|
||||
}
|
39
contracts/contracts/common/Proxy/Proxy.sol
Normal file
39
contracts/contracts/common/Proxy/Proxy.sol
Normal file
|
@ -0,0 +1,39 @@
|
|||
pragma solidity 0.6.6;
|
||||
import {IERCProxy} from "./IERCProxy.sol";
|
||||
|
||||
abstract contract Proxy is IERCProxy {
|
||||
function delegatedFwd(address _dst, bytes memory _calldata) internal {
|
||||
// solium-disable-next-line security/no-inline-assembly
|
||||
assembly {
|
||||
let result := delegatecall(
|
||||
sub(gas(), 10000),
|
||||
_dst,
|
||||
add(_calldata, 0x20),
|
||||
mload(_calldata),
|
||||
0,
|
||||
0
|
||||
)
|
||||
let size := returndatasize()
|
||||
|
||||
let ptr := mload(0x40)
|
||||
returndatacopy(ptr, 0, size)
|
||||
|
||||
// revert instead of invalid() bc if the underlying call failed with invalid() it already wasted gas.
|
||||
// if the call returned error data, forward it
|
||||
switch result
|
||||
case 0 {
|
||||
revert(ptr, size)
|
||||
}
|
||||
default {
|
||||
return(ptr, size)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function proxyType() external virtual override pure returns (uint256 proxyTypeId) {
|
||||
// Upgradeable proxy
|
||||
proxyTypeId = 2;
|
||||
}
|
||||
|
||||
function implementation() external virtual override view returns (address);
|
||||
}
|
103
contracts/contracts/common/Proxy/UpgradableProxy.sol
Normal file
103
contracts/contracts/common/Proxy/UpgradableProxy.sol
Normal file
|
@ -0,0 +1,103 @@
|
|||
pragma solidity 0.6.6;
|
||||
|
||||
import {Proxy} from "./Proxy.sol";
|
||||
|
||||
contract UpgradableProxy is Proxy {
|
||||
event ProxyUpdated(address indexed _new, address indexed _old);
|
||||
event ProxyOwnerUpdate(address _new, address _old);
|
||||
|
||||
bytes32 constant IMPLEMENTATION_SLOT = keccak256("matic.network.proxy.implementation");
|
||||
bytes32 constant OWNER_SLOT = keccak256("matic.network.proxy.owner");
|
||||
|
||||
constructor(address _proxyTo) public {
|
||||
setProxyOwner(msg.sender);
|
||||
setImplementation(_proxyTo);
|
||||
}
|
||||
|
||||
fallback() external payable {
|
||||
delegatedFwd(loadImplementation(), msg.data);
|
||||
}
|
||||
|
||||
receive() external payable {
|
||||
delegatedFwd(loadImplementation(), msg.data);
|
||||
}
|
||||
|
||||
modifier onlyProxyOwner() {
|
||||
require(loadProxyOwner() == msg.sender, "NOT_OWNER");
|
||||
_;
|
||||
}
|
||||
|
||||
function proxyOwner() external view returns(address) {
|
||||
return loadProxyOwner();
|
||||
}
|
||||
|
||||
function loadProxyOwner() internal view returns(address) {
|
||||
address _owner;
|
||||
bytes32 position = OWNER_SLOT;
|
||||
assembly {
|
||||
_owner := sload(position)
|
||||
}
|
||||
return _owner;
|
||||
}
|
||||
|
||||
function implementation() external override view returns (address) {
|
||||
return loadImplementation();
|
||||
}
|
||||
|
||||
function loadImplementation() internal view returns(address) {
|
||||
address _impl;
|
||||
bytes32 position = IMPLEMENTATION_SLOT;
|
||||
assembly {
|
||||
_impl := sload(position)
|
||||
}
|
||||
return _impl;
|
||||
}
|
||||
|
||||
function transferProxyOwnership(address newOwner) public onlyProxyOwner {
|
||||
require(newOwner != address(0), "ZERO_ADDRESS");
|
||||
emit ProxyOwnerUpdate(newOwner, loadProxyOwner());
|
||||
setProxyOwner(newOwner);
|
||||
}
|
||||
|
||||
function setProxyOwner(address newOwner) private {
|
||||
bytes32 position = OWNER_SLOT;
|
||||
assembly {
|
||||
sstore(position, newOwner)
|
||||
}
|
||||
}
|
||||
|
||||
function updateImplementation(address _newProxyTo) public onlyProxyOwner {
|
||||
require(_newProxyTo != address(0x0), "INVALID_PROXY_ADDRESS");
|
||||
require(isContract(_newProxyTo), "DESTINATION_ADDRESS_IS_NOT_A_CONTRACT");
|
||||
|
||||
emit ProxyUpdated(_newProxyTo, loadImplementation());
|
||||
|
||||
setImplementation(_newProxyTo);
|
||||
}
|
||||
|
||||
function updateAndCall(address _newProxyTo, bytes memory data) payable public onlyProxyOwner {
|
||||
updateImplementation(_newProxyTo);
|
||||
|
||||
(bool success, bytes memory returnData) = address(this).call{value: msg.value}(data);
|
||||
require(success, string(returnData));
|
||||
}
|
||||
|
||||
function setImplementation(address _newProxyTo) private {
|
||||
bytes32 position = IMPLEMENTATION_SLOT;
|
||||
assembly {
|
||||
sstore(position, _newProxyTo)
|
||||
}
|
||||
}
|
||||
|
||||
function isContract(address _target) internal view returns (bool) {
|
||||
if (_target == address(0)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
uint256 size;
|
||||
assembly {
|
||||
size := extcodesize(_target)
|
||||
}
|
||||
return size > 0;
|
||||
}
|
||||
}
|
4
contracts/development-secret.json
Normal file
4
contracts/development-secret.json
Normal file
|
@ -0,0 +1,4 @@
|
|||
{
|
||||
"privateKey": "3899a918953e01bfe218116cdfeccbed579e26275c4a89abcbc70d2cb9e9bbb8",
|
||||
"etherScanApiKey": ""
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
var ChildMintableERC20 = artifacts.require("./ChildMintableERC20.sol");
|
||||
var ChildMintableERC20 = artifacts.require("ChildMintableERC20");
|
||||
|
||||
module.exports = function(deployer) {
|
||||
deployer.deploy(ChildMintableERC20, 'BBGO', 'BBG', 18, '0xA6FA4fB5f76172d178d61B04b0ecd319C5d1C0aa');
|
||||
|
|
32452
contracts/package-lock.json
generated
Normal file
32452
contracts/package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
|
@ -17,11 +17,24 @@
|
|||
"ethereum-waffle": "^3.4.0",
|
||||
"ethers": "^5.4.7",
|
||||
"hardhat": "^2.6.5",
|
||||
"prettier": "^2.5.1",
|
||||
"solhint": "^3.3.6",
|
||||
"truffle-plugin-verify": "^0.5.18"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "mocha"
|
||||
"devserver": "KEY=development-secret.json truffle develop",
|
||||
"test": "KEY=development-secret.json truffle test",
|
||||
"migrate:dev": "KEY=development-secret.json truffle migrate --network development",
|
||||
"migrate:polygon": "KEY=polygon-secret.json truffle migrate --network polygon",
|
||||
"migrate:polygon-test": "KEY=polygon-secret.json truffle migrate --network mumbai",
|
||||
"migrate:bsc": "KEY=bsc-secret.json truffle migrate --network bsc",
|
||||
"migrate:bsc-test": "KEY=bsc-secret.json truffle migrate --network bsctestnet",
|
||||
"lint": "npm run lint:sol && npm run lint:js",
|
||||
"lint:js:fix": "prettier --write test/**/*.js",
|
||||
"lint:js": "prettier test/**/*.js",
|
||||
"lint:sol": "solhint contracts/**/*.sol",
|
||||
"lint:sol:fix": "solhint -d contracts/**/*.sol --fix"
|
||||
},
|
||||
"author": "",
|
||||
"license": "ISC"
|
||||
"author": "starcrypto",
|
||||
"license": "MIT"
|
||||
}
|
||||
|
|
4
contracts/polygon-secret.json
Normal file
4
contracts/polygon-secret.json
Normal file
|
@ -0,0 +1,4 @@
|
|||
{
|
||||
"privateKey": "3899a918953e01bfe218116cdfeccbed579e26275c4a89abcbc70d2cb9e9bbb8",
|
||||
"etherScanApiKey": ""
|
||||
}
|
16
contracts/test/erc20.js
Normal file
16
contracts/test/erc20.js
Normal file
|
@ -0,0 +1,16 @@
|
|||
const ChildMintableERC20 = artifacts.require("ChildMintableERC20");
|
||||
contract("ChildMintableERC20", (accounts) => {
|
||||
it("should have BBG deployed", async () => {
|
||||
const instance = await ChildMintableERC20.deployed();
|
||||
const name = await instance.name();
|
||||
const decimal = await instance.decimals();
|
||||
const symbol = await instance.symbol();
|
||||
const balance = await instance.balanceOf(accounts[0]);
|
||||
const totalSupply = await instance.totalSupply();
|
||||
assert.equal(name.valueOf(), "BBGO");
|
||||
assert.equal(symbol.valueOf(), "BBG");
|
||||
assert.equal(decimal.toNumber(), 18);
|
||||
assert.equal(balance.toNumber(), 0);
|
||||
assert.equal(totalSupply.toNumber(), 0);
|
||||
});
|
||||
});
|
|
@ -19,7 +19,8 @@
|
|||
*/
|
||||
const fs = require('fs');
|
||||
const HDWalletProvider = require('@truffle/hdwallet-provider');
|
||||
const secret = JSON.parse(fs.readFileSync("polygon-secret.json").toString().trim());
|
||||
const secret = JSON.parse(fs.readFileSync(process.env.KEY).toString().trim());
|
||||
|
||||
|
||||
module.exports = {
|
||||
/**
|
||||
|
@ -69,19 +70,38 @@ module.exports = {
|
|||
// network_id: 2111, // This network is yours, in the cloud.
|
||||
// production: true // Treats this network as if it was a public net. (default: false)
|
||||
// }
|
||||
development: {
|
||||
host: "127.0.0.1",
|
||||
port: 9545,
|
||||
network_id: "*",
|
||||
},
|
||||
polygon: {
|
||||
provider: () => new HDWalletProvider(secret.privateKey, "https://polygon-rpc.com"),
|
||||
network_id: 137,
|
||||
confirmations: 3,
|
||||
timeoutBlocks: 200,
|
||||
skipDryRun: true
|
||||
provider: () => new HDWalletProvider(secret.privateKey, "https://polygon-rpc.com"),
|
||||
network_id: 137,
|
||||
confirmations: 3,
|
||||
timeoutBlocks: 200,
|
||||
skipDryRun: true
|
||||
},
|
||||
mumbai: {
|
||||
provider: () => new HDWalletProvider(secret.privateKey, "https://matic-mumbai.chainstacklabs.com"),
|
||||
network_id: 80001,
|
||||
confirmations: 3,
|
||||
timeoutBlocks: 200,
|
||||
skipDryRun: true
|
||||
provider: () => new HDWalletProvider(secret.privateKey, "https://matic-mumbai.chainstacklabs.com"),
|
||||
network_id: 80001,
|
||||
confirmations: 3,
|
||||
timeoutBlocks: 200,
|
||||
skipDryRun: true
|
||||
},
|
||||
bsctestnet: {
|
||||
// "https://speedy-nodes-nyc.moralis.io/91d001d6e2a55a9696521b4b/bsc/testnet"
|
||||
provider: () => new HDWalletProvider(secret.privateKey, "https://data-seed-prebsc-1-s1.binance.org:8545"),
|
||||
network_id: 97,
|
||||
confirmations: 10,
|
||||
timeoutBlocks: 200,
|
||||
},
|
||||
bsc: {
|
||||
provider: () => new HDWalletProvider(secret.privateKey, "https://bsc-dataseed1.binance.org"),
|
||||
network_id: 56,
|
||||
confirmations: 10,
|
||||
timeoutBlocks: 200,
|
||||
skipDryRun: true
|
||||
},
|
||||
},
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user