mirror of
https://github.com/chaintool-py/eth-erc20.git
synced 2024-11-21 17:26:47 +01:00
Add burn to giftable tokebs
This commit is contained in:
parent
d7fb3f232c
commit
04f9b5868b
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -12,6 +12,9 @@ from chainlib.eth.contract import (
|
|||||||
ABIContractEncoder,
|
ABIContractEncoder,
|
||||||
ABIContractType,
|
ABIContractType,
|
||||||
)
|
)
|
||||||
|
from chainlib.eth.constant import ZERO_ADDRESS
|
||||||
|
from chainlib.jsonrpc import JSONRPCRequest
|
||||||
|
from hexathon import add_0x
|
||||||
|
|
||||||
# local imports
|
# local imports
|
||||||
from giftable_erc20_token.data import data_dir
|
from giftable_erc20_token.data import data_dir
|
||||||
@ -107,6 +110,48 @@ class GiftableToken(ERC20):
|
|||||||
return tx
|
return tx
|
||||||
|
|
||||||
|
|
||||||
|
def burn(self, contract_address, sender_address, value, tx_format=TxFormat.JSONRPC):
|
||||||
|
enc = ABIContractEncoder()
|
||||||
|
enc.method('burn')
|
||||||
|
enc.typ(ABIContractType.UINT256)
|
||||||
|
enc.uint256(value)
|
||||||
|
data = enc.get()
|
||||||
|
tx = self.template(sender_address, contract_address, use_nonce=True)
|
||||||
|
tx = self.set_code(tx, data)
|
||||||
|
tx = self.finalize(tx, tx_format)
|
||||||
|
return tx
|
||||||
|
|
||||||
|
|
||||||
|
def burned(self, contract_address, sender_address=ZERO_ADDRESS, id_generator=None):
|
||||||
|
j = JSONRPCRequest(id_generator)
|
||||||
|
o = j.template()
|
||||||
|
o['method'] = 'eth_call'
|
||||||
|
enc = ABIContractEncoder()
|
||||||
|
enc.method('burned')
|
||||||
|
data = add_0x(enc.get())
|
||||||
|
tx = self.template(sender_address, contract_address)
|
||||||
|
tx = self.set_code(tx, data)
|
||||||
|
o['params'].append(self.normalize(tx))
|
||||||
|
o['params'].append('latest')
|
||||||
|
o = j.finalize(o)
|
||||||
|
return o
|
||||||
|
|
||||||
|
|
||||||
|
def total_minted(self, contract_address, sender_address=ZERO_ADDRESS, id_generator=None):
|
||||||
|
j = JSONRPCRequest(id_generator)
|
||||||
|
o = j.template()
|
||||||
|
o['method'] = 'eth_call'
|
||||||
|
enc = ABIContractEncoder()
|
||||||
|
enc.method('totalMinted')
|
||||||
|
data = add_0x(enc.get())
|
||||||
|
tx = self.template(sender_address, contract_address)
|
||||||
|
tx = self.set_code(tx, data)
|
||||||
|
o['params'].append(self.normalize(tx))
|
||||||
|
o['params'].append('latest')
|
||||||
|
o = j.finalize(o)
|
||||||
|
return o
|
||||||
|
|
||||||
|
|
||||||
def bytecode(**kwargs):
|
def bytecode(**kwargs):
|
||||||
return GiftableToken.bytecode(version=kwargs.get('version'))
|
return GiftableToken.bytecode(version=kwargs.get('version'))
|
||||||
|
|
||||||
|
@ -80,5 +80,44 @@ class TestExpire(TestGiftableExpireToken):
|
|||||||
self.assertEqual(supply, mint_amount)
|
self.assertEqual(supply, mint_amount)
|
||||||
|
|
||||||
|
|
||||||
|
def test_burn(self):
|
||||||
|
mint_amount = self.initial_supply
|
||||||
|
nonce_oracle = RPCNonceOracle(self.accounts[1], self.rpc)
|
||||||
|
c = GiftableToken(self.chain_spec, signer=self.signer, nonce_oracle=nonce_oracle)
|
||||||
|
(tx_hash, o) = c.burn(self.address, self.accounts[1], int(mint_amount / 4))
|
||||||
|
self.rpc.do(o)
|
||||||
|
o = receipt(tx_hash)
|
||||||
|
r = self.rpc.do(o)
|
||||||
|
self.assertEqual(r['status'], 0)
|
||||||
|
|
||||||
|
nonce_oracle = RPCNonceOracle(self.accounts[0], self.rpc)
|
||||||
|
c = GiftableToken(self.chain_spec, signer=self.signer, nonce_oracle=nonce_oracle)
|
||||||
|
(tx_hash, o) = c.burn(self.address, self.accounts[0], int(mint_amount / 4))
|
||||||
|
self.rpc.do(o)
|
||||||
|
o = receipt(tx_hash)
|
||||||
|
r = self.rpc.do(o)
|
||||||
|
self.assertEqual(r['status'], 1)
|
||||||
|
|
||||||
|
o = c.burned(self.address, sender_address=self.accounts[0])
|
||||||
|
r = self.rpc.do(o)
|
||||||
|
burned = c.parse_balance(r)
|
||||||
|
self.assertEqual(burned, int(mint_amount / 4))
|
||||||
|
|
||||||
|
o = c.balance_of(self.address, self.accounts[0], sender_address=self.accounts[0])
|
||||||
|
r = self.rpc.do(o)
|
||||||
|
balance = c.parse_balance(r)
|
||||||
|
self.assertEqual(balance, mint_amount - burned)
|
||||||
|
|
||||||
|
o = c.total_supply(self.address, sender_address=self.accounts[0])
|
||||||
|
r = self.rpc.do(o)
|
||||||
|
balance = c.parse_balance(r)
|
||||||
|
self.assertEqual(balance, mint_amount - burned)
|
||||||
|
|
||||||
|
o = c.total_minted(self.address, sender_address=self.accounts[0])
|
||||||
|
r = self.rpc.do(o)
|
||||||
|
balance = c.parse_balance(r)
|
||||||
|
self.assertEqual(balance, mint_amount)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
unittest.main()
|
unittest.main()
|
||||||
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -5,8 +5,11 @@ pragma solidity >=0.6.11;
|
|||||||
|
|
||||||
contract GiftableToken {
|
contract GiftableToken {
|
||||||
|
|
||||||
|
// Implements EIP173
|
||||||
address public owner;
|
address public owner;
|
||||||
mapping(address => bool) minters;
|
|
||||||
|
// Implements Writer
|
||||||
|
mapping(address => bool) writer;
|
||||||
|
|
||||||
// Implements ERC20
|
// Implements ERC20
|
||||||
string public name;
|
string public name;
|
||||||
@ -15,62 +18,90 @@ contract GiftableToken {
|
|||||||
// Implements ERC20
|
// Implements ERC20
|
||||||
uint8 public decimals;
|
uint8 public decimals;
|
||||||
// Implements ERC20
|
// Implements ERC20
|
||||||
uint256 public totalSupply;
|
|
||||||
// Implements ERC20
|
|
||||||
mapping (address => uint256) public balanceOf;
|
mapping (address => uint256) public balanceOf;
|
||||||
// Implements ERC20
|
// Implements ERC20
|
||||||
mapping (address => mapping (address => uint256)) public allowance;
|
mapping (address => mapping (address => uint256)) public allowance;
|
||||||
|
|
||||||
// timestamp when token contract expires
|
// Implements Burner
|
||||||
|
uint256 public totalMinted;
|
||||||
|
// Implements Burner
|
||||||
|
uint256 public burned;
|
||||||
|
|
||||||
|
// Implements expire
|
||||||
uint256 public expires;
|
uint256 public expires;
|
||||||
bool expired;
|
bool expired;
|
||||||
|
|
||||||
|
// Implements ERC20
|
||||||
event Transfer(address indexed _from, address indexed _to, uint256 _value);
|
event Transfer(address indexed _from, address indexed _to, uint256 _value);
|
||||||
|
// Implements ERC20
|
||||||
event TransferFrom(address indexed _from, address indexed _to, address indexed _spender, uint256 _value);
|
event TransferFrom(address indexed _from, address indexed _to, address indexed _spender, uint256 _value);
|
||||||
|
// Implements ERC20
|
||||||
event Approval(address indexed _owner, address indexed _spender, uint256 _value);
|
event Approval(address indexed _owner, address indexed _spender, uint256 _value);
|
||||||
|
|
||||||
|
// Implements Minter
|
||||||
event Mint(address indexed _minter, address indexed _beneficiary, uint256 _value);
|
event Mint(address indexed _minter, address indexed _beneficiary, uint256 _value);
|
||||||
|
|
||||||
|
// Implement Expire
|
||||||
event Expired(uint256 _timestamp);
|
event Expired(uint256 _timestamp);
|
||||||
|
|
||||||
|
// Implements Writer
|
||||||
|
event WriterAdded(address _writer);
|
||||||
|
// Implements Writer
|
||||||
|
event WriterRemoved(address _writer);
|
||||||
|
|
||||||
|
// Implements Burner
|
||||||
|
event Burn(uint256 _value);
|
||||||
|
|
||||||
constructor(string memory _name, string memory _symbol, uint8 _decimals, uint256 _expireTimestamp) public {
|
constructor(string memory _name, string memory _symbol, uint8 _decimals, uint256 _expireTimestamp) public {
|
||||||
owner = msg.sender;
|
owner = msg.sender;
|
||||||
name = _name;
|
name = _name;
|
||||||
symbol = _symbol;
|
symbol = _symbol;
|
||||||
decimals = _decimals;
|
decimals = _decimals;
|
||||||
minters[msg.sender] = true;
|
|
||||||
expires = _expireTimestamp;
|
expires = _expireTimestamp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Implements ERC20
|
||||||
|
function totalSupply() public returns (uint256) {
|
||||||
|
return totalMinted - burned;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Implements Minter
|
||||||
|
mapping(address => bool) writers;
|
||||||
function mintTo(address _to, uint256 _value) public returns (bool) {
|
function mintTo(address _to, uint256 _value) public returns (bool) {
|
||||||
require(minters[msg.sender] || msg.sender == owner);
|
require(writers[msg.sender] || msg.sender == owner);
|
||||||
|
|
||||||
balanceOf[_to] += _value;
|
balanceOf[_to] += _value;
|
||||||
totalSupply += _value;
|
totalMinted += _value;
|
||||||
|
|
||||||
emit Mint(msg.sender, _to, _value);
|
emit Mint(msg.sender, _to, _value);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Implements Writer
|
||||||
function addWriter(address _minter) public returns (bool) {
|
function addWriter(address _minter) public returns (bool) {
|
||||||
require(msg.sender == owner);
|
require(msg.sender == owner);
|
||||||
|
|
||||||
minters[_minter] = true;
|
writers[_minter] = true;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Implements Writer
|
||||||
function removeWriter(address _minter) public returns (bool) {
|
function removeWriter(address _minter) public returns (bool) {
|
||||||
require(msg.sender == owner || msg.sender == _minter);
|
require(msg.sender == owner || msg.sender == _minter);
|
||||||
|
|
||||||
minters[_minter] = false;
|
writers[_minter] = false;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Implements Writer
|
||||||
function isWriter(address _minter) public view returns(bool) {
|
function isWriter(address _minter) public view returns(bool) {
|
||||||
return minters[_minter] || _minter == owner;
|
return writers[_minter] || _minter == owner;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Implements Expire
|
||||||
function applyExpiry() public returns(uint8) {
|
function applyExpiry() public returns(uint8) {
|
||||||
if (expires == 0) {
|
if (expires == 0) {
|
||||||
return 0;
|
return 0;
|
||||||
@ -97,6 +128,17 @@ contract GiftableToken {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Implements Burner
|
||||||
|
function burn(uint256 _value) public returns (bool) {
|
||||||
|
require(msg.sender == owner, 'ERR_ACCESS');
|
||||||
|
require(balanceOf[msg.sender] >= _value, 'ERR_FUNDS');
|
||||||
|
|
||||||
|
balanceOf[msg.sender] -= _value;
|
||||||
|
burned += _value;
|
||||||
|
|
||||||
|
emit Burn(_value);
|
||||||
|
}
|
||||||
|
|
||||||
// Implements ERC20
|
// Implements ERC20
|
||||||
function transferFrom(address _from, address _to, uint256 _value) public returns (bool) {
|
function transferFrom(address _from, address _to, uint256 _value) public returns (bool) {
|
||||||
require(applyExpiry() == 0);
|
require(applyExpiry() == 0);
|
||||||
@ -140,6 +182,12 @@ contract GiftableToken {
|
|||||||
if (_sum == 0x9493f8b2) { // EIP173
|
if (_sum == 0x9493f8b2) { // EIP173
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
if (_sum == 0xabe1f1f5) { // Writer
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (_sum == 0xfccc2e79) { // Burner
|
||||||
|
return true;
|
||||||
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user