Add approve, transferfrom

This commit is contained in:
nolash 2021-02-05 09:22:36 +01:00
parent d795a77deb
commit 179e25adff
Signed by: lash
GPG Key ID: 21D2E7BB88C2A746
2 changed files with 65 additions and 10 deletions

View File

@ -45,7 +45,7 @@ class Test(unittest.TestCase):
provider = web3.Web3.EthereumTesterProvider(self.eth_tester)
self.w3 = web3.Web3(provider)
c = self.w3.eth.contract(abi=self.abi, bytecode=self.bytecode)
tx_hash = c.constructor('Foo Token', 'FOO', TAX_LEVEL, PERIOD).transact({'from': self.w3.eth.accounts[0]})
tx_hash = c.constructor('Foo Token', 'FOO', 6, TAX_LEVEL, PERIOD).transact({'from': self.w3.eth.accounts[0]})
r = self.w3.eth.getTransactionReceipt(tx_hash)
self.contract = self.w3.eth.contract(abi=self.abi, address=r.contractAddress)
@ -56,14 +56,12 @@ class Test(unittest.TestCase):
pass
@unittest.skip('test')
def test_hello(self):
self.assertEqual(self.contract.functions.actualPeriod().call(), 1)
self.eth_tester.mine_blocks(PERIOD)
self.assertEqual(self.contract.functions.actualPeriod().call(), 2)
@unittest.skip('test')
def test_mint(self):
tx_hash = self.contract.functions.mintTo(self.w3.eth.accounts[1], 1024).transact()
r = self.w3.eth.getTransactionReceipt(tx_hash)
@ -101,7 +99,32 @@ class Test(unittest.TestCase):
self.assertEqual(r.status, 1)
logg.debug('tx {}'.format(r))
@unittest.skip('test')
def test_transfer_from(self):
tx_hash = self.contract.functions.mintTo(self.w3.eth.accounts[1], 1024).transact()
r = self.w3.eth.getTransactionReceipt(tx_hash)
self.assertEqual(r.status, 1)
tx_hash = self.contract.functions.approve(self.w3.eth.accounts[2], 500).transact({'from': self.w3.eth.accounts[1]})
r = self.w3.eth.getTransactionReceipt(tx_hash)
self.assertEqual(r.status, 1)
logg.debug('tx {}'.format(r))
balance_alice = self.contract.functions.balanceOf(self.w3.eth.accounts[1]).call()
self.assertEqual(balance_alice, 1024)
tx_hash = self.contract.functions.transferFrom(self.w3.eth.accounts[1], self.w3.eth.accounts[3], 500).transact({'from': self.w3.eth.accounts[2]})
r = self.w3.eth.getTransactionReceipt(tx_hash)
self.assertEqual(r.status, 1)
logg.debug('tx {}'.format(r))
balance_alice = self.contract.functions.balanceOf(self.w3.eth.accounts[1]).call()
self.assertEqual(balance_alice, 524)
balance_alice = self.contract.functions.balanceOf(self.w3.eth.accounts[3]).call()
self.assertEqual(balance_alice, 500)
def test_apply_tax(self):
self.eth_tester.mine_blocks(PERIOD)
tx_hash = self.contract.functions.applyTax().transact()
@ -116,7 +139,6 @@ class Test(unittest.TestCase):
self.assertEqual(self.contract.functions.demurrageModifier().call(), 960400)
@unittest.skip('test')
def test_tax_balance(self):
tx_hash = self.contract.functions.mintTo(self.w3.eth.accounts[1], 1000).transact()
r = self.w3.eth.getTransactionReceipt(tx_hash)
@ -131,7 +153,6 @@ class Test(unittest.TestCase):
self.assertEqual(balance, 980)
@unittest.skip('test')
def test_taxed_transfer(self):
tx_hash = self.contract.functions.mintTo(self.w3.eth.accounts[1], 1000000).transact()
r = self.w3.eth.getTransactionReceipt(tx_hash)

View File

@ -17,8 +17,9 @@ contract RedistributedDemurrageToken {
uint256 public demurrageModifier; // PPM
bytes32[] public redistributions; // uint1(usedDustSink) | uint1(isFractional) | uint38(participants) | uint160(value) | uint56(period)
mapping (address => bytes32) account; // uint12(period) | uint160(value)
mapping (address => bytes32) account; // uint20(unused) | uint56(period) | uint160(value)
mapping (address => bool) minter;
mapping (address => mapping (address => uint256 ) ) allowance; // holder -> spender -> amount (amount is subject to demurrage)
event Transfer(address indexed _from, address indexed _to, uint256 _value);
event Approval(address indexed _owner, address indexed _spender, uint256 _value);
@ -27,7 +28,7 @@ contract RedistributedDemurrageToken {
event Taxed(uint256 indexed _period);
event Redistribution(address indexed _account, uint256 indexed _period, uint256 _value);
constructor(string memory _name, string memory _symbol, uint32 _taxLevel, uint256 _period) {
constructor(string memory _name, string memory _symbol, uint8 _decimals, uint32 _taxLevel, uint256 _period) {
owner = msg.sender;
minter[owner] = true;
periodStart = block.number;
@ -35,7 +36,7 @@ contract RedistributedDemurrageToken {
taxLevel = _taxLevel;
name = _name;
symbol = _symbol;
decimals = 6;
decimals = _decimals;
demurrageModifier = 1000000;
bytes32 initialRedistribution = toRedistribution(0, 0, 1);
redistributions.push(initialRedistribution);
@ -250,6 +251,11 @@ contract RedistributedDemurrageToken {
return true;
}
// Inflates the given amount according to the current demurrage modifier
function toBaseAmount(uint256 _value) public view returns (uint256) {
return (_value * 1000000) / demurrageModifier;
}
// ERC20, triggers tax and/or redistribution
function transfer(address _to, uint256 _value) public returns (bool) {
uint256 baseValue;
@ -259,7 +265,7 @@ contract RedistributedDemurrageToken {
applyRedistributionOnAccount(msg.sender);
// TODO: Prefer to truncate the result, instead it seems to round to nearest :/
baseValue = (_value * 1000000) / demurrageModifier;
baseValue = toBaseAmount(_value);
result = transferBase(msg.sender, _to, baseValue);
return result;
@ -281,4 +287,32 @@ contract RedistributedDemurrageToken {
}
return true;
}
// ERC20, triggers tax and/or redistribution
function transferFrom(address _from, address _to, uint256 _value) public returns (bool) {
uint256 baseValue;
bool result;
applyTax();
applyRedistributionOnAccount(msg.sender);
baseValue = toBaseAmount(_value);
require(allowance[_from][msg.sender] >= baseValue);
result = transferBase(_from, _to, baseValue);
return result;
}
// ERC20, triggers tax and/or redistribution
function approve(address _spender, uint256 _value) public returns (bool) {
uint256 baseValue;
applyTax();
applyRedistributionOnAccount(msg.sender);
baseValue = toBaseAmount(_value);
allowance[msg.sender][_spender] += baseValue;
emit Approval(msg.sender, _spender, _value);
return true;
}
}