Rewrite contract, new license, adds settable minters

This commit is contained in:
nolash 2020-12-06 14:12:49 +01:00
parent 27ea14772f
commit 30baee6d19
Signed by: lash
GPG Key ID: 21D2E7BB88C2A746
5 changed files with 134 additions and 166 deletions

45
python/LICENSE Normal file
View File

@ -0,0 +1,45 @@
Bprotocol Foundation (Bancor) LICENSE
1. SUBJECT TO THE PROVISIONS SET FORTH HEREIN, INCLUDING “EFFECTIVE DATE”, YOU CAN
USE THIS CODE, FILE AND/OR SOFTWARE (“SOFTWARE”) ONLY IN CONNECTION WITH THE
BANCOR LIQUIDITY NETWORK AND/OR THE USE OF BNT ("PERMITTED USE"). ANY OTHER USE IS
PROHIBITED UNLESS THE USER SHALL RECEIVE AN EXPLICIT PRIOR WRITTEN APPROVAL FROM
BPROTOCOL FOUNDATION (BANCOR) TO DO SO (PLEASE CONTACT license@bancor.network IN
THIS REGARD), WHICH APPROVAL, IF GIVEN, MAY REQUIRE THE OBTAINMENT OF SEPARATE
LICENSE UNDER A DIFFERENT LICENSING MODEL. USING THIS SOFTWARE NOT IN THE FRAME OF
SUCH PERMITTED USE MAY, AMONG OTHERS, ALSO BREACH PATENT RIGHTS CONCERNING PATENTS
WHICH ARE EMBODIED/INCORPORATED/USED IN THIS SOFTWARE.
2. ANY SUCH PERMITTED USE SHOULD ALSO COMPLY WITH THE TERMS BELOW.
3. Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
A. Redistributions of source code must retain the above copyright notice, this list
of conditions and the following disclaimer.
B. Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or other
materials provided with the distribution.
C. Neither the name of the copyright holder nor the names of its contributors may be
used to endorse or promote products derived from this software without specific prior
written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
EFFECTIVE DATE: THIS LICENSE SHALL APPLY ONLY TO SOFTWARE (OR ANY VERSION THEREOF),
THAT HAS BEEN PUBLISHED AFTER THE DATE AND TIME THIS LICENSE HAS BEEN FIRST PUBLISHED
(“EFFECTIVE DATE”); Any previous versions published prior to the effective date (“Older Versions”)
shall remain licensed under the Apache License, Version 2.0 (the "Older Versions License");
You may obtain a copy of the Older Version License at http://www.apache.org/licenses/LICENSE-2.0
you may not use this file except in compliance with the Older Version License. Unless
required by applicable law or agreed to in writing, Older Versions distributed under the
Older Version License are distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS
OF ANY KIND, either express or implied. See the Older Version License for the specific
language governing permissions and limitations under the Older Version License.

View File

@ -24,11 +24,11 @@ logging.getLogger('urllib3').setLevel(logging.WARNING)
argparser = argparse.ArgumentParser() argparser = argparse.ArgumentParser()
argparser.add_argument('-p', '--provider', dest='p', default='http://localhost:8545', type=str, help='Web3 provider url (http only)') argparser.add_argument('-p', '--provider', dest='p', default='http://localhost:8545', type=str, help='Web3 provider url (http only)')
#argparser.add_argument('-g', '--gift', dest='g', action='store_true', help='If set, tokens will be gifted to all accounts in provider wallet')
argparser.add_argument('-n', '--name', dest='n', default='Giftable Token', type=str, help='Token name') argparser.add_argument('-n', '--name', dest='n', default='Giftable Token', type=str, help='Token name')
argparser.add_argument('-s', '--symbol', dest='s', default='GFT', type=str, help='Token symbol') argparser.add_argument('-s', '--symbol', dest='s', default='GFT', type=str, help='Token symbol')
argparser.add_argument('-d', '--decimals', dest='d', default=18, type=int, help='Token decimals') argparser.add_argument('-d', '--decimals', dest='d', default=18, type=int, help='Token decimals')
argparser.add_argument('-a', '--account', dest='a', action='append', type=str, help='Account to fund') argparser.add_argument('-a', '--account', dest='a', action='append', type=str, help='Account to fund')
argparser.add_argument('-m', '--minter', dest='m', action='append', type=str, help='Minter to add')
argparser.add_argument('--contracts-dir', dest='contracts_dir', type=str, default='.', help='Directory containing bytecode and abi') argparser.add_argument('--contracts-dir', dest='contracts_dir', type=str, default='.', help='Directory containing bytecode and abi')
argparser.add_argument('-v', action='store_true', help='Be verbose') argparser.add_argument('-v', action='store_true', help='Be verbose')
argparser.add_argument('amount', type=int, help='Initial token supply (will be owned by contract creator)') argparser.add_argument('amount', type=int, help='Initial token supply (will be owned by contract creator)')
@ -51,25 +51,34 @@ def main():
w3.eth.defaultAccount = w3.eth.accounts[0] w3.eth.defaultAccount = w3.eth.accounts[0]
c = w3.eth.contract(abi=abi, bytecode=bytecode) c = w3.eth.contract(abi=abi, bytecode=bytecode)
tx_hash = c.constructor(args.n, args.s, args.d, args.amount).transact() tx_hash = c.constructor(args.n, args.s, args.d).transact()
rcpt = w3.eth.getTransactionReceipt(tx_hash) rcpt = w3.eth.getTransactionReceipt(tx_hash)
address = rcpt.contractAddress address = rcpt.contractAddress
c = w3.eth.contract(abi=abi, address=address) c = w3.eth.contract(abi=abi, address=address)
logg.debug('construct tx {} address {}'.format(tx_hash.hex(), address)) logg.debug('construct tx {} address {}'.format(tx_hash.hex(), address))
balance = c.functions.balanceOf(w3.eth.defaultAccount).call() balance = c.functions.balanceOf(w3.eth.defaultAccount).call()
logg.info('balance {}: {}'.format(w3.eth.defaultAccount, balance)) logg.info('balance {}: {} {}'.format(w3.eth.defaultAccount, balance, tx_hash))
if args.a != None: if args.a != None:
for a in args.a: for a in args.a:
if a == w3.eth.defaultAccount: if a == w3.eth.defaultAccount:
continue continue
tx_hash = c.functions.gift(a, args.amount).transact() tx_hash_mint = c.functions.mint(args.amount).transact()
tx_hash_transfer = c.functions.transfer(a, args.amount).transact()
rcpt = w3.eth.getTransactionReceipt(tx_hash) rcpt = w3.eth.getTransactionReceipt(tx_hash)
balance = c.functions.balanceOf(a).call() balance = c.functions.balanceOf(a).call()
logg.info('balance {}: {}'.format(a, balance)) logg.info('balance {}: {}'.format(a, balance))
if args.m != None:
for a in args.m:
if a == w3.eth.defaultAccount:
continue
tx_hash_minter = c.functions.addMinter(a).transact()
logg.info('minter {}'.format(a))
print(address) print(address)

View File

@ -1 +1 @@
[{"inputs":[{"internalType":"string","name":"_name","type":"string"},{"internalType":"string","name":"_symbol","type":"string"},{"internalType":"uint8","name":"_decimals","type":"uint8"},{"internalType":"uint256","name":"_initialSupply","type":"uint256"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_owner","type":"address"},{"indexed":true,"internalType":"address","name":"_spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"_value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"_oldTotal","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_newTotal","type":"uint256"}],"name":"ChangedSupply","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_from","type":"address"},{"indexed":true,"internalType":"address","name":"_to","type":"address"},{"indexed":false,"internalType":"uint256","name":"_value","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_spender","type":"address"},{"internalType":"uint256","name":"_value","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256","name":"_value","type":"uint256"}],"name":"gift","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256","name":"_value","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_from","type":"address"},{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256","name":"_value","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"}] [{"inputs":[{"internalType":"string","name":"_name","type":"string"},{"internalType":"string","name":"_symbol","type":"string"},{"internalType":"uint8","name":"_decimals","type":"uint8"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_owner","type":"address"},{"indexed":true,"internalType":"address","name":"_spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"_value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_from","type":"address"},{"indexed":true,"internalType":"address","name":"_to","type":"address"},{"indexed":false,"internalType":"uint256","name":"_value","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_from","type":"address"},{"indexed":true,"internalType":"address","name":"_to","type":"address"},{"indexed":true,"internalType":"address","name":"_spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"_value","type":"uint256"}],"name":"TransferFrom","type":"event"},{"inputs":[{"internalType":"address","name":"_minter","type":"address"}],"name":"addMinter","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"name":"allowances","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_spender","type":"address"},{"internalType":"uint256","name":"_value","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_value","type":"uint256"}],"name":"mint","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_minter","type":"address"}],"name":"removeMinter","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256","name":"_value","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_from","type":"address"},{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256","name":"_value","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"}]

File diff suppressed because one or more lines are too long

View File

@ -1,160 +1,74 @@
pragma solidity ^0.6.12; pragma solidity >=0.6.12;
// SPDX-License-Identifier: SEE LICENSE IN LICENSE // SPDX-License-Identifier: GPL-3.0-or-later
/* contract GiftableToken {
* This is a MOCK token used for DEVELOPMENT PURPOSES ONLY.
* It allows anyone to freely mint tokens with themselves as beneficiaries address owner;
* Code is based on the ERC20Token contract from Bancor's contracts-solidity repository mapping(address => bool) minters;
*
* @dev ERC20 Standard Token implementation string public name;
*/ string public symbol;
uint8 public decimals;
contract GiftableToken { //is IERC20Token, Utils { uint256 public totalSupply;
//using SafeMath for uint256; mapping (address => uint256) public balanceOf;
mapping (address => mapping (address => uint256)) public allowances;
string public name;
string public symbol; event Transfer(address indexed _from, address indexed _to, uint256 _value);
uint8 public decimals; event TransferFrom(address indexed _from, address indexed _to, address indexed _spender, uint256 _value);
uint256 public totalSupply; event Approval(address indexed _owner, address indexed _spender, uint256 _value);
mapping (address => uint256) public balanceOf;
mapping (address => mapping (address => uint256)) public allowance; constructor(string memory _name, string memory _symbol, uint8 _decimals) {
owner = msg.sender;
/** name = _name;
* @dev triggered when tokens are transferred between wallets symbol = _symbol;
* decimals = _decimals;
* @param _from source address minters[msg.sender] = true;
* @param _to target address }
* @param _value transfer amount
*/ function mint(uint256 _value) public returns (bool) {
event Transfer(address indexed _from, address indexed _to, uint256 _value); require(minters[msg.sender]);
/** balanceOf[msg.sender] += _value;
* @dev triggered when a wallet allows another wallet to transfer tokens from on its behalf totalSupply += _value;
*
* @param _owner wallet that approves the allowance return true;
* @param _spender wallet that receives the allowance }
* @param _value allowance amount
*/ function addMinter(address _minter) public returns (bool) {
event Approval(address indexed _owner, address indexed _spender, uint256 _value); require(msg.sender == owner);
event ChangedSupply(uint256 _oldTotal, uint256 _newTotal); minters[_minter] = true;
/** return true;
* @dev initializes a new ERC20Token instance }
*
* @param _name token name function removeMinter(address _minter) public returns (bool) {
* @param _symbol token symbol require(msg.sender == owner || msg.sender == _minter);
* @param _decimals decimal points, for display purposes
* @param _initialSupply total supply of token units minters[_minter] = false;
*/
constructor(string memory _name, string memory _symbol, uint8 _decimals, uint256 _initialSupply) public { return true;
// validate input }
require(bytes(_name).length > 0, "ERR_INVALID_NAME");
require(bytes(_symbol).length > 0, "ERR_INVALID_SYMBOL"); function transfer(address _to, uint256 _value) public returns (bool) {
balanceOf[msg.sender] -= _value;
name = _name; balanceOf[_to] += _value;
symbol = _symbol; emit Transfer(msg.sender, _to, _value);
decimals = _decimals; return true;
totalSupply = _initialSupply; }
balanceOf[msg.sender] = _initialSupply;
} function transferFrom(address _from, address _to, uint256 _value) public returns (bool) {
allowances[_from][msg.sender] = allowances[_from][msg.sender] - _value;
// validates an address - currently only checks that it isn't null balanceOf[_from] -= _value;
modifier validAddress(address _address) { balanceOf[_to] += _value;
_validAddress(_address); emit TransferFrom(_from, _to, msg.sender, _value);
_; return true;
} }
// error message binary size optimization function approve(address _spender, uint256 _value) public returns (bool) {
function _validAddress(address _address) internal pure { allowances[msg.sender][_spender] += _value;
require(_address != address(0), "ERR_INVALID_ADDRESS"); emit Approval(msg.sender, _spender, _value);
} return true;
}
}
function gift(address _to, uint256 _value)
public
virtual
validAddress(_to)
returns (bool)
{
totalSupply = totalSupply + _value;
uint256 oldSupply = balanceOf[_to];
balanceOf[_to] = balanceOf[_to] + _value;
emit ChangedSupply(oldSupply, balanceOf[_to]);
emit Transfer(address(0x00), _to, _value);
return true;
}
/**
* @dev transfers tokens to a given address
* throws on any error rather then return a false flag to minimize user errors
*
* @param _to target address
* @param _value transfer amount
*
* @return true if the transfer was successful, false if it wasn't
*/
function transfer(address _to, uint256 _value)
public
virtual
validAddress(_to)
returns (bool)
{
balanceOf[msg.sender] = balanceOf[msg.sender] - _value;
balanceOf[_to] = balanceOf[_to] + _value;
emit Transfer(msg.sender, _to, _value);
return true;
}
/**
* @dev transfers tokens to a given address on behalf of another address
* throws on any error rather then return a false flag to minimize user errors
*
* @param _from source address
* @param _to target address
* @param _value transfer amount
*
* @return true if the transfer was successful, false if it wasn't
*/
function transferFrom(address _from, address _to, uint256 _value)
public
virtual
validAddress(_from)
validAddress(_to)
returns (bool)
{
allowance[_from][msg.sender] = allowance[_from][msg.sender] - _value;
balanceOf[_from] = balanceOf[_from] - _value;
balanceOf[_to] = balanceOf[_to] + _value;
emit Transfer(_from, _to, _value);
return true;
}
/**
* @dev allows another account/contract to transfers tokens on behalf of the caller
* throws on any error rather then return a false flag to minimize user errors
*
* also, to minimize the risk of the approve/transferFrom attack vector
* (see https://docs.google.com/document/d/1YLPtQxZu1UAvO9cZ1O2RPXBbT0mooh4DYKjA_jp-RLM/), approve has to be called twice
* in 2 separate transactions - once to change the allowance to 0 and secondly to change it to the new allowance value
*
* @param _spender approved address
* @param _value allowance amount
*
* @return true if the approval was successful, false if it wasn't
*/
function approve(address _spender, uint256 _value)
public
virtual
validAddress(_spender)
returns (bool)
{
// if the allowance isn't 0, it can only be updated to 0 to prevent an allowance change immediately after withdrawal
require(_value == 0 || allowance[msg.sender][_spender] == 0, "ERR_INVALID_AMOUNT");
allowance[msg.sender][_spender] = _value;
emit Approval(msg.sender, _spender, _value);
return true;
}
}