/
test_company.py
131 lines (110 loc) · 5.11 KB
/
test_company.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
import pytest
from ethereum.tools import tester as t
from vyper import compiler
@pytest.fixture
def tester():
tester = t
tester.s = t.Chain()
tester.s.head_state.gas_limit = 10**9
tester.languages['vyper'] = compiler.Compiler()
contract_code = open('examples/stock/company.v.py').read()
tester.company_address = t.a0
# Company with 1000 shares @ 10^6 wei / share
tester.c = tester.s.contract(contract_code, language='vyper',
args=[tester.company_address, 1000, 10**6])
return tester
def test_overbuy(tester, assert_tx_failed):
# If all the stock has been bought, no one can buy more
test_shares = int(tester.c.get_total_shares() / 2)
test_value = int(test_shares * tester.c.get_price())
tester.c.buy_stock(sender=t.k1, value=test_value)
tester.c.buy_stock(sender=t.k1, value=test_value)
assert tester.c.stock_available() == 0
assert tester.c.get_holding(t.a1) == (test_shares * 2)
one_stock = tester.c.get_price()
assert_tx_failed(lambda: tester.c.buy_stock(sender=t.k1, value=one_stock))
assert_tx_failed(lambda: tester.c.buy_stock(sender=t.k2, value=one_stock))
def test_sell_without_stock(tester, assert_tx_failed):
# If you don't have any stock, you can't sell
assert_tx_failed(lambda: tester.c.sell_stock(1, sender=t.k1))
assert_tx_failed(lambda: tester.c.sell_stock(1, sender=t.k2))
# Negative stock doesn't work either
assert_tx_failed(lambda: tester.c.sell_stock(-1, sender=t.k1))
# But if you do, you can!
test_shares = int(tester.c.get_total_shares())
test_value = int(test_shares * tester.c.get_price())
tester.c.buy_stock(sender=t.k1, value=test_value)
assert tester.c.get_holding(t.a1) == test_shares
tester.c.sell_stock(test_shares, sender=t.k1)
# But only until you run out
assert_tx_failed(lambda: tester.c.sell_stock(1, sender=t.k1))
def test_oversell(tester, assert_tx_failed):
# You can't sell more than you own
test_shares = int(tester.c.get_total_shares())
test_value = int(test_shares * tester.c.get_price())
tester.c.buy_stock(sender=t.k1, value=test_value)
assert_tx_failed(lambda: tester.c.sell_stock(test_shares + 1, sender=t.k1))
def test_transfer(tester, assert_tx_failed):
# If you don't have any stock, you can't transfer
assert_tx_failed(lambda: tester.c.transfer_stock(t.a2, 1, sender=t.k1))
assert_tx_failed(lambda: tester.c.transfer_stock(t.a1, 1, sender=t.k2))
# You can't do negative transfers to gain stock
assert_tx_failed(lambda: tester.c.transfer_stock(t.a2, -1, sender=t.k1))
# If you transfer, you don't have the stock anymore
test_shares = int(tester.c.get_total_shares())
test_value = int(test_shares * tester.c.get_price())
tester.c.buy_stock(sender=t.k1, value=test_value)
assert tester.c.get_holding(t.a1) == test_shares
tester.c.transfer_stock(t.a2, test_shares, sender=t.k1)
assert_tx_failed(lambda: tester.c.sell_stock(1, sender=t.k1))
# But the other person does
tester.c.sell_stock(test_shares, sender=t.k2)
def test_paybill(tester, assert_tx_failed):
# Only the company can authorize payments
assert_tx_failed(lambda: tester.c.pay_bill(t.a2, 1, sender=t.k1))
# A company can only pay someone if it has the money
assert_tx_failed(lambda: tester.c.pay_bill(t.a2, 1, sender=t.k0))
# If it has the money, it can pay someone
test_value = int(tester.c.get_total_shares() * tester.c.get_price())
tester.c.buy_stock(sender=t.k1, value=test_value)
tester.c.pay_bill(t.a2, test_value, sender=t.k0)
# Until it runs out of money
assert_tx_failed(lambda: tester.c.pay_bill(t.a3, 1, sender=t.k0))
# Then no stockholders can sell their stock either
assert_tx_failed(lambda: tester.c.sell_stock(1, sender=t.k1))
def test_valuation(tester):
# Valuation is number of shares held times price
assert tester.c.debt() == 0
test_value = int(tester.c.get_total_shares() * tester.c.get_price())
tester.c.buy_stock(sender=t.k1, value=test_value)
assert tester.c.debt() == test_value
def test_logs(tester, get_logs):
# Buy is logged
tester.c.buy_stock(sender=t.k1, value=7 * tester.c.get_price())
receipt = tester.s.head_state.receipts[-1]
logs = get_logs(receipt, tester.c)
assert len(logs) == 1
assert logs[0]["_event_type"] == b'Buy'
assert logs[0]["_buy_order"] == 7
# Sell is logged
tester.c.sell_stock(3, sender=t.k1)
receipt = tester.s.head_state.receipts[-1]
logs = get_logs(receipt, tester.c)
assert len(logs) == 1
assert logs[0]["_event_type"] == b'Sell'
assert logs[0]["_sell_order"] == 3
# Transfer is logged
tester.c.transfer_stock(t.a2, 4, sender=t.k1)
receipt = tester.s.head_state.receipts[-1]
logs = get_logs(receipt, tester.c)
assert len(logs) == 1
assert logs[0]["_event_type"] == b'Transfer'
assert logs[0]["_value"] == 4
# Pay is logged
amount = 10**4
tester.c.pay_bill(t.a3, amount)
receipt = tester.s.head_state.receipts[-1]
logs = get_logs(receipt, tester.c)
assert len(logs) == 1
assert logs[0]["_event_type"] == b'Pay'
assert logs[0]["_amount"] == amount